From e425d768dd0a1145dddd9612cc4b5d9aa5d741a7 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 7 Apr 2021 09:41:39 -0700 Subject: [PATCH 001/106] Remove owner guard from analytics (#8842) --- src/panels/config/core/ha-config-analytics.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/panels/config/core/ha-config-analytics.ts b/src/panels/config/core/ha-config-analytics.ts index b582b5ed5e..26a2515e2f 100644 --- a/src/panels/config/core/ha-config-analytics.ts +++ b/src/panels/config/core/ha-config-analytics.ts @@ -33,10 +33,6 @@ class ConfigAnalytics extends LitElement { @internalProperty() private _error?: string; protected render(): TemplateResult { - if (!this.hass.user?.is_owner) { - return html``; - } - const error = this._error ? this._error : !isComponentLoaded(this.hass, "analytics") From 4b1d7863f8d84383fc0a6d0e9167a87385b7a198 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 8 Apr 2021 00:48:34 +0000 Subject: [PATCH 002/106] Translation update --- translations/frontend/bg.json | 41 +++++++--- translations/frontend/ca.json | 21 +++--- translations/frontend/cs.json | 23 ++++-- translations/frontend/de.json | 39 ++++++---- translations/frontend/en.json | 16 ++-- translations/frontend/es.json | 51 ++++++------- translations/frontend/et.json | 15 ++-- translations/frontend/it.json | 23 ++++-- translations/frontend/ko.json | 9 +++ translations/frontend/nb.json | 23 ++++-- translations/frontend/nl.json | 3 +- translations/frontend/pl.json | 15 ++-- translations/frontend/ru.json | 115 ++++++++++++++++------------- translations/frontend/sk.json | 9 ++- translations/frontend/sv.json | 17 +++++ translations/frontend/zh-Hant.json | 23 ++++-- 16 files changed, 272 insertions(+), 171 deletions(-) diff --git a/translations/frontend/bg.json b/translations/frontend/bg.json index e1a2fcb6fe..93080df54b 100644 --- a/translations/frontend/bg.json +++ b/translations/frontend/bg.json @@ -304,8 +304,8 @@ "text": "Искате ли да рестартирате добавката с вашите промени?" }, "update": { - "create_snapshot": "Създаване на снапшот на {name} преди актуализиране", - "snapshot": "Снапшот", + "create_snapshot": "Създаване на моментна снимка на {name} преди актуализиране", + "snapshot": "Моментна снимка", "snapshotting": "Създава се моментна снимка на {name}", "updating": "Актуализиране на {name} до версия {version}" } @@ -317,17 +317,18 @@ }, "panel": { "dashboard": "Табло", - "snapshots": "Снапшоти", + "snapshots": "Моментни снимки", "store": "Хранилище за добавки", "system": "Система" }, "snapshot": { "addons": "Добавки", - "available_snapshots": "Налични Снапшоти", - "could_not_create": "Не можа да се създаде снапшот", + "available_snapshots": "Налични системни снимки", + "could_not_create": "Не можа да се създаде моментна снимка", "create": "Създаване", - "create_snapshot": "Създаване на снапшот", - "description": "Снапшотите ви позволяват лесно да архивирате и възстановявате всички данни от вашия екземпляр на Home Assistant.", + "create_blocked_not_running": "Създаването на моментна снимка в момента не е възможно, тъй като системата е в състояние {state}.", + "create_snapshot": "Създаване на моментна снимка", + "description": "Моментните снимки Ви позволяват лесно да архивирате и възстановявате всички данни от вашия екземпляр на Home Assistant.", "enter_password": "Моля, въведете парола.", "folder": { "addons/local": "Локални добавки", @@ -337,16 +338,16 @@ "ssl": "SSL" }, "folders": "Папки", - "full_snapshot": "Пълен снапшот", + "full_snapshot": "Пълена моментна снимка", "name": "Име", - "no_snapshots": "Все още нямате снапшоти", - "partial_snapshot": "Частичен снапшот", + "no_snapshots": "Все още нямате моментни снимки", + "partial_snapshot": "Частичена моментна снимка", "password": "Парола", "password_protected": "защитен с парола", "password_protection": "Защита с парола", "security": "Сигурност", "type": "Тип", - "upload_snapshot": "Качване на снапшот" + "upload_snapshot": "Качване на моментна снимка" }, "store": { "missing_addons": "Липсват добавки? Активирайте разширения режим в страницата на потребителския си профил", @@ -1063,6 +1064,11 @@ "error_detected": "Открити са грешки в конфигурацията", "key_missing": "Липсва задължителният ключ \"{key}\".", "no_template_editor_support": "Шаблоните не се поддържат във визуалния редактор" + }, + "supervisor": { + "ask": "Помолете за помощ", + "reboot": "Опитайте да рестартирате хоста", + "system_health": "Проверете здравето на системата" } }, "login-form": { @@ -1511,6 +1517,7 @@ "integrations_introduction2": "Проверете уебсайта за", "integrations_link_all_features": "всички налични функции", "manage_account": "Управление на акаунта", + "nabu_casa_account": "Акаунт в Nabu Casa", "not_connected": "Не е свързан", "remote": { "certificate_info": "Информация за сертификата", @@ -1609,6 +1616,7 @@ "feature_google_home": "Интеграция с Google Assistant", "feature_webhook_apps": "Лесна интеграция с базирани на webhook приложения като OwnTracks", "headline": "Започнете безплатния си пробен период", + "information2": "Пробният период ще ви даде достъп до всички предимства на Home Assistant Cloud, включително:", "information3": "Тази услуга се управлява от нашия партньор", "information3a": ", компания основана от основателите на Home Assistant и Hass.io.", "link_privacy_policy": "Политика за поверителност", @@ -1616,6 +1624,7 @@ "password": "Парола", "password_error_msg": "Паролите са най-малко 8 знака", "resend_confirm_email": "Повторно изпращане на имейл за потвърждение", + "start_trial": "Започнете пробен период", "title": "Регистриране на акаунт" } }, @@ -1774,6 +1783,7 @@ "confirm_title": "Искате ли да забраните {number} {number, plural,\n one {обект}\n other {обекта}\n}?" }, "enable_selected": { + "button": "Активиране на избраните", "confirm_title": "Искате ли да разрешите {number} {number, plural,\n one {обект}\n other {обекта}\n}?" }, "filter": { @@ -1798,6 +1808,7 @@ "confirm_title": "Искате ли да премахнете {number} {number, plural,\n one {обект}\n other {обекта}\n}?" }, "search": "Търсене на обекти", + "selected": "{number} избрани", "status": { "ok": "ДА", "readonly": "Само за четене", @@ -2139,6 +2150,7 @@ "id_already_exists_save_error": "Не можете да запазите този скрипт, защото идентификаторът не е уникален, изберете друг идентификатор или го оставете празен, за да се генерира автоматично.", "introduction": "Използвайте скриптове за изпълнение на последователност от действия.", "link_available_actions": "Научете повече за наличните действия.", + "load_error_not_editable": "Само скриптове в scripts.yaml са редактируеми.", "modes": { "label": "Режим", "parallel": "Паралелно", @@ -2446,6 +2458,7 @@ "column_description": "Описание", "column_example": "Пример", "column_parameter": "Параметър", + "no_template_ui_support": "Потребителският интерфейс не поддържа шаблони, все още можете да използвате YAML редактора.", "title": "Услуги", "yaml_parameters": "Параметрите са налични само в YAML режим" }, @@ -2674,6 +2687,9 @@ "name": "Карта", "source": "Източник" }, + "markdown": { + "content": "Съдържание" + }, "media-control": { "description": "Картата за управление на плейърите се използва за показване на обекти на мултимедийния плейър в интерфейс с лесни за използване контроли.", "name": "Управление на плейърите" @@ -3132,7 +3148,8 @@ "decimal_comma": "1.234.567,89", "language": "Авто (изп. езикова настройка)", "none": "Без", - "space_comma": "1 234 567,89" + "space_comma": "1 234 567,89", + "system": "Изп. системната настройка" }, "header": "Формат на числата" }, diff --git a/translations/frontend/ca.json b/translations/frontend/ca.json index 28c77a96bf..01765e17de 100644 --- a/translations/frontend/ca.json +++ b/translations/frontend/ca.json @@ -473,6 +473,7 @@ "unhealthy_title": "La teva instal·lació no és bona", "unsupported_description": "A continuació es mostra una llista de problemes relacionats amb la instal·lació, fes clic als enllaços per obtenir informació sobre com resoldre'ls.", "unsupported_reason": { + "apparmor": "AppArmor no està habilitat a l'amfitrió", "container": "Els contenidors són coneguts per causar problemes", "content-trust": "Validació de continguts de confiança desactivada", "dbus": "DBUS", @@ -1872,28 +1873,28 @@ "documentation": "Abans d'activar això, revisa't la documentació d'anàlisi a {link}, per entendre el què s'enviarà i com s'emmagatzemarà.", "header": "Dades analítiques", "instance_id": "ID de la instància: {huuid}", - "introduction": "Comparteix dades analítiques de la teva instància. Aquestes dades estaran disponibles públicament a {link}", - "learn_more": "Més informació sobre com les teves dades es processaran.", + "introduction": "Comparteix informació de la teva instal·lació per ajudar a millorar Home Assistant i ajudar-nos a convèncer als fabricants perquè afegeixin control local i funcions centrades en la privadesa.", + "learn_more": "Com processem les teves dades", "needs_base": "Has d'habilitar l'anàlisi bàsica perquè aquesta opció estigui disponible", "preference": { "base": { - "description": "Inclou l'ID de la instància, la versió i el tipus d'instal·lació", + "description": "ID de la instància, versió i tipus d'instal·lació.", "title": "Anàlisi bàsica" }, "diagnostics": { - "description": "Comparteix informes d'errors i informació de diagnòstic", + "description": "Comparteix informes d'error quan es produeixin errors inesperats.", "title": "Diagnòstics" }, "statistics": { - "description": "Això inclou un seguit d'elements de la teva instal·lació. Per obtenir-ne una llista completa, consulta la documentació", + "description": "Nombre total d'entitats utilitzades, usuaris i altres elements.", "title": "Estadístiques d’ús" }, "usage_supervisor": { - "description": "Inclou els noms i funcionalitats de les teves integracions i complements", + "description": "Noms, versions i funcionalitats.", "title": "Integracions i complements utilitzats" }, "usage": { - "description": "Inclou els noms de les teves integracions", + "description": "Noms i informació de versió.", "title": "Integracions utilitzades" } } @@ -2259,7 +2260,7 @@ "debug": "DEPURACIÓ", "error": "ERROR", "info": "INFO", - "warning": "ADVERTÈNCIA" + "warning": "ALERTA" }, "load_full_log": "Carrega el registre complet de Home Assistant", "loading_log": "Carregant el registre d'errors...", @@ -3874,7 +3875,7 @@ }, "number_format": { "description": "Trieu el format dels números.", - "dropdown_label": "Format de número", + "dropdown_label": "Format dels números", "formats": { "comma_decimal": "1,234,567.89", "decimal_comma": "1.234.567,89", @@ -3883,7 +3884,7 @@ "space_comma": "1 234 567,89", "system": "Utilitza la configuració regional del sistema" }, - "header": "Format de número" + "header": "Format dels números" }, "push_notifications": { "add_device_prompt": { diff --git a/translations/frontend/cs.json b/translations/frontend/cs.json index fe960aad20..6d11f9fc69 100644 --- a/translations/frontend/cs.json +++ b/translations/frontend/cs.json @@ -473,6 +473,7 @@ "unhealthy_title": "Instalace není v pořádku", "unsupported_description": "Níže je uveden seznam problémů nalezených ve vaší instalaci. Kliknutím na odkazy se dozvíte, jak tyto problémy vyřešit.", "unsupported_reason": { + "apparmor": "AppArmor není na hostiteli povolen", "container": "Kontejnery, o nichž je známo, že způsobují problémy", "content-trust": "Ověřování důvěryhodnosti obsahu je zakázáno.", "dbus": "DBUS", @@ -1213,6 +1214,14 @@ "key_wrong_type": "Zadávanou hodnotu \"{key}\" nepodporuje vizuální editor. Podporuje ({type_correct}), ale obdržel ({type_wrong}).", "no_template_editor_support": "Šablony nejsou podporovány v uživatelském rozhraní", "no_type_provided": "Není k dispozici žádný typ." + }, + "supervisor": { + "ask": "Požádat o pomoc", + "observer": "Zkontrolovat Observer", + "reboot": "Zkuste restartovat hostitele", + "system_health": "Kontrola stavu systému", + "title": "Nelze načíst panel Supervisora!", + "wait": "Pokud jste právě začali, ujistěte se, že jste poskytli dostatek času na start Supervisora." } }, "login-form": { @@ -1864,28 +1873,28 @@ "documentation": "Před povolením této možnosti se ujistěte, že jste navštívili stránku dokumentace analytiky {link}, abyste pochopili, co odesíláte za data a jak budou uložena.", "header": "Analytika", "instance_id": "ID instance: {huuid}", - "introduction": "Sdílejte analytiku ze své instance. Tato data budou veřejně dostupná na {link}", - "learn_more": "Zjistěte více, jak budou vaše údaje zpracovány.", + "introduction": "Sdílejte informace o instalaci, abyste pomohli vylepšit Home Assistant a pomohli nám přesvědčit výrobce, aby přidali funkce místního ovládání a ochrany soukromí.", + "learn_more": "Jak budou vaše údaje zpracovány", "needs_base": "Aby byla tato možnost k dispozici, musíte povolit základní analytiku", "preference": { "base": { - "description": "To zahrnuje ID instance, verzi a typ instalace", + "description": "ID instance, verze a typ instalace.", "title": "Základní analytika" }, "diagnostics": { - "description": "Sdílet zprávy o selhání a diagnostické informace", + "description": "Sdílejte zprávy o selhání, když dojde k neočekávané chybě.", "title": "Diagnostika" }, "statistics": { - "description": "To zahrnuje počet prvků v instalaci, úplný seznam najdete v dokumentaci", + "description": "Celkový počet entit, uživatelů a dalších prvků.", "title": "Statistiky používání" }, "usage_supervisor": { - "description": "To zahrnuje názvy a možnosti vašich integrací a doplňků", + "description": "Názvy, verze a funkce.", "title": "Použité integrace a doplňky" }, "usage": { - "description": "To zahrnuje názvy vašich integrací", + "description": "Informace o názvech a verzích.", "title": "Použité integrace" } } diff --git a/translations/frontend/de.json b/translations/frontend/de.json index 15e999f66d..50ce985e6a 100644 --- a/translations/frontend/de.json +++ b/translations/frontend/de.json @@ -467,12 +467,15 @@ "docker": "Die Docker Umgebung arbeitet nicht fehlerfrei", "privileged": "Der Supervisor ist nicht berechtigt", "setup": "Die Einrichtung des Supervisors ist fehlgeschlagen", - "supervisor": "Supervisor konnte nicht aktualisiert werden" + "supervisor": "Supervisor konnte nicht aktualisiert werden", + "untrusted": "Nicht vertrauenswürdiger Inhalt erkannt" }, "unhealthy_title": "Deine Installation ist fehlerhaft", "unsupported_description": "Unten ist eine Liste der Probleme, die bei deiner Installation aufgetreten sind. Klicke auf die Links, um zu erfahren, wie du die Probleme beheben kannst.", "unsupported_reason": { + "apparmor": "AppArmor ist auf dem Host nicht aktiviert", "container": "Container, von denen bekannt ist, dass sie Probleme verursachen", + "content-trust": "Content-Trust-Validierung ist deaktiviert", "dbus": "DBUS", "docker_configuration": "Docker Konfiguration", "docker_version": "Docker Version", @@ -1218,7 +1221,7 @@ "reboot": "Versuche den Host neuzustarten", "system_health": "Überprüfe Systemzustand", "title": "Supervisor-Bedienfeld konnte nicht geladen werden!", - "wait": "Wenn du gerade erst hochgefahren hast, dann stelle sicher dass du den Supervisor genug Zeit zum Starten gegeben hast." + "wait": "Wenn du gerade erst hochgefahren hast, dann stelle sicher dass du dem Supervisor genug Zeit zum Starten gegeben hast." } }, "login-form": { @@ -1594,7 +1597,7 @@ "zone": "Zone" } }, - "unsupported_platform": "Nicht unterstützte Plattform: {platform}" + "unsupported_platform": "Visueller Editor nicht unterstützt für Plattform: {platform}" }, "unsaved_confirm": "Sie haben ungespeicherte Änderungen. Sind Sie sicher, dass Sie den Editor verlassen möchten?" }, @@ -1613,7 +1616,7 @@ }, "introduction": "Mit dem Automations-Editor können Automatisierungen erstellt und bearbeitet werden. Bitte folgen Sie dem nachfolgenden Link, um die Anleitung zu lesen und um sicherzustellen, dass Sie Home Assistant richtig konfiguriert haben.", "learn_more": "Erfahre mehr über Automatisierungen", - "no_automations": "Wir konnten keine editierbaren Automatisierungen finden", + "no_automations": "Wir konnten keine Automatisierungen finden", "only_editable": "Nur Automatisierungen in automations.yaml sind editierbar.", "pick_automation": "Wähle eine Automatisierung zum Bearbeiten", "show_info_automation": "Informationen über die Automatisierung anzeigen" @@ -1870,28 +1873,28 @@ "documentation": "Bevor du dies aktivierst, stelle sicher, dass du die Statistikdokumentationsseite {link} besuchst, um zu verstehen, was gesendet und gespeichert wird.", "header": "Statistiken", "instance_id": "Instanz-ID: {huuid}", - "introduction": "Teile Statistiken aus deiner Instanz. Diese Daten werden öffentlich verfügbar sein unter {link}", - "learn_more": "Erfahre mehr darüber, wie deine Daten verarbeitet werden.", + "introduction": "Teile deine Installationsinformationen, um Home Assistant zu verbessern und Hersteller davon zu überzeugen, lokale Steuerungs- und Datenschutzfunktionen hinzuzufügen.", + "learn_more": "Wie werden deine Daten verarbeitet", "needs_base": "Du musst die Basisstatistiken aktivieren, damit diese Option verfügbar ist", "preference": { "base": { - "description": "Dies umfasst die Instanz-ID, die Version und den Installationstyp", + "description": "Instanz-ID, Version und Installationstyp.", "title": "Grundlegende Statistiken" }, "diagnostics": { - "description": "Teile Absturzberichte und Diagnoseinformationen", + "description": "Teile Absturzberichte, wenn unerwartete Fehler auftreten.", "title": "Diagnoseinformationen" }, "statistics": { - "description": "Dies umfasst die Anzahl von Elementen in deiner Installation. Eine vollständige Liste findest du in der Dokumentation", + "description": "Anzahl verwendeter Entitäten, Benutzer und anderer Elemente.", "title": "Nutzungsstatistiken" }, "usage_supervisor": { - "description": "Dies umfasst die Namen und Funktionen deiner Integrationen und Add-ons", + "description": "Namen, Versionen und Funktionen.", "title": "Verwendete Integrationen und Add-ons" }, "usage": { - "description": "Dies umfasst die Namen deiner Integrationen", + "description": "Namen und Versionsinformationen.", "title": "Verwendete Integrationen" } } @@ -2244,7 +2247,7 @@ "reconfigure": "Neu konfigurieren", "rename_dialog": "Bearbeite den Namen dieses Konfigurationseintrags", "rename_input_label": "Eintragsname", - "search": "Such-Integrationen" + "search": "Integrationen suchen" }, "introduction": "Hier ist es möglich, deine Komponenten und Home Assistant zu konfigurieren. Noch ist nicht alles über die GUI einstellbar, aber wir arbeiten daran.", "logs": { @@ -2262,7 +2265,7 @@ "load_full_log": "Vollständiges Home Assistant-Protokoll laden", "loading_log": "Fehlerprotokoll wird geladen...", "multiple_messages": "Die Nachricht ist zum ersten Mal um {time} aufgetreten und erscheint {counter} mal", - "no_errors": "Es wurden keine Fehler gemeldet.", + "no_errors": "Es wurden keine Fehler gemeldet", "no_issues": "Es gibt keine neuen Probleme!", "refresh": "Aktualisieren" }, @@ -2543,7 +2546,7 @@ }, "introduction": "Mit dem Szeneneditor können Szenen erstellt und bearbeitet werden. Bitte folge dem untenstehenden Link, um die Anleitung zu finden. Dies stellt sicher, dass Home Assistant korrekt konfiguriert ist.", "learn_more": "Erfahre mehr über Szenen.", - "no_scenes": "Wir konnten keine editierbaren Szenen finden", + "no_scenes": "Wir konnten keine Szenen finden", "only_editable": "Nur Szenen in der scenes.yaml sind editierbar.", "pick_scene": "Wähle eine Szene zum Bearbeiten aus.", "show_info_scene": "Informationen über die Szene anzeigen" @@ -2593,7 +2596,7 @@ }, "introduction": "Mit dem Skript-Editor können Skripte erstellt und bearbeitet werden. Bitte folge dem untenstehenden Link, um die Anleitung zu finden. Das stellt sicher, dass Home Assistant richtig konfiguriert ist.", "learn_more": "Weitere Informationen zu Skripten", - "no_scripts": "Wir konnten keine bearbeitbaren Skripte finden", + "no_scripts": "Wir konnten keine Skripte finden", "run_script": "Skript ausführen", "show_info": "Informationen zum Skript anzeigen" } @@ -3874,8 +3877,12 @@ "description": "Wähle aus, wie Zahlen formatiert werden sollen.", "dropdown_label": "Zahlenformat", "formats": { + "comma_decimal": "1,234,567.89", + "decimal_comma": "1.234.567,89", "language": "Auto (Spracheinstellung verwenden)", - "none": "Keine" + "none": "Keine", + "space_comma": "1 234 567,89", + "system": "Systemeinstellungen verwenden" }, "header": "Zahlenformat" }, diff --git a/translations/frontend/en.json b/translations/frontend/en.json index 0ef42cb95c..9c59dfc713 100644 --- a/translations/frontend/en.json +++ b/translations/frontend/en.json @@ -1873,29 +1873,29 @@ "documentation": "Before you enable this make sure you visit the analytics documentation page {link} to understand what you are sending and how it's stored.", "header": "Analytics", "instance_id": "Instance ID: {huuid}", - "introduction": "Share analytics from your instance. This data will be publicly available at {link}", - "learn_more": "Learn more about how your data will be processed.", + "introduction": "Share your installation information to help make Home Assistant better and help us convince manufacturers to add local control and privacy-focused features.", + "learn_more": "How we process your data", "needs_base": "You need to enable base analytics for this option to be available", "preference": { "base": { - "description": "This includes the instance ID, the version and the installation type", + "description": "Instance ID, version and installation type.", "title": "Basic analytics" }, "diagnostics": { - "description": "Share crash reports and diagnostic information", + "description": "Share crash reports when unexpected errors occur.", "title": "Diagnostics" }, "statistics": { - "description": "This includes a count of elements in your installation, for a full list look at the documentation", + "description": "Total used entities, users and other elements.", "title": "Usage statistics" }, "usage_supervisor": { - "description": "This includes the names and capabilities of your integrations and add-ons", + "description": "Names, versions and capabilities.", "title": "Used integrations and add-ons" }, "usage": { - "description": "This includes the names of your integrations", - "title": "Used integrations" + "description": "Names and version information.", + "title": "Used Integrations" } } }, diff --git a/translations/frontend/es.json b/translations/frontend/es.json index cecc759715..933f3e43d1 100644 --- a/translations/frontend/es.json +++ b/translations/frontend/es.json @@ -277,7 +277,7 @@ }, "failed_to_restart_name": "No se pudo reiniciar {name}", "failed_to_update_name": "No se pudo actualizar {name}", - "learn_more": "Aprende más", + "learn_more": "Saber más", "new_version_available": "Nueva versión disponible", "newest_version": "Versión más reciente", "no": "No", @@ -473,6 +473,7 @@ "unhealthy_title": "Tu instalación está en mal estado", "unsupported_description": "A continuación se muestra una lista de problemas encontrados con tu instalación, haz clic en los enlaces para saber cómo puedes resolver los problemas.", "unsupported_reason": { + "apparmor": "AppArmor no está habilitado en el host", "container": "Contenedores conocidos por causar problemas", "content-trust": "La validación de contenido de confianza está deshabilitada", "dbus": "DBUS", @@ -819,7 +820,7 @@ "video": "Vídeo" }, "documentation": "documentación", - "learn_adding_local_media": "Aprende más sobre cómo añadir contenido multimedia en la {documentation}.", + "learn_adding_local_media": "Saber más sobre cómo añadir contenido multimedia en la {documentation}.", "local_media_files": "Coloca tus archivos de vídeo, audio e imagen en el directorio multimedia para poder navegar y reproducirlos en el navegador o en los reproductores compatibles.", "media_browsing_error": "Error de navegación de medios", "media_not_supported": "El Reproductor multimedia del navegador no es compatible con este tipo de medio", @@ -1303,7 +1304,7 @@ "duplicate": "Duplicar", "header": "Acciones", "introduction": "Las acciones son lo que hará Home Assistant cuando se desencadene la automatización.", - "learn_more": "Aprende más sobre las acciones.", + "learn_more": "Saber más sobre las acciones.", "name": "Acción", "type_select": "Tipo de acción", "type": { @@ -1395,7 +1396,7 @@ "duplicate": "Duplicar", "header": "Condiciones", "introduction": "Las condiciones son opcionales y evitarán que la automatización funcione a menos que se cumplan todas las condiciones.", - "learn_more": "Aprende más sobre las condiciones", + "learn_more": "Saber más sobre las condiciones", "name": "Condición", "type_select": "Tipo de condición", "type": { @@ -1502,7 +1503,7 @@ "duplicate": "Duplicar", "header": "Desencadenantes", "introduction": "Los desencadenantes son los que inician el funcionamiento de una regla de automatización. Es posible especificar varios desencadenantes para la misma regla. Una vez que se inicia un desencadenante, Home Assistant comprobará las condiciones, si las hubiere, y ejecutará la acción.", - "learn_more": "Aprende más sobre los desencadenantes", + "learn_more": "Saber más sobre los desencadenantes", "name": "Desencadenante", "type_select": "Tipo de desencadenante", "type": { @@ -1613,7 +1614,7 @@ "name": "Nombre" }, "introduction": "El editor de automatización te permite crear y editar automatizaciones. En el enlace siguiente puedes leer las instrucciones para asegurarte de que has configurado correctamente Home Assistant.", - "learn_more": "Aprende más sobre las automatizaciones", + "learn_more": "Saber más sobre las automatizaciones", "no_automations": "No pudimos encontrar ninguna automatización", "only_editable": "Solo las automatizaciones definidas en automations.yaml son editables.", "pick_automation": "Elije la automatización para editar", @@ -1667,7 +1668,7 @@ "name": "Nombre" }, "introduction": "La configuración de planos te permite importar y administrar tus planos.", - "learn_more": "Aprende más sobre el uso de planos", + "learn_more": "Saber más sobre el uso de planos", "share_blueprint": "Compartir plano", "share_blueprint_no_url": "No se puede compartir el plano: no hay URL de origen", "use_blueprint": "Crear automatización" @@ -1746,7 +1747,7 @@ "webhooks": { "disable_hook_error_msg": "No se pudo deshabilitar el webhook:", "info": "Cualquier cosa que esté configurada para ser activada por un webhook puede recibir una URL de acceso público para permitirte enviar datos a Home Assistant desde cualquier lugar, sin exponer tu instancia a Internet.", - "link_learn_more": "Aprende más sobre la creación de automatizaciones basadas en webhook.", + "link_learn_more": "Saber más sobre la creación de automatizaciones basadas en webhook.", "loading": "Cargando ...", "manage": "Administrar", "no_hooks_yet": "Parece que aún no tienes webhooks. Comienza configurando un", @@ -1825,7 +1826,7 @@ "introduction2": "Este servicio está a cargo de nuestro socio.", "introduction2a": ", una compañía fundada por los fundadores de Home Assistant y Hass.io.", "introduction3": "Home Assistant Cloud es un servicio de suscripción con una prueba gratuita de un mes. No se necesita información de pago.", - "learn_more_link": "Aprende más sobre Home Assistant Cloud", + "learn_more_link": "Saber más sobre Home Assistant Cloud", "password": "Contraseña", "password_error_msg": "Las contraseñas tienen al menos 8 caracteres.", "sign_in": "Inicia sesión", @@ -1871,28 +1872,28 @@ "documentation": "Antes de habilitar esto, asegúrate de visitar la página de documentación de análisis {link} para comprender qué estás enviando y cómo se almacena.", "header": "Analítica", "instance_id": "ID de instancia: {huuid}", - "introduction": "Comparte análisis de tu instancia. Estos datos estarán disponibles públicamente en {link}", - "learn_more": "Aprende más sobre cómo se procesarán tus datos.", + "introduction": "Comparte la información de tu instalación para ayudar a mejorar Home Assistant y ayudarnos a convencer a los fabricantes de que agreguen funciones de control local y centradas en la privacidad.", + "learn_more": "Cómo tratamos tus datos", "needs_base": "Debes habilitar el análisis base para que esta opción esté disponible", "preference": { "base": { - "description": "Esto incluye el ID de la instancia, la versión y el tipo de instalación.", + "description": "ID de instancia, versión y tipo de instalación.", "title": "Analítica básica" }, "diagnostics": { - "description": "Comparte informes de fallos e información de diagnóstico", + "description": "Comparte informes de fallos cuando se produzcan errores inesperados.", "title": "Diagnósticos" }, "statistics": { - "description": "Esto incluye un recuento de elementos en tu instalación, para obtener una lista completa, consulta la documentación", + "description": "Total de entidades, usuarios y otros elementos utilizados.", "title": "Estadísticas de uso" }, "usage_supervisor": { - "description": "Esto incluye los nombres y las capacidades de tus integraciones y complementos.", + "description": "Nombres, versiones y capacidades.", "title": "Integraciones y complementos utilizados" }, "usage": { - "description": "Esto incluye los nombres de tus integraciones.", + "description": "Nombres e información de versión.", "title": "Integraciones utilizadas" } } @@ -2499,7 +2500,7 @@ "update": "Actualizar" }, "introduction": "Aquí puedes definir a cada persona de interés en Home Assistant.", - "learn_more": "Aprende más sobre las personas", + "learn_more": "Saber más sobre las personas", "no_persons_created_yet": "Parece que aún no has creado ninguna persona.", "note_about_persons_configured_in_yaml": "Nota: las personas configuradas a través de configuration.yaml no se pueden editar a través de la IU.", "person_not_found": "No pudimos encontrar a la persona que intentabas editar.", @@ -2543,7 +2544,7 @@ "name": "Nombre" }, "introduction": "El editor de escenas te permite crear y editar escenas. Por favor, sigue el siguiente enlace para leer las instrucciones para asegurarte de que has configurado Home Assistant correctamente.", - "learn_more": "Aprende más sobre las escenas", + "learn_more": "Saber más sobre las escenas", "no_scenes": "No pudimos encontrar ninguna escena", "only_editable": "Solo las escenas definidas en scenes.yaml son editables.", "pick_scene": "Elige una escena para editar", @@ -2564,7 +2565,7 @@ "id_already_exists": "Este ID ya existe", "id_already_exists_save_error": "No puedes guardar este script porque el ID no es único, elije otro ID o déjalo en blanco para generar uno automáticamente.", "introduction": "Utiliza scripts para ejecutar una secuencia de acciones.", - "link_available_actions": "Aprende más sobre las acciones disponibles.", + "link_available_actions": "Saber más sobre las acciones disponibles.", "load_error_not_editable": "Solo los scripts dentro de scripts.yaml son editables.", "max": { "parallel": "Número máximo de ejecuciones paralelas", @@ -2593,7 +2594,7 @@ "name": "Nombre" }, "introduction": "El editor de scripts te permite crear y editar scripts. Por favor, sigue el siguiente enlace para leer las instrucciones para asegurarte de que has configurado Home Assistant correctamente.", - "learn_more": "Aprende más sobre los scripts", + "learn_more": "Saber más sobre los scripts", "no_scripts": "No pudimos encontrar ningún script", "run_script": "Ejecutar script", "show_info": "Mostrar información sobre el script" @@ -2680,7 +2681,7 @@ "last_scanned": "Última vez escaneada", "name": "Nombre" }, - "learn_more": "Aprende más sobre las etiquetas", + "learn_more": "Saber más sobre las etiquetas", "never_scanned": "Nunca escaneado", "no_tags": "Sin etiquetas", "write": "Escribir" @@ -2937,7 +2938,7 @@ "wakeup_interval": "Intervalo de activación" }, "description": "Administra tu red Z-Wave", - "learn_more": "Aprende más sobre Z-Wave", + "learn_more": "Saber más sobre Z-Wave", "migration": { "ozw": { "header": "Migrar a OpenZWave", @@ -3715,7 +3716,7 @@ "demo": { "demo_by": "por {name}", "introduction": "¡Bienvenido a casa! Has llegado a la demostración de Home Assistant donde mostramos las mejores interfaces de usuario creadas por nuestra comunidad.", - "learn_more": "Aprende más sobre Home Assistant", + "learn_more": "Saber más sobre Home Assistant", "next_demo": "Siguiente demostración" } }, @@ -3801,7 +3802,7 @@ "profile": { "advanced_mode": { "description": "Desbloquea las funciones avanzadas.", - "link_promo": "Aprende más", + "link_promo": "Saber más", "title": "Modo avanzado" }, "change_password": { @@ -3892,7 +3893,7 @@ "error_load_platform": "Configurar notify.html5.", "error_use_https": "Requiere SSL activado para frontend.", "header": "Notificaciones push", - "link_promo": "Aprende más", + "link_promo": "Saber más", "push_notifications": "Notificaciones push" }, "refresh_tokens": { diff --git a/translations/frontend/et.json b/translations/frontend/et.json index 03812e2747..1a88fc93b8 100644 --- a/translations/frontend/et.json +++ b/translations/frontend/et.json @@ -473,6 +473,7 @@ "unhealthy_title": "Paigaldus on vigane", "unsupported_description": "Allpool on loend paigaldusel leitud probleemidest. Klõpsa linkidel, et saada teada, kuidas saad probleeme lahendada.", "unsupported_reason": { + "apparmor": "AppArmor pole hostis lubatud", "container": "Konteinerid mis teadaolevalt põhjustavad probleeme", "content-trust": "Sisu usaldatavuse kontroll on keelatud", "dbus": "DBUS", @@ -1872,28 +1873,28 @@ "documentation": "Enne selle lubamist külasta kindlasti olekuteabe dokumentatsiooni lehte {link} et aru saada, mida saadetakse ja kuidas see talletatakse.", "header": "Olekuteave", "instance_id": "Eksemplari ID: {huuid}", - "introduction": "Jaga oma Home Assistanti oleku teavet. Need andmed on avalikult saadaval aadressil {link}", - "learn_more": "Uuri lisateavet andmete töötlemise kohta.", + "introduction": "Jaga oma paigalduse teavet, et muuta Home Assistant paremaks ja aidata meil veenda tootjaid lisama kohalikku juhtimist ja privaatsusele keskendunud funktsioone.", + "learn_more": "Uuri lisateavet andmete töötlemise kohta", "needs_base": "Selle suvandi kasutamiseks pead lubama põhilise olekuteabe", "preference": { "base": { - "description": "See hõlmab eksemplari ID-d, versiooni ja paigalduse tüüpi", + "description": "Eksemplari ID, versioon ja paigalduse tüüp.", "title": "Põhiline olekuteave" }, "diagnostics": { - "description": "Jaga krahhiaruandeid ja diagnostikateavet", + "description": "Ootamatute vigade ilmnemisel jaga krahhiaruandeid.", "title": "Diagnostika" }, "statistics": { - "description": "See hõlmab paigalduse elementide arvu, täieliku loendi saamiseks vaata dokumentatsiooni", + "description": "Kasutatud olemid, kasutajad ja muud elemendid kokku.", "title": "Kasutusstatistika" }, "usage_supervisor": { - "description": "See hõlmab sidumiste ja lisandmoodulite nimesid ja võimalusi", + "description": "Nimed, versioonid ja võimalused.", "title": "Kasutusel olevad sidumised ja lisandmoodulid" }, "usage": { - "description": "See hõlmab kasutusel olevate sidumiste nimesid", + "description": "Nimed ja teave versiooni kohta.", "title": "Kasutusel olevad sidumised" } } diff --git a/translations/frontend/it.json b/translations/frontend/it.json index 217bb31b80..c08de46641 100644 --- a/translations/frontend/it.json +++ b/translations/frontend/it.json @@ -473,6 +473,7 @@ "unhealthy_title": "L'installazione non è integra", "unsupported_description": "Di seguito è riportato un elenco dei problemi riscontrati con l'installazione, fare clic sui collegamenti per scoprire come risolvere i problemi.", "unsupported_reason": { + "apparmor": "AppArmor non è abilitato sull'host", "container": "Container noti per causare problemi", "content-trust": "La convalida dell'attendibilità del contenuto è disabilitata", "dbus": "DBUS", @@ -1213,6 +1214,14 @@ "key_wrong_type": "Il valore fornito per \"{key}\" non è supportato dall'editor visivo. Supportiamo ({type_correct}) ma ricevuto ({type_wrong}).", "no_template_editor_support": "Modelli non supportati nell'editor visivo", "no_type_provided": "Nessun tipo fornito." + }, + "supervisor": { + "ask": "Chiedere aiuto", + "observer": "Controlla l'Observer", + "reboot": "Prova a riavviare l'host", + "system_health": "Controlla l'integrità del sistema", + "title": "Impossibile caricare il pannello Supervisor!", + "wait": "Se hai appena avviato, assicurati di aver dato al Supervisor abbastanza tempo per partire." } }, "login-form": { @@ -1864,28 +1873,28 @@ "documentation": "Prima di abilitarlo, assicurati di visitare la pagina della documentazione di analisi {link} per capire cosa stai inviando e come viene archiviato.", "header": "Analisi", "instance_id": "ID istanza: {huuid}", - "introduction": "Condividi l'analisi dalla tua istanza. Questi dati saranno disponibili pubblicamente all'indirizzo {link}", - "learn_more": "Scopri di più su come verranno elaborati i tuoi dati.", + "introduction": "Condividi le informazioni di installazione per migliorare Home Assistant e aiutarci a convincere i produttori ad aggiungere funzionalità incentrate sul controllo locale e sulla privacy.", + "learn_more": "Come elaboriamo i tuoi dati", "needs_base": "È necessario abilitare l'analisi di base affinché questa opzione sia disponibile", "preference": { "base": { - "description": "Questo include l'ID dell'istanza, la versione e il tipo di installazione", + "description": "ID dell'istanza, versione e tipo di installazione.", "title": "Analisi di base" }, "diagnostics": { - "description": "Condividi i rapporti sugli arresti anomali e le informazioni diagnostiche", + "description": "Condividi i rapporti sugli arresti anomali quando si verificano errori imprevisti.", "title": "Diagnostica" }, "statistics": { - "description": "Questo include un conteggio degli elementi nella tua installazione, per un elenco completo guarda la documentazione", + "description": "Totale entità, utenti e altri elementi utilizzati.", "title": "Statistiche d'uso" }, "usage_supervisor": { - "description": "Questo include i nomi e le funzionalità delle integrazioni e dei componenti aggiuntivi", + "description": "Nomi, versioni e funzionalità.", "title": "Integrazioni e componenti aggiuntivi utilizzati" }, "usage": { - "description": "Questo include i nomi delle tue integrazioni", + "description": "Nomi e informazioni sulla versione.", "title": "Integrazioni usate" } } diff --git a/translations/frontend/ko.json b/translations/frontend/ko.json index 49431e7819..f5c8990b8f 100644 --- a/translations/frontend/ko.json +++ b/translations/frontend/ko.json @@ -473,6 +473,7 @@ "unhealthy_title": "설치 상태가 비정상적입니다", "unsupported_description": "다음은 설치된 Supervisor에서 발견된 문제 목록입니다. 문제를 해결하는 방법에 대해 알아보려면 링크를 클릭해주세요.", "unsupported_reason": { + "apparmor": "호스트에서 AppArmor가 활성화되지 않았습니다.", "container": "문제를 일으키는 것으로 알려진 컨테이너입니다", "content-trust": "이미지 무결성 검사가 비활성화되었습니다", "dbus": "DBUS", @@ -1213,6 +1214,14 @@ "key_wrong_type": "\"{key}\"에 제공된 값은 비주얼 편집기에서 지원되지 않습니다. ({type_correct})을(를) 지원하지만 ({type_wrong})을(를) 받았습니다.", "no_template_editor_support": "비주얼 편집기에서 템플릿이 지원되지 않습니다", "no_type_provided": "유형이 제공되지 않았습니다." + }, + "supervisor": { + "ask": "문의하기", + "observer": "Observer 확인하기", + "reboot": "호스트 재부팅 시도하기", + "system_health": "시스템 상태 확인하기", + "title": "Supervisor 화면을 불러올 수 없습니다.", + "wait": "방금 시작한 경우 Supervisor가 완전히 시작되기까지 잠시 기다려주세요." } }, "login-form": { diff --git a/translations/frontend/nb.json b/translations/frontend/nb.json index a59b4f694a..162c194a16 100644 --- a/translations/frontend/nb.json +++ b/translations/frontend/nb.json @@ -473,6 +473,7 @@ "unhealthy_title": "Installasjonen din er usunn", "unsupported_description": "Nedenfor er en liste over problemer som er funnet med installasjonen din. Klikk på lenkene for å lære hvordan du kan løse problemene.", "unsupported_reason": { + "apparmor": "AppArmor er ikke aktivert på verten", "container": "Containere som er kjent for å forårsake problemer", "content-trust": "Validering av innholds klarering er deaktivert", "dbus": "", @@ -1213,6 +1214,14 @@ "key_wrong_type": "Den angitte verdien for \"{key}\" støttes ikke av det visuelle redigeringsprogrammet. Vi støtter ({type_correct}), men mottatt ({type_wrong}).", "no_template_editor_support": "Maler støttes ikke i visual editor", "no_type_provided": "Ingen type oppgitt." + }, + "supervisor": { + "ask": "Be om hjelp", + "observer": "Sjekk observatøren", + "reboot": "Prøv en omstart av verten", + "system_health": "Sjekk systemtilstand", + "title": "Kunne ikke laste Supervisor-panelet!", + "wait": "Hvis du nettopp startet, må du sørge for at du har gitt veilederen nok tid til å starte." } }, "login-form": { @@ -1864,28 +1873,28 @@ "documentation": "Før du aktiverer dette, må du gå til analysedokumentasjonssiden {link} å forstå hva du sender og hvordan den er lagret.", "header": "Analytics", "instance_id": "Forekomst-ID: {huuid}", - "introduction": "Del analyser fra forekomsten din. Disse dataene vil være offentlig tilgjengelige på {link}", - "learn_more": "Lær mer om hvordan dataene dine blir behandlet.", + "introduction": "Del installasjonsinformasjonen din for å gjøre Home Assistant bedre og hjelpe oss med å overbevise produsenter om å legge til lokal kontroll og personvernfokuserte funksjoner.", + "learn_more": "Hvordan vi behandler dataene dine", "needs_base": "Du må aktivere basisanalyse for at dette alternativet skal være tilgjengelig", "preference": { "base": { - "description": "Dette inkluderer forekomst-ID, versjon og installasjonstype", + "description": "Forekomst-ID, versjon og installasjonstype.", "title": "Grunnleggende analyse" }, "diagnostics": { - "description": "Del krasjrapporter og diagnostisk informasjon", + "description": "Del krasjrapporter når uventede feil oppstår.", "title": "Diagnostikk" }, "statistics": { - "description": "Dette inkluderer en rekke elementer i installasjonen din, for å se en fullstendig liste i dokumentasjonen", + "description": "Totalt brukte enheter, brukere og andre elementer.", "title": "Bruksstatistikk" }, "usage_supervisor": { - "description": "Dette inkluderer navnene og funksjonene til integrasjonene og tilleggene dine", + "description": "Navn, versjoner og evner.", "title": "Brukte integrasjoner og tillegg" }, "usage": { - "description": "Dette inkluderer navnene på integrasjonene dine", + "description": "Navn og versjonsinformasjon.", "title": "Brukte integrasjoner" } } diff --git a/translations/frontend/nl.json b/translations/frontend/nl.json index cfd2067c2d..aad14cec2d 100644 --- a/translations/frontend/nl.json +++ b/translations/frontend/nl.json @@ -473,6 +473,7 @@ "unhealthy_title": "Er is iets mis met je installatie", "unsupported_description": "Hieronder vindt je een lijst met problemen die bij je installatie zijn aangetroffen. Klik op de links om te zien hoe je de problemen kunt oplossen.", "unsupported_reason": { + "apparmor": "AppArmor is niet ingeschakeld op de host", "container": "Containers waarvan bekend is dat ze problemen veroorzaken", "content-trust": "Validatie van content-trust is uitgeschakeld", "dbus": "DBUS", @@ -2649,7 +2650,7 @@ }, "validation": { "check_config": "Controleer configuratie", - "heading": "Valideer configuratie", + "heading": "Configuratie validatie", "introduction": "Controleer je configuratie als je onlangs wijzigingen hebt aangebracht en zeker wilt weten dat ze geldig zijn", "invalid": "Ongeldige configuratie", "valid": "Geldige configuratie!" diff --git a/translations/frontend/pl.json b/translations/frontend/pl.json index e05f09283b..aa912786b1 100644 --- a/translations/frontend/pl.json +++ b/translations/frontend/pl.json @@ -473,6 +473,7 @@ "unhealthy_title": "Twoja instalacja jest \"niezdrowa\"", "unsupported_description": "Poniżej znajduje się lista problemów z Twoją instalacją. Kliknij łącza, aby dowiedzieć się, jak możesz je rozwiązać.", "unsupported_reason": { + "apparmor": "AppArmor nie jest włączony na hoście", "container": "Kontenery, o których wiadomo, że powodują problemy", "content-trust": "Weryfikacja zaufania zawartości jest wyłączona", "dbus": "DBUS", @@ -1872,28 +1873,28 @@ "documentation": "Zanim to włączysz, odwiedź stronę z dokumentacją analityczną {link}, aby zrozumieć, co wysyłasz i jak to jest przechowywane.", "header": "Analityka", "instance_id": "Identyfikator instancji: {huuid}", - "introduction": "Udostępniaj dane analityczne ze swojej instancji. Te dane będą publicznie dostępne pod adresem {link}", - "learn_more": "Dowiedz się więcej, jak Twoje dane będą przetwarzane.", + "introduction": "Udostępnij informacje o instalacji, aby ulepszyć Home Assistant i pomóż nam przekonać producentów do dodania lokalnych funkcji sterowania i prywatności.", + "learn_more": "Jak przetwarzamy Twoje dane", "needs_base": "Aby ta opcja była dostępna, musisz włączyć podstawowe analityki", "preference": { "base": { - "description": "Obejmuje to identyfikator instancji, wersję i typ instalacji", + "description": "Identyfikator instancji, wersja i typ instalacji.", "title": "Podstawowe analityki" }, "diagnostics": { - "description": "Udostępniaj raporty o awariach i informacje diagnostyczne", + "description": "Udostępniaj raporty o awariach, gdy wystąpią nieoczekiwane błędy.", "title": "Diagnostyka" }, "statistics": { - "description": "Obejmuje to liczbę elementów w instalacji. Pełną listę można znaleźć w dokumentacji.", + "description": "Suma wykorzystanych encji, użytkowników i innych elementów.", "title": "Statystyki użycia" }, "usage_supervisor": { - "description": "Obejmuje to nazwy i możliwości twoich integracji i dodatków", + "description": "Nazwy, wersje i możliwości.", "title": "Użyte integracje i dodatki" }, "usage": { - "description": "Obejmuje to nazwy twoich integracji", + "description": "Informacje o nazwie i wersji.", "title": "Używane integracje" } } diff --git a/translations/frontend/ru.json b/translations/frontend/ru.json index b80637f77e..73175f13b4 100644 --- a/translations/frontend/ru.json +++ b/translations/frontend/ru.json @@ -405,7 +405,7 @@ "upload_snapshot": "Загрузить снимок" }, "store": { - "missing_addons": "Пропали дополнения? Включите расширенный режим на странице Вашего профиля пользователя", + "missing_addons": "Пропали дополнения? Активируйте расширенный режим на странице Вашего профиля пользователя", "no_results_found": "Не найдено результатов в {repository}.", "registries": "Реестры", "repositories": "Репозитории" @@ -460,7 +460,7 @@ "reload_supervisor": "Перезагрузить Supervisor", "share_diagnostics": "Отправлять данные для диагностики", "share_diagnostics_description": "Автоматически отправлять отчеты о сбоях и диагностическую информацию", - "share_diagonstics_description": "Хотели бы Вы автоматически отправлять отчеты о сбоях и другую диагностическую информацию, когда Supervisor обнаруживает неожиданные ошибки? {line_break} Это позволит разработчикам получать необходимые данные для решения проблем. Данные не будут содержать никакой личной или конфиденциальной информации и будут доступны только основной команде Home Assistant. {line_break} Вы сможете отключить отправку данных в настройках в любое время.", + "share_diagonstics_description": "Хотели бы Вы автоматически отправлять отчеты о сбоях и другую диагностическую информацию, когда Supervisor обнаруживает неожиданные ошибки? {line_break} Это позволит разработчикам получать необходимые данные для решения проблем. Данные не будут содержать никакой личной или конфиденциальной информации и будут доступны только основной команде Home Assistant. {line_break} Вы сможете отменить отправку данных в настройках в любое время.", "share_diagonstics_title": "Помогите улучшить Home Assistant", "unhealthy_description": "Запуск неработоспособной системы может вызвать проблемы. Ниже приведен список проблем, обнаруженных при установке. Перейдите по ссылкам, чтобы узнать, как их решить.", "unhealthy_reason": { @@ -473,6 +473,7 @@ "unhealthy_title": "Ваша система неработоспособна", "unsupported_description": "Ниже приведен список проблем, обнаруженных при установке. Перейдите по ссылкам, чтобы узнать, как их решить.", "unsupported_reason": { + "apparmor": "На хосте не активирован AppArmor", "container": "Контейнеры, известные как вызывающие проблемы", "content-trust": "Проверка доверия к контенту отключена", "dbus": "DBUS", @@ -662,8 +663,8 @@ "copied": "Скопировано", "copied_clipboard": "Скопировано в буфер обмена", "delete": "Удалить", - "disable": "Отключить", - "enable": "Включить", + "disable": "Деактивировать", + "enable": "Активировать", "error_required": "Обязательное поле", "leave": "Выйти", "loading": "Загрузка", @@ -761,7 +762,7 @@ "no_history_found": "История не найдена." }, "logbook": { - "by": "от", + "by": "пользователем", "by_service": "службой", "entries_not_found": "В журнале нет записей.", "messages": { @@ -931,11 +932,11 @@ "change_device_area": "Изменить помещение для устройства", "confirm_delete": "Вы уверены, что хотите удалить эту запись?", "delete": "Удалить", - "device_disabled": "Родительское устройство этого объекта скрыто.", - "enabled_cause": "Скрыто {cause}.", + "device_disabled": "Родительское устройство этого объекта деактивировано.", + "enabled_cause": "Деактивировано {cause}.", "enabled_delay_confirm": "Объекты будут добавлены в Home Assistant через {delay} секунд", - "enabled_description": "Скрытые объекты не будут доступны в Home Assistant.", - "enabled_label": "Отображать объект", + "enabled_description": "Деактивированные объекты не будут доступны в Home Assistant.", + "enabled_label": "Активировать объект", "enabled_restart_confirm": "Перезапустите Home Assistant, чтобы завершить изменение объектов", "entity_id": "ID объекта", "follow_device_area": "Получить настройки помещения от устройства", @@ -1213,6 +1214,14 @@ "key_wrong_type": "Предоставленное значение для \"{key}\" не поддерживается визуальным редактором. Поддерживается: ({type_correct}), получено: ({type_wrong}).", "no_template_editor_support": "В форме ввода шаблоны не поддерживаются", "no_type_provided": "Тип не указан." + }, + "supervisor": { + "ask": "Обратиться за помощью", + "observer": "Проверьте Observer", + "reboot": "Попробуйте перезагрузить хост", + "system_health": "Проверьте статус системы", + "title": "Не удалось загрузить панель Supervisor!", + "wait": "Убедитесь, что у Supervisor было достаточно времени для запуска." } }, "login-form": { @@ -1467,7 +1476,7 @@ }, "edit_ui": "Форма ввода", "edit_yaml": "Текстовый редактор", - "enable_disable": "Включить / выключить правило автоматизации", + "enable_disable": "Активировать / деактивировать правило автоматизации", "introduction": "Используйте автоматизацию, чтобы оживить Ваш дом.", "load_error_not_editable": "Доступны для редактирования только автоматизации из automations.yaml.", "load_error_unknown": "Ошибка загрузки автоматизации ({err_no}).", @@ -1670,12 +1679,12 @@ "account": { "alexa": { "config_documentation": "Инструкция по настройке", - "disable": "отключить", - "enable": "включить", + "disable": "деактивировать", + "enable": "активировать", "enable_ha_skill": "Активировать навык Home Assistant для Alexa", "enable_state_reporting": "Отправлять изменения состояний объектов", "info": "Интеграция Alexa позволяет управлять устройствами, добавленными в Home Assistant, через любое устройство с поддержкой Alexa.", - "info_state_reporting": "Если Вы включите этот параметр, Home Assistant будет отправлять все изменения состояний объектов, доступных Amazon. Это позволит Вам всегда видеть актуальные состояния в приложениях Alexa и использовать изменения состояний для автоматизации повседневных задач.", + "info_state_reporting": "Если Вы активируете этот параметр, Home Assistant будет отправлять все изменения состояний объектов, доступных Amazon. Это позволит Вам всегда видеть актуальные состояния в приложениях Alexa и использовать изменения состояний для автоматизации повседневных задач.", "manage_entities": "Управление объектами", "state_reporting_error": "Не удалось {enable_disable} отправку изменения состояний.", "sync_entities": "Синхронизировать объекты с Amazon", @@ -1694,7 +1703,7 @@ "enter_pin_hint": "PIN-код", "enter_pin_info": "Введите PIN-код для взаимодействия с устройствами безопасности. Устройства безопасности — это двери, гаражные ворота и замки. При взаимодействии с такими устройствами через Google Assistant, Вам будет предложено сказать или ввести этот PIN-код.", "info": "Интеграция Google Assistant позволяет управлять устройствами, добавленными в Home Assistant, через любое устройство с поддержкой Google Assistant.", - "info_state_reporting": "Если Вы включите этот параметр, Home Assistant будет отправлять все изменения состояний объектов, доступных Google. Это позволит Вам всегда видеть актуальные состояния в приложениях Google.", + "info_state_reporting": "Если Вы активируете этот параметр, Home Assistant будет отправлять все изменения состояний объектов, доступных Google. Это позволит Вам всегда видеть актуальные состояния в приложениях Google.", "manage_entities": "Управление объектами", "not_configured_text": "Перед использованием Google Assistant необходимо активировать навык Home Assistant Cloud в приложении \"Google Home\".", "not_configured_title": "Google Assistant не активирован", @@ -1864,28 +1873,28 @@ "documentation": "Прежде всего, посетите страницу документации по аналитике {link}, чтобы понять, что Вы будете отправлять и как это будет храниться.", "header": "Аналитика", "instance_id": "ID экземпляра Home Assistant: {huuid}", - "introduction": "Поделитесь аналитикой из Вашего Home Assistant. Эти данные будут доступны для всех по адресу {link}.", - "learn_more": "Узнайте больше о том, как будут обрабатываться Ваши данные.", - "needs_base": "Включите базовую аналитику, чтобы эта опция была доступна", + "introduction": "Поделитесь информацией о Вашем Home Assistant, чтобы помочь сделать его ещё лучше. Полученные данные также помогут нам убедить производителей добавлять в свои продукты локальный контроль и функции, ориентированные на конфиденциальность.", + "learn_more": "Как будут обрабатываться Ваши данные", + "needs_base": "Активируйте базовую аналитику, чтобы эта опция была доступна", "preference": { "base": { - "description": "Включает в себя ID экземпляра, версию и тип установки.", + "description": "ID экземпляра Home Assistant, его версия и тип установки.", "title": "Базовая аналитика" }, "diagnostics": { - "description": "Отправлять отчеты о сбоях и диагностическую информацию", + "description": "Отправлять отчеты при сбоях и возникновении непредвиденных ошибок.", "title": "Диагностика" }, "statistics": { - "description": "Включает в себя подсчёт элементов для Вашего Home Assistant. О том, как получить полный список, смотрите в документации.", + "description": "Подсчёт количества объектов, пользователей и других элементов.", "title": "Статистика использования" }, "usage_supervisor": { - "description": "Включает в себя названия и возможности используемых Вами интеграций и дополнений.", + "description": "Названия, версии и возможности.", "title": "Используемые интеграции и дополнения" }, "usage": { - "description": "Включает в себя названия используемых Вами интеграций", + "description": "Названия интеграций и информация о версиях.", "title": "Используемые интеграции" } } @@ -1948,7 +1957,7 @@ "unknown_condition": "Неизвестное условие" }, "create": "Создать автоматизацию", - "create_disable": "Скрытые устройства нельзя использовать для создания автоматизаций", + "create_disable": "Деактивированные устройства нельзя использовать для создания автоматизаций", "no_automations": "Нет автоматизаций", "no_device_automations": "Для этого устройства нет средств автоматизации.", "triggers": { @@ -1961,7 +1970,7 @@ "cant_edit": "Вы можете редактировать только созданные в пользовательском интерфейсе элементы.", "caption": "Устройства", "confirm_delete": "Вы уверены, что хотите удалить это устройство?", - "confirm_disable_config_entry": "Для записи конфигурации {entry_name} больше нет устройств. Отключить вместо этого запись конфигурации?", + "confirm_disable_config_entry": "Для записи конфигурации {entry_name} больше нет устройств. Деактивировать вместо этого запись конфигурации?", "confirm_rename_entity_ids": "Хотите ли Вы также переименовать идентификаторы объектов?", "confirm_rename_entity_ids_warning": "Переименование повлечёт за собой необходимость вручную обновлять изменённые данные в правилах автоматизации, скриптах, сценах и пользовательском интерфейсе.", "data_table": { @@ -1977,20 +1986,20 @@ "description": "Управление подключенными устройствами", "device_info": "Устройство", "device_not_found": "Устройство не найдено", - "disabled": "Скрыто", + "disabled": "Деактивировано", "disabled_by": { "config_entry": "конфигурацией", "integration": "интеграцией", "user": "пользователем" }, - "enabled_cause": "Устройство скрыто {cause}.", - "enabled_description": "Скрытые устройства и их дочерние объекты не будут доступны в Home Assistant.", - "enabled_label": "Отображать устройство", + "enabled_cause": "Устройство деактивировано {cause}.", + "enabled_description": "Деактивированные устройства и их дочерние объекты не будут доступны в Home Assistant.", + "enabled_label": "Активировать устройство", "entities": { "add_entities_lovelace": "Добавить объекты в Lovelace UI", - "disabled_entities": "Показать {count} {count, plural,\n one {скрытый объект}\n other {скрытых объектов}\n}", + "disabled_entities": "Показать {count, plural,\n one {деактивированные объекты:}\n other {деактивированные объекты:}\n} {count}", "entities": "Объекты", - "hide_disabled": "Не показывать скрытые", + "hide_disabled": "Скрыть деактивированные объекты", "none": "У этого устройства нет объектов" }, "name": "Название", @@ -1998,22 +2007,22 @@ "picker": { "filter": { "filter": "Фильтр", - "hidden_devices": "{number, plural,\n one {скрытых устройств:}\n other {скрытых устройств:}\n} {number}", + "hidden_devices": "{number, plural,\n one {Скрытых устройств:}\n other {Скрытых устройств:}\n} {number}", "show_all": "Показать все", - "show_disabled": "Скрытые устройства" + "show_disabled": "Деактивированные устройства" }, "search": "Поиск устройств" }, "scene": { "create": "Создать сцену", - "create_disable": "Скрытые устройства нельзя использовать для создания сцен", + "create_disable": "Деактивированные устройства нельзя использовать для создания сцен", "no_scenes": "Нет сцен", "scenes": "Сцены" }, "scenes": "Сцены", "script": { "create": "Создать скрипт", - "create_disable": "Скрытые устройства нельзя использовать для создания скриптов", + "create_disable": "Деактивированные устройства нельзя использовать для создания скриптов", "no_scripts": "Нет скриптов", "scripts": "Скрипты" }, @@ -2027,20 +2036,20 @@ "description": "Управление доступными объектами", "picker": { "disable_selected": { - "button": "Скрыть выбранные", - "confirm_text": "Скрытые объекты не будут доступны в Home Assistant.", - "confirm_title": "Вы уверены, что хотите скрыть {number} {number, plural,\n one {выбранный объект}\n other {выбранных объектов}\n}?" + "button": "Деактивировать выбранные", + "confirm_text": "Деактивированные объекты не будут доступны в Home Assistant.", + "confirm_title": "Вы уверены, что хотите деактивировать {number} {number, plural,\n one {выбранный объект}\n other {выбранных объектов}\n}?" }, "enable_selected": { - "button": "Отображать выбранные", - "confirm_text": "Если эти объекты ранее были скрыты, они снова будут отображаться в Home Assistant.", - "confirm_title": "Отображать {number} {number, plural,\n one {выбранный объект}\n other {выбранных объектов}\n}?" + "button": "Активировать выбранные", + "confirm_text": "Если эти объекты ранее были деактивированы, они снова будут доступными в Home Assistant.", + "confirm_title": "Активировать {number} {number, plural,\n one {выбранный объект}\n other {выбранных объектов}\n}?" }, "filter": { "filter": "Фильтр", - "hidden_entities": "{number, plural,\n one {скрытых объектов:}\n other {скрытых объектов:}\n} {number}", + "hidden_entities": "{number, plural,\n one {Скрытых объектов:}\n other {Скрытых объектов:}\n} {number}", "show_all": "Показать все", - "show_disabled": "Скрытые объекты", + "show_disabled": "Деактивированные объекты", "show_readonly": "Объекты, доступные только для чтения", "show_unavailable": "Недоступные объекты" }, @@ -2064,7 +2073,7 @@ "search": "Поиск объектов", "selected": "Выбрано: {number}", "status": { - "disabled": "Скрыто", + "disabled": "Деактивировано", "ok": "Ok", "readonly": "Только для чтения", "restored": "Восстановлено", @@ -2149,16 +2158,16 @@ "delete_confirm": "Вы уверены, что хотите удалить эту интеграцию?", "device_unavailable": "Устройство недоступно", "devices": "{count, plural,\n one {устройств:}\n other {устройств:}\n} {count}", - "disable_restart_confirm": "Перезапустите Home Assistant, чтобы завершить отключение этой интеграции.", + "disable_restart_confirm": "Перезапустите Home Assistant, чтобы завершить деактивацию этой интеграции.", "disable": { - "disable_confirm": "Вы уверены, что хотите отключить эту запись конфигурации? Её дочерние устройства и объекты будут также отключены.", - "disabled": "Отключено", + "disable_confirm": "Вы уверены, что хотите деактивировать эту запись конфигурации? Её дочерние устройства и объекты будут также деактивированы.", + "disabled": "Деактивировано", "disabled_by": { "device": "устройством", "integration": "интеграцией", "user": "пользователем" }, - "disabled_cause": "Отключено {cause}" + "disabled_cause": "Деактивировано {cause}" }, "documentation": "Документация", "enable_restart_confirm": "Перезапустите Home Assistant, чтобы завершить подключение этой интеграции.", @@ -2208,22 +2217,22 @@ "description": "Управление интеграциями с устройствами или службами", "details": "Детали интеграции", "disable": { - "disabled_integrations": "Отключено: {number}", - "hide_disabled": "Скрыть отключенные интеграции", + "disabled_integrations": "Деактивировано: {number}", + "hide_disabled": "Скрыть деактивированные интеграции", "show": "Показать", - "show_disabled": "Показать отключенные интеграции" + "show_disabled": "Деактивированные интеграции" }, "discovered": "Обнаружено", "home_assistant_website": "сайте Home Assistant", "ignore": { "confirm_delete_ignore": "Эта интеграция станет доступна для обнаружения системой. Обнаружение произойдёт автоматически в течении некоторого времени, либо после перезапуска системы.", "confirm_delete_ignore_title": "Прекратить игнорировать {name}?", - "confirm_ignore": "Вы сможете снова включить обнаружение этой интеграции. Для этого откройте меню в правом верхнем углу и нажмите «Показать игнорируемые интеграции».", + "confirm_ignore": "Вы сможете снова включить обнаружение этой интеграции. Для этого откройте меню в правом верхнем углу и нажмите «Игнорируемые интеграции».", "confirm_ignore_title": "Игнорировать обнаружение интеграции {name}?", "hide_ignored": "Скрыть игнорируемые интеграции", "ignore": "Игнорировать", "ignored": "Игнорируется", - "show_ignored": "Показать игнорируемые интеграции", + "show_ignored": "Игнорируемые интеграции", "stop_ignore": "Прекратить игнорировать" }, "integration": "интеграции", @@ -2247,7 +2256,7 @@ "description": "Журналы работы сервера", "details": "Уровень: {level}", "level": { - "critical": "КРИТИЧЕСКАЯ НЕИСПРАВНОСТЬ", + "critical": "КРИТИЧЕСКАЯ ОШИБКА", "debug": "ОТЛАДКА", "error": "ОШИБКА", "info": "ИНФОРМАЦИЯ", diff --git a/translations/frontend/sk.json b/translations/frontend/sk.json index 59aa2e9108..1470603626 100644 --- a/translations/frontend/sk.json +++ b/translations/frontend/sk.json @@ -149,7 +149,7 @@ }, "ingress": { "description": "Tento doplnok používa vniknutie na bezpečné vloženie svojho rozhrania do Home Assistant.", - "title": "vniknutie" + "title": "Vniknutie" }, "label": { "apparmor": "apparmor", @@ -1121,7 +1121,7 @@ "picker": { "create_area": "Vytvoriť oblasť", "header": "Register oblastí", - "integrations_page": "Stránka Integrácie", + "integrations_page": "Stránka Integrácií", "introduction": "Oblasti sa používajú na usporiadanie zariadení. Tieto informácie sa použijú v službe Home Assistant, aby vám pomohli pri organizovaní rozhrania, povolení a integrácií s inými systémami.", "introduction2": "Ak chcete umiestniť zariadenia do oblasti, pomocou odkazu nižšie prejdite na stránku integrácií a potom kliknite na nakonfigurovanú integráciu a prejdite na karty zariadení.", "no_areas": "Vyzerá to, že ešte nemáte žiadne oblasti!" @@ -1850,7 +1850,8 @@ } }, "integration_panel_move": { - "link_integration_page": "stránka integrácie" + "link_integration_page": "stránka integrácií", + "missing_zha": "Chýba vám konfiguračný panel ZHA? Bol presunutý do položky ZHA na {integrations_page}." }, "integrations": { "add_integration": "Pridať integráciu", @@ -2116,7 +2117,7 @@ "device_tracker_intro": "Vyberte zariadenia, ktoré patria tejto osobe.", "device_tracker_pick": "Vyberte zariadenie na sledovanie", "device_tracker_picked": "Sledovať zariadenie", - "link_integrations_page": "Stránka Integrácie", + "link_integrations_page": "Stránka Integrácií", "link_presence_detection_integrations": "Integrácie detekcie prítomnosti", "linked_user": "Prepojený používateľa", "name": "Meno", diff --git a/translations/frontend/sv.json b/translations/frontend/sv.json index f4e7f913b1..27c43699ae 100644 --- a/translations/frontend/sv.json +++ b/translations/frontend/sv.json @@ -1049,6 +1049,10 @@ "key_not_expected": "Nyckeln \"{key}\" förväntas inte eller stöds inte av den visuella redigeraren.", "key_wrong_type": "Det angivna värdet för \"{key}\" stöds inte av den visuella redigeraren. Vi stöder ({type_correct}) men fick ({type_wrong}).", "no_type_provided": "Ingen typ angiven." + }, + "supervisor": { + "ask": "Be om hjälp", + "wait": "Om du precis börjat, se till att du har gett Supervisor tillräckligt med tid för att starta." } }, "login-form": { @@ -1682,6 +1686,9 @@ "description": "Ändra din grundkonfiguration för Home Assistant.", "section": { "core": { + "analytics": { + "learn_more": "Hur vi behandlar din data" + }, "core_config": { "edit_requires_storage": "Redigeraren är inaktiverad eftersom konfigurationen lagras i configuration.yaml.", "elevation": "Höjd över havet", @@ -1867,6 +1874,9 @@ "clear": "Rensa", "filtering_by": "Filtrera efter" }, + "hassio": { + "button": "Konfigurera" + }, "header": "Konfigurera Home Assistant", "helpers": { "caption": "Hjälpare", @@ -2020,6 +2030,13 @@ "clear": "Rensa", "description": "Visa Home Assistant loggarna", "details": "Logginformation ({level})", + "level": { + "critical": "KRITISK", + "debug": "DEBUG", + "error": "FEL", + "info": "INFO", + "warning": "VARNING" + }, "load_full_log": "Ladda hela Home Assistant-loggen", "loading_log": "Läser in fellogg ...", "multiple_messages": "Meddelandet inträffade först {time} och har hänt {counter} gånger", diff --git a/translations/frontend/zh-Hant.json b/translations/frontend/zh-Hant.json index f67f03898d..4dcfdcfec2 100644 --- a/translations/frontend/zh-Hant.json +++ b/translations/frontend/zh-Hant.json @@ -473,6 +473,7 @@ "unhealthy_title": "安裝版本不健康", "unsupported_description": "執行不健康的安裝版本可能會導致問題。下方列表為安裝問題清單,點選連結以了解如何解決問題。", "unsupported_reason": { + "apparmor": "主機端未啟用 AppArmor", "container": "已知造成問題的 Container", "content-trust": "內容認證已關閉", "dbus": "DBUS", @@ -1213,6 +1214,14 @@ "key_wrong_type": "視覺化編輯器不支援所提供的 \"{key}\" 數值。支援 ({type_correct}) 但卻收到 ({type_wrong})。", "no_template_editor_support": "視覺化編輯器不支援模版", "no_type_provided": "未提供類型。" + }, + "supervisor": { + "ask": "尋求協助", + "observer": "檢查 Observer", + "reboot": "嘗試重啟主機", + "system_health": "檢查系統健康狀態", + "title": "無法載入 Supervisor 面板!", + "wait": "假如為剛剛啟動,請確認已經給予 Supervisor 足夠時間進行啟動。" } }, "login-form": { @@ -1864,28 +1873,28 @@ "documentation": "於開啟前,請先確定您已經瀏覽分析資料文件頁面 {link}、並了解所要傳送的資料及相關資料如何儲存。", "header": "分析資料", "instance_id": "實例 ID:{huuid}", - "introduction": "分享實例分析資料,資料將可透過 {link} 連結公開取得", - "learn_more": "詳細了解資料會如何處理。", + "introduction": "分享安裝資訊將有助於協助 Home Assistant 改善、並協助說服更多製造廠商包含本地端控制與隱私權相關功能。", + "learn_more": "資料會如何處理。", "needs_base": "需要開啟基本分析、方能使用此選項", "preference": { "base": { - "description": "將包含實例 ID、版本與安裝類型", + "description": "實例 ID、版本與安裝類型。", "title": "基本分析" }, "diagnostics": { - "description": "分享當機回報與診斷資訊", + "description": "當發生位預期錯誤時,分享當機回報。", "title": "診斷資料" }, "statistics": { - "description": "將包含安裝的元件總數,完整列表、請參閱文件", + "description": "已使用實體、使用者與其他元素總數。", "title": "統計資訊" }, "usage_supervisor": { - "description": "將包含整合與附加元件的名稱與功能", + "description": "名稱、版本與功能。", "title": "已使用整合與附加元件" }, "usage": { - "description": "將包含整合名稱", + "description": "名稱與版本資訊。", "title": "已使用整合" } } From 2d15bd651e8aa381ba5caff556bbc9f8ece8e2e6 Mon Sep 17 00:00:00 2001 From: Donnie Date: Wed, 7 Apr 2021 21:18:55 -0700 Subject: [PATCH 003/106] Fix spinner regression and remove unnecessary twoline config (#8847) --- src/dialogs/quick-bar/ha-quick-bar.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dialogs/quick-bar/ha-quick-bar.ts b/src/dialogs/quick-bar/ha-quick-bar.ts index dea0a35a17..443b8b8470 100644 --- a/src/dialogs/quick-bar/ha-quick-bar.ts +++ b/src/dialogs/quick-bar/ha-quick-bar.ts @@ -238,7 +238,6 @@ export class QuickBar extends LitElement { @@ -268,10 +267,10 @@ export class QuickBar extends LitElement { private _renderCommandItem(item: CommandItem, index?: number) { return html` Date: Thu, 8 Apr 2021 09:47:25 +0200 Subject: [PATCH 004/106] Mention unique ID requirement in trace button tooltip (#8853) --- src/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translations/en.json b/src/translations/en.json index 44e8dae6c6..143647766d 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1237,7 +1237,7 @@ "no_automations": "We couldn’t find any automations", "add_automation": "Add automation", "only_editable": "Only automations defined in automations.yaml are editable.", - "dev_only_editable": "Only automations defined in automations.yaml are debuggable.", + "dev_only_editable": "Only automations that have a unique ID assigned are debuggable.", "edit_automation": "Edit automation", "dev_automation": "Debug automation", "show_info_automation": "Show info about automation", From c3f0932794f22c4ddb4ef41de9a6e05e4ffdb7bd Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Thu, 8 Apr 2021 10:52:10 +0200 Subject: [PATCH 005/106] Use number format setting for attribute rows (#8844) --- src/panels/lovelace/special-rows/hui-attribute-row.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/panels/lovelace/special-rows/hui-attribute-row.ts b/src/panels/lovelace/special-rows/hui-attribute-row.ts index da15054a57..ce215b0f2e 100644 --- a/src/panels/lovelace/special-rows/hui-attribute-row.ts +++ b/src/panels/lovelace/special-rows/hui-attribute-row.ts @@ -10,6 +10,7 @@ import { TemplateResult, } from "lit-element"; import checkValidDate from "../../../common/datetime/check_valid_date"; +import { formatNumber } from "../../../common/string/format_number"; import { HomeAssistant } from "../../../types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import "../components/hui-generic-entity-row"; @@ -71,6 +72,8 @@ class HuiAttributeRow extends LitElement implements LovelaceRow { .ts=${date} .format=${this._config.format} >` + : typeof attribute === "number" + ? formatNumber(attribute, this.hass.locale) : attribute ?? "-"} ${this._config.suffix} From de7264327ad4703431290897272f8d2d75566ea4 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Thu, 8 Apr 2021 16:47:04 +0200 Subject: [PATCH 006/106] Do not use "media_play_pause" but atomic services instead (#8845) --- src/data/media-player.ts | 8 +++++--- .../lovelace/cards/hui-media-control-card.ts | 2 ++ .../entity-rows/hui-media-player-entity-row.ts | 15 ++++++++++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/data/media-player.ts b/src/data/media-player.ts index 95b5156c33..143b7e1bf0 100644 --- a/src/data/media-player.ts +++ b/src/data/media-player.ts @@ -292,9 +292,11 @@ export const computeMediaControls = ( ? "hass:pause" : "hass:stop", action: - state === "playing" && !supportsFeature(stateObj, SUPPORT_PAUSE) - ? "media_stop" - : "media_play_pause", + state !== "playing" + ? "media_play" + : supportsFeature(stateObj, SUPPORT_PAUSE) + ? "media_pause" + : "media_stop", }); } diff --git a/src/panels/lovelace/cards/hui-media-control-card.ts b/src/panels/lovelace/cards/hui-media-control-card.ts index cd53ba0f4b..c1fd6788d9 100644 --- a/src/panels/lovelace/cards/hui-media-control-card.ts +++ b/src/panels/lovelace/cards/hui-media-control-card.ts @@ -666,6 +666,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard { ha-icon-button[action="media_play"], ha-icon-button[action="media_play_pause"], + ha-icon-button[action="media_pause"], ha-icon-button[action="media_stop"], ha-icon-button[action="turn_on"], ha-icon-button[action="turn_off"] { @@ -743,6 +744,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard { .narrow ha-icon-button[action="media_play"], .narrow ha-icon-button[action="media_play_pause"], + .narrow ha-icon-button[action="media_pause"], .narrow ha-icon-button[action="turn_on"] { --mdc-icon-button-size: 50px; --mdc-icon-size: 36px; diff --git a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts index f252ea2b88..f92f5eadfe 100644 --- a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts @@ -115,7 +115,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { ? html` ` : ""} @@ -256,8 +256,17 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { ); } - private _playPause(): void { - this.hass!.callService("media_player", "media_play_pause", { + private _playPauseStop(): void { + const stateObj = this.hass!.states[this._config!.entity]; + + const service = + stateObj.state !== "playing" + ? "media_play" + : supportsFeature(stateObj, SUPPORT_PAUSE) + ? "media_pause" + : "media_stop"; + + this.hass!.callService("media_player", service, { entity_id: this._config!.entity, }); } From 7758bd89c1fe4376b5733621eec3230e3eba1baa Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 8 Apr 2021 18:04:08 +0200 Subject: [PATCH 007/106] Check if logbook component loaded when fetching trace (#8861) --- .../config/automation/trace/ha-automation-trace.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/panels/config/automation/trace/ha-automation-trace.ts b/src/panels/config/automation/trace/ha-automation-trace.ts index 53c7131dc3..11030655f2 100644 --- a/src/panels/config/automation/trace/ha-automation-trace.ts +++ b/src/panels/config/automation/trace/ha-automation-trace.ts @@ -40,6 +40,7 @@ import { mdiDownload, } from "@mdi/js"; import "./ha-automation-trace-blueprint-config"; +import { isComponentLoaded } from "../../../../common/config/is_component_loaded"; @customElement("ha-automation-trace") export class HaAutomationTrace extends LitElement { @@ -378,11 +379,13 @@ export class HaAutomationTrace extends LitElement { this.automationId, this._runId! ); - this._logbookEntries = await getLogbookDataForContext( - this.hass, - trace.timestamp.start, - trace.context.id - ); + this._logbookEntries = isComponentLoaded(this.hass, "logbook") + ? await getLogbookDataForContext( + this.hass, + trace.timestamp.start, + trace.context.id + ) + : []; this._trace = trace; } From 1127750c5ef789fc067830d2902d94271f621b60 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 8 Apr 2021 07:30:47 -1000 Subject: [PATCH 008/106] Show which integrations are being setup at startup (#8834) Co-authored-by: Bram Kragten --- src/data/bootstrap_integrations.ts | 16 ++++++ src/state/disconnect-toast-mixin.ts | 79 ++++++++++++++++++++++++++++- src/translations/en.json | 2 + 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/data/bootstrap_integrations.ts diff --git a/src/data/bootstrap_integrations.ts b/src/data/bootstrap_integrations.ts new file mode 100644 index 0000000000..864cc2efef --- /dev/null +++ b/src/data/bootstrap_integrations.ts @@ -0,0 +1,16 @@ +import { HomeAssistant } from "../types"; + +export type BootstrapIntegrationsTimings = { [key: string]: number }; + +export const subscribeBootstrapIntegrations = ( + hass: HomeAssistant, + callback: (message: BootstrapIntegrationsTimings) => void +) => { + const unsubProm = hass.connection.subscribeMessage< + BootstrapIntegrationsTimings + >((message) => callback(message), { + type: "subscribe_bootstrap_integrations", + }); + + return unsubProm; +}; diff --git a/src/state/disconnect-toast-mixin.ts b/src/state/disconnect-toast-mixin.ts index 1bf402ce8f..09efcc3f89 100644 --- a/src/state/disconnect-toast-mixin.ts +++ b/src/state/disconnect-toast-mixin.ts @@ -2,13 +2,21 @@ import { STATE_NOT_RUNNING, STATE_RUNNING, STATE_STARTING, + UnsubscribeFunc, } from "home-assistant-js-websocket"; import { Constructor } from "../types"; import { showToast } from "../util/toast"; import { HassBaseEl } from "./hass-base-mixin"; +import { domainToName } from "../data/integration"; +import { + subscribeBootstrapIntegrations, + BootstrapIntegrationsTimings, +} from "../data/bootstrap_integrations"; export default >(superClass: T) => class extends superClass { + private _subscribedBootstrapIntegrations?: Promise; + protected firstUpdated(changedProps) { super.firstUpdated(changedProps); // Need to load in advance because when disconnected, can't dynamically load code. @@ -35,15 +43,19 @@ export default >(superClass: T) => action: { text: this.hass!.localize("ui.notification_toast.dismiss") || "Dismiss", - action: () => {}, + action: () => { + this._unsubscribeBootstrapIntergrations(); + }, }, }); + this._subscribeBootstrapIntergrations(); } else if ( oldHass?.config && oldHass.config.state === STATE_NOT_RUNNING && (this.hass!.config.state === STATE_STARTING || this.hass!.config.state === STATE_RUNNING) ) { + this._unsubscribeBootstrapIntergrations(); showToast(this, { message: this.hass!.localize("ui.notification_toast.started"), duration: 5000, @@ -68,4 +80,69 @@ export default >(superClass: T) => dismissable: false, }); } + + private _handleMessage(message: BootstrapIntegrationsTimings): void { + if (this.hass!.config.state !== STATE_NOT_RUNNING) { + return; + } + + if (Object.keys(message).length === 0) { + showToast(this, { + message: + this.hass!.localize("ui.notification_toast.wrapping_up_startup") || + `Wrapping up startup, not everything will be available until it is finished.`, + duration: 0, + dismissable: false, + action: { + text: + this.hass!.localize("ui.notification_toast.dismiss") || "Dismiss", + action: () => {}, + }, + }); + return; + } + + // Show the integration that has been starting for the longest time + const integration = Object.entries(message).sort( + ([, a], [, b]) => b - a + )[0][0]; + + showToast(this, { + message: + this.hass!.localize( + "ui.notification_toast.intergration_starting", + "integration", + domainToName(this.hass!.localize, integration) + ) || + `Starting ${integration}, not everything will be available until it is finished.`, + duration: 0, + dismissable: false, + action: { + text: + this.hass!.localize("ui.notification_toast.dismiss") || "Dismiss", + action: () => { + this._unsubscribeBootstrapIntergrations(); + }, + }, + }); + } + + private _unsubscribeBootstrapIntergrations() { + if (this._subscribedBootstrapIntegrations) { + this._subscribedBootstrapIntegrations.then((unsub) => unsub()); + this._subscribedBootstrapIntegrations = undefined; + } + } + + private _subscribeBootstrapIntergrations() { + if (!this.hass) { + return; + } + this._subscribedBootstrapIntegrations = subscribeBootstrapIntegrations( + this.hass!, + (message) => { + this._handleMessage(message); + } + ); + } }; diff --git a/src/translations/en.json b/src/translations/en.json index 143647766d..65ec334f84 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -850,6 +850,8 @@ "connection_lost": "Connection lost. Reconnecting…", "started": "Home Assistant has started!", "starting": "Home Assistant is starting, not everything will be available until it is finished.", + "wrapping_up_startup": "Wrapping up startup, not everything will be available until it is finished.", + "intergration_starting": "Starting {integration}, not everything will be available until it is finished.", "triggered": "Triggered {name}", "dismiss": "Dismiss" }, From d69accd9a54f02c17a6eae21b2ad0e7fc51a93d0 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 8 Apr 2021 20:32:31 +0200 Subject: [PATCH 009/106] Add dev import buttons for debugging traces (#8860) --- .../automation/trace/ha-automation-trace.ts | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/panels/config/automation/trace/ha-automation-trace.ts b/src/panels/config/automation/trace/ha-automation-trace.ts index 11030655f2..e319c36de4 100644 --- a/src/panels/config/automation/trace/ha-automation-trace.ts +++ b/src/panels/config/automation/trace/ha-automation-trace.ts @@ -86,12 +86,24 @@ export class HaAutomationTrace extends LitElement { const title = stateObj?.attributes.friendly_name || this._entityId; + let devButtons: TemplateResult | string = ""; + if (__DEV__) { + devButtons = html`
+ + +
`; + } + const actionButtons = html` this._loadTraces()}> @@ -100,6 +112,7 @@ export class HaAutomationTrace extends LitElement { `; return html` + ${devButtons} Date: Thu, 8 Apr 2021 20:48:49 +0200 Subject: [PATCH 010/106] Handle choose being null (#8859) Co-authored-by: Paulus Schoutsen --- src/components/trace/hat-script-graph.ts | 8 ++++++-- src/data/script.ts | 2 +- .../action/types/ha-automation-action-choose.ts | 10 +++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/components/trace/hat-script-graph.ts b/src/components/trace/hat-script-graph.ts index 9abf4ec9b8..ab10f0360b 100644 --- a/src/components/trace/hat-script-graph.ts +++ b/src/components/trace/hat-script-graph.ts @@ -143,7 +143,7 @@ class HatScriptGraph extends LitElement { const trace = this.trace.trace[path] as ChooseActionTraceStep[] | undefined; const trace_path = trace?.[0].result ? trace[0].result.choice === "default" - ? [config.choose.length] + ? [config.choose?.length || 0] : [trace[0].result.choice] : []; return html` @@ -167,7 +167,7 @@ class HatScriptGraph extends LitElement { nofocus > - ${config.choose.map((branch, i) => { + ${config.choose?.map((branch, i) => { const branch_path = `${path}/choose/${i}`; const track_this = trace !== undefined && trace[0].result?.choice === i; @@ -466,6 +466,10 @@ class HatScriptGraph extends LitElement { `; } catch (err) { + if (__DEV__) { + // eslint-disable-next-line no-console + console.log("Error creating script graph:", err); + } return html`
Error rendering graph. Please download trace and share with the diff --git a/src/data/script.ts b/src/data/script.ts index 096835a49d..bb614696a2 100644 --- a/src/data/script.ts +++ b/src/data/script.ts @@ -112,7 +112,7 @@ export interface ChooseActionChoice { export interface ChooseAction { alias?: string; - choose: ChooseActionChoice[]; + choose: ChooseActionChoice[] | null; default?: Action | Action[]; } diff --git a/src/panels/config/automation/action/types/ha-automation-action-choose.ts b/src/panels/config/automation/action/types/ha-automation-action-choose.ts index bb9ac0f8a6..2c356bca70 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-choose.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-choose.ts @@ -31,7 +31,7 @@ export class HaChooseAction extends LitElement implements ActionElement { const action = this.action; return html` - ${action.choose.map( + ${(action.choose || []).map( (option, idx) => html` Date: Thu, 8 Apr 2021 11:52:37 -0700 Subject: [PATCH 011/106] Add logbook note (#8843) Co-authored-by: Bram Kragten --- src/components/trace/hat-logbook-note.ts | 26 +++++++++ .../trace/ha-automation-trace-logbook.ts | 54 +++++++++++++++++++ .../trace/ha-automation-trace-path-details.ts | 18 ++++--- .../trace/ha-automation-trace-timeline.ts | 14 ++--- .../automation/trace/ha-automation-trace.ts | 7 +-- 5 files changed, 103 insertions(+), 16 deletions(-) create mode 100644 src/components/trace/hat-logbook-note.ts create mode 100644 src/panels/config/automation/trace/ha-automation-trace-logbook.ts diff --git a/src/components/trace/hat-logbook-note.ts b/src/components/trace/hat-logbook-note.ts new file mode 100644 index 0000000000..5d5b1f9df7 --- /dev/null +++ b/src/components/trace/hat-logbook-note.ts @@ -0,0 +1,26 @@ +import { LitElement, css, html, customElement } from "lit-element"; + +@customElement("hat-logbook-note") +class HatLogbookNote extends LitElement { + render() { + return html` + Not all shown logbook entries might be related to this automation. + `; + } + + static styles = css` + :host { + display: block; + text-align: center; + font-style: italic; + padding: 16px; + margin-top: 8px; + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "hat-logbook-note": HatLogbookNote; + } +} diff --git a/src/panels/config/automation/trace/ha-automation-trace-logbook.ts b/src/panels/config/automation/trace/ha-automation-trace-logbook.ts new file mode 100644 index 0000000000..b18d83d1be --- /dev/null +++ b/src/panels/config/automation/trace/ha-automation-trace-logbook.ts @@ -0,0 +1,54 @@ +import { + css, + CSSResult, + customElement, + html, + LitElement, + property, + TemplateResult, +} from "lit-element"; +import type { HomeAssistant } from "../../../../types"; +import type { LogbookEntry } from "../../../../data/logbook"; +import "../../../../components/trace/hat-logbook-note"; +import "../../../logbook/ha-logbook"; + +@customElement("ha-automation-trace-logbook") +export class HaAutomationTraceLogbook extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ type: Boolean, reflect: true }) public narrow!: boolean; + + @property({ attribute: false }) public logbookEntries!: LogbookEntry[]; + + protected render(): TemplateResult { + return this.logbookEntries.length + ? html` + + + ` + : html`
+ No Logbook entries found for this step. +
`; + } + + static get styles(): CSSResult[] { + return [ + css` + .padded-box { + padding: 16px; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-automation-trace-logbook": HaAutomationTraceLogbook; + } +} diff --git a/src/panels/config/automation/trace/ha-automation-trace-path-details.ts b/src/panels/config/automation/trace/ha-automation-trace-path-details.ts index b27edf9814..2416ea2ad6 100644 --- a/src/panels/config/automation/trace/ha-automation-trace-path-details.ts +++ b/src/panels/config/automation/trace/ha-automation-trace-path-details.ts @@ -9,6 +9,7 @@ import { property, TemplateResult, } from "lit-element"; +import { classMap } from "lit-html/directives/class-map"; import { ActionTraceStep, AutomationTraceExtended, @@ -18,11 +19,11 @@ import { import "../../../../components/ha-icon-button"; import "../../../../components/ha-code-editor"; import type { NodeInfo } from "../../../../components/trace/hat-graph"; +import "../../../../components/trace/hat-logbook-note"; import { HomeAssistant } from "../../../../types"; import { formatDateTimeWithSeconds } from "../../../../common/datetime/format_date_time"; import { LogbookEntry } from "../../../../data/logbook"; import { traceTabStyles } from "./styles"; -import { classMap } from "lit-html/directives/class-map"; import "../../../logbook/ha-logbook"; @customElement("ha-automation-trace-path-details") @@ -205,12 +206,15 @@ ${safeDump(trace.changed_variables).trimRight()}` + ? html` + + + ` : html`
No Logbook entries found for this step.
`; diff --git a/src/panels/config/automation/trace/ha-automation-trace-timeline.ts b/src/panels/config/automation/trace/ha-automation-trace-timeline.ts index 63599b2db5..b61ce862ee 100644 --- a/src/panels/config/automation/trace/ha-automation-trace-timeline.ts +++ b/src/panels/config/automation/trace/ha-automation-trace-timeline.ts @@ -7,19 +7,20 @@ import { property, TemplateResult, } from "lit-element"; -import { AutomationTraceExtended } from "../../../../data/trace"; -import { HomeAssistant } from "../../../../types"; -import { LogbookEntry } from "../../../../data/logbook"; +import type { AutomationTraceExtended } from "../../../../data/trace"; +import type { HomeAssistant } from "../../../../types"; +import type { LogbookEntry } from "../../../../data/logbook"; import "../../../../components/trace/hat-trace-timeline"; -import { NodeInfo } from "../../../../components/trace/hat-graph"; +import type { NodeInfo } from "../../../../components/trace/hat-graph"; +import "../../../../components/trace/hat-logbook-note"; @customElement("ha-automation-trace-timeline") export class HaAutomationTraceTimeline extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property() public trace!: AutomationTraceExtended; + @property({ attribute: false }) public trace!: AutomationTraceExtended; - @property() public logbookEntries!: LogbookEntry[]; + @property({ attribute: false }) public logbookEntries!: LogbookEntry[]; @property() public selected!: NodeInfo; @@ -33,6 +34,7 @@ export class HaAutomationTraceTimeline extends LitElement { allowPick > + `; } diff --git a/src/panels/config/automation/trace/ha-automation-trace.ts b/src/panels/config/automation/trace/ha-automation-trace.ts index e319c36de4..e0a0cd1ce6 100644 --- a/src/panels/config/automation/trace/ha-automation-trace.ts +++ b/src/panels/config/automation/trace/ha-automation-trace.ts @@ -30,6 +30,7 @@ import { showAlertDialog } from "../../../../dialogs/generic/show-dialog-box"; import "./ha-automation-trace-path-details"; import "./ha-automation-trace-timeline"; import "./ha-automation-trace-config"; +import "./ha-automation-trace-logbook"; import { classMap } from "lit-html/directives/class-map"; import { traceTabStyles } from "./styles"; import { @@ -252,10 +253,10 @@ export class HaAutomationTrace extends LitElement { ` : this._view === "logbook" ? html` - + .logbookEntries=${this._logbookEntries} + > ` : this._view === "blueprint" ? html` From ba9e410393da18948803d8b58c71c2d171b65e55 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 8 Apr 2021 13:59:24 -0700 Subject: [PATCH 012/106] Pass narrow (#8864) --- src/panels/config/automation/trace/ha-automation-trace.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/panels/config/automation/trace/ha-automation-trace.ts b/src/panels/config/automation/trace/ha-automation-trace.ts index e0a0cd1ce6..b8e480d7a9 100644 --- a/src/panels/config/automation/trace/ha-automation-trace.ts +++ b/src/panels/config/automation/trace/ha-automation-trace.ts @@ -255,6 +255,7 @@ export class HaAutomationTrace extends LitElement { ? html` ` From 21140f437e00efc52927e9d0408dfb2d379cd4cd Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 9 Apr 2021 01:31:46 +0200 Subject: [PATCH 013/106] Update value of date input (#8865) --- src/components/ha-date-input.ts | 2 ++ src/dialogs/more-info/controls/more-info-input_datetime.js | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/ha-date-input.ts b/src/components/ha-date-input.ts index e3342396c5..b23f1f5b6b 100644 --- a/src/components/ha-date-input.ts +++ b/src/components/ha-date-input.ts @@ -118,6 +118,8 @@ export class HaDateInput extends LitElement { !this.value || (this._inited && !this._compareStringDates(ev.detail.value, this.value)) ) { + this.value = ev.detail.value; + fireEvent(this, "change"); fireEvent(this, "value-changed", { value: ev.detail.value }); } } diff --git a/src/dialogs/more-info/controls/more-info-input_datetime.js b/src/dialogs/more-info/controls/more-info-input_datetime.js index fad03c408a..cff1b5233b 100644 --- a/src/dialogs/more-info/controls/more-info-input_datetime.js +++ b/src/dialogs/more-info/controls/more-info-input_datetime.js @@ -16,7 +16,6 @@ class DatetimeInput extends PolymerElement {
From 87fe84b1ac9efdf777334b09523f5c74c0a9dd7d Mon Sep 17 00:00:00 2001 From: Charles Garwood Date: Thu, 8 Apr 2021 19:32:47 -0400 Subject: [PATCH 014/106] Add units to Z-Wave JS Node Config inputs (#8869) Co-authored-by: Paulus Schoutsen --- .../integration-panels/zwave_js/zwave_js-node-config.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts index 33e08cb18b..a9ddcf897e 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts @@ -230,6 +230,9 @@ class ZWaveJSNodeConfig extends SubscribeMixin(LitElement) { .disabled=${!item.metadata.writeable} @value-changed=${this._numericInputChanged} > + ${item.metadata.unit + ? html`${item.metadata.unit}` + : ""} `; } From d46123771a85961868a6b5b89ea96b9950d14e43 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 9 Apr 2021 00:48:50 +0000 Subject: [PATCH 015/106] Translation update --- translations/frontend/bg.json | 30 +++++++++++++++++++++++++----- translations/frontend/ca.json | 6 ++++-- translations/frontend/cs.json | 10 +++++----- translations/frontend/en.json | 6 ++++-- translations/frontend/es.json | 2 ++ translations/frontend/ko.json | 26 +++++++++++++------------- translations/frontend/nl.json | 20 ++++++++++---------- translations/frontend/ru.json | 4 ++-- translations/frontend/zh-Hans.json | 19 ++++++++++++++----- 9 files changed, 79 insertions(+), 44 deletions(-) diff --git a/translations/frontend/bg.json b/translations/frontend/bg.json index 93080df54b..a7d1e42636 100644 --- a/translations/frontend/bg.json +++ b/translations/frontend/bg.json @@ -203,12 +203,16 @@ "uninstall": "деинсталиране", "visit_addon_page": "Посетете страницата {name} за повече подробности" }, + "documentation": { + "get_documentation": "Неуспешно получаване на документация за добавката, {error}" + }, "failed_to_reset": "Нулирането на конфигурацията на добавката не бе успешно, {error}", "failed_to_save": "Запазването на конфигурацията на добавката не бе успешно, {error}", "panel": { "configuration": "Конфигурация", "documentation": "Документация", - "info": "Информация" + "info": "Информация", + "log": "Журнал" }, "state": { "installed": "Добавката е инсталирана", @@ -1742,7 +1746,7 @@ "enabled_label": "Активиране на устройството", "entities": { "add_entities_lovelace": "Добавете към Lovelace", - "disabled_entities": "+{count} {count, plural,\n one {деактивиран обект}\n other {деактивирани обекти}\n}", + "disabled_entities": "+{count} {count, plural,\n one {деактивиран обект}\n other {деактивирани обекта}\n}", "entities": "Обекти", "hide_disabled": "Скриване на деактивираните" }, @@ -1797,6 +1801,7 @@ "header": "Обекти", "headers": { "area": "Област", + "entity_id": "ID на обекта", "integration": "Интеграция", "name": "Име", "status": "Състояние" @@ -1832,6 +1837,7 @@ }, "picker": { "headers": { + "entity_id": "ID на обекта", "name": "Име", "type": "Тип" } @@ -1883,10 +1889,11 @@ }, "documentation": "Документация", "enable_restart_confirm": "Рестартирайте Home Assistant за да завършите активирането на тази интеграция", - "entities": "{count} {count, plural,\n one {обект}\n other {обекти}\n}", + "entities": "{count} {count, plural,\n one {обект}\n other {обекта}\n}", "entity_unavailable": "Обектът е недостъпен", "firmware": "Фърмуер: {version}", "hub": "Свързан чрез", + "logs": "Журнали", "manuf": "от {manufacturer}", "no_area": "Без област", "not_loaded": "Не е зареден, проверете {logs_link}", @@ -1942,6 +1949,7 @@ }, "introduction": "Тук е възможно да конфигурирате Вашите компоненти и Home Assistant. Не всичко е възможно да се конфигурира от Интерфейса, но работим по върпоса.", "logs": { + "caption": "Журнали", "clear": "Изчистване", "level": { "critical": "КРИТИЧНО", @@ -1950,6 +1958,8 @@ "info": "ИНФО", "warning": "ВНИМАНИЕ" }, + "load_full_log": "Зареждане на пълния журнал на Home Assistant", + "loading_log": "Зарежда се журнала за грешки...", "multiple_messages": "съобщението е възникнало за първи път в {time} и се показва {counter} пъти", "refresh": "Опресняване" }, @@ -1971,7 +1981,9 @@ "edit_dashboard": "Редактиране на таблото", "icon": "Икона", "new_dashboard": "Добавяне на ново табло", + "remove_default": "Премахване по подразбиране на това устройство", "require_admin": "Само администратори", + "set_default": "Задаване по подразбиране на това устройство", "show_sidebar": "Показване в страничната лента", "title": "Заглавие", "title_required": "Заглавието е задължително.", @@ -2146,6 +2158,7 @@ "delete_script": "Изтриване на скрипта", "header": "Скрипт: {name}", "icon": "Икона", + "id": "ID на обекта", "id_already_exists": "Това ID вече съществува", "id_already_exists_save_error": "Не можете да запазите този скрипт, защото идентификаторът не е уникален, изберете друг идентификатор или го оставете празен, за да се генерира автоматично.", "introduction": "Използвайте скриптове за изпълнение на последователност от действия.", @@ -2618,7 +2631,7 @@ "name": "Обекти", "secondary_info_values": { "brightness": "Яркост", - "entity-id": "ID на обект", + "entity-id": "ID на обекта", "last-changed": "Последна промяна", "last-triggered": "Последно задействане", "last-updated": "Последна актуализация", @@ -2862,6 +2875,7 @@ }, "unused_entities": { "available_entities": "Това са обектите, които имате на разположение, но все още не са във вашия потребителски интерфейс на Lovelace.", + "entity_id": "ID на обекта", "last_changed": "Последна промяна", "no_data": "Не са намерени неизползвани обекти", "search": "Търсене на обекти", @@ -3033,6 +3047,9 @@ } }, "page-onboarding": { + "analytics": { + "finish": "Следващ" + }, "core-config": { "button_detect": "Откриване", "finish": "Напред", @@ -3048,9 +3065,12 @@ "more_integrations": "Още" }, "intro": "Готови ли сте да събудите дома си, да отвоювате независимостта си и да се присъедините към световна общност от хора автоматизиращи домовете си?", + "next": "Следващ", "restore": { "description": "Като алтернатива можете да възстановите от предишна моментна снимка.", - "in_progress": "Възстановяването е в ход" + "hide_log": "Скриване на пълния дневник", + "in_progress": "Възстановяването е в ход", + "show_log": "Показване на пълния дневник" }, "user": { "create_account": "Създай акаунт", diff --git a/translations/frontend/ca.json b/translations/frontend/ca.json index 01765e17de..be958cca82 100644 --- a/translations/frontend/ca.json +++ b/translations/frontend/ca.json @@ -1239,10 +1239,12 @@ "notification_toast": { "connection_lost": "Connexió perduda. Tornant a connectar...", "dismiss": "Omet", + "intergration_starting": "Iniciant {integration}, no estarà tot disponible fins que acabi.", "service_call_failed": "Ha fallat la crida al servei {service}.", "started": "Home Assistant s'ha iniciat!", "starting": "Home Assistant està iniciant-se, no estarà tot disponible fins que acabi", - "triggered": "{name} disparat/ada" + "triggered": "{name} disparat/ada", + "wrapping_up_startup": "Finalitzant l'arrencada, no estarà tot disponible fins que acabi." }, "panel": { "config": { @@ -1606,7 +1608,7 @@ "delete_automation": "Elimina l'automatització", "delete_confirm": "Estàs segur que vols eliminar aquesta automatització?", "dev_automation": "Depurar automatització", - "dev_only_editable": "Només es poden depurar les automatitzacions definides al fitxer automations.yaml.", + "dev_only_editable": "Només es poden depurar les automatitzacions que tinguin un identificador únic.", "duplicate": "Duplica", "duplicate_automation": "Duplica l'automatització", "edit_automation": "Edita automatització", diff --git a/translations/frontend/cs.json b/translations/frontend/cs.json index 6d11f9fc69..f79ba25073 100644 --- a/translations/frontend/cs.json +++ b/translations/frontend/cs.json @@ -29,7 +29,7 @@ "state_attributes": { "climate": { "fan_mode": { - "auto": "Automatika", + "auto": "Auto", "off": "Neaktivní", "on": "Aktivní" }, @@ -54,7 +54,7 @@ }, "humidifier": { "mode": { - "auto": "Automatika", + "auto": "Auto", "away": "Pryč", "baby": "Dítě", "boost": "Boost", @@ -792,7 +792,7 @@ "was_unplugged": "bylo odpojeno", "was_unsafe": "bylo v nebezpečí" }, - "show_trace": "Zobrazit stopu" + "show_trace": "Zobrazit trasu" }, "media-browser": { "audio_not_supported": "Váš prohlížeč nepodporuje element \"audio\".", @@ -1496,7 +1496,7 @@ "move_down": "Posunout dolů", "move_up": "Posunout nahoru", "save": "Uložit", - "show_trace": "Zobrazit trasování", + "show_trace": "Zobrazit trasu", "triggers": { "add": "Přidat spouštěč", "delete": "Smazat", @@ -2042,7 +2042,7 @@ }, "enable_selected": { "button": "Povolit vybrané", - "confirm_text": "Pokud budou nyní deaktivovány, budou opět k dispozici v Home Assistant.", + "confirm_text": "Tím se znovu zpřístupní v Home Assistant, pokud jsou nyní deaktivované.", "confirm_title": "Chcete povolit {number} {number, plural,\n one {entitu}\n few {entity}\n other {entit}\n}?" }, "filter": { diff --git a/translations/frontend/en.json b/translations/frontend/en.json index 9c59dfc713..35b156baba 100644 --- a/translations/frontend/en.json +++ b/translations/frontend/en.json @@ -1239,10 +1239,12 @@ "notification_toast": { "connection_lost": "Connection lost. Reconnecting…", "dismiss": "Dismiss", + "intergration_starting": "Starting {integration}, not everything will be available until it is finished.", "service_call_failed": "Failed to call service {service}.", "started": "Home Assistant has started!", "starting": "Home Assistant is starting, not everything will be available until it is finished.", - "triggered": "Triggered {name}" + "triggered": "Triggered {name}", + "wrapping_up_startup": "Wrapping up startup, not everything will be available until it is finished." }, "panel": { "config": { @@ -1606,7 +1608,7 @@ "delete_automation": "Delete automation", "delete_confirm": "Are you sure you want to delete this automation?", "dev_automation": "Debug automation", - "dev_only_editable": "Only automations defined in automations.yaml are debuggable.", + "dev_only_editable": "Only automations that have a unique ID assigned are debuggable.", "duplicate": "Duplicate", "duplicate_automation": "Duplicate automation", "edit_automation": "Edit automation", diff --git a/translations/frontend/es.json b/translations/frontend/es.json index 933f3e43d1..2be24dde03 100644 --- a/translations/frontend/es.json +++ b/translations/frontend/es.json @@ -1130,6 +1130,7 @@ "reload": "{domain}", "rest": "Entidades rest y notificar servicios", "rpi_gpio": "Entidades GPIO de Raspberry Pi", + "scene": "Escenas", "script": "Scripts", "smtp": "Servicios de notificación SMTP", "statistics": "Entidades de estadísticas", @@ -2629,6 +2630,7 @@ "reload": "{domain}", "rest": "Entidades rest y notificar servicios", "rpi_gpio": "Entidades GPIO de Raspberry Pi", + "scene": "Escenas", "script": "Scripts", "smtp": "Servicios de notificación SMTP", "statistics": "Entidades de estadísticas", diff --git a/translations/frontend/ko.json b/translations/frontend/ko.json index f5c8990b8f..2529897008 100644 --- a/translations/frontend/ko.json +++ b/translations/frontend/ko.json @@ -290,7 +290,7 @@ "restart_name": "{name} 다시 시작하기", "running_version": "현재 {version} 버전을 실행 중입니다", "save": "저장하기", - "show_more": "이에 대한 자세한 정보 표시하기", + "show_more": "자세한 정보 표시하기", "update": "업데이트하기", "update_available": "{count, plural,\n one{개의 업데이트}\n other{{count}개의 업데이트}\n} 보류 중", "version": "버전", @@ -453,14 +453,14 @@ "failed_to_set_option": "Supervisor 옵션을 설정하지 못했습니다", "failed_to_update": "Supervisor를 업데이트하지 못했습니다", "join_beta_action": "베타 채널에 가입하기", - "join_beta_description": "Home Assistant (출시 직전버전), Supervisor 및 호스트에 대한 베타 업데이트를 가져옵니다", + "join_beta_description": "Home Assistant (출시 직전버전), Supervisor 및 호스트의 베타 업데이트를 가져옵니다", "leave_beta_action": "베타 채널에서 탈퇴하기", - "leave_beta_description": "Home Assistant, Supervisor 및 호스트에 대한 안정적인 업데이트를 가져옵니다", + "leave_beta_description": "Home Assistant, Supervisor 및 호스트의 공식 업데이트를 가져옵니다", "ram_usage": "Supervisor RAM 사용량", "reload_supervisor": "Supervisor 다시 읽어오기", "share_diagnostics": "진단 정보 공유하기", "share_diagnostics_description": "충돌 보고서 및 진단 정보를 공유합니다.", - "share_diagonstics_description": "Supervisor에서 예기치 않은 오류가 발생할 경우 충돌 보고서 및 진단 정보를 자동으로 공유하시겠습니까? {line_break} 공유된 내용으로 발생된 문제를 해결할 수 있으며, 해당 정보는 Home Assistant Core 팀에서만 접근할 수 있을 뿐, 다른 사람과 공유되지 않습니다.{line_break} 데이터에는 개인 및 민감한 정보가 포함되어 있지 않으므로 언제든지 설정에서 이 정보를 사용하지 않도록 설정할 수 있습니다.", + "share_diagonstics_description": "Supervisor에서 예기치 않은 오류가 발생한 경우 충돌 보고서 및 진단 정보를 자동으로 공유하시겠습니까? {line_break} 공유된 내용으로 발생된 문제를 해결할 수 있으며, 해당 정보는 Home Assistant Core 팀에서만 접근할 수 있을 뿐, 다른 사람과 공유되지 않습니다.{line_break} 데이터에는 개인정보 및 민감한 정보가 포함되어 있지 않으므로 언제든지 설정에서 이 정보를 사용하지 않도록 설정할 수 있습니다.", "share_diagonstics_title": "Home Assistant 개선 도와주기", "unhealthy_description": "비정상적으로 설치된 Supervisor를 실행하면 문제가 발생합니다. 다음은 설치 환경에서 발견된 문제 목록입니다. 문제를 해결하는 방법에 대해 알아보려면 링크를 클릭해주세요.", "unhealthy_reason": { @@ -1870,15 +1870,15 @@ "section": { "core": { "analytics": { - "documentation": "이 옵션을 활성화하기 전에 분석 관련 문서 페이지 {link}을(를) 방문하여 사용자 통계를 보내는 내용과 저장 방법에 대해 알아보세요.", + "documentation": "이 옵션을 활성화하기 전에 분석 관련 문서 페이지 {link}을(를) 방문하여 어떤 데이터가 공유되는지, 어떻게 저장되는지 알아보세요.", "header": "분석", "instance_id": "인스턴스 ID: {huuid}", - "introduction": "인스턴스의 분석 내용을 공유합니다. 이 데이터는 {link}에서 공개적으로 사용될 수 있습니다", - "learn_more": "통계자료가 어떻게 처리되는지 알아보기.", + "introduction": "설치 정보를 공유하여 Home Assistant를 개선하고 제조업체가 로컬 제어 및 개인 정보 보호 기능을 추가하도록 설득하는 데 도움이됩니다.", + "learn_more": "수집된 데이터가 어떻게 처리되는지 알아보기.", "needs_base": "이 옵션을 사용하려면 기본 분석을 활성화해야 합니다", "preference": { "base": { - "description": "여기에는 인스턴스 ID, 버전 및 설치 유형이 포함됩니다", + "description": "인스턴스 ID, 버전과 설치 방법.", "title": "기본 분석" }, "diagnostics": { @@ -1886,15 +1886,15 @@ "title": "진단" }, "statistics": { - "description": "여기에는 설치에 사용된 요소의 개수가 포함되며 전체 목록은 문서를 참조해주세요", + "description": "사용된 구성요소와 사용자계정 갯수 외 기타 요소.", "title": "사용 통계" }, "usage_supervisor": { - "description": "여기에는 통합 구성요소 및 애드온의 이름과 기능이 포함됩니다", + "description": "이름, 버전 그리고 기타 정보.", "title": "사용된 통합 구성요소 및 애드온" }, "usage": { - "description": "여기에는 통합 구성요소의 이름이 포함됩니다", + "description": "이름과 버전 정보.", "title": "사용된 통합 구성요소" } } @@ -3050,7 +3050,7 @@ "type": "이벤트 유형" }, "services": { - "accepts_target": "이 서비스는 대상을 지정받습니다. 예: `entity_id: light.bed_light`", + "accepts_target": "이 서비스는 대상을 지정할 수 있습니다. 예: `entity_id: light.bed_light`", "all_parameters": "사용 가능한 모든 매개 변수", "call_service": "서비스 호출", "column_description": "상세정보", @@ -3760,7 +3760,7 @@ "page-onboarding": { "analytics": { "finish": "다음", - "intro": "인스턴스의 분석 내용을 공유합니다. 이 데이터는 {link}에서 공개적으로 사용될 수 있습니다" + "intro": "시스템 분석 내용을 공유합니다. 이 데이터는 {link}에서 공개적으로 사용될 수 있습니다" }, "core-config": { "button_detect": "탐색", diff --git a/translations/frontend/nl.json b/translations/frontend/nl.json index aad14cec2d..65c0047cf5 100644 --- a/translations/frontend/nl.json +++ b/translations/frontend/nl.json @@ -1433,9 +1433,9 @@ }, "sun": { "after": "Na:", - "after_offset": "Na offset (optioneel)", + "after_offset": "Afwijking na (optioneel)", "before": "Voor:", - "before_offset": "Voor offset (optioneel)", + "before_offset": "Afwijking voor (optioneel)", "label": "Zon", "sunrise": "Zonsopkomst", "sunset": "Zonsondergang" @@ -1561,7 +1561,7 @@ "sun": { "event": "Gebeurtenis:", "label": "Zon", - "offset": "Offset (optioneel)", + "offset": "Afwijking (optioneel)", "sunrise": "Zonsopkomst", "sunset": "Zonsondergang" }, @@ -1873,28 +1873,28 @@ "documentation": "Voordat u dit inschakelt, moet u de analytics documentatie pagina {link} bezoeken om te begrijpen wat u verstuurt en hoe het wordt opgeslagen.", "header": "Analytics", "instance_id": "Instantie-ID: {huuid}", - "introduction": "Deel analyses vanuit uw instantie. Deze gegevens zijn openbaar beschikbaar op {link}", - "learn_more": "Lees meer over hoe uw gegevens worden verwerkt.", + "introduction": "Deel uw installatie-informatie om Home Assistant te helpen verbeteren en ons te helpen fabrikanten te overtuigen om lokale controle en privacygerichte functies toe te voegen.", + "learn_more": "Hoe wij uw gegevens verwerken", "needs_base": "U moet basisanalyses inschakelen om deze optie beschikbaar te maken", "preference": { "base": { - "description": "Dit bevat de instantie-ID, de versie en het installatietype", + "description": "Instantie-ID, versie en installatietype.", "title": "Basisanalyses" }, "diagnostics": { - "description": "Deel crashrapporten en diagnostische informatie", + "description": "Deel crashrapporten wanneer onverwachte fouten optreden.", "title": "Diagnostiek" }, "statistics": { - "description": "Dit omvat een telling van elementen in uw installatie, voor een volledige lijst zie de documentatie", + "description": "Totaal gebruikte entiteiten, gebruikers en andere elementen.", "title": "Gebruiksstatistieken" }, "usage_supervisor": { - "description": "Dit omvat de namen en mogelijkheden van uw integraties en add-ons", + "description": "Namen, versies en mogelijkheden.", "title": "Gebruikte integraties en add-ons" }, "usage": { - "description": "Dit bevat de namen van uw integraties", + "description": "Namen en versie-informatie.", "title": "Gebruikte integraties" } } diff --git a/translations/frontend/ru.json b/translations/frontend/ru.json index 73175f13b4..5229e0c54a 100644 --- a/translations/frontend/ru.json +++ b/translations/frontend/ru.json @@ -762,7 +762,7 @@ "no_history_found": "История не найдена." }, "logbook": { - "by": "пользователем", + "by": "- инициатор:", "by_service": "службой", "entries_not_found": "В журнале нет записей.", "messages": { @@ -1687,7 +1687,7 @@ "info_state_reporting": "Если Вы активируете этот параметр, Home Assistant будет отправлять все изменения состояний объектов, доступных Amazon. Это позволит Вам всегда видеть актуальные состояния в приложениях Alexa и использовать изменения состояний для автоматизации повседневных задач.", "manage_entities": "Управление объектами", "state_reporting_error": "Не удалось {enable_disable} отправку изменения состояний.", - "sync_entities": "Синхронизировать объекты с Amazon", + "sync_entities": "Синхронизировать объекты", "sync_entities_error": "Не удалось синхронизировать объекты:", "title": "Alexa" }, diff --git a/translations/frontend/zh-Hans.json b/translations/frontend/zh-Hans.json index b1effc5b06..e0b401d4a7 100644 --- a/translations/frontend/zh-Hans.json +++ b/translations/frontend/zh-Hans.json @@ -473,6 +473,7 @@ "unhealthy_title": "系统状态不佳", "unsupported_description": "以下是系统存在的问题的列表,请点击链接以了解如何解决问题。", "unsupported_reason": { + "apparmor": "主机上未启用AppArmor", "container": "已知会导致问题的容器", "content-trust": "内容信任验证已禁用", "dbus": "DBUS", @@ -1213,6 +1214,14 @@ "key_wrong_type": "“{key}”的值不受可视化编辑器支持。支持 ({type_correct}) 但得到 ({type_wrong})。", "no_template_editor_support": "可视化编辑器不支持模板", "no_type_provided": "未提供类型。" + }, + "supervisor": { + "ask": "寻求帮助", + "observer": "检查 Observer", + "reboot": "请尝试重启主机", + "system_health": "检查系统健康状况", + "title": "无法加载 Supervisor 面板!", + "wait": "如果系统刚刚启动,请确保已等候足够的时间以便 Supervisor 启动完成。" } }, "login-form": { @@ -1864,8 +1873,8 @@ "documentation": "在启用此功能之前,请确保您已阅读了分析文档页面 {link},以了解将发送的内容及其存储方式。", "header": "分析", "instance_id": "实例ID: {huuid}", - "introduction": "共享实例的分析。此数据将在 {link} 公开。", - "learn_more": "详细了解您的数据将被如何处理。", + "introduction": "分享您的安装信息,让 Home Assistant 变得更好,并帮助我们与厂商沟通,增加本地控制和注重隐私的功能。", + "learn_more": "详细了解您的数据将被如何处理", "needs_base": "需要启用基础分析才能启用此选项", "preference": { "base": { @@ -1873,7 +1882,7 @@ "title": "基础分析" }, "diagnostics": { - "description": "共享崩溃报告和诊断信息", + "description": "发生意外错误时共享崩溃报告。", "title": "诊断" }, "statistics": { @@ -1881,11 +1890,11 @@ "title": "使用情况统计" }, "usage_supervisor": { - "description": "包括集成和加载项的名称和能力", + "description": "名称,版本和功能。", "title": "使用的集成和加载项" }, "usage": { - "description": "包括集成的名称", + "description": "名称和版本信息。", "title": "使用的集成" } } From 9833accc799e5e8e96acf5c8192045ebb33adac5 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 8 Apr 2021 23:01:12 -0700 Subject: [PATCH 016/106] Fix failed conditions reason (#8870) --- gallery/src/demos/demo-automation-trace-timeline.ts | 2 +- src/components/trace/hat-trace-timeline.ts | 2 +- src/data/trace.ts | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/gallery/src/demos/demo-automation-trace-timeline.ts b/gallery/src/demos/demo-automation-trace-timeline.ts index 2a8ecce1fa..740c589023 100644 --- a/gallery/src/demos/demo-automation-trace-timeline.ts +++ b/gallery/src/demos/demo-automation-trace-timeline.ts @@ -17,7 +17,7 @@ import { DemoTrace } from "../data/traces/types"; const traces: DemoTrace[] = [ mockDemoTrace({ state: "running" }), mockDemoTrace({ state: "debugged" }), - mockDemoTrace({ state: "stopped", script_execution: "failed_condition" }), + mockDemoTrace({ state: "stopped", script_execution: "failed_conditions" }), mockDemoTrace({ state: "stopped", script_execution: "failed_single" }), mockDemoTrace({ state: "stopped", script_execution: "failed_max_runs" }), mockDemoTrace({ state: "stopped", script_execution: "finished" }), diff --git a/src/components/trace/hat-trace-timeline.ts b/src/components/trace/hat-trace-timeline.ts index 742c6c839c..a17cb3c81e 100644 --- a/src/components/trace/hat-trace-timeline.ts +++ b/src/components/trace/hat-trace-timeline.ts @@ -475,7 +475,7 @@ export class HaAutomationTracer extends LitElement { let extra: TemplateResult | undefined; switch (this.trace.script_execution) { - case "failed_condition": + case "failed_conditions": reason = "a condition failed"; break; case "failed_single": diff --git a/src/data/trace.ts b/src/data/trace.ts index abe9d06830..cf5f18e6c2 100644 --- a/src/data/trace.ts +++ b/src/data/trace.ts @@ -66,7 +66,7 @@ export interface AutomationTrace { }; script_execution: | // The script was not executed because the automation's condition failed - "failed_condition" + "failed_conditions" // The script was not executed because the run mode is single | "failed_single" // The script was not executed because max parallel runs would be exceeded @@ -80,8 +80,7 @@ export interface AutomationTrace { | "error" // The exception is in the trace itself or in the last element of the trace // Script execution stopped by async_stop called on the script run because home assistant is shutting down, script mode is SCRIPT_MODE_RESTART etc: - | "cancelled" - | string; + | "cancelled"; // Automation only, should become it's own type when we support script in frontend trigger: string; } From ed1cd4632f8c846cd26933c4314516e07ab2cf7f Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sat, 10 Apr 2021 00:48:37 +0000 Subject: [PATCH 017/106] Translation update --- translations/frontend/cs.json | 5 +++-- translations/frontend/de.json | 8 +++++--- translations/frontend/es.json | 8 +++++--- translations/frontend/et.json | 6 ++++-- translations/frontend/fr.json | 19 +++++++++++++++++-- translations/frontend/it.json | 6 ++++-- translations/frontend/ja.json | 4 ++-- translations/frontend/ko.json | 6 ++++-- translations/frontend/nb.json | 6 ++++-- translations/frontend/ru.json | 6 ++++-- translations/frontend/zh-Hant.json | 6 ++++-- 11 files changed, 56 insertions(+), 24 deletions(-) diff --git a/translations/frontend/cs.json b/translations/frontend/cs.json index f79ba25073..0e4a29f33d 100644 --- a/translations/frontend/cs.json +++ b/translations/frontend/cs.json @@ -307,7 +307,7 @@ }, "update": { "text": "Opravdu chcete aktualizovat {name} na verzi {version}?", - "title": "Aktualizovat {název}" + "title": "Aktualizovat {name}" } }, "dashboard": { @@ -1239,6 +1239,7 @@ "notification_toast": { "connection_lost": "Připojení bylo ztraceno. Připojuji se znovu...", "dismiss": "Zavřít", + "intergration_starting": "Integrace {integration} se spouští - dokud nebude spuštění dokončeno, nemusí být vše k dispozici.", "service_call_failed": "Službu {service} se nepodařilo zavolat.", "started": "Home Assistant je spuštěn!", "starting": "Home Assistant se spouští, ne všechno bude k dispozici, dokud nebude spuštění dokončeno.", @@ -1606,7 +1607,7 @@ "delete_automation": "Odstranit automatizaci", "delete_confirm": "Opravdu chcete odstranit tuto automatizaci?", "dev_automation": "Debugování automatizace", - "dev_only_editable": "Pouze automatizace definované v automations.yaml jsou debugovatelné", + "dev_only_editable": "Pouze automatizace s unikátní ID jsou debugovatelné.", "duplicate": "Duplikát", "duplicate_automation": "Duplikovat automatizaci", "edit_automation": "Upravit automatizaci", diff --git a/translations/frontend/de.json b/translations/frontend/de.json index 50ce985e6a..a55df9731e 100644 --- a/translations/frontend/de.json +++ b/translations/frontend/de.json @@ -1239,10 +1239,12 @@ "notification_toast": { "connection_lost": "Verbindung getrennt. Verbinde erneut...", "dismiss": "Ausblenden", + "intergration_starting": "Starte {integration}. Währenddessen ist noch nicht alles verfügbar.", "service_call_failed": "Fehler beim Aufrufen des Diensts {service}.", "started": "Home Assistant wurde vollständig gestartet!", - "starting": "Home Assistant startet. Währenddessen kann es sein, dass nicht alles verfügbar ist.", - "triggered": "{name} ausgelöst" + "starting": "Home Assistant startet. Währenddessen ist noch nicht alles verfügbar.", + "triggered": "{name} ausgelöst", + "wrapping_up_startup": "Startvorgang fast fertig. Währenddessen ist noch nicht alles verfügbar." }, "panel": { "config": { @@ -1606,7 +1608,7 @@ "delete_automation": "Automatisierung löschen", "delete_confirm": "Bist du sicher, dass du diese Automatisierung löschen möchtest?", "dev_automation": "Automatisierung debuggen", - "dev_only_editable": "Nur Automatisierungen in automations.yaml können debuggt werden.", + "dev_only_editable": "Nur Automatisierungen, die eine eindeutige ID haben, können debuggt werden.", "duplicate": "Duplizieren", "duplicate_automation": "Automatisierung duplizieren", "edit_automation": "Automatisierung bearbeiten", diff --git a/translations/frontend/es.json b/translations/frontend/es.json index 2be24dde03..4de1126bc6 100644 --- a/translations/frontend/es.json +++ b/translations/frontend/es.json @@ -768,7 +768,7 @@ "messages": { "became_unavailable": "dejó de estar disponible", "changed_to_state": "cambiado a {state}", - "cleared_device_class": "borrado (no se detecta {device_class})", + "cleared_device_class": "despejado (no se detecta {device_class})", "detected_device_class": "detectado {device_class}", "is_closing": "se está cerrando", "is_opening": "se está abriendo", @@ -1239,10 +1239,12 @@ "notification_toast": { "connection_lost": "Conexión perdida. Reconectando...", "dismiss": "Descartar", + "intergration_starting": "Iniciando {integration}, no estará todo disponible hasta que finalice.", "service_call_failed": "Error al llamar al servicio {service}.", "started": "¡Home Assistant se ha iniciado!", "starting": "Home Assistant se está iniciando, no estará todo disponible hasta que finalice.", - "triggered": "Activado {name}" + "triggered": "Activado {name}", + "wrapping_up_startup": "Completando el inicio, no estará todo disponible hasta que finalice." }, "panel": { "config": { @@ -1606,7 +1608,7 @@ "delete_automation": "Eliminar la automatización", "delete_confirm": "¿Estás seguro de que quieres eliminar esta automatización?", "dev_automation": "Depurar automatización", - "dev_only_editable": "Solo las automatizaciones definidas en automations.yaml se pueden depurar", + "dev_only_editable": "Solo las automatizaciones que tienen un ID único asignado se pueden depurar.", "duplicate": "Duplicar", "duplicate_automation": "Duplicar la automatización", "edit_automation": "Editar automatización", diff --git a/translations/frontend/et.json b/translations/frontend/et.json index 1a88fc93b8..3b061b6455 100644 --- a/translations/frontend/et.json +++ b/translations/frontend/et.json @@ -1239,10 +1239,12 @@ "notification_toast": { "connection_lost": "Ühendus kadunud. Taasühendamine...", "dismiss": "Loobu", + "intergration_starting": "Sidumine {integration} käivitub, kõik elemendid pole veel saadaval.", "service_call_failed": "Teenuse {service} väljakutsumine ebaõnnestus.", "started": "Home Assistant on käivitunud!", "starting": "Home Assistant käivitub, kõik elemendid ei pruugi veel saadaval olla", - "triggered": "Käivitati {name}" + "triggered": "Käivitati {name}", + "wrapping_up_startup": "Lõpetan käivitumist, kõik elemendid pole veel saadaval." }, "panel": { "config": { @@ -1606,7 +1608,7 @@ "delete_automation": "Kustuta automatiseering", "delete_confirm": "Oled kindel, et soovid selle automatiseeringu kustutada?", "dev_automation": "Automatiseeringu silumine", - "dev_only_editable": "Siluda saab ainult kirjes automations.yaml olevaid automatiseeringuid.", + "dev_only_editable": "Siluda saab ainult kordumatu ID-ga automatiseeringuid.", "duplicate": "Paljunda", "duplicate_automation": "Paljunda automatiseering", "edit_automation": "Muuda automatiseeringut", diff --git a/translations/frontend/fr.json b/translations/frontend/fr.json index 6002e035da..0b76df15d1 100644 --- a/translations/frontend/fr.json +++ b/translations/frontend/fr.json @@ -1213,6 +1213,11 @@ "key_wrong_type": "La valeur fournie pour \"{key}\" n'est pas prise en charge par l'éditeur visuel. Nous supportons ({type_correct}) mais avons reçu ({type_wrong}).", "no_template_editor_support": "Modèles non pris en charge dans l'éditeur visuel", "no_type_provided": "Aucun type fourni." + }, + "supervisor": { + "ask": "Demandez de l’aide", + "reboot": "Essayez un redémarrage de l’hôte", + "wait": "Si vous venez de commencer, assurez-vous d’avoir donné au Superviseur suffisamment de temps pour démarrer." } }, "login-form": { @@ -2156,6 +2161,7 @@ "logs": "journaux", "manuf": "par {manufacturer}", "no_area": "Pas de zone", + "not_loaded": "Non chargé, vérifiez le {logs_link}", "options": "Options", "reload": "Recharger", "reload_confirm": "L'intégration a été rechargée", @@ -2234,6 +2240,7 @@ "details": "Détails du journal ( {level} )", "level": { "critical": "CRITIQUE", + "debug": "DEBUG", "error": "ERREUR", "info": "INFO", "warning": "ATTENTION" @@ -3034,6 +3041,7 @@ "column_parameter": "Paramètre", "description": "L'outil de développement 'services' vous permet d'appeler n'importe quel service disponible dans Home Assistant.", "fill_example_data": "Remplir des exemples de données", + "no_template_ui_support": "L'interface utilisateur ne prend pas en charge les modèles, vous pouvez toujours utiliser l'éditeur YAML.", "title": "Services", "ui_mode": "Passer en mode UI", "yaml_mode": "Passez en mode YAML", @@ -3849,9 +3857,16 @@ }, "number_format": { "description": "Définir le formatage des nombres", + "dropdown_label": "Format de nombre", "formats": { - "none": "Aucun" - } + "comma_decimal": "1,234,567.89", + "decimal_comma": "1.234.567,89", + "language": "Auto (utiliser le paramètre de langue)", + "none": "Aucun", + "space_comma": "1 234 567,89", + "system": "Utiliser les paramètres régionaux du système" + }, + "header": "Format de nombre" }, "push_notifications": { "add_device_prompt": { diff --git a/translations/frontend/it.json b/translations/frontend/it.json index c08de46641..c0d6fe6c52 100644 --- a/translations/frontend/it.json +++ b/translations/frontend/it.json @@ -1239,10 +1239,12 @@ "notification_toast": { "connection_lost": "Connessione persa. Riconnessione…", "dismiss": "Rimuovi", + "intergration_starting": "{integration} si sta avviando, non tutto sarà disponibile fino ad avvio completo.", "service_call_failed": "Fallita chiamata a servizio {service} .", "started": "Home Assistant si è avviato!", "starting": "Home Assistant si sta avviando, non tutto sarà disponibile fino ad avvio completo.", - "triggered": "Attivato {name}" + "triggered": "Attivato {name}", + "wrapping_up_startup": "Si sta concludendo l'avvio, non tutto sarà disponibile fino al termine." }, "panel": { "config": { @@ -1606,7 +1608,7 @@ "delete_automation": "Elimina automazione", "delete_confirm": "Sei sicuro di voler eliminare questa automazione?", "dev_automation": "Debug dell'automazione", - "dev_only_editable": "È possibile eseguire il debug solo delle automazioni definite in automations.yaml.", + "dev_only_editable": "Solo le automazioni che hanno assegnato un ID univoco sono debuggabili.", "duplicate": "Duplica", "duplicate_automation": "Duplica automazione", "edit_automation": "Modifica automazione", diff --git a/translations/frontend/ja.json b/translations/frontend/ja.json index c2be0b070b..a983e5a011 100644 --- a/translations/frontend/ja.json +++ b/translations/frontend/ja.json @@ -767,9 +767,9 @@ "set": "セット", "turned_off": "オフになりました", "turned_on": "オンになりました", - "was_at_home": "家にいた", + "was_at_home": "在宅中", "was_at_state": "{state}でした", - "was_away": "離れていた", + "was_away": "外出中", "was_closed": "閉鎖されました", "was_connected": "接続されました", "was_disconnected": "切断されました", diff --git a/translations/frontend/ko.json b/translations/frontend/ko.json index 2529897008..85e4a107c8 100644 --- a/translations/frontend/ko.json +++ b/translations/frontend/ko.json @@ -1239,10 +1239,12 @@ "notification_toast": { "connection_lost": "서버와 연결이 끊어졌습니다. 다시 연결하는 중...", "dismiss": "해제하기", + "intergration_starting": "{integration} 시작 중. 완료되기 전 일부 기능은 작동하지 않을 수 있습니다.", "service_call_failed": "{service} 서비스를 호출하지 못했습니다.", "started": "Home Assistant가 시작되었습니다!", "starting": "Home Assistant가 시작됩니다. 완료될 때까지 모든 기능을 사용할 수 있는 것은 아닙니다.", - "triggered": "{name}이(가) 트리거됨" + "triggered": "{name}이(가) 트리거됨", + "wrapping_up_startup": "시작되기를 기다립니다. 완료되기 전 일부 기능은 작동하지 않을 수 있습니다." }, "panel": { "config": { @@ -1874,7 +1876,7 @@ "header": "분석", "instance_id": "인스턴스 ID: {huuid}", "introduction": "설치 정보를 공유하여 Home Assistant를 개선하고 제조업체가 로컬 제어 및 개인 정보 보호 기능을 추가하도록 설득하는 데 도움이됩니다.", - "learn_more": "수집된 데이터가 어떻게 처리되는지 알아보기.", + "learn_more": "수집된 데이터가 어떻게 처리되는지 알아보기", "needs_base": "이 옵션을 사용하려면 기본 분석을 활성화해야 합니다", "preference": { "base": { diff --git a/translations/frontend/nb.json b/translations/frontend/nb.json index 162c194a16..62c288b714 100644 --- a/translations/frontend/nb.json +++ b/translations/frontend/nb.json @@ -1239,10 +1239,12 @@ "notification_toast": { "connection_lost": "Forbindelsen ble brutt. Kobler til på nytt...", "dismiss": "Avvis", + "intergration_starting": "Fra og med {integration} vil ikke alt være tilgjengelig før den er ferdig.", "service_call_failed": "Kunne ikke tilkalle tjenesten: {service}", "started": "Home Assistant har startet!", "starting": "Home Assistant starter, alt er ikke tilgjengelig før starten er fullført.", - "triggered": "Utløst {name}" + "triggered": "Utløst {name}", + "wrapping_up_startup": "Ved oppstart, vil ikke alt være tilgjengelig før den er ferdig." }, "panel": { "config": { @@ -1606,7 +1608,7 @@ "delete_automation": "Slett automasjon", "delete_confirm": "Er du sikker på at du vil slette denne automasjonen?", "dev_automation": "Feilsøk automatisering", - "dev_only_editable": "Bare automatiseringer definert i automations.yaml kan feilsøkes.", + "dev_only_editable": "Bare automatisering som har en unik ID tildelt, kan feilsøkes.", "duplicate": "Dupliser", "duplicate_automation": "Dupliser automasjon", "edit_automation": "Rediger automasjon", diff --git a/translations/frontend/ru.json b/translations/frontend/ru.json index 5229e0c54a..31eea63b8a 100644 --- a/translations/frontend/ru.json +++ b/translations/frontend/ru.json @@ -1239,10 +1239,12 @@ "notification_toast": { "connection_lost": "Соединение потеряно. Повторное подключение ...", "dismiss": "Закрыть", + "intergration_starting": "Запуск {integration}, пока что не всё может быть доступно.", "service_call_failed": "Не удалось вызвать службу {service}.", "started": "Home Assistant работает!", "starting": "Home Assistant запускается, пока что не всё может быть доступно.", - "triggered": "Сработало от {name}" + "triggered": "Сработало от {name}", + "wrapping_up_startup": "Завершение запуска, пока что не всё может быть доступно." }, "panel": { "config": { @@ -1606,7 +1608,7 @@ "delete_automation": "Удалить автоматизацию", "delete_confirm": "Вы уверены, что хотите удалить эту автоматизацию?", "dev_automation": "Отладка автоматизации", - "dev_only_editable": "Процесс отладки доступен только для автоматизаций, созданных в automations.yaml", + "dev_only_editable": "Процесс отладки доступен только для автоматизаций с уникальным идентификатором.", "duplicate": "Дублировать", "duplicate_automation": "Дублировать", "edit_automation": "Редактировать автоматизацию", diff --git a/translations/frontend/zh-Hant.json b/translations/frontend/zh-Hant.json index 4dcfdcfec2..49da45aa5b 100644 --- a/translations/frontend/zh-Hant.json +++ b/translations/frontend/zh-Hant.json @@ -1239,10 +1239,12 @@ "notification_toast": { "connection_lost": "連線中斷。重新連線中...", "dismiss": "關閉", + "intergration_starting": "{integration} 正在啟動,在完成載入前、可能無法顯示所有功能。", "service_call_failed": "服務 {service} 執行失敗。", "started": "Home Assistant 已啟動!", "starting": "Home Assistant 正在啟動,在完成載入前、可能無法顯示所有功能。", - "triggered": "觸發 {name}" + "triggered": "觸發 {name}", + "wrapping_up_startup": "啟動完成中,在完成載入前、可能無法顯示所有功能。" }, "panel": { "config": { @@ -1606,7 +1608,7 @@ "delete_automation": "刪除自動化", "delete_confirm": "確定要刪除此自動化?", "dev_automation": "自動化除錯", - "dev_only_editable": "僅有於 automations.yaml 內定義的自動化、方能進行除錯。", + "dev_only_editable": "僅有具有唯一 ID 指派的自動化、方能進行除錯。", "duplicate": "複製", "duplicate_automation": "複製自動化", "edit_automation": "編輯自動化", From db122346113922064764b9e27db699a5da9eaa83 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 11 Apr 2021 00:48:30 +0000 Subject: [PATCH 018/106] Translation update --- translations/frontend/de.json | 6 +++--- translations/frontend/fr.json | 26 +++++++++++++++++++++++--- translations/frontend/nl.json | 8 +++++--- translations/frontend/pl.json | 6 ++++-- translations/frontend/zh-Hans.json | 4 +++- 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/translations/frontend/de.json b/translations/frontend/de.json index a55df9731e..0b79a86bd8 100644 --- a/translations/frontend/de.json +++ b/translations/frontend/de.json @@ -724,7 +724,7 @@ "today": "Heute" }, "data-table": { - "clear": "Leeren", + "clear": "Löschen", "filtering_by": "Filtern nach", "hidden": "{number} ausgeblendet", "no-data": "Keine Daten", @@ -2084,7 +2084,7 @@ } }, "filtering": { - "clear": "Leeren", + "clear": "Löschen", "filtering_by": "Filtern nach", "show": "Anzeigen" }, @@ -2254,7 +2254,7 @@ "introduction": "Hier ist es möglich, deine Komponenten und Home Assistant zu konfigurieren. Noch ist nicht alles über die GUI einstellbar, aber wir arbeiten daran.", "logs": { "caption": "Logs", - "clear": "Leeren", + "clear": "Löschen", "description": "Home Assistant Logs einsehen", "details": "Protokolldetails ({level})", "level": { diff --git a/translations/frontend/fr.json b/translations/frontend/fr.json index 0b76df15d1..9340add2f1 100644 --- a/translations/frontend/fr.json +++ b/translations/frontend/fr.json @@ -473,6 +473,7 @@ "unhealthy_title": "Votre installation est défectueuse", "unsupported_description": "Vous trouverez ci-dessous une liste des problèmes rencontrés avec votre installation, cliquez sur les liens pour savoir comment vous pouvez résoudre les problèmes.", "unsupported_reason": { + "apparmor": "AppArmo n'est pas activé sur l'hôte", "container": "Conteneurs connus pour causer des problèmes", "content-trust": "La validation de la confiance du contenu est désactivée", "dbus": "DBUS", @@ -1216,7 +1217,10 @@ }, "supervisor": { "ask": "Demandez de l’aide", + "observer": "Vérifiez l'observateur", "reboot": "Essayez un redémarrage de l’hôte", + "system_health": "Vérifier la santé du système", + "title": "Impossible de charger le panneau du Supervisor!", "wait": "Si vous venez de commencer, assurez-vous d’avoir donné au Superviseur suffisamment de temps pour démarrer." } }, @@ -1235,10 +1239,12 @@ "notification_toast": { "connection_lost": "Connexion perdue. Reconnexion en cours ...", "dismiss": "Ignorer", + "intergration_starting": "Démarrage de {integration}, tout ne sera pas disponible tant qu'il n'aura pas terminé", "service_call_failed": "Échec d'appel du service \"{service}\".", "started": "Home Assistant a démarré !", "starting": "Home Assistant est en cours de démarrage, tout ne sera pas disponible tant qu’il n’aura pas terminé.", - "triggered": "{name} déclenché" + "triggered": "{name} déclenché", + "wrapping_up_startup": "En terminant le démarrage, tout ne sera pas disponible tant qu'il ne sera pas terminé." }, "panel": { "config": { @@ -1867,17 +1873,30 @@ "core": { "analytics": { "documentation": "Avant d'activer cette fonction, prenez soin de visiter la page de documentation {link} afin de comprendre ce que vous envoyez et comment cela est conservé.", + "header": "Analytique", "instance_id": "ID de l'instance: {huuid}", - "learn_more": "En appendre plus sur le traitement de vos données", + "introduction": "Partagez vos informations d'installation pour améliorer Home Assistant et nous aider à convaincre les fabricants d'ajouter des fonctionnalités de contrôle local et de confidentialité.", + "learn_more": "En apprendre plus sur le traitement de vos données", + "needs_base": "Vous devez activer l'analyse de base pour que cette option soit disponible", "preference": { + "base": { + "description": "ID de l'instance, version et type d'installation.", + "title": "Analyse de base" + }, "diagnostics": { "description": "Partager les rapports d'accident et les informations de diagnostic", "title": "Diagnostiques" }, "statistics": { + "description": "Nombre total d’entités, d’utilisateurs et d’autres éléments utilisés.", "title": "Statistiques d'utilisation" }, + "usage_supervisor": { + "description": "Noms, versions et fonctionnalités.", + "title": "Intégrations et add-ons utilisés" + }, "usage": { + "description": "Noms et versions", "title": "Intégrations utilisées" } } @@ -3742,7 +3761,8 @@ }, "page-onboarding": { "analytics": { - "finish": "Suivant" + "finish": "Suivant", + "intro": "Partagez les analyses de votre instance. Ces données seront accessibles au public à l' {link}" }, "core-config": { "button_detect": "Détecter", diff --git a/translations/frontend/nl.json b/translations/frontend/nl.json index 65c0047cf5..1ef809d900 100644 --- a/translations/frontend/nl.json +++ b/translations/frontend/nl.json @@ -1239,10 +1239,12 @@ "notification_toast": { "connection_lost": "Verbinding verbroken. Opnieuw verbinden...", "dismiss": "Afwijzen", + "intergration_starting": "Start {integration}, niet alles is beschikbaar totdat het voltooid is.", "service_call_failed": "Kan service {service} niet aanroepen", "started": "Home Assistant is gestart!", - "starting": "Home Assistant is aan het opstarten. Gedurende het opstarten is niet alles beschikbaar.", - "triggered": "Geactiveerd {name}" + "starting": "Home Assistant is aan het opstarten. Tijdens het opstarten is niet alles beschikbaar.", + "triggered": "Geactiveerd {name}", + "wrapping_up_startup": "Opstarten aan het afronden, niet alles is beschikbaar totdat het voltooid is." }, "panel": { "config": { @@ -3596,7 +3598,7 @@ "entity_non_numeric": "Entiteit is niet-numeriek: {entity}", "entity_not_found": "Entiteit niet beschikbaar: {entity}", "entity_unavailable": "Entiteit is momenteel niet beschikbaar: {entity}", - "starting": "Home Assistant is aan het opstarten, wellicht is nog niet alles beschikbaar" + "starting": "Home Assistant is aan het opstarten, nog niet alles is beschikbaar" } }, "mailbox": { diff --git a/translations/frontend/pl.json b/translations/frontend/pl.json index aa912786b1..a77f468777 100644 --- a/translations/frontend/pl.json +++ b/translations/frontend/pl.json @@ -1239,10 +1239,12 @@ "notification_toast": { "connection_lost": "Utracono połączenie. Łączę ponownie...", "dismiss": "Ukryj", + "intergration_starting": "{integration} uruchamia się, nie wszystko będzie dostępne, dopóki uruchamianie się nie zakończy.", "service_call_failed": "Nie udało się wywołać usługi {service}.", "started": "Home Assistant uruchomił się!", "starting": "Home Assistant uruchamia się, nie wszystko będzie dostępne, dopóki uruchamianie się nie zakończy.", - "triggered": "Wyzwolenie {name}" + "triggered": "Wyzwolenie {name}", + "wrapping_up_startup": "Home Assistant uruchamia się, nie wszystko będzie dostępne, dopóki uruchamianie się nie zakończy." }, "panel": { "config": { @@ -1606,7 +1608,7 @@ "delete_automation": "Usuń automatyzację", "delete_confirm": "Czy na pewno chcesz usunąć tę automatyzację?", "dev_automation": "Debuguj automatyzację", - "dev_only_editable": "Można debugować tylko automatyzacje zdefiniowane w pliku automations.yaml.", + "dev_only_editable": "Można debugować tylko automatyzacje mające unikalne identyfikatory.", "duplicate": "Duplikuj", "duplicate_automation": "Duplikuj automatyzację", "edit_automation": "Edytuj automatyzację", diff --git a/translations/frontend/zh-Hans.json b/translations/frontend/zh-Hans.json index e0b401d4a7..1c3f39e16d 100644 --- a/translations/frontend/zh-Hans.json +++ b/translations/frontend/zh-Hans.json @@ -1239,10 +1239,12 @@ "notification_toast": { "connection_lost": "连接中断。正在重新连接...", "dismiss": "关闭", + "intergration_starting": "正在启动 {integration}。在启动完成前,部分功能暂不可用。", "service_call_failed": "调用服务 {service} 失败。", "started": "Home Assistant 已启动!", "starting": "Home Assistant 正在启动。在启动完成前,部分功能暂不可用。", - "triggered": "已触发 {name}" + "triggered": "已触发 {name}", + "wrapping_up_startup": "启动即将完成。完成后即可使用全部功能。" }, "panel": { "config": { From 73f945458ac36c992550f3a1a3dbfb44b9cda835 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 12 Apr 2021 00:48:46 +0000 Subject: [PATCH 019/106] Translation update --- translations/frontend/zh-Hans.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/translations/frontend/zh-Hans.json b/translations/frontend/zh-Hans.json index 1c3f39e16d..d234f0c7f2 100644 --- a/translations/frontend/zh-Hans.json +++ b/translations/frontend/zh-Hans.json @@ -950,7 +950,7 @@ }, "faq": "文档", "info_customize": "您可以在{customize_link}部分中覆盖一些属性。", - "no_unique_id": "该实体 (\"{entity_id}\") 没有唯一的 ID,因此无法由 UI 管理其设置。请参阅 {faq_link} 以详细了解。", + "no_unique_id": "该实体 (\"{entity_id}\") 没有 unique ID,因此无法由 UI 管理其设置。请参阅 {faq_link} 以详细了解。", "related": "关联", "settings": "设置" }, @@ -1608,7 +1608,7 @@ "delete_automation": "删除自动化", "delete_confirm": "您确定要删除此自动化吗?", "dev_automation": "调试自动化", - "dev_only_editable": "只能调试 automations.yaml 中的自动化。", + "dev_only_editable": "只能调试具有 unique ID 的自动化。", "duplicate": "制作副本", "duplicate_automation": "复制自动化", "edit_automation": "编辑自动化", From c03017208d0eaf701868d267e53924aac268b026 Mon Sep 17 00:00:00 2001 From: Charles Garwood Date: Mon, 12 Apr 2021 14:17:31 -0400 Subject: [PATCH 020/106] Remove link/text about ZHA/Z-Wave config panels moving to integration page (#8867) --- .../config/dashboard/ha-config-dashboard.ts | 30 ------------------- src/translations/en.json | 5 ---- 2 files changed, 35 deletions(-) diff --git a/src/panels/config/dashboard/ha-config-dashboard.ts b/src/panels/config/dashboard/ha-config-dashboard.ts index b6dfd0bfc1..5e4afb8cf0 100644 --- a/src/panels/config/dashboard/ha-config-dashboard.ts +++ b/src/panels/config/dashboard/ha-config-dashboard.ts @@ -79,36 +79,6 @@ class HaConfigDashboard extends LitElement { ` )} - ${isComponentLoaded(this.hass, "zha") - ? html` -
- ${this.hass.localize( - "ui.panel.config.integration_panel_move.missing_zha", - "integrations_page", - html` - ${this.hass.localize( - "ui.panel.config.integration_panel_move.link_integration_page" - )} - ` - )} -
- ` - : ""} - ${isComponentLoaded(this.hass, "zwave") - ? html` -
- ${this.hass.localize( - "ui.panel.config.integration_panel_move.missing_zwave", - "integrations_page", - html` - ${this.hass.localize( - "ui.panel.config.integration_panel_move.link_integration_page" - )} - ` - )} -
- ` - : ""} ${!this.showAdvanced ? html`
diff --git a/src/translations/en.json b/src/translations/en.json index 65ec334f84..9a79e8ff86 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -876,11 +876,6 @@ "hint_enable": "Missing config options? Enable advanced mode on", "link_profile_page": "your profile page" }, - "integration_panel_move": { - "missing_zha": "Missing the ZHA config panel? It was moved to the ZHA entry on the {integrations_page}.", - "missing_zwave": "Missing the Z-Wave config panel? It was moved to the Z-Wave entry on the {integrations_page}.", - "link_integration_page": "integrations page" - }, "common": { "editor": { "confirm_unsaved": "You have unsaved changes. Are you sure you want to leave?" From d00927c31fe4e6efe5780a71b1be8fa7b60fa43a Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 12 Apr 2021 22:04:58 +0200 Subject: [PATCH 021/106] Update codemirror (#8903) --- package.json | 3 +-- yarn.lock | 63 ++++++++++++++++++++++++---------------------------- 2 files changed, 30 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index d0482825d6..66acebbe3e 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@braintree/sanitize-url": "^5.0.0", "@codemirror/commands": "^0.18.0", "@codemirror/gutter": "^0.18.0", - "@codemirror/highlight": "^0.18.1", + "@codemirror/highlight": "^0.18.0", "@codemirror/history": "^0.18.0", "@codemirror/legacy-modes": "^0.18.0", "@codemirror/rectangular-selection": "^0.18.0", @@ -100,7 +100,6 @@ "@webcomponents/webcomponentsjs": "^2.2.7", "chart.js": "~2.8.0", "chartjs-chart-timeline": "^0.3.0", - "codemirror": "^5.49.0", "comlink": "^4.3.0", "core-js": "^3.6.5", "cropperjs": "^1.5.7", diff --git a/yarn.lock b/yarn.lock index da1bba399b..1c1ffef5e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1906,9 +1906,9 @@ integrity sha512-WmKrB/575EJCzbeSJR3YQ5sET5FaizeljLRw1382qVUeGqzuWBgIS+AF5a0FO51uQTrDpoRgvuHC2IWVsgwkkA== "@codemirror/commands@^0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-0.18.0.tgz#10344d7d7a0fecad826e9853c1e6069d706298c6" - integrity sha512-4H63B4oqr8dmJ3VOKvMI7xrZIBJjAdtz3Z0V/Jt0HlIYTe76Omy4h9BS3b9EgyNaWjIO/Slz3KQPwihcC8uR5Q== + version "0.18.1" + resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-0.18.1.tgz#2866a15936b7ab3ff30112eb1887a0e01fef6205" + integrity sha512-JBdGjRTCHi/eVsj5oL1S4kzhepyUVW0EnmOvwh1IYH9iN6FnRkEgaxJBryRgbos7Or8RomOKK01pprGjfqN6oA== dependencies: "@codemirror/language" "^0.18.0" "@codemirror/matchbrackets" "^0.18.0" @@ -1926,7 +1926,7 @@ "@codemirror/state" "^0.18.0" "@codemirror/view" "^0.18.0" -"@codemirror/highlight@^0.18.0", "@codemirror/highlight@^0.18.1": +"@codemirror/highlight@^0.18.0": version "0.18.3" resolved "https://registry.yarnpkg.com/@codemirror/highlight/-/highlight-0.18.3.tgz#50e268630f113c322a2dc97c9f68d71934fffcb0" integrity sha512-NmRmkmWl8ht6Y6Y39ghov84AMPCqhUPIH9fmILs2NaWxZFZf4jGCTzrULnmREGsTie+26+LbKUncIU+PBu1Qng== @@ -1939,17 +1939,17 @@ style-mod "^4.0.0" "@codemirror/history@^0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@codemirror/history/-/history-0.18.0.tgz#1267499e20f977b5b4179ec2cfd5013d78ab0cbc" - integrity sha512-oMpvu7c8GQnEn1nX98+WuVQuMEVxOPJFU1yrA22sWfqG7lkrJAv7p4geCWOpwQY9/LWw4sICkDbCeirre4BqBA== + version "0.18.1" + resolved "https://registry.yarnpkg.com/@codemirror/history/-/history-0.18.1.tgz#853cde4b138b172235d58f945871f0fc08b7310a" + integrity sha512-Aad3p4zs6UYKCUMXYjh7cvPK0ajuL+rMib9yBZ61w81LLl6OkM31Xrn9J6CLJmPxCwP3OJFiqBmNSBQ05oIsTw== dependencies: - "@codemirror/state" "^0.18.0" + "@codemirror/state" "^0.18.3" "@codemirror/view" "^0.18.0" "@codemirror/language@^0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-0.18.0.tgz#16c3beaf372d0ecfcb76d708a8f55efccaa25563" - integrity sha512-gryu0Sej1vG3S3njwsJ+bhz9zLoJxZ2TahLlxpqOB3uqVGZrGDyE+GmZBnA6I3hwHvaO1O4WXKScVsKoW6HqFA== + version "0.18.1" + resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-0.18.1.tgz#23682324228606c4ae5b6a9f7cd0a4b9fdff83dd" + integrity sha512-j/TWV8sNmzU79kk/hPLb9NqSPoH59850kQSpgY11LxOEBlKVRKgaWabgNtUCSeVCAnfisGekupk3aq2ftILqug== dependencies: "@codemirror/state" "^0.18.0" "@codemirror/text" "^0.18.0" @@ -1974,10 +1974,10 @@ "@codemirror/view" "^0.18.0" lezer-tree "^0.13.0" -"@codemirror/panel@^0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@codemirror/panel/-/panel-0.18.0.tgz#79726a4506f45b5abbe31a6dd80f4cd29a810e49" - integrity sha512-wgKpe+QRjZwFKoMbMxqUFlV4j3dvgm8Q4v12SS0L6yxnFZkMsdbmowh0+pBa1Cp5iTSb0pdEOjAQaiWFZyIk9g== +"@codemirror/panel@^0.18.1": + version "0.18.1" + resolved "https://registry.yarnpkg.com/@codemirror/panel/-/panel-0.18.1.tgz#b2179cdfb7d7c2913ba682d61d00edff160cfad0" + integrity sha512-5Zo9cUw0QDlFzX4nhIDYjTARPOnPk5rzxAUQo1O35kTLV+6zRh7wsGlvU7VrZnBcIoaAmHfKrZ4lt6+h7fbFGw== dependencies: "@codemirror/state" "^0.18.0" "@codemirror/view" "^0.18.0" @@ -1999,28 +1999,28 @@ "@codemirror/view" "^0.18.0" "@codemirror/search@^0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@codemirror/search/-/search-0.18.0.tgz#aabb53d4678196e82309241753cd67403149e35d" - integrity sha512-gjg1yDz6gof0lhOEzjqofidd5tH2dwUwiyzym6E78n3tZBh/KygLKmw0B0T9a5s9JTVZtzup95i+TmcHrz2MQg== + version "0.18.2" + resolved "https://registry.yarnpkg.com/@codemirror/search/-/search-0.18.2.tgz#7f6311ce4d5749d92aefb41b2f8628d28d90918c" + integrity sha512-t90Ra34piJDF589hNDmuA1fVKCFDh0FTuTZTHDmmSaWS5OWq2++zAwRTQnOdQD+uGfEUwLQPiLJzu60NDhA5xw== dependencies: - "@codemirror/panel" "^0.18.0" + "@codemirror/panel" "^0.18.1" "@codemirror/rangeset" "^0.18.0" "@codemirror/state" "^0.18.0" "@codemirror/text" "^0.18.0" "@codemirror/view" "^0.18.0" crelt "^1.0.5" -"@codemirror/state@^0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-0.18.0.tgz#5bb5600c5bf32d4103b6576cd33bdb8cf926d602" - integrity sha512-E5Tgx/CVmQQdiIOoJ4xX4hy2RGqTjxbpzDifGn8wUu3Driq/uZ+ncr7M4ojWs1T83yYFevNBmPtT5vprD25vYA== +"@codemirror/state@^0.18.0", "@codemirror/state@^0.18.3": + version "0.18.5" + resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-0.18.5.tgz#db936f80c40f329fb803bd284cbb5aa556dafb88" + integrity sha512-lHR+yE08jEz7MqA5hgNvK4/ksF2mQsJJ/pedKKfB94CUobMX20tsFQ27lZbXCxZDQcz5lO0AZuFuRqrbDlRtKA== dependencies: "@codemirror/text" "^0.18.0" "@codemirror/stream-parser@^0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@codemirror/stream-parser/-/stream-parser-0.18.0.tgz#d4eaf7043324bf9d20c518732a2ce2ff845256a5" - integrity sha512-qxtSBvn2kKMm0XlfJ0e7FbVIg10RsaNjX5n/jRWlK2Y0kHjk+Huk5vkkGR3vjwHDgRdfwQe/vqZtkPz3DFQpLQ== + version "0.18.1" + resolved "https://registry.yarnpkg.com/@codemirror/stream-parser/-/stream-parser-0.18.1.tgz#20248b79d0fb9243a1431437dba79112c025058e" + integrity sha512-Q7HXbZRbAg5SboM0/3Hw9bKX7UxRWVsrtFjeQXzti2be/VHfMUAykidqWwWHe1SSn3Me3izpw9vLNEoGCm7tBw== dependencies: "@codemirror/highlight" "^0.18.0" "@codemirror/language" "^0.18.0" @@ -2035,9 +2035,9 @@ integrity sha512-HMzHNIAbjCiCf3tEJMRg6ul01KPuXxQGNiHlHgAnqPguq/CX+L4Nvj5JlWQAI91Pupk18zhmM1c6eaazX4YeTg== "@codemirror/view@^0.18.0": - version "0.18.1" - resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-0.18.1.tgz#5fbc97acd28997ed2aafbe6e8d48d9446b4bf5ff" - integrity sha512-chyy+oEnywKMUFDMafVAMcrV+DkjJT3l6pSfN1cvM2LBM/eY54gekv/aXtmsBFRSnd+u09mhjb/kGB+EdNHIjg== + version "0.18.6" + resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-0.18.6.tgz#3598e72658e37b30e3260e4e623a81599b67a9a0" + integrity sha512-j0TtJbV+41g/0eGH7Pgx9wtO7Y3Rg0s9shLFGvUtJ4jMIimkCelQsEBtUmfEbNxAVXOsN+CbmsKg8M9p0ISeCA== dependencies: "@codemirror/rangeset" "^0.18.0" "@codemirror/state" "^0.18.0" @@ -5887,11 +5887,6 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -codemirror@^5.49.0: - version "5.49.0" - resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.49.0.tgz#adedbffcc81091e4a0334bcb96b1ae3b7ada5e3f" - integrity sha512-Hyzr0HToBdZpLBN9dYFO/KlJAsKH37/cXVHPAqa+imml0R92tb9AkmsvjnXL+SluEvjjdfkDgRjc65NG5jnMYA== - collection-map@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" From 9eb59062aae715e6910129a30e8b4517eb42b00e Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Mon, 12 Apr 2021 23:02:09 +0200 Subject: [PATCH 022/106] Increase supervisor metric value span width to account for blank (#8885) --- hassio/src/components/supervisor-metric.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hassio/src/components/supervisor-metric.ts b/hassio/src/components/supervisor-metric.ts index 25eabcdf60..5241733876 100644 --- a/hassio/src/components/supervisor-metric.ts +++ b/hassio/src/components/supervisor-metric.ts @@ -73,7 +73,7 @@ class SupervisorMetric extends LitElement { ); } .value { - width: 42px; + width: 48px; padding-right: 4px; } `; From ea60f7005b22261d2a4ad38f4e79d1319383587b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20D=C4=85browski?= Date: Mon, 12 Apr 2021 23:04:35 +0200 Subject: [PATCH 023/106] Fix saving entities of the device in scene editor (#8884) --- src/panels/config/scene/ha-scene-editor.ts | 26 ++++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/panels/config/scene/ha-scene-editor.ts b/src/panels/config/scene/ha-scene-editor.ts index 1f02dec32c..c3c9c32450 100644 --- a/src/panels/config/scene/ha-scene-editor.ts +++ b/src/panels/config/scene/ha-scene-editor.ts @@ -556,20 +556,18 @@ export class HaSceneEditor extends SubscribeMixin( if (this._entities.includes(entityId)) { return; } - this._entities = [...this._entities, entityId]; - this._storeState(entityId); - const entityRegistry = this._entityRegistryEntries.find( (entityReg) => entityReg.entity_id === entityId ); - if ( entityRegistry?.device_id && !this._devices.includes(entityRegistry.device_id) ) { - this._devices = [...this._devices, entityRegistry.device_id]; + this._pickDevice(entityRegistry.device_id); + } else { + this._entities = [...this._entities, entityId]; + this._storeState(entityId); } - this._dirty = true; } @@ -582,14 +580,12 @@ export class HaSceneEditor extends SubscribeMixin( this._dirty = true; } - private _devicePicked(ev: CustomEvent) { - const device = ev.detail.value; - (ev.target as any).value = ""; - if (this._devices.includes(device)) { + private _pickDevice(device_id: string) { + if (this._devices.includes(device_id)) { return; } - this._devices = [...this._devices, device]; - const deviceEntities = this._deviceEntityLookup[device]; + this._devices = [...this._devices, device_id]; + const deviceEntities = this._deviceEntityLookup[device_id]; if (!deviceEntities) { return; } @@ -600,6 +596,12 @@ export class HaSceneEditor extends SubscribeMixin( this._dirty = true; } + private _devicePicked(ev: CustomEvent) { + const device = ev.detail.value; + (ev.target as any).value = ""; + this._pickDevice(device); + } + private _deleteDevice(ev: Event) { const deviceId = (ev.target as any).device; this._devices = this._devices.filter((device) => device !== deviceId); From 56fe4b07f395bf8e87ced760744e3f5486f00718 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 13 Apr 2021 02:10:25 +0200 Subject: [PATCH 024/106] Show toast with call service error (#8904) --- .../service/developer-tools-service.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/panels/developer-tools/service/developer-tools-service.ts b/src/panels/developer-tools/service/developer-tools-service.ts index 4ad74bcd53..eef7f9ceb2 100644 --- a/src/panels/developer-tools/service/developer-tools-service.ts +++ b/src/panels/developer-tools/service/developer-tools-service.ts @@ -28,6 +28,7 @@ import { haStyle } from "../../../resources/styles"; import "../../../styles/polymer-ha-style"; import { HomeAssistant } from "../../../types"; import "../../../util/app-localstorage-document"; +import { showToast } from "../../../util/toast"; class HaPanelDevService extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -267,11 +268,22 @@ class HaPanelDevService extends LitElement { } ); - private _callService() { + private async _callService() { if (!this._serviceData?.service) { return; } - callExecuteScript(this.hass, [this._serviceData]); + try { + await callExecuteScript(this.hass, [this._serviceData]); + } catch (err) { + showToast(this, { + message: + this.hass.localize( + "ui.notification_toast.service_call_failed", + "service", + this._serviceData.service + ) + ` ${err.message}`, + }); + } } private _toggleYaml() { From 1d3b95d24f7b23e93286b40ec3a57ac1411bdae3 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 13 Apr 2021 00:49:02 +0000 Subject: [PATCH 025/106] Translation update --- translations/frontend/bg.json | 162 +++++++++++++++++++++++++---- translations/frontend/cs.json | 2 +- translations/frontend/el.json | 7 +- translations/frontend/ko.json | 8 +- translations/frontend/nb.json | 16 +-- translations/frontend/zh-Hans.json | 8 +- 6 files changed, 167 insertions(+), 36 deletions(-) diff --git a/translations/frontend/bg.json b/translations/frontend/bg.json index a7d1e42636..1549cdcbca 100644 --- a/translations/frontend/bg.json +++ b/translations/frontend/bg.json @@ -148,16 +148,26 @@ "full_access": { "title": "Пълен достъп до хардуера" }, + "ingress": { + "description": "Тази добавка използва Проникване (Ingress), за да вгради безопасно своя интерфейс в Home Assistant.", + "title": "Проникване" + }, "label": { + "apparmor": "apparmor", + "auth": "авт", "docker": "docker", "hardware": "хардуер", "hass": "hass", "hassio": "hassio", "host": "хост", - "rating": "рейтинг" + "host_pid": "хост pid", + "ingress": "Проникване", + "rating": "рейтинг", + "stage": "Етап" }, "role": { "admin": "админ", + "backup": "архивиране", "default": "по подразбиране", "homeassistant": "homeassistant", "manager": "мениджър" @@ -184,6 +194,7 @@ "title": "Показване в страничната лента" }, "protected": { + "description": "Блокира елевиран системен достъп на добавката", "title": "Режим на защита" }, "watchdog": { @@ -208,6 +219,9 @@ }, "failed_to_reset": "Нулирането на конфигурацията на добавката не бе успешно, {error}", "failed_to_save": "Запазването на конфигурацията на добавката не бе успешно, {error}", + "logs": { + "get_logs": "Неуспешно получаване журнали на добавка, {грешка}" + }, "panel": { "configuration": "Конфигурация", "documentation": "Документация", @@ -296,6 +310,8 @@ "password": "Парола", "registry": "Регистър", "remove": "Премахване", + "title_add": "Добавяне регистър на контейнер", + "title_manage": "Управление на регистрите на контейнери", "username": "Потребителско име" }, "repositories": { @@ -316,8 +332,9 @@ }, "my": { "error": "Възникна неизвестна грешка", - "error_addon_not_found": "Добавката не е намерена", - "faq_link": "My Home Assistant ЧЗВ" + "error_addon_not_found": "Не е намерена добавка", + "faq_link": "My Home Assistant ЧЗВ", + "not_supported": "Тази препратка не се поддържа от вашата Home Assistant инсталация. Последвайте {link} за поддържани препратки както и версиите при тяхното пускане." }, "panel": { "dashboard": "Табло", @@ -369,7 +386,9 @@ "change_hostname": "Промяна в името на хоста", "confirm_reboot": "Сигурни ли сте, че искате да рестартирате хоста?", "confirm_shutdown": "Сигурни ли сте, че искате да изключите хоста?", + "deployment": "Зареждане", "docker_version": "Версия на Docker", + "emmc_lifetime_used": "Използван живот на eMMC", "failed_to_get_hardware_list": "Неуспешно получаване на списъка с хардуер", "failed_to_import_from_usb": "Неуспешно импортиране от USB", "failed_to_reboot": "Неуспешно рестартиране на хоста", @@ -385,13 +404,19 @@ "shutdown_host": "Изключване на хоста", "used_space": "Използвано пространство" }, + "log": { + "get_logs": "Неуспешно получаване на {provider} журнали, {error}", + "log_provider": "Доставчик на журнал" + }, "supervisor": { "beta_backup": "Уверете се, че имате резервни копия на вашите данни, преди да активирате тази функция.", "beta_join_confirm": "Искате ли да се присъедините към бета канала?", "beta_release_items": "Това включва бета версии за:", + "beta_warning": "Бета версиите са за тестери и ранни потребители и могат да съдържат нестабилни промени в кода", "channel": "Канал", "cpu_usage": "Използване на CPU от Supervisor", "failed_to_reload": "Неуспешно презареждане на Supervisor", + "failed_to_set_option": "Неуспешно задаване на Супервайзър-опция", "failed_to_update": "Неуспешно актуализиране на Supervisor", "join_beta_action": "Присъединяване към бета канала", "join_beta_description": "Получавайте бета актуализации за Home Assistant (RCs), Supervisor и хоста", @@ -401,18 +426,26 @@ "reload_supervisor": "Презареждане на Supervisor", "share_diagnostics": "Споделяне на диагностика", "share_diagnostics_description": "Споделяйте доклади за сривове и диагностична информация.", + "share_diagonstics_description": "Искате ли да споделяте автоматично отчети за сривове и диагностична информация, когато Supervisor срещне неочаквани грешки? {line_break} Това ще ни позволи да отстраним проблемите, информацията е достъпна само за екипа на Home Assistant Core и няма да бъде споделяна с други. {line_break} Данните не включват никаква частна/чувствителна информация и можете да деактивирате това в настройките по всяко време, когато пожелаете.", "share_diagonstics_title": "Помогнете за подобряването на Home Assistant", + "unhealthy_description": "Управлението на нездрава инсталация ще доведе до проблеми. По-долу са проблемите на вашата инсталация, следвайте връзките за възможни решения.", "unhealthy_reason": { "docker": "Средата на Docker не работи правилно", "privileged": "Supervisor не е привилегирован", "setup": "Настройката на Supervisor не бе успешна", - "supervisor": "Supervisor не успя да се актуализира" + "supervisor": "Supervisor не успя да се актуализира", + "untrusted": "Открито e ненадежден съдържание" }, + "unhealthy_title": "Вашата инсталация е нездрава", + "unsupported_description": "По-долу са откритите проблеми на вашата инсталация, следвайте връзките за възможни решения.", "unsupported_reason": { + "apparmor": "AppArmor не е активиран на хоста", "container": "Контейнери, за които е известно, че причиняват проблеми", + "content-trust": "Проверката за надеждно съдържанието е деактивирана.", "dbus": "DBUS", "docker_configuration": "Конфигурация на Docker", "docker_version": "Docker Версия", + "job_conditions": "Игнорирани условия при работа", "lxc": "LXC", "network_manager": "Мрежов мениджър", "os": "Операционна система", @@ -522,7 +555,8 @@ }, "script": { "cancel": "Отказ", - "cancel_multiple": "Отмяна на {number}" + "cancel_multiple": "Отмяна на {number}", + "run": "Изпълни" }, "service": { "run": "Изпълни" @@ -708,7 +742,8 @@ "was_safe": "беше безопасно", "was_unlocked": "беше отключен", "was_unplugged": "беше изключен" - } + }, + "show_trace": "Показване на следа" }, "media-browser": { "audio_not_supported": "Браузърът не поддържа този аудио елемент.", @@ -1017,6 +1052,8 @@ "stop": "Спиране" }, "types": { + "navigation": "Навигирайте", + "reload": "Презареждане", "server_control": "Сървър" } }, @@ -1033,17 +1070,21 @@ "buttons": { "add": "Добавете устройства чрез това устройство", "clusters": "Управление на клъстери", + "device_children": "Преглед на дъщерни ", + "reconfigure": "Преконфигуриране на устройство", "remove": "Премахване на устройство", "zigbee_information": "Подпис на Zigbee устройството" }, "confirmations": { "remove": "Сигурни ли сте, че искате да премахнете устройството?" }, + "device_children": "Zigbee дъщерно устройство", "device_signature": "Подпис на Zigbee устройството", "last_seen": "Последно видян", "manuf": "от {manufacturer}", "no_area": "Без област", "power_source": "Източник на захранване", + "quirk": "Хрумване", "services": { "reconfigure": "Преконфигурирайте ZHA устройство (оздравяване на устройство). Използвайте това, ако имате проблеми с устройството. Ако въпросното устройство е захранвано с батерии, моля, уверете се, че е будно и приема команди, когато използвате тази услуга.", "remove": "Премахване на устройство от Zigbee мрежата.", @@ -1053,6 +1094,9 @@ "zha_device_card": { "device_name_placeholder": "Променете името на устройството" } + }, + "zha_reconfigure_device": { + "heading": "Преконфигуриране на устройство" } }, "duration": { @@ -1071,8 +1115,11 @@ }, "supervisor": { "ask": "Помолете за помощ", + "observer": "Проверете Надзорника", "reboot": "Опитайте да рестартирате хоста", - "system_health": "Проверете здравето на системата" + "system_health": "Проверете здравето на системата", + "title": "Не може да се зареди Супервайзър-панела!", + "wait": "Ако току-що сте стартирали, дайте достатъчно време за старт на Супервайзъра." } }, "login-form": { @@ -1088,8 +1135,11 @@ }, "notification_toast": { "connection_lost": "Връзката е прекъсната. Повторно свързване...", + "intergration_starting": "Стартиране на {integration}, не всичко ще бъде налично, докато процесът не приключи.", "service_call_failed": "Неуспешно повикване на услуга {service}.", - "started": "Home Assistant стартира успешно!" + "started": "Home Assistant стартира успешно!", + "triggered": "Задействане {name}", + "wrapping_up_startup": "Финализиране на стартирането, не всичко ще бъде налично, докато процесът не приключи." }, "panel": { "config": { @@ -1172,6 +1222,7 @@ "extra_fields": { "brightness_pct": "Яркост", "code": "Код", + "flash": "Флаш", "humidity": "Влажност", "message": "Съобщение", "mode": "Режим", @@ -1251,7 +1302,7 @@ "below": "Под", "for": "Продължителност", "hvac_mode": "HVAC режим", - "preset_mode": "Предварително зададен режим" + "preset_mode": "Зададен режим" }, "label": "Устройство" }, @@ -1332,6 +1383,7 @@ "move_down": "Премести надолу", "move_up": "Премести нагоре", "save": "Запазване", + "show_trace": "Показване на следа", "triggers": { "add": "Добавяне на тригер", "delete": "Изтриване", @@ -1438,6 +1490,8 @@ "add_automation": "Добавяне на автоматизация", "delete_automation": "Изтрийте автоматизацията", "delete_confirm": "Наистина ли искате да изтриете тази автоматизация?", + "dev_automation": "Автоматизирано отстраняване на грешки.", + "dev_only_editable": "Отстраняване на грешки е възможно само за автоматизации с уникален идентификационен номер.", "duplicate": "Дублиране", "duplicate_automation": "Дублиране на автоматизацията", "edit_automation": "Редактиране на автоматизацията", @@ -1494,6 +1548,8 @@ }, "introduction": "Конфигурацията на план ви позволява да импортирате и управлявате вашите планове.", "learn_more": "Научете повече за използването на планове", + "share_blueprint": "Споделяне на план", + "share_blueprint_no_url": "Планът не може да се сподели. Липсва URL-източник", "use_blueprint": "Създайте автоматизация" } }, @@ -1504,10 +1560,17 @@ "disable": "деактивирайте", "enable": "активиране", "enable_ha_skill": "Активирайте умението Home Assistant за Alexa", + "enable_state_reporting": "Разрешаване на отчитане на състояние", + "info": "С интеграцията на Alexa за облака Home Assistant ще можете да контролирате всичките си Home Assistant устройства от всяко устройство с активирана Alexa.", + "info_state_reporting": "Ако активирате отчитане на състояние, Home Assistant ще изпраща всички промени в състоянието на изложените обекти към Amazon. Това позволява да виждате винаги най-актуалните състояния в приложението Alexa, както и да ги използвате за да създавате рутини.", + "manage_entities": "Управление на обекти", + "sync_entities": "Синхронизиране на обекти с Amazon", + "sync_entities_error": "Неуспешно синхронизирани обекти:", "title": "Alexa" }, "connected": "Свързан", "connection_status": "Състояние на връзката с облака", + "fetching_subscription": "Извличане на абонамент...", "google": { "config_documentation": "Документация за конфигурацията", "devices_pin": "ПИН код за Устройства за защита", @@ -1518,13 +1581,18 @@ "title": "Google Assistant" }, "integrations": "Интеграции", + "integrations_introduction": "Интеграциите за облака Assistant Cloud позволяват свързването облачни услуги, като се избягва публичното излагане на инсталацията Home Assistant в интернет.", "integrations_introduction2": "Проверете уебсайта за", "integrations_link_all_features": "всички налични функции", "manage_account": "Управление на акаунта", "nabu_casa_account": "Акаунт в Nabu Casa", "not_connected": "Не е свързан", "remote": { + "access_is_being_prepared": "Подготвя се отдалечен достъп. Ще ви уведомим, когато е готов.", "certificate_info": "Информация за сертификата", + "info": "Облакът Home Assistant осигурява защитена отдалечена връзка с вашата инсталация, докато сте далеч от дома. ", + "instance_is_available": "Вашата инсталация е налична на", + "instance_will_be_available": "Вашата инсталация ще е налична на", "link_learn_how_it_works": "Научете как работи", "title": "Дистанционен контрол" }, @@ -1582,6 +1650,7 @@ "email_error_msg": "Грешен имейл", "instructions": "Въведете вашия имейл адрес и ние ще ви изпратим линк за нулиране на вашата парола.", "send_reset_email": "Изпратете имейл за нулиране", + "subtitle": "Забравена парола", "title": "Забравена парола" }, "google": { @@ -1598,9 +1667,11 @@ "login": { "alert_email_confirm_necessary": "Трябва да потвърдите имейла си, преди да влезете.", "alert_password_change_required": "Трябва да промените паролата си, преди да влезете.", + "dismiss": "Отхвърли", "email": "Имейл", "email_error_msg": "Грешен имейл", "forgot_password": "Забравена парола?", + "introduction": "Облакът Home Assistant осигурява защитена отдалечена връзка с вашата инсталация, докато сте далеч от дома. Също така позволява свързването с изцяло облачни услуги: Amazon Alexa и Google Assistant.", "introduction2": "Тази услуга се управлява от нашия партньор", "introduction2a": ", компания основана от основателите на Home Assistant и Hass.io.", "introduction3": "Home Assistant Cloud е абонаментна услуга с безплатен едномесечен пробен период. Не е необходима информация за плащане.", @@ -1609,6 +1680,7 @@ "password_error_msg": "Паролите са най-малко 8 знака", "sign_in": "Впиши се", "start_trial": "Започнете безплатния си едномесечен пробен период", + "title": "Облачно влизане", "trial_info": "Не е необходима информация за плащане" }, "register": { @@ -1618,11 +1690,14 @@ "email_error_msg": "Грешен имейл", "feature_amazon_alexa": "Интеграция с Amazon Alexa", "feature_google_home": "Интеграция с Google Assistant", + "feature_remote_control": "Контрол на Home Assistant далеч от дома", "feature_webhook_apps": "Лесна интеграция с базирани на webhook приложения като OwnTracks", "headline": "Започнете безплатния си пробен период", + "information": "Създайте акаунт с безплатен едномесечен пробен период в облака Home Assistant. Не се изисква информация за плащане.", "information2": "Пробният период ще ви даде достъп до всички предимства на Home Assistant Cloud, включително:", "information3": "Тази услуга се управлява от нашия партньор", "information3a": ", компания основана от основателите на Home Assistant и Hass.io.", + "information4": "С регистрирането на акаунт се съгласявате със следните условия.", "link_privacy_policy": "Политика за поверителност", "link_terms_conditions": "Правила и условия", "password": "Парола", @@ -1643,11 +1718,15 @@ "section": { "core": { "analytics": { + "documentation": "Преди да активирате това, не забравяйте да посетите страницата с документация за анализа {link} за да разберете какво изпращате и как се съхранява.", "header": "Анализи", - "learn_more": "Научете повече за това как ще бъдат обработени вашите данни.", + "instance_id": "Идент. № на инсталация: {huuid}", + "introduction": "Споделете информация от вашата инсталация, за да подобряваме още Home Assistant и да ни помогнете да убедим производителите да добавят функции за локален контрол с фокус върху поверителността.", + "learn_more": "Как обработваме вашите данни", "needs_base": "Трябва да активирате базовия анализ, за да бъде налична тази опция", "preference": { "base": { + "description": "Идентификационен номер на инсталацията, версия и тип на инсталиране.", "title": "Базов анализ" }, "diagnostics": { @@ -1655,13 +1734,15 @@ "title": "Диагностика" }, "statistics": { + "description": "Общо използвани обекти, потребители и други елементи.", "title": "Статистика за употребата" }, "usage_supervisor": { + "description": "Имена, версии и възможности.", "title": "Използвани интеграции и добавки" }, "usage": { - "description": "Това включва имената на вашите интеграции", + "description": "Информация за име и версия.", "title": "Използвани интеграции" } } @@ -1707,11 +1788,13 @@ "devices": { "automation": { "actions": { + "caption": "Когато нещо се задейства...", "no_actions": "Няма действия", "unknown_action": "Неизвестно действие" }, "automations": "Автоматизации", "conditions": { + "caption": "Направи нещо само ако...", "no_conditions": "Няма условия", "unknown_condition": "Неизвестно условие" }, @@ -1719,6 +1802,9 @@ "create_disable": "Не може да се създаде автоматизация с деактивирано устройство", "no_automations": "Няма автоматизации", "no_device_automations": "Няма налични автоматизации за това устройство.", + "triggers": { + "caption": "Направи нещо, когато..." + }, "unknown_automation": "Неизвестна автоматизация" }, "cant_edit": "Можете да редактирате само елементи, които са създадени в потребителския интерфейс.", @@ -1736,6 +1822,7 @@ "delete": "Изтриване", "description": "Управление на конфигурираните устройства", "device_info": "Информация за устройството", + "device_not_found": "Не е намерено устройство.", "disabled": "Деактивирано", "disabled_by": { "config_entry": "Конфигурационен запис", @@ -1853,6 +1940,7 @@ "info": { "built_using": "Изграден с използване на", "caption": "Информация", + "copy_github": "За GitHub", "description": "Версия, състояние на системата и връзки към документация", "documentation": "Документация", "home_assistant_logo": "Лого на Home Assistant", @@ -1879,6 +1967,7 @@ "devices": "{count} {count, plural,\n one {устройство}\n other {устройства}\n}", "disable_restart_confirm": "Рестартирайте Home Assistant за да завършите деактивирането на тази интеграция", "disable": { + "disable_confirm": "Наистина ли искате да забраните този конфигурационен запис? Устройствата и обекти му ще бъдат деактивирани.", "disabled": "Деактивиран", "disabled_by": { "device": "устройство", @@ -1896,7 +1985,7 @@ "logs": "Журнали", "manuf": "от {manufacturer}", "no_area": "Без област", - "not_loaded": "Не е зареден, проверете {logs_link}", + "not_loaded": "Не е заредено, проверете {logs_link}", "options": "Настройки", "reload": "Презареждане", "reload_confirm": "Интеграцията беше презаредена", @@ -1935,6 +2024,7 @@ "confirm_ignore": "Наистина ли не искате да настроите тази интеграция? Можете да отмените това, като кликнете върху „Показване на игнорирани интеграции“ в менюто горе вдясно." }, "integration": "интеграция", + "integration_not_found": "Не е намерена интеграция.", "new": "Настройте нова интеграция", "no_integrations": "Изглежда, че все още нямате конфигурирани интеграции. Кликнете върху бутона по-долу, за да добавите първата си интеграция!", "none": "Нищо не е конфигурирано към момента", @@ -2106,7 +2196,8 @@ }, "learn_more": "Научете повече за хората", "no_persons_created_yet": "Изглежда все още не сте добавили хора.", - "note_about_persons_configured_in_yaml": "Забележка: хората, конфигурирани чрез configuration.yaml, не могат да бъдат редактирани чрез потребителския интерфейс." + "note_about_persons_configured_in_yaml": "Забележка: хората, конфигурирани чрез configuration.yaml, не могат да бъдат редактирани чрез потребителския интерфейс.", + "person_not_found_title": "Не е намерено лице" }, "scene": { "activated": "Активирана сцена {name} .", @@ -2143,6 +2234,7 @@ "name": "Име" }, "learn_more": "Научете повече за сцените", + "no_scenes": "Не можахме да намерим сцени", "only_editable": "Само сцени дефинирани в scenes.yaml могат да се редактират.", "pick_scene": "Изберете сцена за редактиране", "show_info_scene": "Показване на информация за сцената" @@ -2180,10 +2272,13 @@ "duplicate": "Дублиране", "duplicate_script": "Дублиране на скрипта", "edit_script": "Редактиране на скрипта", + "header": "Скрипт-редактор", "headers": { "name": "Име" }, + "introduction": "Скрипт-редакторът позволява създаването и редактирането на скриптове. Врузката води към допълнитени инструкции за проверка на коректността при конфигурането на Home Assistant.", "learn_more": "Научете повече за скриптовете", + "no_scripts": "Не намираме скриптове", "run_script": "Изпълнете скрипта", "show_info": "Показване на информация за скрипта" } @@ -2336,7 +2431,7 @@ "creating_group": "Създаване на група", "group_info": "Информация за групата", "group_name_placeholder": "Име на групата", - "group_not_found": "Групата не е намерена!", + "group_not_found": "Не е намерена група!", "groups": "Групи", "members": "Членове", "remove_members": "Премахване на членове", @@ -2387,6 +2482,9 @@ "dump_not_ready_confirm": "Изтегляне", "server_version": "Версия на сървъра" }, + "device_info": { + "device_config": "Конфигуриране на устройство" + }, "navigation": { "network": "Мрежа" }, @@ -2395,7 +2493,13 @@ "connecting": "Свързване" }, "node_config": { - "parameter_is_read_only": "Този параметър е само за четене." + "attribution": "Параметрите и описанията на конфигурацията на устройството се предоставят от {device_database}", + "battery_device_notice": "Устройствата на батерии трябва да са будни, за да актуализират конфигурацията си. Моля, вижте ръководството на устройството за инструкции как да го събудите.", + "error_device_not_found": "Не е намерено устройство", + "header": "Z-Wave конфигурация на устройството", + "introduction": "Управление и настройване на специфични конфигурационни параметри на подбраноto устройството (възел, node)", + "parameter_is_read_only": "Този параметър е само за четене.", + "zwave_js_device_database": "Z-Wave JS база данни с устройства" } }, "zwave": { @@ -2510,8 +2614,11 @@ "go_back": "Върнете се", "supervisor": { "ask": "Помолете за помощ", + "observer": "Проверете Надзорника", "reboot": "Опитайте да рестартирате хоста", - "system_health": "Проверете здравето на системата" + "system_health": "Проверете здравето на системата", + "title": "Не може да се зареди Супервайзър-панела!", + "wait": "Ако току-що сте стартирали, дайте достатъчно време за старт на Супервайзъра." } }, "history": { @@ -2549,7 +2656,8 @@ "more_info": "Показване на повече информация: {name}", "navigate_to": "Придвижете се до {location}", "tap": "Натиснете:", - "toggle": "Превключване на {name}" + "toggle": "Превключване на {name}", + "url": "Отваряне на прозорец към {url_path}" }, "shopping-list": { "add_item": "Добави артикул", @@ -2639,6 +2747,7 @@ "position": "Позиция", "tilt-position": "Наклон" }, + "show_header_toggle": "Показване на превключване на заглавка?", "toggle": "Превключване на обекти." }, "entity-filter": { @@ -2651,14 +2760,24 @@ }, "gauge": { "severity": { + "define": "Определете тежестта?", "green": "Зелено", "red": "Червено", "yellow": "Жълто" } }, "generic": { + "aspect_ratio": "Съотношение на пропорциите", "attribute": "Атрибут", + "camera_image": " Камера Обект", + "camera_view": "Камера Изглед", + "entities": "Обекти", + "entity": "Обект", + "hold_action": "Действие Задържане", + "hours_to_show": "Часове за показване", "icon": "Икона", + "icon_height": "Височина на иконата", + "image": "Път до изображението", "maximum": "Максимум", "minimum": "Минимум", "name": "Име", @@ -2669,8 +2788,10 @@ "show_name": "Показване на името?", "show_state": "Показване на състоянието?", "state_color": "Да се оцветят ли иконите спрямо състоянието?", + "tap_action": "Действие Докосване", "theme": "Тема", "title": "Заглавие", + "unit": "Единица", "url": "URL" }, "glance": { @@ -2697,6 +2818,8 @@ }, "map": { "dark_mode": "Тъмен режим?", + "default_zoom": "Мащабиране по подразбиране", + "geo_location_sources": "Източници на геолокация", "name": "Карта", "source": "Източник" }, @@ -2715,6 +2838,7 @@ "name": "Статус на растение" }, "sensor": { + "graph_type": "Графичен тип", "name": "Сензор" }, "shopping-list": { @@ -3048,7 +3172,8 @@ }, "page-onboarding": { "analytics": { - "finish": "Следващ" + "finish": "Следващ", + "intro": "Споделяйте анализи от вашия екземпляр. Тези данни ще бъдат публично достъпни на адрес {link}" }, "core-config": { "button_detect": "Откриване", @@ -3059,6 +3184,7 @@ "location_name": "Име на Вашата Home Assistant инсталация", "location_name_default": "У дома" }, + "finish": "Завърши", "integration": { "finish": "Завърши", "intro": "Устройствата и услугите са представени в Home Assistant като Интеграции. Можете да ги настроите сега или да го направите по-късно от конфигурационния екран.", diff --git a/translations/frontend/cs.json b/translations/frontend/cs.json index 0e4a29f33d..a3e86acf5c 100644 --- a/translations/frontend/cs.json +++ b/translations/frontend/cs.json @@ -383,7 +383,7 @@ "create": "Vytvořit", "create_blocked_not_running": "Vytvoření zálohy není momentálně možné, protože systém je ve \"{state}\".", "create_snapshot": "Vytvořit zálohu", - "description": "Snímky umožňují snadno zálohovat a obnovovat všechna data instance Home Assistant.", + "description": "Zálohy umožňují snadno zálohovat a obnovovat všechna data vaší instance Home Assistant.", "enter_password": "Prosím zadejte heslo.", "folder": { "addons/local": "Místní doplňky", diff --git a/translations/frontend/el.json b/translations/frontend/el.json index 98824653d7..615f0b8308 100644 --- a/translations/frontend/el.json +++ b/translations/frontend/el.json @@ -1199,6 +1199,10 @@ "key_wrong_type": "Η παρεχόμενη τιμή για το \"{key}\" δεν υποστηρίζεται από το οπτικό πρόγραμμα επεξεργασίας. Υποστηρίζουμε ({type_correct}) αλλά λάβαμε ({type_wrong}).", "no_template_editor_support": "Τα πρότυπα δεν υποστηρίζονται στο οπτικό πρόγραμμα επεξεργασίας", "no_type_provided": "Δεν παρέχεται τύπος." + }, + "supervisor": { + "reboot": "Δοκιμάστε μια επανεκκίνηση του διακομιστή", + "title": "Δεν ήταν δυνατή η φόρτωση του πίνακα Supervisor!" } }, "login-form": { @@ -1219,7 +1223,8 @@ "service_call_failed": "Απέτυχε η κλήση στην υπηρεσία {service}.", "started": "Το Home Assistant έχει ξεκινήσει!", "starting": "Το Home Assistant ξεκινά, ενδέχεται να μην είναι ακόμη διαθέσιμα όλα.", - "triggered": "Ενεργοποιήθηκε το {name}" + "triggered": "Ενεργοποιήθηκε το {name}", + "wrapping_up_startup": "Ολοκληρώνοντας την εκκίνηση, δεν θα είναι όλα διαθέσιμα μέχρι να ολοκληρωθεί." }, "panel": { "config": { diff --git a/translations/frontend/ko.json b/translations/frontend/ko.json index 85e4a107c8..cd716818dd 100644 --- a/translations/frontend/ko.json +++ b/translations/frontend/ko.json @@ -15,7 +15,7 @@ }, "panel": { "calendar": "캘린더", - "config": "구성", + "config": "구성하기", "developer_tools": "개발자 도구", "history": "기록 그래프", "logbook": "로그북", @@ -1242,7 +1242,7 @@ "intergration_starting": "{integration} 시작 중. 완료되기 전 일부 기능은 작동하지 않을 수 있습니다.", "service_call_failed": "{service} 서비스를 호출하지 못했습니다.", "started": "Home Assistant가 시작되었습니다!", - "starting": "Home Assistant가 시작됩니다. 완료될 때까지 모든 기능을 사용할 수 있는 것은 아닙니다.", + "starting": "Home Assistant가 시작됩니다. 완료될 때까지 일부 기능은 작동하지 않을 수 있습니다.", "triggered": "{name}이(가) 트리거됨", "wrapping_up_startup": "시작되기를 기다립니다. 완료되기 전 일부 기능은 작동하지 않을 수 있습니다." }, @@ -3762,7 +3762,7 @@ "page-onboarding": { "analytics": { "finish": "다음", - "intro": "시스템 분석 내용을 공유합니다. 이 데이터는 {link}에서 공개적으로 사용될 수 있습니다" + "intro": "인스턴스의 분석 내용을 공유합니다. 이 데이터는 {link}에서 공개적으로 사용될 수 있습니다" }, "core-config": { "button_detect": "탐색", @@ -3876,7 +3876,7 @@ "header": "다단계 인증 모듈" }, "number_format": { - "description": "숫자 형식을 선택해주세요.", + "description": "숫자 형식을 선택합니다.", "dropdown_label": "숫자 형식", "formats": { "comma_decimal": "1,234,567.89", diff --git a/translations/frontend/nb.json b/translations/frontend/nb.json index 62c288b714..4cfcd3c11b 100644 --- a/translations/frontend/nb.json +++ b/translations/frontend/nb.json @@ -1118,7 +1118,7 @@ "group": "Grupper, gruppeenheter og varsler tjenester", "history_stats": "Historikkstatistiske enheter", "homekit": "HomeKit", - "input_boolean": "Inngang booleans", + "input_boolean": "Boolske innganger", "input_datetime": "Inngangsdato ganger", "input_number": "Inndatanumre", "input_select": "Inngang velges", @@ -1221,7 +1221,7 @@ "reboot": "Prøv en omstart av verten", "system_health": "Sjekk systemtilstand", "title": "Kunne ikke laste Supervisor-panelet!", - "wait": "Hvis du nettopp startet, må du sørge for at du har gitt veilederen nok tid til å starte." + "wait": "Hvis du nettopp startet, må du sørge for at du har gitt Supervisor nok tid til å starte." } }, "login-form": { @@ -1239,12 +1239,12 @@ "notification_toast": { "connection_lost": "Forbindelsen ble brutt. Kobler til på nytt...", "dismiss": "Avvis", - "intergration_starting": "Fra og med {integration} vil ikke alt være tilgjengelig før den er ferdig.", + "intergration_starting": "Starter {integration}. Ikke alt er tilgjengelig før lasting er ferdig.", "service_call_failed": "Kunne ikke tilkalle tjenesten: {service}", "started": "Home Assistant har startet!", "starting": "Home Assistant starter, alt er ikke tilgjengelig før starten er fullført.", "triggered": "Utløst {name}", - "wrapping_up_startup": "Ved oppstart, vil ikke alt være tilgjengelig før den er ferdig." + "wrapping_up_startup": "Oppstart pågår, ikke alt er tilgjengelig før den er ferdig." }, "panel": { "config": { @@ -1872,8 +1872,8 @@ "section": { "core": { "analytics": { - "documentation": "Før du aktiverer dette, må du gå til analysedokumentasjonssiden {link} å forstå hva du sender og hvordan den er lagret.", - "header": "Analytics", + "documentation": "Før du aktiverer dette, må du gå til analysedokumentasjonssiden {link} for å forstå hva du sender og hvordan den er lagret.", + "header": "Analyser", "instance_id": "Forekomst-ID: {huuid}", "introduction": "Del installasjonsinformasjonen din for å gjøre Home Assistant bedre og hjelpe oss med å overbevise produsenter om å legge til lokal kontroll og personvernfokuserte funksjoner.", "learn_more": "Hvordan vi behandler dataene dine", @@ -2619,7 +2619,7 @@ "heading": "YAML konfigurasjon lastes på nytt", "history_stats": "Historikkstatistiske enheter", "homekit": "HomeKit", - "input_boolean": "Inngang booleans", + "input_boolean": "Boolske innganger", "input_datetime": "Inngangsdato ganger", "input_number": "Inndatanumre", "input_select": "Inngang velges", @@ -3884,7 +3884,7 @@ "language": "Automatisk (bruk språkinnstilling)", "none": "Ingen", "space_comma": "1 234 567,89", - "system": "Bruk systemområdet" + "system": "Bruk systemets lokasjonsinnstilling." }, "header": "Tallformat" }, diff --git a/translations/frontend/zh-Hans.json b/translations/frontend/zh-Hans.json index d234f0c7f2..1794a3f5bd 100644 --- a/translations/frontend/zh-Hans.json +++ b/translations/frontend/zh-Hans.json @@ -1876,11 +1876,11 @@ "header": "分析", "instance_id": "实例ID: {huuid}", "introduction": "分享您的安装信息,让 Home Assistant 变得更好,并帮助我们与厂商沟通,增加本地控制和注重隐私的功能。", - "learn_more": "详细了解您的数据将被如何处理", + "learn_more": "我们如何处理您的数据", "needs_base": "需要启用基础分析才能启用此选项", "preference": { "base": { - "description": "包括实例 ID,版本号和安装类型", + "description": "实例 ID、版本号和安装类型。", "title": "基础分析" }, "diagnostics": { @@ -1888,11 +1888,11 @@ "title": "诊断" }, "statistics": { - "description": "包括安装的元素数量,完整列表请参阅文档", + "description": "已使用的实体、用户和其他元素数量。", "title": "使用情况统计" }, "usage_supervisor": { - "description": "名称,版本和功能。", + "description": "名称、版本和功能。", "title": "使用的集成和加载项" }, "usage": { From 96bc3ef99af65a6f80a52549af48521fdcafd616 Mon Sep 17 00:00:00 2001 From: LJU Date: Tue, 13 Apr 2021 15:49:53 +0200 Subject: [PATCH 026/106] Improve spelling (#8901) --- src/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translations/en.json b/src/translations/en.json index 9a79e8ff86..d697421ff4 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2098,7 +2098,7 @@ }, "integrations": { "caption": "Integrations", - "description": "Manage integrations with services, devices, ...", + "description": "Manage integrations with services or devices", "integration": "integration", "discovered": "Discovered", "attention": "Attention required", From 62a0cfb0f60788d3d6598bae6f61972d19a76fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20D=C4=85browski?= Date: Tue, 13 Apr 2021 16:25:48 +0200 Subject: [PATCH 027/106] Fix computing cards (#8894) Co-authored-by: Bram Kragten --- src/panels/lovelace/common/generate-lovelace-config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/lovelace/common/generate-lovelace-config.ts b/src/panels/lovelace/common/generate-lovelace-config.ts index 26e6337213..cbeedd4f31 100644 --- a/src/panels/lovelace/common/generate-lovelace-config.ts +++ b/src/panels/lovelace/common/generate-lovelace-config.ts @@ -181,7 +181,7 @@ export const computeCards = ( titlePrefix && stateObj && // eslint-disable-next-line no-cond-assign - (name = computeStateName(stateObj)).startsWith(titlePrefix) + (name = computeStateName(stateObj)) !== titlePrefix && name.startsWith(titlePrefix) ? { entity: entityId, name: adjustName(name.substr(titlePrefix.length)), From 445ae156ef9e517faf7ee85c8c9618b786f32afe Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 13 Apr 2021 08:18:37 -1000 Subject: [PATCH 028/106] Unsubscribe when dismissing during wrap up (#8909) --- src/state/disconnect-toast-mixin.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/state/disconnect-toast-mixin.ts b/src/state/disconnect-toast-mixin.ts index 09efcc3f89..98e36dea7a 100644 --- a/src/state/disconnect-toast-mixin.ts +++ b/src/state/disconnect-toast-mixin.ts @@ -96,7 +96,9 @@ export default >(superClass: T) => action: { text: this.hass!.localize("ui.notification_toast.dismiss") || "Dismiss", - action: () => {}, + action: () => { + this._unsubscribeBootstrapIntergrations(); + }, }, }); return; From 30787fef60acc48923fd8600c3500711355a47f9 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Tue, 13 Apr 2021 20:23:58 +0200 Subject: [PATCH 029/106] Hide new light color mode attributes in more-info (#8895) --- src/dialogs/more-info/controls/more-info-light.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dialogs/more-info/controls/more-info-light.ts b/src/dialogs/more-info/controls/more-info-light.ts index 2ac9af776d..b0f686e412 100644 --- a/src/dialogs/more-info/controls/more-info-light.ts +++ b/src/dialogs/more-info/controls/more-info-light.ts @@ -151,7 +151,7 @@ class MoreInfoLight extends LitElement { : ""}
`; From dc79fc2919d836ae28ce0c065aacd6ef52f47dc7 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 14 Apr 2021 00:48:24 +0000 Subject: [PATCH 030/106] Translation update --- translations/frontend/bg.json | 7 ++- translations/frontend/ca.json | 2 +- translations/frontend/da.json | 2 +- translations/frontend/de.json | 24 ++++----- translations/frontend/en.json | 2 +- translations/frontend/es-419.json | 79 ++++++++++++++++++++++++++++-- translations/frontend/es.json | 2 +- translations/frontend/et.json | 2 +- translations/frontend/fr.json | 2 +- translations/frontend/ko.json | 2 +- translations/frontend/ru.json | 2 +- translations/frontend/zh-Hant.json | 2 +- 12 files changed, 103 insertions(+), 25 deletions(-) diff --git a/translations/frontend/bg.json b/translations/frontend/bg.json index 1549cdcbca..eca046c32a 100644 --- a/translations/frontend/bg.json +++ b/translations/frontend/bg.json @@ -2127,6 +2127,7 @@ "controller": "Контролер", "network": "Мрежа", "query_stage": "Етап на заявка", + "wakeup_instructions": "Инструкции за събуждане", "zwave": "Z-Wave" }, "navigation": { @@ -2141,6 +2142,9 @@ "started": "Свързан към MQTT", "starting": "Свързване към MQTT" }, + "offline": "Извън линия", + "online": "На линия", + "starting": "Стартиране", "unknown": "Неизвестно" }, "node_metadata": { @@ -2839,7 +2843,8 @@ }, "sensor": { "graph_type": "Графичен тип", - "name": "Сензор" + "name": "Сензор", + "show_more_detail": "Показване на повече подробности" }, "shopping-list": { "description": "Картата \"Списък за пазаруване\" ви позволява да добавяте, редактирате, отметвате и изчиствате елементи от вашия списък за пазаруване.", diff --git a/translations/frontend/ca.json b/translations/frontend/ca.json index be958cca82..e8f70bf076 100644 --- a/translations/frontend/ca.json +++ b/translations/frontend/ca.json @@ -2216,7 +2216,7 @@ "configure": "Configurar", "configured": "Configurades", "confirm_new": "Vols configurar {integration}?", - "description": "Gestiona les integracions amb serveis, dispositius, ...", + "description": "Gestiona les integracions amb serveis o dispositius", "details": "Detalls de la integració", "disable": { "disabled_integrations": "{number} desactivada/es", diff --git a/translations/frontend/da.json b/translations/frontend/da.json index c1b82a7061..2237a6af24 100644 --- a/translations/frontend/da.json +++ b/translations/frontend/da.json @@ -3461,7 +3461,7 @@ "unsaved_changes": "Ikke-gemte ændringer" }, "save_config": { - "cancel": "Glem det", + "cancel": "Fortryd", "close": "Luk", "empty_config": "Start med et tomt betjeningspanel", "header": "Tag kontrol over din 'Lovelace'-brugerflade", diff --git a/translations/frontend/de.json b/translations/frontend/de.json index 0b79a86bd8..919f9fa46e 100644 --- a/translations/frontend/de.json +++ b/translations/frontend/de.json @@ -144,7 +144,7 @@ "title": "AppArmor" }, "auth_api": { - "description": "Ein Add-on kann Benutzer gegen Home Assistant authentifizieren, sodass Add-ons Benutzern die Möglichkeit bieten, sich mit ihrem Home Assistant-Benutzernamen/-Kennwort bei Anwendungen anzumelden, die in Add-ons ausgeführt werden. Dieses Abzeichen zeigt an, ob der Add-on-Autor diese Berechtigung anfordert.", + "description": "Ein Add-on kann Benutzer gegen Home Assistant authentifizieren, so dass Add-ons Benutzern die Möglichkeit bieten, sich mit ihrem Home Assistant-Benutzernamen/-Kennwort bei Anwendungen anzumelden, die in Add-ons ausgeführt werden. Dieses Abzeichen zeigt an, ob der Add-on-Autor diese Berechtigung anfordert.", "title": "Home Assistant-Authentifizierung" }, "docker_api": { @@ -156,7 +156,7 @@ "title": "Voller Hardware-Zugriff" }, "hassio_api": { - "description": "Dem Add-on wurde Zugriff auf die Supervisor-API gewährt, wie es der Add-on-Autors angefordert hat. Standardmäßig kann das Add-on auf allgemeine Versionsinformationen von deinem System zugreifen. Wenn das Add-on Zugriff auf die API mit \"Manager\"- oder \"Admin\"-Rechten anfordert, erhält es Zugriff auf mehrere Teile deines Home Assistant-Systems. Diese Berechtigung wird durch dieses Badge angezeigt und wirkt sich negativ auf die Sicherheitsbewertung des Add-ons aus.", + "description": "Dem Add-on wurde Zugriff auf die Supervisor-API gewährt, wie es der Add-on-Autors angefordert hat. Standardmäßig kann das Add-on auf allgemeine Versionsinformationen von deinem System zugreifen. Wenn das Add-on Zugriff auf die API mit \"Manager\"- oder \"Admin\"-Rechten anfordert, erhält es Zugriff auf mehrere Teile deines Home Assistant-Systems. Diese Berechtigung wird durch dieses Abzeichen angezeigt und wirkt sich negativ auf die Sicherheitsbewertung des Add-ons aus.", "title": "Supervisor-API-Zugriff" }, "homeassistant_api": { @@ -200,7 +200,7 @@ "manager": "Manager" }, "stage": { - "description": "Add-ons können sich in einer von drei Phasen befinden:\n\n{icon_stable} **Stable**: Dies sind Add-ons, die bereits vollstandig sind und Updates erhalten.\n\n{icon_experimental} **Experimentell**: Diese können Fehler enthalten und unvollendet sein.\n\n{icon_deprecated} **Veraltet**: Diese Add-ons erhalten keine Updates mehr.", + "description": "Add-ons können sich in einer von drei Phasen befinden:\n\n{icon_stable} **Stable**: Dies sind Add-ons, die bereits vollständig sind und Updates erhalten.\n\n{icon_experimental} **Experimentell**: Diese können Fehler enthalten und unvollendet sein.\n\n{icon_deprecated} **Veraltet**: Diese Add-ons erhalten keine Updates mehr.", "title": "Add-on Phase" } }, @@ -412,7 +412,7 @@ }, "system": { "core": { - "cpu_usage": "Core-CPU Auslastung", + "cpu_usage": "Core CPU Nutzung", "ram_usage": "Core Arbeitsspeicherbedarf" }, "host": { @@ -1218,7 +1218,7 @@ "supervisor": { "ask": "Um Hilfe bitten", "observer": "Überprüfe den Observer", - "reboot": "Versuche den Host neuzustarten", + "reboot": "Versuche den Host neu zu starten", "system_health": "Überprüfe Systemzustand", "title": "Supervisor-Bedienfeld konnte nicht geladen werden!", "wait": "Wenn du gerade erst hochgefahren hast, dann stelle sicher dass du dem Supervisor genug Zeit zum Starten gegeben hast." @@ -1872,7 +1872,7 @@ "section": { "core": { "analytics": { - "documentation": "Bevor du dies aktivierst, stelle sicher, dass du die Statistikdokumentationsseite {link} besuchst, um zu verstehen, was gesendet und gespeichert wird.", + "documentation": "Bevor du dies aktivierst, stelle sicher, dass du die Statistik Dokumentationsseite {link} besuchst, um zu verstehen, was gesendet und gespeichert wird.", "header": "Statistiken", "instance_id": "Instanz-ID: {huuid}", "introduction": "Teile deine Installationsinformationen, um Home Assistant zu verbessern und Hersteller davon zu überzeugen, lokale Steuerungs- und Datenschutzfunktionen hinzuzufügen.", @@ -1945,7 +1945,7 @@ } }, "devices": { - "add_prompt": "Mit diesem Gerät wurden noch keine {name} hinzugefügt. Du kannst eins hinzufügen, indem du auf den + Knopf drückst.", + "add_prompt": "Es existiert noch kein(e) {name} mit diesem Gerät. Füge ein(e) hinzu, indem du auf den + Knopf drückst.", "automation": { "actions": { "caption": "Wenn etwas ausgelöst wird ...", @@ -2180,7 +2180,7 @@ "logs": "Logs", "manuf": "von {manufacturer}", "no_area": "Kein Bereich", - "not_loaded": "Nicht geladen, prüfe den {logs_link}", + "not_loaded": "Nicht geladen, prüfe die {logs_link}", "options": "Optionen", "reload": "Neu laden", "reload_confirm": "Die Integration wurde neu geladen", @@ -2875,7 +2875,7 @@ "home_id": "Heim-ID", "network": "Netzwerk", "node_id": "Knoten-ID", - "remove_node": "Node entfernen" + "remove_node": "Knoten entfernen" }, "dashboard": { "driver_version": "Treiberversion", @@ -3109,7 +3109,7 @@ "supervisor": { "ask": "Um Hilfe bitten", "observer": "Überprüfe den Observer", - "reboot": "Versuche den Host neuzustarten", + "reboot": "Versuche den Host neu zu starten", "system_health": "Überprüfe Systemzustand", "title": "Supervisor-Bedienfeld konnte nicht geladen werden!", "wait": "Wenn du gerade erst hochgefahren hast, dann stelle sicher dass du den Supervisor genug Zeit zum Starten gegeben hast." @@ -3434,7 +3434,7 @@ "none": "Keine" }, "edit_badges": { - "panel_mode": "Diese Badges werden nicht angezeigt, da sich diese Ansicht im \"Panel-Modus\" befindet." + "panel_mode": "Diese Abzeichen werden nicht angezeigt, da sich diese Ansicht im \"Panel-Modus\" befindet." }, "edit_card": { "add": "Karte hinzufügen", @@ -3762,7 +3762,7 @@ "page-onboarding": { "analytics": { "finish": "Weiter", - "intro": "Teile Statistiken aus deiner Instanz. Diese Daten werden unter {link}" + "intro": "Teile Statistiken aus deiner Instanz. Diese Daten werden unter {link} verfügbar sein." }, "core-config": { "button_detect": "Erkennen", diff --git a/translations/frontend/en.json b/translations/frontend/en.json index 35b156baba..1b9cde122a 100644 --- a/translations/frontend/en.json +++ b/translations/frontend/en.json @@ -2216,7 +2216,7 @@ "configure": "Configure", "configured": "Configured", "confirm_new": "Do you want to set up {integration}?", - "description": "Manage integrations with services, devices, ...", + "description": "Manage integrations with services or devices", "details": "Integration details", "disable": { "disabled_integrations": "{number} disabled", diff --git a/translations/frontend/es-419.json b/translations/frontend/es-419.json index 3270baae10..0ddb609097 100644 --- a/translations/frontend/es-419.json +++ b/translations/frontend/es-419.json @@ -473,6 +473,7 @@ "unhealthy_title": "La instalación tiene problemas", "unsupported_description": "A continuación se muestra una lista de problemas encontrados con su instalación, haga clic en los enlaces para saber cómo puede resolverlos.", "unsupported_reason": { + "apparmor": "AppArmor no está activado en el host", "container": "Contenedores conocidos por causar problemas", "content-trust": "La validación de contenido de confianza está desactivada", "dbus": "DBUS", @@ -840,6 +841,14 @@ "label": "Imagen", "unsupported_format": "Formato no admitido, elija una imagen JPEG, PNG o GIF." }, + "related-filter-menu": { + "filter_by_area": "Filtrar por área", + "filter_by_device": "Filtrar por dispositivo", + "filter_by_entity": "Filtrar por entidad", + "filtered_by_area": "área: {area_name}", + "filtered_by_device": "dispositivo: {device_name}", + "filtered_by_entity": "entidad: {entity_name}" + }, "related-items": { "area": "Área", "automation": "Parte de las siguientes automatizaciones", @@ -1182,6 +1191,9 @@ "zha_device_card": { "device_name_placeholder": "Cambiar el nombre del dispositivo" } + }, + "zha_reconfigure_device": { + "heading": "Reconfigurando dispositivo" } }, "duration": { @@ -1202,6 +1214,14 @@ "key_wrong_type": "El valor provisto para \" {key} \" no es compatible con el editor visual. Aceptamos ( {type_correct} ) pero recibimos ( {type_wrong} ).", "no_template_editor_support": "Plantillas no soportadas en el editor visual", "no_type_provided": "No se ha provisto ningún tipo." + }, + "supervisor": { + "ask": "Solicitar ayuda", + "observer": "Verificar Observer", + "reboot": "Intentar reiniciar el host", + "system_health": "Verificar estado del sistema", + "title": "No se pudo cargar el panel de Supervisor!", + "wait": "Si recién inicia, asegúrese de darle tiempo suficiente a Supervisor para que se inicie." } }, "login-form": { @@ -1219,10 +1239,12 @@ "notification_toast": { "connection_lost": "Conexión perdida. Reconectando...", "dismiss": "Descartar", + "intergration_starting": "Iniciando {integration}, no todo estará totalmente disponible hasta que finalice.", "service_call_failed": "Error al llamar al servicio {service} .", "started": "¡Home Assistant ha iniciado!", "starting": "Home Assistant está iniciando, no todo estará disponible hasta que termine.", - "triggered": "{name} activado" + "triggered": "{name} activado", + "wrapping_up_startup": "Finalizando puesta en marcha, no todo estará totalmente disponible hasta que finalice." }, "panel": { "config": { @@ -1586,7 +1608,7 @@ "delete_automation": "Eliminar automatización", "delete_confirm": "¿Está seguro de que desea eliminar esta automatización?", "dev_automation": "Depurar automatización", - "dev_only_editable": "Solo las automatizaciones definidas en automations.yaml son depurables.", + "dev_only_editable": "Solo las automatizaciones que tienen un ID único asignado son depurables.", "duplicate": "Duplicar", "duplicate_automation": "Duplicar automatización", "edit_automation": "Editar automatización", @@ -1685,6 +1707,8 @@ "info": "Con la integración de Google Assistant para Home Assistant Cloud, podrá controlar todos sus dispositivos Home Assistant a través de cualquier dispositivo habilitado para Google Assistant.", "info_state_reporting": "Si habilita los informes estatales, Home Assistant enviará todos los cambios de estado de las entidades expuestas a Google. Esto le permite ver siempre los últimos estados en la aplicación Google.", "manage_entities": "Administrar entidades", + "not_configured_text": "Antes de poder usar el Asistente de Google, debe activar la función de Home Assistant Cloud para el Asistente de Google en la aplicación Google Home.", + "not_configured_title": "El Asistente de Google no está activado", "security_devices": "Dispositivos de seguridad", "sync_entities": "Sincronizar entidades con Google", "sync_entities_404_message": "No se pudo sincronizar las entidades con Google, pida a Google 'Hey Google, sincronizar mis dispositivos' para sincronizar sus entidades.", @@ -1847,6 +1871,36 @@ "description": "Sistema de unidades, ubicación, zona horaria y otros parámetros generales", "section": { "core": { + "analytics": { + "documentation": "Antes de habilitar esto, asegúrese de visitar la página de documentación de análisis {link} para comprender qué está enviando y cómo se almacena.", + "header": "Datos analíticos", + "instance_id": "ID de instancia: {huuid}", + "introduction": "Comparta su información de instalación para ayudar a mejorar Home Assistant y ayúdenos a convencer a los fabricantes para que agreguen funciones de control local y centradas en la privacidad.", + "learn_more": "Cómo procesamos sus datos", + "needs_base": "Debe habilitar Datos analíticos básicos para que esta opción esté disponible", + "preference": { + "base": { + "description": "ID de instancia, versión y tipo de instalación.", + "title": "Datos analíticos básicos" + }, + "diagnostics": { + "description": "Compartir informes de fallos cuando se produzcan errores inesperados.", + "title": "Diagnósticos" + }, + "statistics": { + "description": "Total de entidades, usuarios y otros elementos utilizados.", + "title": "Estadísticas de uso" + }, + "usage_supervisor": { + "description": "Nombres, versiones y capacidades.", + "title": "Integraciones y complementos usados" + }, + "usage": { + "description": "Nombres e información de versión.", + "title": "Integraciones utilizadas" + } + } + }, "core_config": { "edit_requires_storage": "Editor desactivado porque config está almacenado en configuration.yaml.", "elevation": "Elevación", @@ -2034,6 +2088,9 @@ "filtering_by": "Filtrar por", "show": "Mostrar" }, + "hassio": { + "button": "Configurar" + }, "header": "Configurar Home Assistant", "helpers": { "caption": "Auxiliares", @@ -2120,8 +2177,10 @@ "entity_unavailable": "Entidad no disponible", "firmware": "Firmware: {version}", "hub": "Conectado a través de", + "logs": "Registros", "manuf": "por {manufacturer}", "no_area": "Ninguna área", + "not_loaded": "No se ha cargado, consulte en {logs_link}", "options": "Opciones", "reload": "Recargar", "reload_confirm": "La integración se recargó", @@ -2147,6 +2206,7 @@ "finish": "Finalizar", "loading_first_time": "Espere mientras se instala la integración", "not_all_required_fields": "No todos los campos requeridos estén llenos.", + "not_loaded": "No se pudo cargar la integración, intente reiniciar Home Assistant.", "pick_flow_step": { "new_flow": "No, configure otra instancia de {integration}", "title": "Hemos descubierto estos, ¿quieres configurarlos?" @@ -2197,6 +2257,13 @@ "clear": "Limpiar", "description": "Ver los registros de Home Assistant", "details": "Detalles del registro ({level})", + "level": { + "critical": "CRÍTICO", + "debug": "DEPURAR", + "error": "ERROR", + "info": "INFO", + "warning": "ADVERTENCIA" + }, "load_full_log": "Cargar registro completo de Home Assistant", "loading_log": "Cargando registro de errores ...", "multiple_messages": "el mensaje se produjo por primera vez a las {time} y aparece {counter} veces", @@ -2559,7 +2626,7 @@ "input_text": "Recargar controles de texto", "introduction": "Algunas partes de Home Assistant pueden recargarse sin requerir un reinicio. Al presionar recargar se descargará su configuración YAML actual y se cargará la nueva.", "min_max": "Recargar entidades de mín/máx", - "mqtt": "Recargar entidades MQTT manualmente configuradas", + "mqtt": "Entidades MQTT manualmente configuradas", "person": "Recargar personas", "ping": "Recargar entidades de sensor binario PING", "reload": "Recargar {domain}", @@ -3693,6 +3760,10 @@ } }, "page-onboarding": { + "analytics": { + "finish": "Siguiente", + "intro": "Comparta datos analíticos de su instancia. Estos datos estarán disponibles públicamente en {link}" + }, "core-config": { "button_detect": "Detectar", "finish": "Siguiente", @@ -3702,12 +3773,14 @@ "location_name": "Nombre de su instalación de Home Assistant", "location_name_default": "Casa" }, + "finish": "Finalizar", "integration": { "finish": "Terminar", "intro": "Los dispositivos y servicios están representados en Home Assistant como integraciones. Puede configurarlos ahora, o hacerlo más tarde desde la pantalla de configuración.", "more_integrations": "Más" }, "intro": "¿Estás listo para despertar tu hogar, reclamar tu privacidad y unirte a una comunidad mundial de experimentadores?", + "next": "Siguiente", "restore": { "description": "También se puede restaurar desde una instantánea anterior.", "hide_log": "Ocultar registro completo", diff --git a/translations/frontend/es.json b/translations/frontend/es.json index 4de1126bc6..d2fa446d08 100644 --- a/translations/frontend/es.json +++ b/translations/frontend/es.json @@ -3528,7 +3528,7 @@ "unsaved_changes": "Cambios no guardados" }, "save_config": { - "cancel": "No importa", + "cancel": "Mejor no", "close": "Cerrar", "empty_config": "Empezar con un panel de control vacío", "header": "Tomar el control de la interfaz de usuario Lovelace", diff --git a/translations/frontend/et.json b/translations/frontend/et.json index 3b061b6455..6709173383 100644 --- a/translations/frontend/et.json +++ b/translations/frontend/et.json @@ -2216,7 +2216,7 @@ "configure": "Seadista", "configured": "Seadistatud", "confirm_new": "Kas soovid seadistada sidumist {integration}?", - "description": "Halda teenuste, seadmete jne. sidumisi", + "description": "Halda teenuste või seadmete sidumisi", "details": "Sidumise üksikasjad", "disable": { "disabled_integrations": "{number} keelatut", diff --git a/translations/frontend/fr.json b/translations/frontend/fr.json index 9340add2f1..f2fc004613 100644 --- a/translations/frontend/fr.json +++ b/translations/frontend/fr.json @@ -3528,7 +3528,7 @@ "unsaved_changes": "Modifications non enregistrées" }, "save_config": { - "cancel": "Oublie ce que j'ai dit, c'est pas grave.", + "cancel": "Annuler", "close": "Fermer", "empty_config": "Commencer par un tableau de bord vide", "header": "Prenez le contrôle de votre Interface Lovelace", diff --git a/translations/frontend/ko.json b/translations/frontend/ko.json index cd716818dd..4fd23b9725 100644 --- a/translations/frontend/ko.json +++ b/translations/frontend/ko.json @@ -1146,7 +1146,7 @@ "stop": "중지하기" }, "types": { - "navigation": "탐색하기", + "navigation": "이동하기", "reload": "다시 읽어오기", "server_control": "서버 제어하기" } diff --git a/translations/frontend/ru.json b/translations/frontend/ru.json index 31eea63b8a..9748044340 100644 --- a/translations/frontend/ru.json +++ b/translations/frontend/ru.json @@ -503,7 +503,7 @@ "arm_away": "Охрана (не дома)", "arm_custom_bypass": "Охрана с исключениями", "arm_home": "Охрана (дома)", - "arm_night": "Ночная охрана", + "arm_night": "Охрана (ночь)", "clear_code": "Сброс", "code": "Код", "disarm": "Снять с охраны" diff --git a/translations/frontend/zh-Hant.json b/translations/frontend/zh-Hant.json index 49da45aa5b..ae932dd7ed 100644 --- a/translations/frontend/zh-Hant.json +++ b/translations/frontend/zh-Hant.json @@ -2216,7 +2216,7 @@ "configure": "設定", "configured": "已設定整合", "confirm_new": "是否要設定 {integration}?", - "description": "管理服務、裝置整合等", + "description": "管理整合服務或裝置", "details": "整合詳細資訊", "disable": { "disabled_integrations": "{number} 個已關閉", From b8bb0c038dee730684752d79b1449f83d4c45219 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 14 Apr 2021 11:59:00 -0700 Subject: [PATCH 031/106] Highlight if log comes from custom component (#8912) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Joakim Sørensen --- src/data/system_log.ts | 30 ++++++++--- .../config/logs/dialog-system-log-detail.ts | 53 +++++++++++++++++-- src/panels/config/logs/system-log-card.ts | 11 +++- src/translations/en.json | 4 +- 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/src/data/system_log.ts b/src/data/system_log.ts index 865558ebb9..f2acb5f82b 100644 --- a/src/data/system_log.ts +++ b/src/data/system_log.ts @@ -16,9 +16,27 @@ export interface LoggedError { export const fetchSystemLog = (hass: HomeAssistant) => hass.callApi("GET", "error/all"); -export const getLoggedErrorIntegration = (item: LoggedError) => - item.name.startsWith("homeassistant.components.") - ? item.name.split(".")[2] - : item.name.startsWith("custom_components.") - ? item.name.split(".")[1] - : undefined; +export const getLoggedErrorIntegration = (item: LoggedError) => { + // Try to derive from logger name + if (item.name.startsWith("homeassistant.components.")) { + return item.name.split(".")[2]; + } + if (item.name.startsWith("custom_components.")) { + return item.name.split(".")[1]; + } + + // Try to derive from logged location + if (item.source[0].startsWith("custom_components/")) { + return item.source[0].split("/")[1]; + } + + if (item.source[0].startsWith("homeassistant/components/")) { + return item.source[0].split("/")[2]; + } + + return undefined; +}; + +export const isCustomIntegrationError = (item: LoggedError) => + item.name.startsWith("custom_components.") || + item.source[0].startsWith("custom_components/"); diff --git a/src/panels/config/logs/dialog-system-log-detail.ts b/src/panels/config/logs/dialog-system-log-detail.ts index 90d4670eff..db8a33c244 100644 --- a/src/panels/config/logs/dialog-system-log-detail.ts +++ b/src/panels/config/logs/dialog-system-log-detail.ts @@ -1,5 +1,5 @@ import "@material/mwc-icon-button/mwc-icon-button"; -import { mdiClose, mdiContentCopy } from "@mdi/js"; +import { mdiClose, mdiContentCopy, mdiPackageVariant } from "@mdi/js"; import "@polymer/paper-tooltip/paper-tooltip"; import { css, @@ -21,7 +21,10 @@ import { integrationIssuesUrl, IntegrationManifest, } from "../../../data/integration"; -import { getLoggedErrorIntegration } from "../../../data/system_log"; +import { + getLoggedErrorIntegration, + isCustomIntegrationError, +} from "../../../data/system_log"; import { haStyleDialog } from "../../../resources/styles"; import type { HomeAssistant } from "../../../types"; import { showToast } from "../../../util/toast"; @@ -65,6 +68,12 @@ class DialogSystemLogDetail extends LitElement { const integration = getLoggedErrorIntegration(item); + const showDocumentation = + this._manifest && + (this._manifest.is_built_in || + // Custom components with our offical docs should not link to our docs + !this._manifest.documentation.includes("www.home-assistant.io")); + return html` @@ -86,6 +95,14 @@ class DialogSystemLogDetail extends LitElement { + ${this.isCustomIntegration + ? html`
+ + ${this.hass.localize( + "ui.panel.config.logs.error_from_custom_integration" + )} +
` + : ""}

Logger: ${item.name}
@@ -96,7 +113,7 @@ class DialogSystemLogDetail extends LitElement { Integration: ${domainToName(this.hass.localize, integration)} ${!this._manifest || // Can happen with custom integrations - !this._manifest.documentation + !showDocumentation ? "" : html` () `} ${integrations[idx] - ? domainToName( + ? `${domainToName( this.hass!.localize, integrations[idx]! - ) + )}${ + isCustomIntegrationError(item) + ? ` (${this.hass.localize( + "ui.panel.config.logs.custom_integration" + )})` + : "" + }` : item.source[0]} ${item.count > 1 ? html` diff --git a/src/translations/en.json b/src/translations/en.json index d697421ff4..fddffdd30f 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1067,7 +1067,9 @@ "warning": "WARNING", "info": "INFO", "debug": "DEBUG" - } + }, + "custom_integration": "custom integration", + "error_from_custom_integration": "This error originated from a custom integration." }, "lovelace": { "caption": "Lovelace Dashboards", From a43120320e6941f5851b34ec68793860c455d49d Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 14 Apr 2021 21:00:24 +0200 Subject: [PATCH 032/106] Bump typescript to 4.2.4 (#8876) --- package.json | 2 +- src/cast/receiver_messages.ts | 2 +- src/common/util/render-status.ts | 2 +- src/panels/config/cloud/ha-config-cloud.ts | 2 +- src/panels/config/devices/ha-config-device-page.ts | 2 +- .../integration-panels/zha/zha-device-card.ts | 2 +- src/state/haptic-mixin.ts | 2 ++ yarn.lock | 8 ++++---- 8 files changed, 12 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 66acebbe3e..67964e7bf3 100644 --- a/package.json +++ b/package.json @@ -227,7 +227,7 @@ "terser-webpack-plugin": "^5.1.1", "ts-lit-plugin": "^1.2.1", "ts-mocha": "^7.0.0", - "typescript": "^4.0.3", + "typescript": "^4.2.4", "vinyl-buffer": "^1.0.1", "vinyl-source-stream": "^2.0.0", "webpack": "^5.24.1", diff --git a/src/cast/receiver_messages.ts b/src/cast/receiver_messages.ts index 460054135d..953d766abd 100644 --- a/src/cast/receiver_messages.ts +++ b/src/cast/receiver_messages.ts @@ -62,7 +62,7 @@ export const ensureConnectedCastSession = (cast: CastManager, auth: Auth) => { return undefined; } - return new Promise((resolve) => { + return new Promise((resolve) => { const unsub = cast.addEventListener("connection-changed", () => { if (cast.castConnectedToOurHass) { unsub(); diff --git a/src/common/util/render-status.ts b/src/common/util/render-status.ts index b51baffce4..c0319c623c 100644 --- a/src/common/util/render-status.ts +++ b/src/common/util/render-status.ts @@ -1,4 +1,4 @@ -export const afterNextRender = (cb: () => void): void => { +export const afterNextRender = (cb: (value: unknown) => void): void => { requestAnimationFrame(() => setTimeout(cb, 0)); }; diff --git a/src/panels/config/cloud/ha-config-cloud.ts b/src/panels/config/cloud/ha-config-cloud.ts index f3ad9778a6..1bf79fac77 100644 --- a/src/panels/config/cloud/ha-config-cloud.ts +++ b/src/panels/config/cloud/ha-config-cloud.ts @@ -73,7 +73,7 @@ class HaConfigCloud extends HassRouterPage { private _resolveCloudStatusLoaded!: () => void; - private _cloudStatusLoaded = new Promise((resolve) => { + private _cloudStatusLoaded = new Promise((resolve) => { this._resolveCloudStatusLoaded = resolve; }); diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index 8b04716baf..187a05f875 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -728,7 +728,7 @@ export class HaConfigDevicePage extends LitElement { } if (!newName && !newEntityId) { - return new Promise((resolve) => resolve()); + return undefined; } return updateEntityRegistryEntry(this.hass!, entity.entity_id, { diff --git a/src/panels/config/integrations/integration-panels/zha/zha-device-card.ts b/src/panels/config/integrations/integration-panels/zha/zha-device-card.ts index 0cf283011e..d2c37635ac 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-device-card.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-device-card.ts @@ -159,7 +159,7 @@ class ZHADeviceCard extends SubscribeMixin(LitElement) { } if (!newName && !newEntityId) { - return new Promise((resolve) => resolve()); + return undefined; } return updateEntityRegistryEntry(this.hass!, entity.entity_id, { diff --git a/src/state/haptic-mixin.ts b/src/state/haptic-mixin.ts index 384c31b9a9..6a4483c3bb 100644 --- a/src/state/haptic-mixin.ts +++ b/src/state/haptic-mixin.ts @@ -40,6 +40,7 @@ export const hapticMixin = >(superClass: T) => super.firstUpdated(changedProps); this.addEventListener("hass-vibrate", (ev) => { const vibrate = ev.detail.vibrate; + // @ts-expect-error not all browsers support vibrate if (navigator.vibrate && vibrate) { window.addEventListener("haptic", handleHaptic); } else { @@ -52,6 +53,7 @@ export const hapticMixin = >(superClass: T) => protected hassConnected() { super.hassConnected(); + // @ts-expect-error not all browsers support vibrate if (navigator.vibrate && this.hass!.vibrate) { window.addEventListener("haptic", handleHaptic); } diff --git a/yarn.lock b/yarn.lock index 1c1ffef5e4..5abd1ee959 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13468,10 +13468,10 @@ typescript@^3.8.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== -typescript@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.3.tgz#153bbd468ef07725c1df9c77e8b453f8d36abba5" - integrity sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg== +typescript@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" + integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== typical@^4.0.0: version "4.0.0" From aaa50b4d1d1feb96ebf48561c05ce4f11ed7b448 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 14 Apr 2021 21:01:42 +0200 Subject: [PATCH 033/106] Don't add toast to history (#8915) --- src/dialogs/make-dialog-manager.ts | 46 ++++++++++++++++-------------- src/state/dialog-manager-mixin.ts | 5 +++- src/state/notification-mixin.ts | 1 + 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/dialogs/make-dialog-manager.ts b/src/dialogs/make-dialog-manager.ts index a7c496d960..129349e556 100644 --- a/src/dialogs/make-dialog-manager.ts +++ b/src/dialogs/make-dialog-manager.ts @@ -45,7 +45,8 @@ export const showDialog = async ( root: ShadowRoot | HTMLElement, dialogTag: string, dialogParams: unknown, - dialogImport?: () => Promise + dialogImport?: () => Promise, + addHistory = true ) => { if (!(dialogTag in LOADED)) { if (!dialogImport) { @@ -59,30 +60,31 @@ export const showDialog = async ( }); } - history.replaceState( - { - dialog: dialogTag, - open: false, - oldState: - history.state?.open && history.state?.dialog !== dialogTag - ? history.state - : null, - }, - "" - ); - try { - history.pushState( - { dialog: dialogTag, dialogParams: dialogParams, open: true }, - "" - ); - } catch (err) { - // dialogParams could not be cloned, probably contains callback - history.pushState( - { dialog: dialogTag, dialogParams: null, open: true }, + if (addHistory) { + history.replaceState( + { + dialog: dialogTag, + open: false, + oldState: + history.state?.open && history.state?.dialog !== dialogTag + ? history.state + : null, + }, "" ); + try { + history.pushState( + { dialog: dialogTag, dialogParams: dialogParams, open: true }, + "" + ); + } catch (err) { + // dialogParams could not be cloned, probably contains callback + history.pushState( + { dialog: dialogTag, dialogParams: null, open: true }, + "" + ); + } } - const dialogElement = await LOADED[dialogTag]; dialogElement.showDialog(dialogParams); }; diff --git a/src/state/dialog-manager-mixin.ts b/src/state/dialog-manager-mixin.ts index b75db54c83..acb0c7c5e3 100644 --- a/src/state/dialog-manager-mixin.ts +++ b/src/state/dialog-manager-mixin.ts @@ -8,6 +8,7 @@ interface RegisterDialogParams { dialogShowEvent: keyof HASSDomEvents; dialogTag: keyof HTMLElementTagNameMap; dialogImport: () => Promise; + addHistory?: boolean; } declare global { @@ -38,6 +39,7 @@ export const dialogManagerMixin = >( dialogShowEvent, dialogTag, dialogImport, + addHistory = true, }: RegisterDialogParams) { this.addEventListener(dialogShowEvent, (showEv) => { showDialog( @@ -45,7 +47,8 @@ export const dialogManagerMixin = >( this.shadowRoot!, dialogTag, (showEv as HASSDomEvent).detail, - dialogImport + dialogImport, + addHistory ); }); } diff --git a/src/state/notification-mixin.ts b/src/state/notification-mixin.ts index 4c34ef77d1..22619b4e2f 100644 --- a/src/state/notification-mixin.ts +++ b/src/state/notification-mixin.ts @@ -10,6 +10,7 @@ export default >(superClass: T) => dialogShowEvent: "hass-notification", dialogTag: "notification-manager", dialogImport: () => import("../managers/notification-manager"), + addHistory: false, }); } }; From 193016a46ab55f95c1f62bf7e6defaf3cd9f5a61 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 14 Apr 2021 21:51:29 +0200 Subject: [PATCH 034/106] Fix time selector + base am/pm on user language (#8908) Co-authored-by: Paulus Schoutsen --- .../ha-selector/ha-selector-time.ts | 31 ++++++++++++------- src/components/paper-time-input.js | 12 +++---- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/components/ha-selector/ha-selector-time.ts b/src/components/ha-selector/ha-selector-time.ts index f573773868..8fb0d530c0 100644 --- a/src/components/ha-selector/ha-selector-time.ts +++ b/src/components/ha-selector/ha-selector-time.ts @@ -1,12 +1,9 @@ import { customElement, html, LitElement, property } from "lit-element"; +import memoizeOne from "memoize-one"; import { fireEvent } from "../../common/dom/fire_event"; import { TimeSelector } from "../../data/selector"; import { HomeAssistant } from "../../types"; import "../paper-time-input"; - -const test = new Date().toLocaleString(); -const useAMPM = test.includes("AM") || test.includes("PM"); - @customElement("ha-selector-time") export class HaTimeSelector extends LitElement { @property() public hass!: HomeAssistant; @@ -19,16 +16,24 @@ export class HaTimeSelector extends LitElement { @property({ type: Boolean }) public disabled = false; + private _useAmPm = memoizeOne((language: string) => { + const test = new Date().toLocaleString(language); + return test.includes("AM") || test.includes("PM"); + }); + protected render() { + const useAMPM = this._useAmPm(this.hass.locale.language); + const parts = this.value?.split(":") || []; - const hours = useAMPM ? parts[0] ?? "12" : parts[0] ?? "0"; + const hours = parts[0]; return html` 12 ? Number(hours) - 12 : hours} - .min=${parts[1] ?? "00"} - .sec=${parts[2] ?? "00"} + .hour=${hours && + (useAMPM && Number(hours) > 12 ? Number(hours) - 12 : hours)} + .min=${parts[1]} + .sec=${parts[2]} .format=${useAMPM ? 12 : 24} .amPm=${useAMPM && (Number(hours) > 12 ? "PM" : "AM")} .disabled=${this.disabled} @@ -42,12 +47,16 @@ export class HaTimeSelector extends LitElement { private _timeChanged(ev) { let value = ev.target.value; - if (useAMPM) { - let hours = Number(ev.target.hour); + const useAMPM = this._useAmPm(this.hass.locale.language); + let hours = Number(ev.target.hour || 0); + if (value && useAMPM) { if (ev.target.amPm === "PM") { hours += 12; } - value = `${hours}:${ev.target.min}:${ev.target.sec}`; + value = `${hours}:${ev.target.min || "00"}:${ev.target.sec || "00"}`; + } + if (value === this.value) { + return; } fireEvent(this, "value-changed", { value, diff --git a/src/components/paper-time-input.js b/src/components/paper-time-input.js index c057b3dc36..bc4f442ba7 100644 --- a/src/components/paper-time-input.js +++ b/src/components/paper-time-input.js @@ -133,7 +133,7 @@ export class PaperTimeInput extends PolymerElement { always-float-label$="[[alwaysFloatInputLabels]]" disabled="[[disabled]]" > - : + : @@ -303,28 +303,28 @@ export class PaperTimeInput extends PolymerElement { notify: true, }, /** - * Suffix for the hour input + * Label for the hour input */ hourLabel: { type: String, value: "", }, /** - * Suffix for the min input + * Label for the min input */ minLabel: { type: String, - value: ":", + value: "", }, /** - * Suffix for the sec input + * Label for the sec input */ secLabel: { type: String, value: "", }, /** - * Suffix for the milli sec input + * Label for the milli sec input */ millisecLabel: { type: String, From c53575a74f7be4e7d61f413a20e95645b11d411f Mon Sep 17 00:00:00 2001 From: Carlos Garcia Saura Date: Wed, 14 Apr 2021 23:09:31 +0200 Subject: [PATCH 035/106] Set standard name for Cancel button, to align translations (#8914) --- src/panels/lovelace/editor/hui-dialog-save-config.ts | 2 +- src/translations/en.json | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/panels/lovelace/editor/hui-dialog-save-config.ts b/src/panels/lovelace/editor/hui-dialog-save-config.ts index f2b2602fbe..3cf9fae524 100644 --- a/src/panels/lovelace/editor/hui-dialog-save-config.ts +++ b/src/panels/lovelace/editor/hui-dialog-save-config.ts @@ -127,7 +127,7 @@ export class HuiSaveConfig extends LitElement implements HassDialog { ? html` ${this.hass!.localize( - "ui.panel.lovelace.editor.save_config.cancel" + "ui.common.cancel" )} Date: Wed, 14 Apr 2021 15:29:10 -0700 Subject: [PATCH 036/106] Refactor sequence matching to accept item rather than word array (#8866) * Refactor sequence matching to require an item rather than array of words to filter against * change 'words' to 'strings'. Add tsdoc description for ScorableTextItem * Replace type checking with 'as' to clean up code --- src/common/string/filter/sequence-matching.ts | 37 ++++-- src/dialogs/quick-bar/ha-quick-bar.ts | 120 ++++++++++-------- .../common/string/sequence_matching.test.ts | 34 ++--- 3 files changed, 99 insertions(+), 92 deletions(-) diff --git a/src/common/string/filter/sequence-matching.ts b/src/common/string/filter/sequence-matching.ts index aa67093497..8c50326fd2 100644 --- a/src/common/string/filter/sequence-matching.ts +++ b/src/common/string/filter/sequence-matching.ts @@ -10,10 +10,13 @@ import { fuzzyScore } from "./filter"; * @return {number} Score representing how well the word matches the filter. Return of 0 means no match. */ -export const fuzzySequentialMatch = (filter: string, ...words: string[]) => { +export const fuzzySequentialMatch = ( + filter: string, + item: ScorableTextItem +) => { let topScore = Number.NEGATIVE_INFINITY; - for (const word of words) { + for (const word of item.strings) { const scores = fuzzyScore( filter, filter.toLowerCase(), @@ -28,13 +31,9 @@ export const fuzzySequentialMatch = (filter: string, ...words: string[]) => { continue; } - // The VS Code implementation of filter returns a: - // - Negative score for a good match that starts in the middle of the string - // - Positive score if the match starts at the beginning of the string - // - 0 if the filter string is just barely a match - // - undefined for no match - // The "0" return is problematic since .filter() will remove that match, even though a 0 == good match. - // So, if we encounter a 0 return, set it to 1 so the match will be included, and still respect ordering. + // The VS Code implementation of filter returns a 0 for a weak match. + // But if .filter() sees a "0", it considers that a failed match and will remove it. + // So, we set score to 1 in these cases so the match will be included, and mostly respect correct ordering. const score = scores[0] === 0 ? 1 : scores[0]; if (score > topScore) { @@ -49,10 +48,22 @@ export const fuzzySequentialMatch = (filter: string, ...words: string[]) => { return topScore; }; +/** + * An interface that objects must extend in order to use the fuzzy sequence matcher + * + * @param {number} score - A number representing the existence and strength of a match. + * - `< 0` means a good match that starts in the middle of the string + * - `> 0` means a good match that starts at the beginning of the string + * - `0` means just barely a match + * - `undefined` means not a match + * + * @param {string} strings - Array of strings (aliases) representing the item. The filter string will be compared against each of these for a match. + * + */ + export interface ScorableTextItem { score?: number; - filterText: string; - altText?: string; + strings: string[]; } type FuzzyFilterSort = ( @@ -63,9 +74,7 @@ type FuzzyFilterSort = ( export const fuzzyFilterSort: FuzzyFilterSort = (filter, items) => { return items .map((item) => { - item.score = item.altText - ? fuzzySequentialMatch(filter, item.filterText, item.altText) - : fuzzySequentialMatch(filter, item.filterText); + item.score = fuzzySequentialMatch(filter, item); return item; }) .filter((item) => item.score !== undefined) diff --git a/src/dialogs/quick-bar/ha-quick-bar.ts b/src/dialogs/quick-bar/ha-quick-bar.ts index 443b8b8470..2e6147f7df 100644 --- a/src/dialogs/quick-bar/ha-quick-bar.ts +++ b/src/dialogs/quick-bar/ha-quick-bar.ts @@ -66,10 +66,11 @@ interface CommandItem extends QuickBarItem { } interface EntityItem extends QuickBarItem { + altText: string; icon?: string; } -const isCommandItem = (item: EntityItem | CommandItem): item is CommandItem => { +const isCommandItem = (item: QuickBarItem): item is CommandItem => { return (item as CommandItem).categoryKey !== undefined; }; @@ -230,7 +231,7 @@ export class QuickBar extends LitElement { private _renderItem(item: QuickBarItem, index?: number) { return isCommandItem(item) ? this._renderCommandItem(item, index) - : this._renderEntityItem(item, index); + : this._renderEntityItem(item as EntityItem, index); } private _renderEntityItem(item: EntityItem, index?: number) { @@ -289,13 +290,6 @@ export class QuickBar extends LitElement { ${item.primaryText} - ${item.altText - ? html` - ${item.altText} - ` - : null} `; } @@ -389,17 +383,20 @@ export class QuickBar extends LitElement { } } - private _generateEntityItems(): QuickBarItem[] { + private _generateEntityItems(): EntityItem[] { return Object.keys(this.hass.states) .map((entityId) => { - const primaryText = computeStateName(this.hass.states[entityId]); - return { - primaryText, - filterText: primaryText, + const entityItem = { + primaryText: computeStateName(this.hass.states[entityId]), altText: entityId, icon: domainIcon(computeDomain(entityId), this.hass.states[entityId]), action: () => fireEvent(this, "hass-more-info", { entityId }), }; + + return { + ...entityItem, + strings: [entityItem.primaryText, entityItem.altText], + }; }) .sort((a, b) => compare(a.primaryText.toLowerCase(), b.primaryText.toLowerCase()) @@ -412,7 +409,10 @@ export class QuickBar extends LitElement { ...this._generateServerControlCommands(), ...this._generateNavigationCommands(), ].sort((a, b) => - compare(a.filterText.toLowerCase(), b.filterText.toLowerCase()) + compare( + a.strings.join(" ").toLowerCase(), + b.strings.join(" ").toLowerCase() + ) ); } @@ -420,24 +420,27 @@ export class QuickBar extends LitElement { const reloadableDomains = componentsWithService(this.hass, "reload").sort(); return reloadableDomains.map((domain) => { - const categoryText = this.hass.localize( - `ui.dialogs.quick-bar.commands.types.reload` - ); - const primaryText = - this.hass.localize(`ui.dialogs.quick-bar.commands.reload.${domain}`) || - this.hass.localize( - "ui.dialogs.quick-bar.commands.reload.reload", - "domain", - domainToName(this.hass.localize, domain) - ); + const commandItem = { + primaryText: + this.hass.localize( + `ui.dialogs.quick-bar.commands.reload.${domain}` + ) || + this.hass.localize( + "ui.dialogs.quick-bar.commands.reload.reload", + "domain", + domainToName(this.hass.localize, domain) + ), + action: () => this.hass.callService(domain, "reload"), + iconPath: mdiReload, + categoryText: this.hass.localize( + `ui.dialogs.quick-bar.commands.types.reload` + ), + }; return { - primaryText, - filterText: `${categoryText} ${primaryText}`, - action: () => this.hass.callService(domain, "reload"), + ...commandItem, categoryKey: "reload", - iconPath: mdiReload, - categoryText, + strings: [`${commandItem.categoryText} ${commandItem.primaryText}`], }; }); } @@ -446,26 +449,28 @@ export class QuickBar extends LitElement { const serverActions = ["restart", "stop"]; return serverActions.map((action) => { - const categoryKey = "server_control"; - const categoryText = this.hass.localize( - `ui.dialogs.quick-bar.commands.types.${categoryKey}` - ); - const primaryText = this.hass.localize( - "ui.dialogs.quick-bar.commands.server_control.perform_action", - "action", - this.hass.localize( - `ui.dialogs.quick-bar.commands.server_control.${action}` - ) - ); + const categoryKey: CommandItem["categoryKey"] = "server_control"; + + const item = { + primaryText: this.hass.localize( + "ui.dialogs.quick-bar.commands.server_control.perform_action", + "action", + this.hass.localize( + `ui.dialogs.quick-bar.commands.server_control.${action}` + ) + ), + iconPath: mdiServerNetwork, + categoryText: this.hass.localize( + `ui.dialogs.quick-bar.commands.types.${categoryKey}` + ), + categoryKey, + action: () => this.hass.callService("homeassistant", action), + }; return this._generateConfirmationCommand( { - primaryText, - filterText: `${categoryText} ${primaryText}`, - categoryKey, - iconPath: mdiServerNetwork, - categoryText, - action: () => this.hass.callService("homeassistant", action), + ...item, + strings: [`${item.categoryText} ${item.primaryText}`], }, this.hass.localize("ui.dialogs.generic.ok") ); @@ -550,18 +555,21 @@ export class QuickBar extends LitElement { items: BaseNavigationCommand[] ): CommandItem[] { return items.map((item) => { - const categoryKey = "navigation"; - const categoryText = this.hass.localize( - `ui.dialogs.quick-bar.commands.types.${categoryKey}` - ); + const categoryKey: CommandItem["categoryKey"] = "navigation"; + + const navItem = { + ...item, + iconPath: mdiEarth, + categoryText: this.hass.localize( + `ui.dialogs.quick-bar.commands.types.${categoryKey}` + ), + action: () => navigate(this, item.path), + }; return { - ...item, + ...navItem, + strings: [`${navItem.categoryText} ${navItem.primaryText}`], categoryKey, - iconPath: mdiEarth, - categoryText, - filterText: `${categoryText} ${item.primaryText}`, - action: () => navigate(this, item.path), }; }); } diff --git a/test-mocha/common/string/sequence_matching.test.ts b/test-mocha/common/string/sequence_matching.test.ts index 1b079cb4ba..f631a23285 100644 --- a/test-mocha/common/string/sequence_matching.test.ts +++ b/test-mocha/common/string/sequence_matching.test.ts @@ -3,10 +3,13 @@ import { assert } from "chai"; import { fuzzyFilterSort, fuzzySequentialMatch, + ScorableTextItem, } from "../../../src/common/string/filter/sequence-matching"; describe("fuzzySequentialMatch", () => { - const entity = { entity_id: "automation.ticker", friendly_name: "Stocks" }; + const item: ScorableTextItem = { + strings: ["automation.ticker", "Stocks"], + }; const createExpectation: ( pattern, @@ -53,25 +56,17 @@ describe("fuzzySequentialMatch", () => { "stox", ]; - describe(`Entity '${entity.entity_id}'`, () => { + describe(`Entity '${item.strings[0]}'`, () => { for (const expectation of shouldMatchEntity) { it(`matches '${expectation.pattern}' with return of '${expectation.expected}'`, () => { - const res = fuzzySequentialMatch( - expectation.pattern, - entity.entity_id, - entity.friendly_name - ); + const res = fuzzySequentialMatch(expectation.pattern, item); assert.equal(res, expectation.expected); }); } for (const badFilter of shouldNotMatchEntity) { it(`fails to match with '${badFilter}'`, () => { - const res = fuzzySequentialMatch( - badFilter, - entity.entity_id, - entity.friendly_name - ); + const res = fuzzySequentialMatch(badFilter, item); assert.equal(res, undefined); }); } @@ -81,28 +76,23 @@ describe("fuzzySequentialMatch", () => { describe("fuzzyFilterSort", () => { const filter = "ticker"; const automationTicker = { - filterText: "automation.ticker", - altText: "Stocks", + strings: ["automation.ticker", "Stocks"], score: 0, }; const ticker = { - filterText: "ticker", - altText: "Just ticker", + strings: ["ticker", "Just ticker"], score: 0, }; const sensorTicker = { - filterText: "sensor.ticker", - altText: "Stocks up", + strings: ["sensor.ticker", "Stocks up"], score: 0, }; const timerCheckRouter = { - filterText: "automation.check_router", - altText: "Timer Check Router", + strings: ["automation.check_router", "Timer Check Router"], score: 0, }; const badMatch = { - filterText: "light.chandelier", - altText: "Chandelier", + strings: ["light.chandelier", "Chandelier"], score: 0, }; const itemsBeforeFilter = [ From 92aa8580db30536b960c91d9231be0634ab3297a Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 15 Apr 2021 00:48:36 +0000 Subject: [PATCH 037/106] Translation update --- translations/frontend/en.json | 2 + translations/frontend/es.json | 6 +- translations/frontend/et.json | 6 +- translations/frontend/he.json | 160 +++++++++++++++++++++++++++-- translations/frontend/id.json | 79 +++++++++++++- translations/frontend/nb.json | 2 +- translations/frontend/nl.json | 6 +- translations/frontend/sv.json | 2 +- translations/frontend/zh-Hans.json | 4 +- 9 files changed, 248 insertions(+), 19 deletions(-) diff --git a/translations/frontend/en.json b/translations/frontend/en.json index 1b9cde122a..2af8d7bdfc 100644 --- a/translations/frontend/en.json +++ b/translations/frontend/en.json @@ -2255,8 +2255,10 @@ "logs": { "caption": "Logs", "clear": "Clear", + "custom_integration": "custom integration", "description": "View the Home Assistant logs", "details": "Log Details ({level})", + "error_from_custom_integration": "This error originated from a custom integration.", "level": { "critical": "CRITICAL", "debug": "DEBUG", diff --git a/translations/frontend/es.json b/translations/frontend/es.json index d2fa446d08..f3c6f92a4a 100644 --- a/translations/frontend/es.json +++ b/translations/frontend/es.json @@ -2216,7 +2216,7 @@ "configure": "Configurar", "configured": "Configurado", "confirm_new": "¿Quieres configurar {integration}?", - "description": "Gestiona integraciones con servicios, dispositivos, ...", + "description": "Gestiona integraciones con servicios o dispositivos.", "details": "Detalles de la integración", "disable": { "disabled_integrations": "{number} deshabilitadas", @@ -2255,8 +2255,10 @@ "logs": { "caption": "Registros", "clear": "Limpiar", + "custom_integration": "integración personalizada", "description": "Ve los registros de Home Assistant", "details": "Detalles de registro ({level})", + "error_from_custom_integration": "Este error se originó a partir de una integración personalizada.", "level": { "critical": "CRÍTICO", "debug": "DEPURACIÓN", @@ -3528,7 +3530,7 @@ "unsaved_changes": "Cambios no guardados" }, "save_config": { - "cancel": "Mejor no", + "cancel": "No importa", "close": "Cerrar", "empty_config": "Empezar con un panel de control vacío", "header": "Tomar el control de la interfaz de usuario Lovelace", diff --git a/translations/frontend/et.json b/translations/frontend/et.json index 6709173383..e6f10d7c5c 100644 --- a/translations/frontend/et.json +++ b/translations/frontend/et.json @@ -923,7 +923,7 @@ }, "entity_registry": { "control": "Juhtimine", - "customize_link": "olemite kohandused", + "customize_link": "olemite kohandamised", "dismiss": "Loobu", "editor": { "advanced": "Täpsemad sätted", @@ -1936,7 +1936,7 @@ "picker": { "documentation": "Kohandamiste dokumentatsioon", "header": "Kohandamine", - "introduction": "Kohanda olemi atribuute. Lisatud või muudetud kohandused rakenduvad kohe. Eemaldatud kohandused rakenduvad olemi värskendamisel." + "introduction": "Kohanda olemi atribuute. Lisatud või muudetud kohandamised rakenduvad kohe. Eemaldatud kohandamised rakenduvad olemi värskendamisel." }, "warning": { "include_link": "kaasa customize.yaml", @@ -2255,8 +2255,10 @@ "logs": { "caption": "Logid", "clear": "Puhasta", + "custom_integration": "kohandatud sidumine", "description": "Home Assistanti logid", "details": "Logi üksikasjad ({level})", + "error_from_custom_integration": "Selle tõrke põhjustas kohandatud sidumine.", "level": { "critical": "OLULINE", "debug": "SILUMINE", diff --git a/translations/frontend/he.json b/translations/frontend/he.json index 11c7f7517d..f526bcc088 100644 --- a/translations/frontend/he.json +++ b/translations/frontend/he.json @@ -119,8 +119,34 @@ } }, "dialog": { + "network": { + "connected_to": "מחובר אל {ssid}", + "dhcp": "DHCP", + "disabled": "מושבת", + "dns_servers": "שרתי DNS", + "failed_to_change": "שינוי הגדרות הרשת נכשל", + "gateway": "כתובת Gateway", + "ip_netmask": "כתובת IP/Netmask", + "open": "פתוח", + "scan_ap": "חפש נקודות גישה", + "static": "סטטי", + "title": "הגדרות רשת", + "unsaved": "יש לך שינויים שלא נשמרו ויאבדו אם תעבור כרטיסיות, האם אתה רוצה להמשיך?", + "warning": "אם אתה משנה את כתובות ה- Wi-Fi, ה- IP או ה Gateway, אתה עלול לאבד את החיבור!", + "wep": "WEP", + "wpa": "wpa-psk" + }, "registries": { + "add_new_registry": "הוסף מאגר חדש", + "add_registry": "הוסף מאגר", + "failed_to_add": "הוספת המאגר נכשלה", + "failed_to_remove": "הסרת המאגר נכשלה", + "no_registries": "לא הוגדרו מאגרים", "password": "סיסמה", + "registry": "מאגר", + "remove": "הסר", + "title_add": "הוסף מאגר Container", + "title_manage": "ניהול מאגרי Container", "username": "שם משתמש" }, "repositories": { @@ -141,6 +167,36 @@ }, "my": { "error_addon_not_found": "התוסף לא נמצא" + }, + "snapshot": { + "folder": { + "addons/local": "תוספות מקומיות", + "media": "תוכן", + "share": "שיתוף", + "ssl": "SSL" + } + }, + "system": { + "supervisor": { + "beta_backup": "ודא שיש לך גיבויים של הנתונים לפני הפעלת תכונה זו.", + "beta_join_confirm": "האם אתה רוצה להצטרף לערוץ הבטא?", + "beta_release_items": "זה כולל גרסאות בטא עבור:", + "beta_warning": "גרסאות בטא מיועדות לבודקים ומאמצים מוקדמים ויכולות להכיל שינויי קוד לא יציבים", + "reload_supervisor": "טען מחדש את ה Supervisor", + "share_diagonstics_description": "האם ברצונך לשתף באופן אוטומטי דוחות קריסה ומידע אבחון כאשר ה Supervisor נתקל בשגיאות בלתי צפויות? {line_break} זה יאפשר לנו לתקן את הבעיות, המידע נגיש רק לצוות הליבה של Home Assistant ולא ישותף עם אחרים. {line_break} הנתונים אינם כוללים מידע פרטי/רגיש ובאפשרותך להפוך מידע זה ללא זמין בהגדרות בכל עת שתרצה.", + "share_diagonstics_title": "עזור לשפר את Home Assistant", + "unhealthy_reason": { + "untrusted": "זוהה תוכן לא מהימן" + }, + "unsupported_reason": { + "apparmor": "AppArmor אינו זמין במחשב המארח", + "container": "ה Container ידוע כבעייתי", + "content-trust": "אימות אמון תוכן מושבת", + "dbus": "DBUS", + "docker_configuration": "תצורת Docker" + }, + "warning": "אזהרה" + } } }, "ui": { @@ -398,7 +454,8 @@ "was_unlocked": "לא היה נעול", "was_unplugged": "היה מנותק", "was_unsafe": "היה לא בטוח" - } + }, + "show_trace": "הצג מעקב" }, "media-browser": { "class": { @@ -415,8 +472,10 @@ "related-filter-menu": { "filter_by_area": "סנן לפי אזור", "filter_by_device": "סנן לפי מכשיר", + "filter_by_entity": "סנן לפי ישות", "filtered_by_area": "אזור: {area_name}", - "filtered_by_device": "מכשיר: {device_name}" + "filtered_by_device": "מכשיר: {device_name}", + "filtered_by_entity": "ישות: {entity_name}" }, "related-items": { "area": "אֵזוֹר", @@ -642,6 +701,7 @@ "buttons": { "add": "הוסף מכשירים", "clusters": "ניהול אשכולות", + "device_children": "צפה בילדים", "reconfigure": "הגדר מחדש את המכשיר", "remove": "הסר מכשיר", "zigbee_information": "מידע על Zigbee" @@ -649,6 +709,7 @@ "confirmations": { "remove": "האם אתה בטוח שברצונך למחוק מכשיר זה?" }, + "device_children": "ילדי מכשיר זיגבי", "device_signature": "חתימת התקן Zigbee", "last_seen": "נראה לאחרונה", "manuf": "לפי {manufacturer}", @@ -665,6 +726,9 @@ "zha_device_card": { "device_name_placeholder": "שנה שם התקן" } + }, + "zha_reconfigure_device": { + "heading": "מגדיר תצורה מחדש של המכשיר" } }, "duration": { @@ -676,7 +740,16 @@ }, "errors": { "config": { - "key_wrong_type": "הערך שסופק עבור \"{key}\" אינו נתמך על-ידי העורך החזותי. אנו תומכים ({type_correct}) אך קיבלנו ({type_wrong})." + "key_wrong_type": "הערך שסופק עבור \"{key}\" אינו נתמך על-ידי העורך החזותי. אנו תומכים ({type_correct}) אך קיבלנו ({type_wrong}).", + "no_template_editor_support": "תבניות אינן נתמכות בעורך החזותי" + }, + "supervisor": { + "ask": "בקש עזרה", + "observer": "בדוק את המשקיף", + "reboot": "נסה אתחול מחדש של המחשב המארח", + "system_health": "בדוק את בריאות המערכת", + "title": "לא היתה אפשרות לטעון את לוח ה Supervisor!", + "wait": "אם רק התחלת, ודא שנתת ל Supervisor מספיק זמן להתחיל." } }, "login-form": { @@ -693,10 +766,12 @@ "notification_toast": { "connection_lost": "החיבור אבד. מתחבר מחדש...", "dismiss": "בטל", + "intergration_starting": "מפעיל את {integration} , לא הכל יהיה זמין עד לסיום.", "service_call_failed": "נכשלה הקריאה לשירות {service} .", "started": "Home Assistant עלה!", "starting": "Home Assistant בעלייה, ייתכן שלא הכל יהיה זמין עד שהעליה תסתיים", - "triggered": "הופעל {שם}" + "triggered": "הופעל {שם}", + "wrapping_up_startup": "סיום העליה, לא הכל יהיה זמין עד לסיום." }, "panel": { "config": { @@ -768,7 +843,12 @@ "device_id": { "action": "פעולה", "extra_fields": { - "code": "קוד" + "brightness_pct": "בהירות", + "code": "קוד", + "flash": "הבהוב", + "humidity": "לחות", + "mode": "מצב", + "value": "ערך" }, "label": "מכשיר" }, @@ -829,7 +909,9 @@ "extra_fields": { "above": "מעל", "below": "מתחת", - "for": "משך הזמן" + "for": "משך הזמן", + "hvac_mode": "מצב HVAC", + "preset_mode": "מצב מוגדר מראש" }, "label": "מכשיר" }, @@ -912,6 +994,7 @@ "move_down": "הזז למטה", "move_up": "הזז למעלה", "save": "שמור", + "show_trace": "הצג מעקב", "triggers": { "add": "הוספת טריגר", "delete": "מחק", @@ -1014,6 +1097,8 @@ "add_automation": "הוסף אוטומציה", "delete_automation": "מחק אוטומציה", "delete_confirm": "האם אתה בטוח שברצונך למחוק אוטומציה זו?", + "dev_automation": "דבג אוטומציה", + "dev_only_editable": "רק אוטומציות שהוקצה להן מזהה ייחודי ניתנות לדיבוג.", "edit_automation": "ערוך אוטומציה", "header": "עורך אוטומציה", "headers": { @@ -1062,6 +1147,8 @@ "file_name": "שם קובץ" }, "learn_more": "למד עוד אודות שימוש בשרטוטים", + "share_blueprint": "שתף שרטוט", + "share_blueprint_no_url": "אין אפשרות לשתף שרטוט: אין כתובת URL", "use_blueprint": "צור אוטומציה" } }, @@ -1244,7 +1331,34 @@ "section": { "core": { "analytics": { - "learn_more": "למד עוד על אופן עיבוד הנתונים שלך." + "documentation": "לפני שתאפשר זאת וודא שאתה מבקר בדף תיעוד המידע {link} כדי להבין מה אתה שולח ואיך זה נשמר.", + "header": "ניתוח", + "instance_id": "מזהה מופע: {huuid}", + "introduction": "שתף את פרטי ההתקנה שלך כדי לעזור לשפר את Home Assistant ולעזור לנו לשכנע יצרנים להוסיף שליטה מקומית ותכונות ממוקדות לפרטיות.", + "learn_more": "למד עוד על אופן עיבוד הנתונים שלך.", + "needs_base": "עליך לאפשר ניתוח בסיס כדי שאפשרות זו תהיה זמינה", + "preference": { + "base": { + "description": "מזהה מופע, גרסה וסוג התקנה.", + "title": "ניתוח בסיסי" + }, + "diagnostics": { + "description": "שתף דוחות קריסה כאשר מתרחשות שגיאות בלתי צפויות.", + "title": "אבחון" + }, + "statistics": { + "description": "סה\"כ ישויות בשימוש, משתמשים ואלמנטים אחרים.", + "title": "סטטיסטיקות שימוש" + }, + "usage_supervisor": { + "description": "שמות, גרסאות ויכולות.", + "title": "שילובים ותוספות שבשימוש" + }, + "usage": { + "description": "מידע אודות שמות וגרסאות", + "title": "אינטגרציות שבשימוש" + } + } }, "core_config": { "edit_requires_storage": "העורך מושבת משום שהתצורה מאוחסנת ב- configuration.yaml.", @@ -2019,6 +2133,7 @@ "caption": "רשת" }, "visualization": { + "auto_zoom": "זום אוטומטי", "caption": "ויזואליזציה", "header": "הדמית רשת", "highlight_label": "הדגש התקנים", @@ -2063,6 +2178,17 @@ "dump_not_ready_text": "אם אתה יוצר ייצוא בזמן שלא כל הצמתים מוכנים, אתה עלול לפספס את הנתונים הדרושים. תן לרשת שלך זמן לשאילת כל הצמתים. האם אתה רוצה להמשיך?", "dump_not_ready_title": "עדיין לא כל הצמתים מוכנים", "nodes_ready": "צמתים מוכנים" + }, + "device_info": { + "device_config": "הגדר את המכשיר" + }, + "node_config": { + "attribution": "פרמטרים ותיאורי תצורת המכשיר מסופקים על ידי {device_database}", + "battery_device_notice": "התקני סוללה חייבים להיות ערים כדי לעדכן את תצורתם. נא עיין במדריך למשתמש לקבלת הוראות כיצד להעיר את ההתקן.", + "header": "תצורת מכשיר Z-Wave", + "introduction": "נהל והתאם פרמטרי תצורה ספציפיים למכשיר (צומת) עבור ההתקן שנבחר", + "parameter_is_read_only": "פרמטר זה מוגדר לקריאה בלבד.", + "zwave_js_device_database": "מאגר התקני Z-Wave JS" } }, "zwave": { @@ -2214,6 +2340,17 @@ } } }, + "error": { + "go_back": "חזור", + "supervisor": { + "ask": "בקש עזרה", + "observer": "בדוק את הצופה", + "reboot": "נסה אתחול מחדש של המחשב המארח", + "system_health": "בדוק את בריאות המערכת", + "title": "לא היתה אפשרות לטעון את לוח ה Supervisor!", + "wait": "אם רק התחלת, ודא שנתת ל Supervisor מספיק זמן להתחיל." + } + }, "history": { "ranges": { "last_week": "שבוע שעבר", @@ -2898,6 +3035,15 @@ "enable": "הפעל", "header": "מודלי אימות מרובה גורמים" }, + "number_format": { + "formats": { + "comma_decimal": "1,234,567.89", + "decimal_comma": "1.234.567,89", + "none": "לא נבחר", + "space_comma": "1 234 567,89", + "system": "השתמש ב System Locale" + } + }, "push_notifications": { "add_device_prompt": { "input_label": "שם התקן", diff --git a/translations/frontend/id.json b/translations/frontend/id.json index 55e4d150c1..fafa0de0fa 100644 --- a/translations/frontend/id.json +++ b/translations/frontend/id.json @@ -473,6 +473,7 @@ "unhealthy_title": "Instalasi Anda tidak sehat", "unsupported_description": "Di bawah ini adalah daftar masalah yang ditemukan pada instalasi Anda, klik pada tautan untuk mempelajari cara menyelesaikan masalah tersebut.", "unsupported_reason": { + "apparmor": "AppArmor tidak diaktifkan di host", "container": "Kontainer diketahui menyebabkan masalah", "content-trust": "Validasi kepercayaan konten dinonaktifkan", "dbus": "DBUS", @@ -723,6 +724,9 @@ "today": "Hari ini" }, "data-table": { + "clear": "Hapus", + "filtering_by": "Filter menurut", + "hidden": "{number} disembunyikan", "no-data": "Tidak ada data", "search": "Cari" }, @@ -837,6 +841,14 @@ "label": "Gambar", "unsupported_format": "Format tidak didukung, pilih gambar JPEG, PNG, atau GIF." }, + "related-filter-menu": { + "filter_by_area": "Filter menurut area", + "filter_by_device": "Filter menurut perangkat", + "filter_by_entity": "Filter menurut entitas", + "filtered_by_area": "area: {area_name}", + "filtered_by_device": "perangkat: {device_name}", + "filtered_by_entity": "entitas: {entity_name}" + }, "related-items": { "area": "Area", "automation": "Bagian dari otomasi berikut", @@ -1179,6 +1191,9 @@ "zha_device_card": { "device_name_placeholder": "Ubah nama perangkat" } + }, + "zha_reconfigure_device": { + "heading": "Mengonfigurasi ulang perangkat" } }, "duration": { @@ -1199,6 +1214,14 @@ "key_wrong_type": "Nilai yang disediakan untuk \"{key}\" tidak didukung oleh editor visual. Kami mendukung ({type_correct}) tetapi diterima ({type_wrong}).", "no_template_editor_support": "Templat tidak didukung di editor visual", "no_type_provided": "Tidak ada tipe yang tersedia." + }, + "supervisor": { + "ask": "Dapatkan bantuan", + "observer": "Periksa Observer", + "reboot": "Coba me-reboot host", + "system_health": "Periksa Kesehatan Sistem", + "title": "Tidak dapat memuat panel Supervisor!", + "wait": "Jika Anda baru saja memulai, pastikan Anda telah memberikan cukup waktu kepada Supervisor untuk memulai." } }, "login-form": { @@ -1216,10 +1239,12 @@ "notification_toast": { "connection_lost": "Koneksi terputus. Menghubungkan kembali…", "dismiss": "Tutup", + "intergration_starting": "Memulai {integration}, tidak semuanya akan tersedia hingga prosesnya selesai.", "service_call_failed": "Gagal memanggil layanan {service}.", "started": "Home Assistant telah dimulai!", "starting": "Home Assistant sedang dimulai, belum semuanya akan tersedia hingga selesai.", - "triggered": "Dipicu {name}" + "triggered": "Dipicu {name}", + "wrapping_up_startup": "Menyelesaikan proses mulai, tidak semuanya akan tersedia hingga prosesnya selesai." }, "panel": { "config": { @@ -1307,6 +1332,7 @@ "extra_fields": { "brightness_pct": "Kecerahan", "code": "Kode", + "flash": "Flash", "humidity": "Kelembaban", "message": "Pesan", "mode": "Mode", @@ -1472,6 +1498,7 @@ "move_down": "Pindahkan ke bawah", "move_up": "Pindahkan ke atas", "save": "Simpan", + "show_trace": "Tampilkan jejak", "triggers": { "add": "Tambah pemicu", "delete": "Hapus", @@ -1678,6 +1705,8 @@ "info": "Dengan integrasi Google Assistant untuk Home Assistant Cloud, Anda akan dapat mengontrol semua perangkat Home Assistant melalui perangkat yang mendukung Home Assistant.", "info_state_reporting": "Jika Anda mengaktifkan pelaporan status, Home Assistant akan mengirim semua perubahan status entitas yang terpapar ke Google. Ini memungkinkan Anda untuk selalu melihat status terbaru di aplikasi Google.", "manage_entities": "Kelola Entitas", + "not_configured_text": "Sebelum dapat menggunakan Asisten Google, Anda harus mengaktifkan keterampilan Home Assistant Cloud untuk Asisten Google di aplikasi Google Home.", + "not_configured_title": "Asisten Google tidak diaktifkan", "security_devices": "Perangkat Keamanan", "sync_entities": "Sinkronkan Entitas ke Google", "sync_entities_404_message": "Gagal menyinkronkan entitas Anda ke Google, minta Google 'Ok Google, sinkronkan perangkat saya' untuk menyinkronkan entitas Anda.", @@ -1840,6 +1869,21 @@ "description": "Sistem unit, lokasi, zona waktu & parameter umum lainnya", "section": { "core": { + "analytics": { + "documentation": "Sebelum Anda mengaktifkan, pastikan Anda mengunjungi halaman dokumentasi analitika {link} untuk memahami apa yang Anda kirim dan bagaimana penyimpanannya.", + "header": "Analitika", + "instance_id": "ID Instans: {huuid}", + "learn_more": "Cara kami memproses data Anda", + "needs_base": "Anda perlu mengaktifkan analitik dasar agar opsi ini tersedia", + "preference": { + "base": { + "description": "ID instans, versi, dan jenis instalasi." + }, + "usage_supervisor": { + "title": "Integrasi dan add-on yang digunakan" + } + } + }, "core_config": { "edit_requires_storage": "Editor dinonaktifkan karena konfigurasi disimpan dalam configuration.yaml.", "elevation": "Ketinggian", @@ -2027,6 +2071,9 @@ "filtering_by": "Filter menurut", "show": "Tampilkan" }, + "hassio": { + "button": "Konfigurasi" + }, "header": "Mengonfigurasi Home Assistant", "helpers": { "caption": "Pembantu", @@ -2113,8 +2160,10 @@ "entity_unavailable": "Entitas tidak tersedia", "firmware": "Firmware: {version}", "hub": "Terhubung via", + "logs": "log", "manuf": "oleh {manufacturer}", "no_area": "Tidak Ada Area", + "not_loaded": "Tidak dimuat, periksa {logs_link}", "options": "Opsi", "reload": "Muat Ulang", "reload_confirm": "Integrasi telah dimuat ulang", @@ -2140,6 +2189,7 @@ "finish": "Selesai", "loading_first_time": "Mohon tunggu sementara integrasi sedang dipasang", "not_all_required_fields": "Belum semua bidang wajib telah terisi.", + "not_loaded": "Integrasi tidak dapat dimuat, coba mulai ulang Home Assistant.", "pick_flow_step": { "new_flow": "Tidak, siapkan instans {integration} lainnya", "title": "Kami menemukan yang berikut, ingin menyiapkannya?" @@ -2154,6 +2204,7 @@ "disable": { "disabled_integrations": "{number} dinonaktifkan", "hide_disabled": "Sembunyikan integrasi yang dinonaktifkan", + "show": "Tampilkan", "show_disabled": "Tampilkan integrasi yang dinonaktifkan" }, "discovered": "Ditemukan", @@ -2189,6 +2240,13 @@ "clear": "Bersihkan", "description": "Lihat log Home Assistant", "details": "Detail Log ({level})", + "level": { + "critical": "CRITICAL", + "debug": "DEBUG", + "error": "ERROR", + "info": "INFO", + "warning": "WARNING" + }, "load_full_log": "Muat Log Lengkap Home Assistant", "loading_log": "Memuat log kesalahan…", "multiple_messages": "pesan pertama kali muncul pada {time} dan muncul {counter} kali", @@ -3674,6 +3732,10 @@ } }, "page-onboarding": { + "analytics": { + "finish": "Berikutnya", + "intro": "Bagikan analitika dari instans Anda. Data ini akan tersedia untuk umum di {link}" + }, "core-config": { "button_detect": "Deteksi", "finish": "Berikutnya", @@ -3683,12 +3745,14 @@ "location_name": "Beri nama instalasi Home Assistant Anda", "location_name_default": "Rumah" }, + "finish": "Selesai", "integration": { "finish": "Selesai", "intro": "Perangkat dan layanan diwakili di Home Assistant sebagai integrasi. Anda dapat mengaturnya sekarang, atau melakukannya nanti dari layar konfigurasi.", "more_integrations": "Lebih Lanjut" }, "intro": "Siap untuk membuat rumah Anda lebih hidup, merebut kembali privasi Anda, dan bergabung dengan komunitas pemikir di seluruh dunia?", + "next": "Berikutnya", "restore": { "description": "Atau, Anda dapat memulihkan dari snapshot sebelumnya.", "hide_log": "Sembunyikan log lengkap", @@ -3783,6 +3847,19 @@ "enable": "Aktifkan", "header": "Modul Autentikasi Multifaktor" }, + "number_format": { + "description": "Pilih cara pemformatan bilangan", + "dropdown_label": "Format bilangan", + "formats": { + "comma_decimal": "1,234,567.89", + "decimal_comma": "1.234.567,89", + "language": "Otomatis (gunakan pengaturan bahasa)", + "none": "Tidak ada", + "space_comma": "1 234 567,89", + "system": "Gunakan pelokalan sistem" + }, + "header": "Format Bilangan" + }, "push_notifications": { "add_device_prompt": { "input_label": "Nama perangkat", diff --git a/translations/frontend/nb.json b/translations/frontend/nb.json index 4cfcd3c11b..552f265e0b 100644 --- a/translations/frontend/nb.json +++ b/translations/frontend/nb.json @@ -2216,7 +2216,7 @@ "configure": "Konfigurer", "configured": "Konfigurert", "confirm_new": "Vil du sette opp {integration}?", - "description": "Administrer integrasjoner med tjenester, enheter, ...", + "description": "Administrer integrasjoner med tjenester eller enheter", "details": "Integrasjonsdetaljer", "disable": { "disabled_integrations": "{number} deaktivert", diff --git a/translations/frontend/nl.json b/translations/frontend/nl.json index 1ef809d900..be96640688 100644 --- a/translations/frontend/nl.json +++ b/translations/frontend/nl.json @@ -240,7 +240,7 @@ "title": "Waarschuwing: Beschermingsmodus is uitgeschakeld!" }, "ram_usage": "Add-on RAM-gebruik", - "rebuild": "Herbouw", + "rebuild": "herbouw", "restart": "herstart", "start": "start", "stop": "stop", @@ -1123,7 +1123,7 @@ "input_number": "Input numbers", "input_select": "Input selects", "input_text": "Input texts", - "min_max": "Laad min/max entiteiten opnieuw", + "min_max": "Min/max entiteiten", "mqtt": "Handmatig geconfigureerde MQTT-entiteiten", "person": "Personen", "ping": "Ping binaire sensor entiteiten", @@ -2216,7 +2216,7 @@ "configure": "Configureer", "configured": "Geconfigureerd", "confirm_new": "Wil je {integration} instellen?", - "description": "Beheer integraties met services, apparaten, ...", + "description": "Beheer integraties met services of apparaten", "details": "Integratiedetails", "disable": { "disabled_integrations": "{number} uitgeschakeld", diff --git a/translations/frontend/sv.json b/translations/frontend/sv.json index 27c43699ae..39c7792d77 100644 --- a/translations/frontend/sv.json +++ b/translations/frontend/sv.json @@ -3279,7 +3279,7 @@ "unsaved_changes": "Osparade ändringar" }, "save_config": { - "cancel": "Glöm det", + "cancel": "Avbryt", "close": "Stäng", "empty_config": "Börja med en tom instrumentpanel", "header": "Ta kontroll över Lovelace UI", diff --git a/translations/frontend/zh-Hans.json b/translations/frontend/zh-Hans.json index 1794a3f5bd..0dec74815d 100644 --- a/translations/frontend/zh-Hans.json +++ b/translations/frontend/zh-Hans.json @@ -473,7 +473,7 @@ "unhealthy_title": "系统状态不佳", "unsupported_description": "以下是系统存在的问题的列表,请点击链接以了解如何解决问题。", "unsupported_reason": { - "apparmor": "主机上未启用AppArmor", + "apparmor": "未在主机上启用 AppArmor", "container": "已知会导致问题的容器", "content-trust": "内容信任验证已禁用", "dbus": "DBUS", @@ -1219,7 +1219,7 @@ "ask": "寻求帮助", "observer": "检查 Observer", "reboot": "请尝试重启主机", - "system_health": "检查系统健康状况", + "system_health": "检查系统状态", "title": "无法加载 Supervisor 面板!", "wait": "如果系统刚刚启动,请确保已等候足够的时间以便 Supervisor 启动完成。" } From 9d29b55beeddae20a82a2ac56d8c03c69d79b714 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 15 Apr 2021 09:46:19 +0200 Subject: [PATCH 038/106] Add z-index to add user dialog (#8917) --- src/panels/config/users/dialog-add-user.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/panels/config/users/dialog-add-user.ts b/src/panels/config/users/dialog-add-user.ts index 04c65c7738..b18bfc7a7e 100644 --- a/src/panels/config/users/dialog-add-user.ts +++ b/src/panels/config/users/dialog-add-user.ts @@ -270,6 +270,7 @@ export class DialogAddUser extends LitElement { css` ha-dialog { --mdc-dialog-max-width: 500px; + --dialog-z-index: 10; } ha-switch { margin-top: 8px; From f6e223c18d825299798e41d5af64278929081c39 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Thu, 15 Apr 2021 09:54:32 +0200 Subject: [PATCH 039/106] Use const everywhere for "group.default_view" (#8918) --- src/panels/lovelace/common/generate-lovelace-config.ts | 7 ++++--- test-mocha/common/entity/extract_views.spec.ts | 5 ++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/panels/lovelace/common/generate-lovelace-config.ts b/src/panels/lovelace/common/generate-lovelace-config.ts index cbeedd4f31..4251172c82 100644 --- a/src/panels/lovelace/common/generate-lovelace-config.ts +++ b/src/panels/lovelace/common/generate-lovelace-config.ts @@ -3,6 +3,8 @@ import { HassEntity, STATE_NOT_RUNNING, } from "home-assistant-js-websocket"; +import { isComponentLoaded } from "../../../common/config/is_component_loaded"; +import { DEFAULT_VIEW_ENTITY_ID } from "../../../common/const"; import { computeDomain } from "../../../common/entity/compute_domain"; import { computeObjectId } from "../../../common/entity/compute_object_id"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; @@ -13,7 +15,6 @@ import { splitByGroups } from "../../../common/entity/split_by_groups"; import { compare } from "../../../common/string/compare"; import { LocalizeFunc } from "../../../common/translations/localize"; import { subscribeOne } from "../../../common/util/subscribe-one"; -import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { AreaRegistryEntry, subscribeAreaRegistry, @@ -45,7 +46,6 @@ import { } from "../cards/types"; import { LovelaceRowConfig } from "../entity-rows/types"; -const DEFAULT_VIEW_ENTITY_ID = "group.default_view"; const HIDE_DOMAIN = new Set([ "automation", "configurator", @@ -181,7 +181,8 @@ export const computeCards = ( titlePrefix && stateObj && // eslint-disable-next-line no-cond-assign - (name = computeStateName(stateObj)) !== titlePrefix && name.startsWith(titlePrefix) + (name = computeStateName(stateObj)) !== titlePrefix && + name.startsWith(titlePrefix) ? { entity: entityId, name: adjustName(name.substr(titlePrefix.length)), diff --git a/test-mocha/common/entity/extract_views.spec.ts b/test-mocha/common/entity/extract_views.spec.ts index aa53fd3d78..e3cb85c111 100644 --- a/test-mocha/common/entity/extract_views.spec.ts +++ b/test-mocha/common/entity/extract_views.spec.ts @@ -1,7 +1,6 @@ import * as assert from "assert"; - +import { DEFAULT_VIEW_ENTITY_ID } from "../../../src/common/const"; import { extractViews } from "../../../src/common/entity/extract_views"; - import { createEntities, createView } from "./test_util"; describe("extractViews", () => { @@ -14,7 +13,7 @@ describe("extractViews", () => { entities[view2.entity_id] = view2; const view3 = createView({ - entity_id: "group.default_view", + entity_id: DEFAULT_VIEW_ENTITY_ID, attributes: { order: 8 }, }); entities[view3.entity_id] = view3; From 8e11aa91301f84a5b172523bc5e747e1ec81ccf0 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 15 Apr 2021 13:02:09 +0200 Subject: [PATCH 040/106] Fix activate scene button + allow removing icon (#8916) --- src/panels/config/scene/ha-scene-dashboard.ts | 2 +- src/panels/config/scene/ha-scene-editor.ts | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/panels/config/scene/ha-scene-dashboard.ts b/src/panels/config/scene/ha-scene-dashboard.ts index 177d7da864..2aebf9293a 100644 --- a/src/panels/config/scene/ha-scene-dashboard.ts +++ b/src/panels/config/scene/ha-scene-dashboard.ts @@ -228,7 +228,7 @@ class HaSceneDashboard extends LitElement { private async _activateScene(ev) { ev.stopPropagation(); - const scene = ev.target.scene as SceneEntity; + const scene = ev.currentTarget.scene as SceneEntity; await activateScene(this.hass, scene.entity_id); showToast(this, { message: this.hass.localize( diff --git a/src/panels/config/scene/ha-scene-editor.ts b/src/panels/config/scene/ha-scene-editor.ts index c3c9c32450..63a0e8df14 100644 --- a/src/panels/config/scene/ha-scene-editor.ts +++ b/src/panels/config/scene/ha-scene-editor.ts @@ -629,7 +629,12 @@ export class HaSceneEditor extends SubscribeMixin( if ((this._config![name] || "") === newVal) { return; } - this._config = { ...this._config!, [name]: newVal }; + if (!newVal) { + delete this._config![name]; + this._config = { ...this._config! }; + } else { + this._config = { ...this._config!, [name]: newVal }; + } this._dirty = true; } From 2dcd0d2b0ad531766db9d5d2905afcdc986a1c10 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 16 Apr 2021 00:48:38 +0000 Subject: [PATCH 041/106] Translation update --- translations/frontend/ca.json | 2 ++ translations/frontend/ja.json | 47 +++++++++++++++++++++++++++++++---- translations/frontend/ko.json | 16 ++++++------ translations/frontend/nb.json | 2 ++ translations/frontend/nl.json | 4 ++- translations/frontend/pl.json | 2 ++ translations/frontend/ru.json | 2 ++ 7 files changed, 62 insertions(+), 13 deletions(-) diff --git a/translations/frontend/ca.json b/translations/frontend/ca.json index e8f70bf076..6c2ccced2b 100644 --- a/translations/frontend/ca.json +++ b/translations/frontend/ca.json @@ -2255,8 +2255,10 @@ "logs": { "caption": "Registres", "clear": "Esborra", + "custom_integration": "integració personalitzada", "description": "Consulta els registres de Home Assistant", "details": "Detalls del registre ({level})", + "error_from_custom_integration": "Aquest error té origen en una integració personalitzada.", "level": { "critical": "CRÍTIC", "debug": "DEPURACIÓ", diff --git a/translations/frontend/ja.json b/translations/frontend/ja.json index a983e5a011..7e032802f8 100644 --- a/translations/frontend/ja.json +++ b/translations/frontend/ja.json @@ -467,6 +467,7 @@ "unhealthy_title": "インストールが正常でない", "unsupported_description": "以下は、インストールに関する問題の一覧です。", "unsupported_reason": { + "apparmor": "ホストでAppArmorが有効になっていない", "container": "問題が発生することが知られているコンテナ", "content-trust": "コンテンツ信頼の検証が無効になっています", "dbus": "DBUS", @@ -1173,6 +1174,9 @@ "zha_device_card": { "device_name_placeholder": "デバイス名の変更" } + }, + "zha_reconfigure_device": { + "heading": "デバイスを再設定" } }, "duration": { @@ -1193,6 +1197,14 @@ "key_wrong_type": "\"{key}\" に指定された値は、ビジュアル エディターではサポートされていません。({type_correct}) をサポートしていますが、受信しました ({type_wrong})。", "no_template_editor_support": "ビジュアルエディタでサポートされていないテンプレート", "no_type_provided": "タイプは提供されていません。" + }, + "supervisor": { + "ask": "ヘルプを確認する", + "observer": "オブザーバーの確認", + "reboot": "ホストを再起動してみてください", + "system_health": "システム状態のチェック", + "title": "スーパーバイザ パネルを読み込めませんでした。", + "wait": "開始したばかりの場合は、開始するのに十分な時間をスーパーバイザーに与えていることを確認してください。" } }, "login-form": { @@ -1210,10 +1222,12 @@ "notification_toast": { "connection_lost": "接続が切れました。再接続中...", "dismiss": "閉じる", + "intergration_starting": "{integration}を開始すると、完了するまですべてが利用できるわけではありません。", "service_call_failed": "サービス{service}の呼び出しに失敗しました。", "started": "ホームアシスタントが開始されました!", "starting": "Home Assistantが起動中です。全て利用可能なるまでもうしばらくお待ち下さい。", - "triggered": "トリガーしました {name}" + "triggered": "トリガーしました {name}", + "wrapping_up_startup": "スタートアップを総括すると、完成するまですべてが公開されるわけではありません。" }, "panel": { "config": { @@ -1373,7 +1387,7 @@ "type_select": "条件の種類", "type": { "and": { - "label": "の" + "label": "AND" }, "device": { "condition": "条件", @@ -1387,16 +1401,16 @@ "label": "デバイス" }, "not": { - "label": "ない" + "label": "Not" }, "numeric_state": { "above": "超過", "below": "未満", - "label": "数的な状態", + "label": "数的状態", "value_template": "バリューテンプレート(オプショナル)" }, "or": { - "label": "または" + "label": "OR" }, "state": { "label": "状態", @@ -1676,6 +1690,8 @@ "info": "ホーム アシスタント クラウド向けの Google アシスタント統合機能を使用すると、Google アシスタント対応のデバイスを介してすべてのホーム アシスタント デバイスを制御できます。", "info_state_reporting": "状態レポートを有効にすると、ホーム アシスタントは公開されたエンティティのすべての状態変更を Google に送信します。これにより、Google アプリで最新の状態を常に確認できます。", "manage_entities": "エンティティの管理", + "not_configured_text": "Google アシスタントを使用する前に、「Google Home」アプリで「Google アシスタント」のホームアシスタントクラウドスキルを有効にする必要があります。", + "not_configured_title": "Googleアシスタントがアクティブ化されていません", "security_devices": "セキュリティデバイス", "sync_entities": "エンティティをGoogleに同期", "sync_entities_404_message": "エンティティをGoogleに同期できませんでした。Googleに「OK Google、デバイスを同期して」と尋ねてエンティティを同期してください。", @@ -1843,6 +1859,7 @@ "header": "アナリティクス", "instance_id": "インスタンス ID: {huuid}", "introduction": "インスタンスからの分析を共有します。 {link}で公開されます", + "learn_more": "データの処理方法", "needs_base": "このオプションを有効にするには、ベースアナリティクスを有効にする必要があります。", "preference": { "base": { @@ -2054,6 +2071,9 @@ "filtering_by": "フィルタリング", "show": "表示" }, + "hassio": { + "button": "設定" + }, "header": "Home Assistant の設定", "helpers": { "caption": "ヘルパー", @@ -2140,8 +2160,10 @@ "entity_unavailable": "エンティティは利用できません", "firmware": "ファームウェア: {version}", "hub": "経由で接続", + "logs": "ログ", "manuf": "{manufacturer}", "no_area": "エリアなし", + "not_loaded": "読み込まれていない場合は{logs_link} を確認してください", "options": "オプション", "reload": "再読込", "reload_confirm": "インテグレーションが再読み込みされました", @@ -2167,6 +2189,7 @@ "finish": "完了", "loading_first_time": "インテグレーションのインストールを完了するまでお待ちください", "not_all_required_fields": "必須フィールドの一覧に入力するわけではありません。", + "not_loaded": "インテグレーションファイルを読み込めませんでした。ホームアシスタントを再起動してください。", "pick_flow_step": { "new_flow": "いいえ、{integration} の他のインスタンスを設定します", "title": "これらを発見しました。設定しますか?" @@ -2215,8 +2238,17 @@ "logs": { "caption": "ログ", "clear": "消去", + "custom_integration": "カスタム・インテグレーション", "description": "Home Assistantログを表示する", "details": "ログの詳細( {level} )", + "error_from_custom_integration": "このエラーは、カスタム統合から発生しました。", + "level": { + "critical": "クリティカル", + "debug": "デバッグ", + "error": "エラー", + "info": "情報", + "warning": "警告" + }, "load_full_log": "完全な Home Assistant ログを読み込む", "loading_log": "エラーログを読み込んでいます…", "multiple_messages": "メッセージは最初に{time}発生し、 {counter}回表示されます", @@ -3712,6 +3744,10 @@ } }, "page-onboarding": { + "analytics": { + "finish": "次", + "intro": "インスタンスのアナリティクスを共有する。このデータは{link}で公開されます。" + }, "core-config": { "button_detect": "検出", "finish": "次", @@ -3721,6 +3757,7 @@ "location_name": "ホーム アシスタントの名前", "location_name_default": "自宅" }, + "finish": "終了", "integration": { "finish": "完了", "intro": "デバイスとサービスは、統合としてHome Assistantに表示されます。今すぐ設定することも、後で設定画面から設定することもできます。", diff --git a/translations/frontend/ko.json b/translations/frontend/ko.json index 4fd23b9725..2a90f645d9 100644 --- a/translations/frontend/ko.json +++ b/translations/frontend/ko.json @@ -1220,7 +1220,7 @@ "observer": "Observer 확인하기", "reboot": "호스트 재부팅 시도하기", "system_health": "시스템 상태 확인하기", - "title": "Supervisor 화면을 불러올 수 없습니다.", + "title": "Supervisor 패널을 불러올 수 없습니다!", "wait": "방금 시작한 경우 Supervisor가 완전히 시작되기까지 잠시 기다려주세요." } }, @@ -1239,12 +1239,12 @@ "notification_toast": { "connection_lost": "서버와 연결이 끊어졌습니다. 다시 연결하는 중...", "dismiss": "해제하기", - "intergration_starting": "{integration} 시작 중. 완료되기 전 일부 기능은 작동하지 않을 수 있습니다.", + "intergration_starting": "{integration}을(를) 시작하는 중입니다. 완료될 때까지 일부 기능은 작동하지 않을 수 있습니다.", "service_call_failed": "{service} 서비스를 호출하지 못했습니다.", "started": "Home Assistant가 시작되었습니다!", "starting": "Home Assistant가 시작됩니다. 완료될 때까지 일부 기능은 작동하지 않을 수 있습니다.", "triggered": "{name}이(가) 트리거됨", - "wrapping_up_startup": "시작되기를 기다립니다. 완료되기 전 일부 기능은 작동하지 않을 수 있습니다." + "wrapping_up_startup": "시작을 마무리하는 중입니다. 완료될 때까지 일부 기능은 작동하지 않을 수 있습니다." }, "panel": { "config": { @@ -1872,7 +1872,7 @@ "section": { "core": { "analytics": { - "documentation": "이 옵션을 활성화하기 전에 분석 관련 문서 페이지 {link}을(를) 방문하여 어떤 데이터가 공유되는지, 어떻게 저장되는지 알아보세요.", + "documentation": "이 옵션을 활성화하기 전에 분석 관련 문서 페이지 {link}을(를) 방문하여 어떤 데이터를 보내고 어떻게 저장되는지 알아보세요.", "header": "분석", "instance_id": "인스턴스 ID: {huuid}", "introduction": "설치 정보를 공유하여 Home Assistant를 개선하고 제조업체가 로컬 제어 및 개인 정보 보호 기능을 추가하도록 설득하는 데 도움이됩니다.", @@ -1884,7 +1884,7 @@ "title": "기본 분석" }, "diagnostics": { - "description": "충돌 보고서 및 진단 정보를 공유합니다", + "description": "예기치 않은 오류가 발생할 경우 충돌 보고서를 공유합니다.", "title": "진단" }, "statistics": { @@ -2216,7 +2216,7 @@ "configure": "구성하기", "configured": "구성된 통합 구성요소", "confirm_new": "{integration}을(를) 설정하시겠습니까?", - "description": "통합 구성요소를 관리합니다", + "description": "서비스 또는 기기의 통합 구성요소를 관리합니다", "details": "통합 구성요소 상세정보", "disable": { "disabled_integrations": "{number}개의 비활성화된 통합 구성요소", @@ -2255,8 +2255,10 @@ "logs": { "caption": "로그", "clear": "지우기", + "custom_integration": "사용자 통합 구성요소", "description": "Home Assistant 로그 내역을 봅니다", "details": "로그 상세정보 ({level})", + "error_from_custom_integration": "이 오류는 사용자 통합 구성요소에서 발생했습니다.", "level": { "critical": "치명적오류", "debug": "디버그", @@ -3111,7 +3113,7 @@ "observer": "Observer 확인하기", "reboot": "호스트 재부팅 시도하기", "system_health": "시스템 상태 확인하기", - "title": "Supervisor 화면을 불러올 수 없습니다!", + "title": "Supervisor 패널을 불러올 수 없습니다!", "wait": "방금 시작한 경우 Supervisor가 완전히 시작되기까지 잠시 기다려주세요." } }, diff --git a/translations/frontend/nb.json b/translations/frontend/nb.json index 552f265e0b..c653c4efa0 100644 --- a/translations/frontend/nb.json +++ b/translations/frontend/nb.json @@ -2255,8 +2255,10 @@ "logs": { "caption": "Logger", "clear": "Tøm", + "custom_integration": "tilpasset integrasjon", "description": "Vis Home Assistant loggene", "details": "Loggdetaljer ({level})", + "error_from_custom_integration": "Denne feilen stammer fra en tilpasset integrasjon.", "level": { "critical": "KRITISK", "debug": "DEBUG", diff --git a/translations/frontend/nl.json b/translations/frontend/nl.json index be96640688..ee21974698 100644 --- a/translations/frontend/nl.json +++ b/translations/frontend/nl.json @@ -1934,7 +1934,7 @@ "different_include": "Mogelijk via een domein, een glob of een andere include.", "pick_attribute": "Kies een attribuut om te overschrijven", "picker": { - "documentation": "Documentatie aanpassen", + "documentation": "Documentatie van aanpassingen", "header": "Aanpassingen", "introduction": "Pas attributen per entiteit aan. Toegevoegde/gewijzigde aanpassingen worden onmiddellijk van kracht. Verwijderde aanpassingen worden van kracht wanneer de entiteit wordt bijgewerkt." }, @@ -2255,8 +2255,10 @@ "logs": { "caption": "Logboek", "clear": "Wis", + "custom_integration": "aangepaste integratie", "description": "Home Assistant logboek bekijken", "details": "Logboekdetails ({level})", + "error_from_custom_integration": "Deze fout is ontstaan door een aangepaste integratie.", "level": { "critical": "KRITISCH", "debug": "DEBUG", diff --git a/translations/frontend/pl.json b/translations/frontend/pl.json index a77f468777..395b3675b5 100644 --- a/translations/frontend/pl.json +++ b/translations/frontend/pl.json @@ -2255,8 +2255,10 @@ "logs": { "caption": "Logi", "clear": "Wyczyść", + "custom_integration": "niestandardowa integracja", "description": "Wyświetlanie logów Home Assistanta", "details": "Szczegóły loga ({level})", + "error_from_custom_integration": "Ten błąd pochodzi z niestandardowej integracji.", "level": { "critical": "KRYTYCZNE", "debug": "DEBUG", diff --git a/translations/frontend/ru.json b/translations/frontend/ru.json index 9748044340..00655d802c 100644 --- a/translations/frontend/ru.json +++ b/translations/frontend/ru.json @@ -2255,8 +2255,10 @@ "logs": { "caption": "Журнал сервера", "clear": "Очистить", + "custom_integration": "кастомная интеграция", "description": "Журналы работы сервера", "details": "Уровень: {level}", + "error_from_custom_integration": "Эта ошибка возникла в кастомной интеграции.", "level": { "critical": "КРИТИЧЕСКАЯ ОШИБКА", "debug": "ОТЛАДКА", From 60fe48d3559e3c0ca5c5e4f6c5545201f99a199b Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 16 Apr 2021 04:16:59 -0700 Subject: [PATCH 042/106] Show config entry state on card (#8911) --- gallery/src/demos/demo-integration-card.ts | 299 +++++++ src/data/config_entries.ts | 10 +- src/data/device_registry.ts | 14 +- src/data/entity_registry.ts | 10 +- src/data/integration.ts | 8 +- .../dialog-device-registry-detail.ts | 2 +- .../entities/entity-registry-basic-editor.ts | 2 +- .../config/entities/ha-config-entities.ts | 4 + .../integrations/ha-config-flow-card.ts | 130 +++ .../ha-config-integrations-common.ts | 75 ++ .../integrations/ha-config-integrations.ts | 407 +++------- .../ha-ignored-config-entry-card.ts | 95 +++ .../ha-integration-action-card.ts | 114 +++ .../integrations/ha-integration-card.ts | 750 +++++++++--------- .../integration-panels/zha/zha-device-card.ts | 2 +- src/translations/en.json | 24 +- 16 files changed, 1233 insertions(+), 713 deletions(-) create mode 100644 gallery/src/demos/demo-integration-card.ts create mode 100644 src/panels/config/integrations/ha-config-flow-card.ts create mode 100644 src/panels/config/integrations/ha-config-integrations-common.ts create mode 100644 src/panels/config/integrations/ha-ignored-config-entry-card.ts create mode 100644 src/panels/config/integrations/ha-integration-action-card.ts diff --git a/gallery/src/demos/demo-integration-card.ts b/gallery/src/demos/demo-integration-card.ts new file mode 100644 index 0000000000..1e805910a8 --- /dev/null +++ b/gallery/src/demos/demo-integration-card.ts @@ -0,0 +1,299 @@ +import { + customElement, + html, + css, + internalProperty, + LitElement, + TemplateResult, + property, +} from "lit-element"; +import "../../../src/components/ha-formfield"; +import "../../../src/components/ha-switch"; + +import { IntegrationManifest } from "../../../src/data/integration"; + +import { provideHass } from "../../../src/fake_data/provide_hass"; +import { HomeAssistant } from "../../../src/types"; +import "../../../src/panels/config/integrations/ha-integration-card"; +import "../../../src/panels/config/integrations/ha-ignored-config-entry-card"; +import "../../../src/panels/config/integrations/ha-config-flow-card"; +import type { + ConfigEntryExtended, + DataEntryFlowProgressExtended, +} from "../../../src/panels/config/integrations/ha-config-integrations"; +import { DeviceRegistryEntry } from "../../../src/data/device_registry"; +import { EntityRegistryEntry } from "../../../src/data/entity_registry"; +import { classMap } from "lit-html/directives/class-map"; + +const createConfigEntry = ( + title: string, + override: Partial = {} +): ConfigEntryExtended => ({ + entry_id: title, + domain: "esphome", + localized_domain_name: "ESPHome", + title, + source: "zeroconf", + state: "loaded", + connection_class: "local_push", + supports_options: false, + supports_unload: true, + disabled_by: null, + ...override, +}); + +const createManifest = ( + isCustom: boolean, + isCloud: boolean +): IntegrationManifest => ({ + name: "ESPHome", + domain: "esphome", + is_built_in: !isCustom, + config_flow: false, + documentation: "https://www.home-assistant.io/integrations/esphome/", + iot_class: isCloud ? "cloud_polling" : "local_polling", +}); + +const loadedEntry = createConfigEntry("Loaded"); +const nameAsDomainEntry = createConfigEntry("ESPHome"); +const longNameEntry = createConfigEntry( + "Entry with a super long name that is going to the next line" +); +const configPanelEntry = createConfigEntry("Config Panel", { + domain: "mqtt", + localized_domain_name: "MQTT", +}); +const optionsFlowEntry = createConfigEntry("Options Flow", { + supports_options: true, +}); +const setupErrorEntry = createConfigEntry("Setup Error", { + state: "setup_error", +}); +const migrationErrorEntry = createConfigEntry("Migration Error", { + state: "migration_error", +}); +const setupRetryEntry = createConfigEntry("Setup Retry", { + state: "setup_retry", +}); +const failedUnloadEntry = createConfigEntry("Failed Unload", { + state: "failed_unload", +}); +const notLoadedEntry = createConfigEntry("Not Loaded", { state: "not_loaded" }); +const disabledEntry = createConfigEntry("Disabled", { + state: "not_loaded", + disabled_by: "user", +}); +const disabledFailedUnloadEntry = createConfigEntry( + "Disabled - Failed Unload", + { + state: "failed_unload", + disabled_by: "user", + } +); + +const configFlows: DataEntryFlowProgressExtended[] = [ + { + flow_id: "adbb401329d8439ebb78ef29837826a8", + handler: "roku", + context: { + source: "ssdp", + unique_id: "YF008D862864", + title_placeholders: { + name: "Living room Roku", + }, + }, + step_id: "discovery_confirm", + localized_title: "Roku: Living room Roku", + }, + { + flow_id: "adbb401329d8439ebb78ef29837826a8", + handler: "hue", + context: { + source: "reauth", + unique_id: "YF008D862864", + title_placeholders: { + name: "Living room Roku", + }, + }, + step_id: "discovery_confirm", + localized_title: "Philips Hue", + }, +]; + +const configEntries: Array<{ + items: ConfigEntryExtended[]; + is_custom?: boolean; + disabled?: boolean; + highlight?: string; +}> = [ + { items: [loadedEntry] }, + { items: [configPanelEntry] }, + { items: [optionsFlowEntry] }, + { items: [nameAsDomainEntry] }, + { items: [longNameEntry] }, + { items: [setupErrorEntry] }, + { items: [migrationErrorEntry] }, + { items: [setupRetryEntry] }, + { items: [failedUnloadEntry] }, + { items: [notLoadedEntry] }, + { + items: [ + loadedEntry, + longNameEntry, + setupErrorEntry, + migrationErrorEntry, + setupRetryEntry, + failedUnloadEntry, + notLoadedEntry, + disabledEntry, + nameAsDomainEntry, + configPanelEntry, + optionsFlowEntry, + ], + }, + { disabled: true, items: [disabledEntry] }, + { disabled: true, items: [disabledFailedUnloadEntry] }, + { + disabled: true, + items: [disabledEntry, disabledFailedUnloadEntry], + }, + { + items: [loadedEntry, configPanelEntry], + highlight: "Loaded", + }, +]; + +const createEntityRegistryEntries = ( + item: ConfigEntryExtended +): EntityRegistryEntry[] => [ + { + config_entry_id: item.entry_id, + device_id: "mock-device-id", + area_id: null, + disabled_by: null, + entity_id: "binary_sensor.updater", + name: null, + icon: null, + platform: "updater", + }, +]; + +const createDeviceRegistryEntries = ( + item: ConfigEntryExtended +): DeviceRegistryEntry[] => [ + { + entry_type: null, + config_entries: [item.entry_id], + connections: [], + manufacturer: "ESPHome", + model: "Mock Device", + name: "Tag Reader", + sw_version: null, + id: "mock-device-id", + identifiers: [], + via_device_id: null, + area_id: null, + name_by_user: null, + disabled_by: null, + }, +]; + +@customElement("demo-integration-card") +export class DemoIntegrationCard extends LitElement { + @property({ attribute: false }) hass?: HomeAssistant; + + @internalProperty() isCustomIntegration = false; + + @internalProperty() isCloud = false; + + protected render(): TemplateResult { + if (!this.hass) { + return html``; + } + return html` +

+ + + + ${configFlows.map( + (flow) => html` + + ` + )} + ${configEntries.map( + (info) => html` + + ` + )} + `; + } + + protected firstUpdated(changedProps) { + super.firstUpdated(changedProps); + const hass = provideHass(this); + hass.updateTranslations(null, "en"); + hass.updateTranslations("config", "en"); + } + + private _toggleCustomIntegration() { + this.isCustomIntegration = !this.isCustomIntegration; + } + + private _toggleCloud() { + this.isCloud = !this.isCloud; + } + + static get styles() { + return css` + :host { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + grid-gap: 16px 16px; + padding: 8px 16px 16px; + margin-bottom: 64px; + } + + :host > * { + max-width: 500px; + } + + ha-formfield { + margin: 8px 0; + display: block; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-integration-card": DemoIntegrationCard; + } +} diff --git a/src/data/config_entries.ts b/src/data/config_entries.ts index d75de78536..603aab6d06 100644 --- a/src/data/config_entries.ts +++ b/src/data/config_entries.ts @@ -5,11 +5,17 @@ export interface ConfigEntry { domain: string; title: string; source: string; - state: string; + state: + | "loaded" + | "setup_error" + | "migration_error" + | "setup_retry" + | "not_loaded" + | "failed_unload"; connection_class: string; supports_options: boolean; supports_unload: boolean; - disabled_by: string | null; + disabled_by: "user" | null; } export interface ConfigEntryMutableParams { diff --git a/src/data/device_registry.ts b/src/data/device_registry.ts index 8fc1807586..d2d119d300 100644 --- a/src/data/device_registry.ts +++ b/src/data/device_registry.ts @@ -9,13 +9,13 @@ export interface DeviceRegistryEntry { config_entries: string[]; connections: Array<[string, string]>; identifiers: Array<[string, string]>; - manufacturer: string; - model?: string; - name?: string; - sw_version?: string; - via_device_id?: string; - area_id?: string; - name_by_user?: string; + manufacturer: string | null; + model: string | null; + name: string | null; + sw_version: string | null; + via_device_id: string | null; + area_id: string | null; + name_by_user: string | null; entry_type: "service" | null; disabled_by: string | null; } diff --git a/src/data/entity_registry.ts b/src/data/entity_registry.ts index 81796ff822..0bf6a5b253 100644 --- a/src/data/entity_registry.ts +++ b/src/data/entity_registry.ts @@ -5,12 +5,12 @@ import { HomeAssistant } from "../types"; export interface EntityRegistryEntry { entity_id: string; - name: string; - icon?: string; + name: string | null; + icon: string | null; platform: string; - config_entry_id?: string; - device_id?: string; - area_id?: string; + config_entry_id: string | null; + device_id: string | null; + area_id: string | null; disabled_by: string | null; } diff --git a/src/data/integration.ts b/src/data/integration.ts index d8caf1b591..f19be078eb 100644 --- a/src/data/integration.ts +++ b/src/data/integration.ts @@ -15,7 +15,13 @@ export interface IntegrationManifest { ssdp?: Array<{ manufacturer?: string; modelName?: string; st?: string }>; zeroconf?: string[]; homekit?: { models: string[] }; - quality_scale?: string; + quality_scale?: "gold" | "internal" | "platinum" | "silver"; + iot_class: + | "assumed_state" + | "cloud_polling" + | "cloud_push" + | "local_polling" + | "local_push"; } export const integrationIssuesUrl = ( diff --git a/src/panels/config/devices/device-registry-detail/dialog-device-registry-detail.ts b/src/panels/config/devices/device-registry-detail/dialog-device-registry-detail.ts index e60439f2de..99bd51dcb7 100644 --- a/src/panels/config/devices/device-registry-detail/dialog-device-registry-detail.ts +++ b/src/panels/config/devices/device-registry-detail/dialog-device-registry-detail.ts @@ -33,7 +33,7 @@ class DialogDeviceRegistryDetail extends LitElement { @internalProperty() private _params?: DeviceRegistryDetailDialogParams; - @internalProperty() private _areaId?: string; + @internalProperty() private _areaId?: string | null; @internalProperty() private _disabledBy!: string | null; diff --git a/src/panels/config/entities/entity-registry-basic-editor.ts b/src/panels/config/entities/entity-registry-basic-editor.ts index 1b1690394c..1063639aa4 100644 --- a/src/panels/config/entities/entity-registry-basic-editor.ts +++ b/src/panels/config/entities/entity-registry-basic-editor.ts @@ -38,7 +38,7 @@ export class HaEntityRegistryBasicEditor extends SubscribeMixin(LitElement) { @internalProperty() private _entityId!: string; - @internalProperty() private _areaId?: string; + @internalProperty() private _areaId?: string | null; @internalProperty() private _disabledBy!: string | null; diff --git a/src/panels/config/entities/ha-config-entities.ts b/src/panels/config/entities/ha-config-entities.ts index be295a57a4..c1277e7b8a 100644 --- a/src/panels/config/entities/ha-config-entities.ts +++ b/src/panels/config/entities/ha-config-entities.ts @@ -663,6 +663,10 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { entity_id: entityId, platform: computeDomain(entityId), disabled_by: null, + area_id: null, + config_entry_id: null, + device_id: null, + icon: null, readonly: true, selectable: false, }); diff --git a/src/panels/config/integrations/ha-config-flow-card.ts b/src/panels/config/integrations/ha-config-flow-card.ts new file mode 100644 index 0000000000..fd6769b22c --- /dev/null +++ b/src/panels/config/integrations/ha-config-flow-card.ts @@ -0,0 +1,130 @@ +import { + customElement, + LitElement, + property, + css, + html, + TemplateResult, +} from "lit-element"; +import { classMap } from "lit-html/directives/class-map"; +import { fireEvent } from "../../../common/dom/fire_event"; +import { + ATTENTION_SOURCES, + DISCOVERY_SOURCES, + ignoreConfigFlow, + localizeConfigFlowTitle, +} from "../../../data/config_flow"; +import type { IntegrationManifest } from "../../../data/integration"; +import { showConfigFlowDialog } from "../../../dialogs/config-flow/show-dialog-config-flow"; +import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; +import type { HomeAssistant } from "../../../types"; +import type { DataEntryFlowProgressExtended } from "./ha-config-integrations"; +import "./ha-integration-action-card"; + +@customElement("ha-config-flow-card") +export class HaConfigFlowCard extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public flow!: DataEntryFlowProgressExtended; + + @property() public manifest?: IntegrationManifest; + + protected render(): TemplateResult { + const attention = ATTENTION_SOURCES.includes(this.flow.context.source); + return html` + + + ${DISCOVERY_SOURCES.includes(this.flow.context.source) && + this.flow.context.unique_id + ? html` + + ` + : ""} + + `; + } + + private _continueFlow() { + showConfigFlowDialog(this, { + continueFlowId: this.flow.flow_id, + dialogClosedCallback: () => { + this._handleFlowUpdated(); + }, + }); + } + + private async _ignoreFlow() { + const confirmed = await showConfirmationDialog(this, { + title: this.hass!.localize( + "ui.panel.config.integrations.ignore.confirm_ignore_title", + "name", + localizeConfigFlowTitle(this.hass.localize, this.flow) + ), + text: this.hass!.localize( + "ui.panel.config.integrations.ignore.confirm_ignore" + ), + confirmText: this.hass!.localize( + "ui.panel.config.integrations.ignore.ignore" + ), + }); + if (!confirmed) { + return; + } + await ignoreConfigFlow( + this.hass, + this.flow.flow_id, + localizeConfigFlowTitle(this.hass.localize, this.flow) + ); + this._handleFlowUpdated(); + } + + private _handleFlowUpdated() { + fireEvent(this, "change", undefined, { + bubbles: false, + }); + } + + static styles = css` + .attention { + --state-color: var(--error-color); + --text-on-state-color: var(--text-primary-color); + } + .discovered { + --state-color: var(--primary-color); + --text-on-state-color: var(--text-primary-color); + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "ha-config-flow-card": HaConfigFlowCard; + } +} diff --git a/src/panels/config/integrations/ha-config-integrations-common.ts b/src/panels/config/integrations/ha-config-integrations-common.ts new file mode 100644 index 0000000000..063e35c178 --- /dev/null +++ b/src/panels/config/integrations/ha-config-integrations-common.ts @@ -0,0 +1,75 @@ +import { mdiPackageVariant, mdiCloud } from "@mdi/js"; +import "@polymer/paper-tooltip/paper-tooltip"; +import { css, html } from "lit-element"; +import { IntegrationManifest } from "../../../data/integration"; +import { HomeAssistant } from "../../../types"; + +export const haConfigIntegrationsStyles = css` + .banner { + background-color: var(--state-color); + color: var(--text-on-state-color); + text-align: center; + padding: 8px; + } + .icons { + position: absolute; + top: 0px; + right: 16px; + color: var(--text-on-state-color, var(--secondary-text-color)); + background-color: var(--state-color, #e0e0e0); + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + padding: 1px 4px 2px; + } + .icons ha-svg-icon { + width: 20px; + height: 20px; + } + paper-tooltip { + white-space: nowrap; + } +`; + +export const haConfigIntegrationRenderIcons = ( + hass: HomeAssistant, + manifest?: IntegrationManifest +) => { + const icons: [string, string][] = []; + + if (manifest) { + if (!manifest.is_built_in) { + icons.push([ + mdiPackageVariant, + hass.localize( + "ui.panel.config.integrations.config_entry.provided_by_custom_component" + ), + ]); + } + + if (manifest.iot_class && manifest.iot_class.startsWith("cloud_")) { + icons.push([ + mdiCloud, + hass.localize( + "ui.panel.config.integrations.config_entry.depends_on_cloud" + ), + ]); + } + } + + return icons.length === 0 + ? "" + : html` +
+ ${icons.map( + ([icon, description]) => html` + + + ${description} + + ` + )} +
+ `; +}; diff --git a/src/panels/config/integrations/ha-config-integrations.ts b/src/panels/config/integrations/ha-config-integrations.ts index b0823087f0..845319c01a 100644 --- a/src/panels/config/integrations/ha-config-integrations.ts +++ b/src/panels/config/integrations/ha-config-integrations.ts @@ -2,9 +2,8 @@ import "@material/mwc-icon-button"; import { ActionDetail } from "@material/mwc-list"; import "@material/mwc-list/mwc-list-item"; import { mdiFilterVariant, mdiPlus } from "@mdi/js"; -import "@polymer/app-route/app-route"; import Fuse from "fuse.js"; -import { UnsubscribeFunc } from "home-assistant-js-websocket"; +import type { UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, CSSResult, @@ -16,31 +15,15 @@ import { PropertyValues, TemplateResult, } from "lit-element"; -import { classMap } from "lit-html/directives/class-map"; import { ifDefined } from "lit-html/directives/if-defined"; import memoizeOne from "memoize-one"; -import { HASSDomEvent } from "../../../common/dom/fire_event"; import { navigate } from "../../../common/navigate"; -import "../../../common/search/search-input"; import { caseInsensitiveCompare } from "../../../common/string/compare"; -import { LocalizeFunc } from "../../../common/translations/localize"; import { extractSearchParam } from "../../../common/url/search-params"; import { nextRender } from "../../../common/util/render-status"; -import "../../../components/ha-button-menu"; -import "../../../components/ha-card"; -import "../../../components/ha-fab"; -import "../../../components/ha-checkbox"; -import "../../../components/ha-svg-icon"; +import { ConfigEntry, getConfigEntries } from "../../../data/config_entries"; import { - ConfigEntry, - deleteConfigEntry, - getConfigEntries, -} from "../../../data/config_entries"; -import { - ATTENTION_SOURCES, - DISCOVERY_SOURCES, getConfigFlowInProgressCollection, - ignoreConfigFlow, localizeConfigFlowTitle, subscribeConfigFlowInProgress, } from "../../../data/config_flow"; @@ -60,21 +43,43 @@ import { } from "../../../data/integration"; import { showConfigFlowDialog } from "../../../dialogs/config-flow/show-dialog-config-flow"; import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; -import "../../../layouts/hass-loading-screen"; -import "../../../layouts/hass-tabs-subpage"; import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; import { haStyle } from "../../../resources/styles"; -import { HomeAssistant, Route } from "../../../types"; -import { brandsUrl } from "../../../util/brands-url"; import { configSections } from "../ha-panel-config"; -import "./ha-integration-card"; -import type { - ConfigEntryRemovedEvent, - ConfigEntryUpdatedEvent, - HaIntegrationCard, -} from "./ha-integration-card"; -interface DataEntryFlowProgressExtended extends DataEntryFlowProgress { +import type { HomeAssistant, Route } from "../../../types"; +import type { HASSDomEvent } from "../../../common/dom/fire_event"; +import type { LocalizeFunc } from "../../../common/translations/localize"; +import type { HaIntegrationCard } from "./ha-integration-card"; + +import "../../../common/search/search-input"; +import "../../../components/ha-button-menu"; +import "../../../components/ha-fab"; +import "../../../components/ha-checkbox"; +import "../../../components/ha-svg-icon"; +import "../../../layouts/hass-loading-screen"; +import "../../../layouts/hass-tabs-subpage"; +import "./ha-integration-card"; +import "./ha-config-flow-card"; +import "./ha-ignored-config-entry-card"; + +export interface ConfigEntryUpdatedEvent { + entry: ConfigEntry; +} + +export interface ConfigEntryRemovedEvent { + entryId: string; +} + +declare global { + // for fire event + interface HASSDomEvents { + "entry-updated": ConfigEntryUpdatedEvent; + "entry-removed": ConfigEntryRemovedEvent; + } +} + +export interface DataEntryFlowProgressExtended extends DataEntryFlowProgress { localized_title?: string; } @@ -119,9 +124,8 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { @internalProperty() private _deviceRegistryEntries: DeviceRegistryEntry[] = []; - @internalProperty() private _manifests!: { - [domain: string]: IntegrationManifest; - }; + @internalProperty() + private _manifests: Record = {}; @internalProperty() private _showIgnored = false; @@ -217,12 +221,6 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { configEntriesInProgress: DataEntryFlowProgressExtended[], filter?: string ): DataEntryFlowProgressExtended[] => { - configEntriesInProgress = configEntriesInProgress.map( - (flow: DataEntryFlowProgressExtended) => ({ - ...flow, - title: localizeConfigFlowTitle(this.hass.localize, flow), - }) - ); if (!filter) { return configEntriesInProgress; } @@ -349,11 +347,12 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { "number", disabledConfigEntries.size )} - - ${this.hass.localize( + + >
` : ""} ${filterMenu} @@ -362,112 +361,30 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
${this._showIgnored ? ignoredConfigEntries.map( - (item: ConfigEntryExtended) => html` - -
- ${this.hass.localize( - "ui.panel.config.integrations.ignore.ignored" - )} -
-
-
- -
-

- ${// In 2020.2 we added support for item.title. All ignored entries before - // that have title "Ignored" so we fallback to localized domain name. - item.title === "Ignored" - ? item.localized_domain_name - : item.title} -

- ${this.hass.localize( - "ui.panel.config.integrations.ignore.stop_ignore" - )} -
-
+ (entry: ConfigEntryExtended) => html` + ` ) : ""} ${configEntriesInProgress.length ? configEntriesInProgress.map( - (flow: DataEntryFlowProgressExtended) => { - const attention = ATTENTION_SOURCES.includes( - flow.context.source - ); - return html` - -
- ${this.hass.localize( - `ui.panel.config.integrations.${ - attention ? "attention" : "discovered" - }` - )} -
-
-
- -
-

- ${flow.localized_title} -

-
- - ${this.hass.localize( - `ui.panel.config.integrations.${ - attention ? "reconfigure" : "configure" - }` - )} - - ${DISCOVERY_SOURCES.includes(flow.context.source) && - flow.context.unique_id - ? html` - - ${this.hass.localize( - "ui.panel.config.integrations.ignore.ignore" - )} - - ` - : ""} -
-
-
- `; - } + (flow: DataEntryFlowProgressExtended) => html` + + ` ) : ""} ${this._showDisabled @@ -498,25 +415,28 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { .deviceRegistryEntries=${this._deviceRegistryEntries} >` ) - : !this._configEntries.length + : // If we're showing 0 cards, show empty state text + (!this._showIgnored || ignoredConfigEntries.length === 0) && + (!this._showDisabled || disabledConfigEntries.size === 0) && + groupedConfigEntries.size === 0 ? 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_integration" - )} -
-
+
+

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

+

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

+ +
` : ""} ${this._filter && @@ -524,7 +444,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { !groupedConfigEntries.size && this._configEntries.length ? html` -
+

${this.hass.localize( "ui.panel.config.integrations.none_found" @@ -581,13 +501,13 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { this._manifests = manifests; } - private _handleRemoved(ev: HASSDomEvent) { + private _handleEntryRemoved(ev: HASSDomEvent) { this._configEntries = this._configEntries!.filter( (entry) => entry.entry_id !== ev.detail.entryId ); } - private _handleUpdated(ev: HASSDomEvent) { + private _handleEntryUpdated(ev: HASSDomEvent) { const newEntry = ev.detail.entry; this._configEntries = this._configEntries!.map((entry) => entry.entry_id === newEntry.entry_id @@ -599,6 +519,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { private _handleFlowUpdated() { this._loadConfigEntries(); getConfigFlowInProgressCollection(this.hass.connection).refresh(); + this._fetchManifests(); } private _createFlow() { @@ -608,50 +529,14 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { }, showAdvanced: this.showAdvanced, }); - // For config entries. Also loading config flow ones for add integration + // For config entries. Also loading config flow ones for added integration this.hass.loadBackendTranslation("title", undefined, true); } - private _continueFlow(ev: Event) { - showConfigFlowDialog(this, { - continueFlowId: (ev.target! as any).flowId, - dialogClosedCallback: () => { - this._handleFlowUpdated(); - }, - }); - } - - private async _ignoreFlow(ev: Event) { - const flow = (ev.target! as any).flow; - const confirmed = await 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" - ), - }); - if (!confirmed) { - return; - } - await ignoreConfigFlow( - this.hass, - flow.flow_id, - localizeConfigFlowTitle(this.hass.localize, flow) - ); - this._loadConfigEntries(); - getConfigFlowInProgressCollection(this.hass.connection).refresh(); - } - private _handleMenuAction(ev: CustomEvent) { switch (ev.detail.index) { case 0: - this._toggleShowIgnored(); + this._showIgnored = !this._showIgnored; break; case 1: this._toggleShowDisabled(); @@ -659,54 +544,14 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { } } - private _toggleShowIgnored() { - this._showIgnored = !this._showIgnored; - } - private _toggleShowDisabled() { this._showDisabled = !this._showDisabled; } - 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" - ) - ); - } - this._loadConfigEntries(); - }, - }); - } - private _handleSearchChange(ev: CustomEvent) { this._filter = ev.detail.value; } - private _onImageLoad(ev) { - ev.target.style.visibility = "initial"; - } - - private _onImageError(ev) { - ev.target.style.visibility = "hidden"; - } - private async _highlightEntry() { await nextRender(); const entryId = this._searchParms.get("config_entry")!; @@ -769,66 +614,18 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { padding: 8px 16px 16px; margin-bottom: 64px; } - ha-card { + .container > * { max-width: 500px; - display: flex; - flex-direction: column; - justify-content: space-between; } - .attention { - --ha-card-border-color: var(--error-color); - } - .attention .header { - background: var(--error-color); - color: var(--text-primary-color); - padding: 8px; - text-align: center; - } - .attention mwc-button { - --mdc-theme-primary: var(--error-color); - } - .discovered { - --ha-card-border-color: var(--primary-color); - } - .discovered .header { - background: var(--primary-color); - color: var(--text-primary-color); - padding: 8px; - text-align: center; - } - .ignored { - --ha-card-border-color: var(--light-theme-disabled-color); - } - .ignored img { - filter: grayscale(1); - } - .ignored .header { - background: var(--light-theme-disabled-color); - color: var(--text-primary-color); - padding: 8px; - text-align: center; - } - .card-content { - display: flex; - height: 100%; - margin-top: 0; - padding: 16px; - text-align: center; - flex-direction: column; - justify-content: space-between; - } - .image { - display: flex; - align-items: center; - justify-content: center; - height: 60px; - margin-bottom: 16px; - vertical-align: middle; - } - .none-found { + + .empty-message { margin: auto; text-align: center; } + .empty-message h1 { + margin-bottom: 0; + } + search-input.header { display: block; position: relative; @@ -848,27 +645,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { position: relative; top: 2px; } - img { - max-height: 100%; - max-width: 90%; - } - .none-found { - margin: auto; - text-align: center; - } - h1 { - margin-bottom: 0; - } - h2 { - margin-top: 0; - word-wrap: break-word; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 3; - overflow: hidden; - text-overflow: ellipsis; - white-space: normal; - } + .active-filters { color: var(--primary-text-color); position: relative; diff --git a/src/panels/config/integrations/ha-ignored-config-entry-card.ts b/src/panels/config/integrations/ha-ignored-config-entry-card.ts new file mode 100644 index 0000000000..e4332bd65e --- /dev/null +++ b/src/panels/config/integrations/ha-ignored-config-entry-card.ts @@ -0,0 +1,95 @@ +import { + customElement, + LitElement, + property, + css, + html, + TemplateResult, +} from "lit-element"; +import { fireEvent } from "../../../common/dom/fire_event"; +import { deleteConfigEntry } from "../../../data/config_entries"; +import type { IntegrationManifest } from "../../../data/integration"; +import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; +import type { HomeAssistant } from "../../../types"; +import type { ConfigEntryExtended } from "./ha-config-integrations"; +import "./ha-integration-action-card"; + +@customElement("ha-ignored-config-entry-card") +export class HaIgnoredConfigEntryCard extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public entry!: ConfigEntryExtended; + + @property() public manifest?: IntegrationManifest; + + protected render(): TemplateResult { + return html` + + + + `; + } + + private async _removeIgnoredIntegration() { + showConfirmationDialog(this, { + title: this.hass!.localize( + "ui.panel.config.integrations.ignore.confirm_delete_ignore_title", + "name", + this.hass.localize(`component.${this.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, this.entry.entry_id); + if (result.require_restart) { + alert( + this.hass.localize( + "ui.panel.config.integrations.config_entry.restart_confirm" + ) + ); + } + fireEvent(this, "change", undefined, { + bubbles: false, + }); + }, + }); + } + + static styles = css` + :host { + --state-color: var(--divider-color, #e0e0e0); + } + + mwc-button { + --mdc-theme-primary: var(--primary-color); + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "ha-ignored-config-entry-card": HaIgnoredConfigEntryCard; + } +} diff --git a/src/panels/config/integrations/ha-integration-action-card.ts b/src/panels/config/integrations/ha-integration-action-card.ts new file mode 100644 index 0000000000..f3223f7f2c --- /dev/null +++ b/src/panels/config/integrations/ha-integration-action-card.ts @@ -0,0 +1,114 @@ +import { + customElement, + LitElement, + property, + CSSResult, + css, +} from "lit-element"; +import { TemplateResult, html } from "lit-html"; +import { IntegrationManifest } from "../../../data/integration"; +import { HomeAssistant } from "../../../types"; +import { brandsUrl } from "../../../util/brands-url"; +import { + haConfigIntegrationRenderIcons, + haConfigIntegrationsStyles, +} from "./ha-config-integrations-common"; + +@customElement("ha-integration-action-card") +export class HaIntegrationActionCard extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public banner!: string; + + @property() public domain!: string; + + @property() public label!: string; + + @property() public manifest?: IntegrationManifest; + + protected render(): TemplateResult { + return html` + + +
+ ${haConfigIntegrationRenderIcons(this.hass, this.manifest)} +
+ +
+

${this.label}

+
+
+
+ `; + } + + private _onImageLoad(ev) { + ev.target.style.visibility = "initial"; + } + + private _onImageError(ev) { + ev.target.style.visibility = "hidden"; + } + + static get styles(): CSSResult[] { + return [ + haConfigIntegrationsStyles, + css` + ha-card { + display: flex; + flex-direction: column; + height: 100%; + --ha-card-border-color: var(--state-color); + --mdc-theme-primary: var(--state-color); + } + .content { + position: relative; + flex: 1; + } + .image { + height: 60px; + margin-top: 16px; + display: flex; + align-items: center; + justify-content: space-around; + } + img { + max-width: 90%; + max-height: 100%; + } + h2 { + text-align: center; + margin: 16px 8px 0; + } + .attention { + --state-color: var(--error-color); + --text-on-state-color: var(--text-primary-color); + } + .discovered { + --state-color: var(--primary-color); + --text-on-state-color: var(--text-primary-color); + } + .actions { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 6px 0; + height: 48px; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-integration-action-card": HaIntegrationActionCard; + } +} diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index be687830cc..fc975fb6bc 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -1,4 +1,8 @@ import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item"; +import "@material/mwc-list/mwc-list-item"; +import "@polymer/paper-listbox"; +import "@material/mwc-button"; +import "@polymer/paper-item"; import "@polymer/paper-tooltip/paper-tooltip"; import { mdiAlertCircle, mdiDotsVertical, mdiOpenInNew } from "@mdi/js"; import { @@ -14,7 +18,9 @@ import { classMap } from "lit-html/directives/class-map"; import { fireEvent } from "../../../common/dom/fire_event"; import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event"; import "../../../components/ha-icon-next"; +import "../../../components/ha-button-menu"; import "../../../components/ha-svg-icon"; +import "../../../components/ha-card"; import { ConfigEntry, deleteConfigEntry, @@ -23,8 +29,8 @@ import { reloadConfigEntry, updateConfigEntry, } from "../../../data/config_entries"; -import { DeviceRegistryEntry } from "../../../data/device_registry"; -import { EntityRegistryEntry } from "../../../data/entity_registry"; +import type { DeviceRegistryEntry } from "../../../data/device_registry"; +import type { EntityRegistryEntry } from "../../../data/entity_registry"; import { domainToName, IntegrationManifest } from "../../../data/integration"; import { showConfigEntrySystemOptionsDialog } from "../../../dialogs/config-entry-system-options/show-dialog-config-entry-system-options"; import { showOptionsFlowDialog } from "../../../dialogs/config-flow/show-dialog-options-flow"; @@ -37,48 +43,25 @@ import { haStyle } from "../../../resources/styles"; import { HomeAssistant } from "../../../types"; import { brandsUrl } from "../../../util/brands-url"; import { ConfigEntryExtended } from "./ha-config-integrations"; +import { + haConfigIntegrationRenderIcons, + haConfigIntegrationsStyles, +} from "./ha-config-integrations-common"; -export interface ConfigEntryUpdatedEvent { - entry: ConfigEntry; -} - -export interface ConfigEntryRemovedEvent { - entryId: string; -} - -declare global { - // for fire event - interface HASSDomEvents { - "entry-updated": ConfigEntryUpdatedEvent; - "entry-removed": ConfigEntryRemovedEvent; - } -} +const ERROR_STATES: ConfigEntry["state"][] = [ + "failed_unload", + "migration_error", + "setup_error", + "setup_retry", +]; const integrationsWithPanel = { - hassio: { - buttonLocalizeKey: "ui.panel.config.hassio.button", - path: "/hassio/dashboard", - }, - mqtt: { - buttonLocalizeKey: "ui.panel.config.mqtt.button", - path: "/config/mqtt", - }, - zha: { - buttonLocalizeKey: "ui.panel.config.zha.button", - path: "/config/zha/dashboard", - }, - ozw: { - buttonLocalizeKey: "ui.panel.config.ozw.button", - path: "/config/ozw/dashboard", - }, - zwave: { - buttonLocalizeKey: "ui.panel.config.zwave.button", - path: "/config/zwave", - }, - zwave_js: { - buttonLocalizeKey: "ui.panel.config.zwave_js.button", - path: "/config/zwave_js/dashboard", - }, + hassio: "/hassio/dashboard", + mqtt: "/config/mqtt", + zha: "/config/zha/dashboard", + ozw: "/config/ozw/dashboard", + zwave: "/config/zwave", + zwave_js: "/config/zwave_js/dashboard", }; @customElement("ha-integration-card") @@ -89,7 +72,7 @@ export class HaIntegrationCard extends LitElement { @property() public items!: ConfigEntryExtended[]; - @property() public manifest!: IntegrationManifest; + @property() public manifest?: IntegrationManifest; @property() public entityRegistryEntries!: EntityRegistryEntry[]; @@ -99,291 +82,325 @@ export class HaIntegrationCard extends LitElement { @property({ type: Boolean }) public disabled = false; - firstUpdated(changedProps) { - super.firstUpdated(changedProps); - } - protected render(): TemplateResult { + let item = this._selectededConfigEntry; + if (this.items.length === 1) { - return this._renderSingleEntry(this.items[0]); - } - if (this.selectedConfigEntryId) { - const configEntry = this.items.find( + item = this.items[0]; + } else if (this.selectedConfigEntryId) { + item = this.items.find( (entry) => entry.entry_id === this.selectedConfigEntryId ); - if (configEntry) { - return this._renderSingleEntry(configEntry); - } } - return this._renderGroupedIntegration(); - } - private _renderGroupedIntegration(): TemplateResult { + let primary: string; + let secondary: string | undefined; + + if (item) { + primary = item.title || item.localized_domain_name || this.domain; + if (primary !== item.localized_domain_name) { + secondary = item.localized_domain_name; + } + } else { + primary = domainToName(this.hass.localize, this.domain, this.manifest); + } + + const hasItem = item !== undefined; + return html` - + ${this.disabled - ? html`
- ${this.hass.localize( - "ui.panel.config.integrations.config_entry.disable.disabled" - )} -
` + ? html` + + ` : ""} -
+ ${this.items.length > 1 + ? html` +
+ +
+ ` + : ""} +
-

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

+
+
${primary}
+ ${secondary ? html`
${secondary}
` : ""} +
+ ${haConfigIntegrationRenderIcons(this.hass, this.manifest)}
- - ${this.items.map( - (item) => - html`${item.title || - this.hass.localize( - "ui.panel.config.integrations.config_entry.unnamed_entry" - )} - ${item.state === "not_loaded" - ? html` - - ${this.hass.localize( - "ui.panel.config.integrations.config_entry.not_loaded", - "logs_link", - this.hass.localize( - "ui.panel.config.integrations.config_entry.logs" - ) - )} - - ` - : ""} - - ` - )} - + ${item + ? this._renderSingleEntry(item) + : this._renderGroupedIntegration()} `; } + private _renderGroupedIntegration(): TemplateResult { + return html` + + ${this.items.map( + (item) => + html`${item.title || + this.hass.localize( + "ui.panel.config.integrations.config_entry.unnamed_entry" + )} + ${ERROR_STATES.includes(item.state) + ? html` + + ${this.hass.localize( + `ui.panel.config.integrations.config_entry.state.${item.state}` + )} + + ` + : ""} + + ` + )} + + `; + } + private _renderSingleEntry(item: ConfigEntryExtended): TemplateResult { const devices = this._getDevices(item); const services = this._getServices(item); const entities = this._getEntities(item); + let stateText: [string, ...unknown[]] | undefined; + let stateTextExtra: TemplateResult | string | undefined; + + if (item.disabled_by) { + stateText = [ + "ui.panel.config.integrations.config_entry.disable.disabled_cause", + "cause", + this.hass.localize( + `ui.panel.config.integrations.config_entry.disable.disabled_by.${item.disabled_by}` + ) || item.disabled_by, + ]; + if (item.state === "failed_unload") { + stateTextExtra = html`. + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.disable_restart_confirm" + )}.`; + } + } else if (item.state === "not_loaded") { + stateText = ["ui.panel.config.integrations.config_entry.not_loaded"]; + } else if (ERROR_STATES.includes(item.state)) { + stateText = [ + `ui.panel.config.integrations.config_entry.state.${item.state}`, + ]; + stateTextExtra = html` +
+
${this.hass.localize( + "ui.panel.config.integrations.config_entry.check_the_logs" + )} + `; + } + return html` - - ${this.items.length > 1 - ? html`` +
+ ${stateText + ? html` +
+ ${this.hass.localize(...stateText)}${stateTextExtra} +
+ ` : ""} - ${item.disabled_by - ? html`
- ${this.hass.localize( - "ui.panel.config.integrations.config_entry.disable.disabled_cause", - "cause", - this.hass.localize( - `ui.panel.config.integrations.config_entry.disable.disabled_by.${item.disabled_by}` - ) || item.disabled_by - )} -
` - : item.state === "not_loaded" - ? html`
- ${this.hass.localize( - "ui.panel.config.integrations.config_entry.not_loaded", - "logs_link", - html`${this.hass.localize( - "ui.panel.config.integrations.config_entry.logs" - )}` - )} -
` + ${devices.length || services.length || entities.length + ? html` +
+ ${devices.length + ? html` + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.devices", + "count", + devices.length + )}${services.length ? "," : ""} + ` + : ""} + ${services.length + ? html` + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.services", + "count", + services.length + )} + ` + : ""} + ${(devices.length || services.length) && entities.length + ? this.hass.localize("ui.common.and") + : ""} + ${entities.length + ? html` + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.entities", + "count", + entities.length + )} + ` + : ""} +
+ ` : ""} -
-
- -
-

- ${item.localized_domain_name} -

-

- ${item.localized_domain_name === item.title ? "" : item.title} -

- ${devices.length || services.length || entities.length +
+
+
+ ${item.disabled_by === "user" + ? html` + ${this.hass.localize("ui.common.enable")} + ` + : item.domain in integrationsWithPanel + ? html` + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.configure" + )} + ` + : item.supports_options ? html` -
- ${devices.length - ? html` - ${this.hass.localize( - "ui.panel.config.integrations.config_entry.devices", - "count", - devices.length - )}${services.length ? "," : ""} - ` - : ""} - ${services.length - ? html` - ${this.hass.localize( - "ui.panel.config.integrations.config_entry.services", - "count", - services.length - )} - ` - : ""} - ${(devices.length || services.length) && entities.length - ? this.hass.localize("ui.common.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.configure" + )} + ` : ""}
-
-
- ${item.disabled_by === "user" - ? html` - ${this.hass.localize("ui.common.enable")} - ` - : ""} - - ${this.hass.localize( - "ui.panel.config.integrations.config_entry.rename" - )} - - ${item.domain in integrationsWithPanel - ? html` + ${!this.manifest + ? "" + : html` + + + + + + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.rename" + )} + + + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.system_options" + )} + + + + ${this.hass.localize( - integrationsWithPanel[item.domain].buttonLocalizeKey - )} - ` - : 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.manifest - ? "" - : html` - - + "ui.panel.config.integrations.config_entry.documentation" + )} + + + ${!item.disabled_by && + item.state === "loaded" && + item.supports_unload && + item.source !== "system" + ? html` ${this.hass.localize( - "ui.panel.config.integrations.config_entry.documentation" - )} - - - `} - ${!item.disabled_by && - item.state === "loaded" && - item.supports_unload && - item.source !== "system" - ? html` - ${this.hass.localize( - "ui.panel.config.integrations.config_entry.reload" - )} - ` - : ""} - ${item.disabled_by === "user" - ? html` - ${this.hass.localize("ui.common.enable")} - ` - : item.source !== "system" - ? html` - ${this.hass.localize("ui.common.disable")} - ` - : ""} - ${item.source !== "system" - ? html` - ${this.hass.localize( - "ui.panel.config.integrations.config_entry.delete" - )} - ` - : ""} - -
- + "ui.panel.config.integrations.config_entry.reload" + )} + ` + : ""} + ${item.disabled_by === "user" + ? html` + ${this.hass.localize("ui.common.enable")} + ` + : item.source !== "system" + ? html` + ${this.hass.localize("ui.common.disable")} + ` + : ""} + ${item.source !== "system" + ? html` + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.delete" + )} + ` + : ""} + + `} +
`; } + private get _selectededConfigEntry(): ConfigEntryExtended | undefined { + return this.items.length === 1 + ? this.items[0] + : this.selectedConfigEntryId + ? this.items.find( + (entry) => entry.entry_id === this.selectedConfigEntryId + ) + : undefined; + } + private _selectConfigEntry(ev: Event) { this.selectedConfigEntryId = (ev.currentTarget as any).entryId; } @@ -588,109 +605,109 @@ export class HaIntegrationCard extends LitElement { static get styles(): CSSResult[] { return [ haStyle, + haConfigIntegrationsStyles, css` - :host { - max-width: 500px; - } ha-card { display: flex; flex-direction: column; height: 100%; + --state-color: var(--divider-color, #e0e0e0); + --ha-card-border-color: var(--state-color); + --state-message-color: var(--state-color); } - ha-card.single { - justify-content: space-between; + .state-error { + --state-color: var(--error-color); + --text-on-state-color: var(--text-primary-color); + } + .state-not-loaded { + --state-message-color: var(--primary-text-color); } :host(.highlight) ha-card { - border: 1px solid var(--accent-color); + --state-color: var(--accent-color); + --text-on-state-color: var(--text-primary-color); } - .disabled { - --ha-card-border-color: var(--warning-color); + ha-card.group { + max-height: 200px; } - .not-loaded { - --ha-card-border-color: var(--error-color); + + .back-btn { + background-color: var(--state-color); + color: var(--text-on-state-color); + --mdc-icon-button-size: 32px; + transition: height 0.1s; + overflow: hidden; } + .hasMultiple.single .back-btn { + height: 32px; + } + .hasMultiple.group .back-btn { + height: 0px; + } + .header { - padding: 8px; - text-align: center; - } - .disabled .header { - background: var(--warning-color); - color: var(--text-primary-color); - } - .not-loaded .header { - background: var(--error-color); - color: var(--text-primary-color); - } - .not-loaded .header a { - color: var(--text-primary-color); - } - .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; + position: relative; align-items: center; - padding-right: 5px; + padding: 16px 8px 8px 16px; } - .group-header { - display: flex; - align-items: center; + .group.disabled .header { + padding-top: 8px; + } + .header img { + margin-right: 16px; + width: 40px; height: 40px; - padding: 16px 16px 8px 16px; - justify-content: center; } - .group-header h1 { - margin: 0; - } - .group-header img { - margin-right: 8px; - } - .image { - display: flex; - align-items: center; - justify-content: center; - height: 60px; - margin-bottom: 16px; - vertical-align: middle; - } - img { - max-height: 100%; - max-width: 90%; - } - .none-found { - margin: auto; - text-align: center; - } - a { - color: var(--primary-color); - } - h1 { - margin-bottom: 0; - } - h2 { - min-height: 24px; - } - h3 { + .header .info div, + paper-item-body { word-wrap: break-word; display: -webkit-box; -webkit-box-orient: vertical; - -webkit-line-clamp: 3; + -webkit-line-clamp: 2; overflow: hidden; text-overflow: ellipsis; } + .primary { + font-size: 16px; + font-weight: 400; + color: var(--primary-text-color); + } + .secondary { + font-size: 14px; + color: var(--secondary-text-color); + } + + .message { + font-weight: bold; + padding-bottom: 16px; + color: var(--state-message-color); + } + + .content { + flex: 1; + padding: 0px 16px 0 72px; + } + + .actions { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 0 0 8px; + height: 48px; + } + .actions a { + text-decoration: none; + } + a { + color: var(--primary-color); + } ha-button-menu { color: var(--secondary-text-color); --mdc-menu-min-width: 200px; } @media (min-width: 563px) { paper-listbox { - max-height: 150px; + flex: 1; overflow: auto; } } @@ -701,11 +718,6 @@ export class HaIntegrationCard extends LitElement { mwc-list-item ha-svg-icon { color: var(--secondary-text-color); } - .back-btn { - position: absolute; - background: rgba(var(--rgb-card-background-color), 0.6); - border-radius: 50%; - } `, ]; } diff --git a/src/panels/config/integrations/integration-panels/zha/zha-device-card.ts b/src/panels/config/integrations/integration-panels/zha/zha-device-card.ts index d2c37635ac..c810a397ee 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-device-card.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-device-card.ts @@ -177,7 +177,7 @@ class ZHADeviceCard extends SubscribeMixin(LitElement) { }); } - private _computeEntityName(entity: EntityRegistryEntry): string { + private _computeEntityName(entity: EntityRegistryEntry): string | null { if (this.hass.states[entity.entity_id]) { return computeStateName(this.hass.states[entity.entity_id]); } diff --git a/src/translations/en.json b/src/translations/en.json index a48c21b76b..d6a4e3f0e0 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2142,7 +2142,7 @@ "entities": "{count} {count, plural,\n one {entity}\n other {entities}\n}", "services": "{count} {count, plural,\n one {service}\n other {services}\n}", "rename": "Rename", - "options": "Options", + "configure": "Configure", "system_options": "System options", "documentation": "Documentation", "delete": "Delete", @@ -2161,8 +2161,8 @@ "entity_unavailable": "Entity unavailable", "area": "In {area}", "no_area": "No Area", - "not_loaded": "Not loaded, check the {logs_link}", - "logs": "logs", + "not_loaded": "Not loaded", + "check_the_logs": "Check the logs", "disable": { "disabled": "Disabled", "disabled_cause": "Disabled by {cause}", @@ -2172,6 +2172,16 @@ "device": "device" }, "disable_confirm": "Are you sure you want to disable this config entry? Its devices and entities will be disabled." + }, + "provided_by_custom_component": "Provided by a custom component", + "depends_on_cloud": "Depends on the cloud", + "state": { + "loaded": "Not loaded", + "setup_error": "Failed to set up", + "migration_error": "Migration error", + "setup_retry": "Retrying to set up", + "not_loaded": "Not loaded", + "failed_unload": "Failed to unload" } }, "config_flow": { @@ -2243,11 +2253,7 @@ "create": "Create" } }, - "hassio": { - "button": "Configure" - }, "mqtt": { - "button": "Configure", "title": "MQTT", "description_publish": "Publish a packet", "topic": "topic", @@ -2261,7 +2267,6 @@ "message_received": "Message {id} received on {topic} at {time}:" }, "ozw": { - "button": "Configure", "common": { "zwave": "Z-Wave", "node_id": "Node ID", @@ -2376,7 +2381,6 @@ } }, "zha": { - "button": "Configure", "common": { "clusters": "Clusters", "manufacturer_code_override": "Manufacturer Code Override", @@ -2464,7 +2468,6 @@ } }, "zwave": { - "button": "Configure", "description": "Manage your Z-Wave network", "learn_more": "Learn more about Z-Wave", "common": { @@ -2555,7 +2558,6 @@ } }, "zwave_js": { - "button": "Configure", "navigation": { "network": "Network" }, From e225d6f546c904e213063c31f1cfa0d9f7c31094 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Fri, 16 Apr 2021 14:41:38 +0200 Subject: [PATCH 043/106] Correct wording from "component" to "integration" on new integration page (#8924) --- src/panels/config/integrations/ha-config-integrations-common.ts | 2 +- src/translations/en.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/panels/config/integrations/ha-config-integrations-common.ts b/src/panels/config/integrations/ha-config-integrations-common.ts index 063e35c178..f7e1117ceb 100644 --- a/src/panels/config/integrations/ha-config-integrations-common.ts +++ b/src/panels/config/integrations/ha-config-integrations-common.ts @@ -41,7 +41,7 @@ export const haConfigIntegrationRenderIcons = ( icons.push([ mdiPackageVariant, hass.localize( - "ui.panel.config.integrations.config_entry.provided_by_custom_component" + "ui.panel.config.integrations.config_entry.provided_by_custom_integration" ), ]); } diff --git a/src/translations/en.json b/src/translations/en.json index d6a4e3f0e0..2d9b56ae44 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2173,7 +2173,7 @@ }, "disable_confirm": "Are you sure you want to disable this config entry? Its devices and entities will be disabled." }, - "provided_by_custom_component": "Provided by a custom component", + "provided_by_custom_integration": "Provided by a custom integration", "depends_on_cloud": "Depends on the cloud", "state": { "loaded": "Not loaded", From cfd18bfb74ca0855be20082ec12c6268fb1d4864 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Fri, 16 Apr 2021 14:45:40 +0200 Subject: [PATCH 044/106] Corrected "not loaded" state string (#8925) --- src/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translations/en.json b/src/translations/en.json index 2d9b56ae44..6071289bc5 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2176,7 +2176,7 @@ "provided_by_custom_integration": "Provided by a custom integration", "depends_on_cloud": "Depends on the cloud", "state": { - "loaded": "Not loaded", + "loaded": "Loaded", "setup_error": "Failed to set up", "migration_error": "Migration error", "setup_retry": "Retrying to set up", From bb4617c53ba060870746b463b44e1ff1d8256d8c Mon Sep 17 00:00:00 2001 From: Carlos Garcia Saura Date: Fri, 16 Apr 2021 14:54:39 +0200 Subject: [PATCH 045/106] Correct two swapped supervisor beta join action/confirm texts (#8922) --- hassio/src/system/hassio-supervisor-info.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hassio/src/system/hassio-supervisor-info.ts b/hassio/src/system/hassio-supervisor-info.ts index 74585bbec2..504cc8fdcb 100644 --- a/hassio/src/system/hassio-supervisor-info.ts +++ b/hassio/src/system/hassio-supervisor-info.ts @@ -273,9 +273,9 @@ class HassioSupervisorInfo extends LitElement {
  • Home Assistant Supervisor
  • Home Assistant Operating System

  • - ${this.supervisor.localize("system.supervisor.join_beta_action")}`, + ${this.supervisor.localize("system.supervisor.beta_join_confirm")}`, confirmText: this.supervisor.localize( - "system.supervisor.beta_join_confirm" + "system.supervisor.join_beta_action" ), dismissText: this.supervisor.localize("common.cancel"), }); From a09b206b0eb038f0dd4a78c77df402e6cb1dd00e Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Fri, 16 Apr 2021 16:06:52 +0200 Subject: [PATCH 046/106] Added missing
      to beta join dialog (#8927) --- hassio/src/system/hassio-supervisor-info.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/hassio/src/system/hassio-supervisor-info.ts b/hassio/src/system/hassio-supervisor-info.ts index 504cc8fdcb..bfa21d0d69 100644 --- a/hassio/src/system/hassio-supervisor-info.ts +++ b/hassio/src/system/hassio-supervisor-info.ts @@ -269,9 +269,11 @@ class HassioSupervisorInfo extends LitElement {

      ${this.supervisor.localize("system.supervisor.beta_release_items")} -
    • Home Assistant Core
    • -
    • Home Assistant Supervisor
    • -
    • Home Assistant Operating System
    • +
        +
      • Home Assistant Core
      • +
      • Home Assistant Supervisor
      • +
      • Home Assistant Operating System
      • +

      ${this.supervisor.localize("system.supervisor.beta_join_confirm")}`, confirmText: this.supervisor.localize( From 1ce17e28471ed65592e5d6cf24363cf3bef82e54 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Fri, 16 Apr 2021 16:29:36 +0200 Subject: [PATCH 047/106] Remove non effective CSS for CM6 search panel input (#8921) --- src/resources/codemirror.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/resources/codemirror.ts b/src/resources/codemirror.ts index 75ed71495a..0c52dd5446 100644 --- a/src/resources/codemirror.ts +++ b/src/resources/codemirror.ts @@ -72,8 +72,6 @@ export const theme = EditorView.theme({ ".cm-panels.top": { borderBottom: "1px solid var(--divider-color)" }, ".cm-panels.bottom": { borderTop: "1px solid var(--divider-color)" }, - ".cm-panel.search input": { margin: "4px 4px 0" }, - ".cm-button": { border: "1px solid var(--primary-color)", padding: "0px 16px", From 841c8ab1f11a957fccc19b18f4ce463bc2f6a69b Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 16 Apr 2021 17:57:07 +0200 Subject: [PATCH 048/106] Update script editor (#8919) --- src/panels/config/script/ha-script-editor.ts | 102 ++++++++++++------- 1 file changed, 63 insertions(+), 39 deletions(-) diff --git a/src/panels/config/script/ha-script-editor.ts b/src/panels/config/script/ha-script-editor.ts index 16c90ebc1e..03f57fc674 100644 --- a/src/panels/config/script/ha-script-editor.ts +++ b/src/panels/config/script/ha-script-editor.ts @@ -176,7 +176,11 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { ${this.narrow ? html` ${this._config?.alias} ` : ""} -
      +
      ${this._errors ? html`
      ${this._errors}
      ` : ""} @@ -350,44 +354,43 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { ` : this._mode === "yaml" ? html` - - ${!this.narrow - ? html`${this._config?.alias}` - : ``} - -
      - - - ${this.hass.localize( - "ui.panel.config.automation.editor.copy_to_clipboard" - )} - -
      - ${this.scriptEntityId - ? html` -
      + ${this._config?.alias} +
      +
      + - - - ${this.hass.localize( - "ui.panel.config.script.picker.run_script" - )} - -
      - ` - : ``} - - + ${this.hass.localize( + "ui.panel.config.script.picker.run_script" + )} + +
      +
      + ` + : ``} + +
      + + ${this.hass.localize( + "ui.panel.config.automation.editor.copy_to_clipboard" + )} + +
      +
      ` : ``}
      @@ -532,7 +535,12 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { if ((this._config![name] || "") === newVal) { return; } - this._config = { ...this._config!, [name]: newVal }; + if (!newVal) { + delete this._config![name]; + this._config = { ...this._config! }; + } else { + this._config = { ...this._config!, [name]: newVal }; + } this._dirty = true; } @@ -693,6 +701,22 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { .content { padding-bottom: 20px; } + .yaml-mode { + height: 100%; + display: flex; + flex-direction: column; + padding-bottom: 0; + } + ha-yaml-editor { + flex-grow: 1; + --code-mirror-height: 100%; + min-height: 0; + } + .yaml-mode ha-card { + overflow: initial; + --ha-card-border-radius: 0; + border-bottom: 1px solid var(--divider-color); + } span[slot="introduction"] a { color: var(--primary-color); } From 25b3bb1285d7892891bbe8d77824f576b35bfe71 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 16 Apr 2021 11:22:22 -0700 Subject: [PATCH 049/106] Fixes for integration cards (#8930) --- gallery/src/demos/demo-integration-card.ts | 116 +++++++++++------- .../integrations/ha-integration-card.ts | 25 ++-- 2 files changed, 90 insertions(+), 51 deletions(-) diff --git a/gallery/src/demos/demo-integration-card.ts b/gallery/src/demos/demo-integration-card.ts index 1e805910a8..966978ffd1 100644 --- a/gallery/src/demos/demo-integration-card.ts +++ b/gallery/src/demos/demo-integration-card.ts @@ -139,9 +139,9 @@ const configEntries: Array<{ { items: [ loadedEntry, - longNameEntry, setupErrorEntry, migrationErrorEntry, + longNameEntry, setupRetryEntry, failedUnloadEntry, notLoadedEntry, @@ -211,47 +211,77 @@ export class DemoIntegrationCard extends LitElement { return html``; } return html` -
      - - - - - - +
      +
      + + + + + + +
      + + + + ${configFlows.map( + (flow) => html` + + ` + )} + ${configEntries.map( + (info) => html` + + ` + )} +
      +
      + +
      - - - - ${configFlows.map( - (flow) => html` - - ` - )} - ${configEntries.map( - (info) => html` - - ` - )} `; } @@ -272,7 +302,7 @@ export class DemoIntegrationCard extends LitElement { static get styles() { return css` - :host { + .container { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); grid-gap: 16px 16px; @@ -280,7 +310,7 @@ export class DemoIntegrationCard extends LitElement { margin-bottom: 64px; } - :host > * { + .container > * { max-width: 500px; } diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index fc975fb6bc..786b394e7e 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -49,7 +49,6 @@ import { } from "./ha-config-integrations-common"; const ERROR_STATES: ConfigEntry["state"][] = [ - "failed_unload", "migration_error", "setup_error", "setup_retry", @@ -116,6 +115,7 @@ export class HaIntegrationCard extends LitElement { hasMultiple: this.items.length > 1, disabled: this.disabled, "state-not-loaded": hasItem && item!.state === "not_loaded", + "state-failed-unload": hasItem && item!.state === "failed_unload", "state-error": hasItem && ERROR_STATES.includes(item!.state), })}" .configEntry=${item} @@ -619,6 +619,10 @@ export class HaIntegrationCard extends LitElement { --state-color: var(--error-color); --text-on-state-color: var(--text-primary-color); } + .state-failed-unload { + --state-color: var(--warning-color); + --text-on-state-color: var(--primary-text-color); + } .state-not-loaded { --state-message-color: var(--primary-text-color); } @@ -626,9 +630,6 @@ export class HaIntegrationCard extends LitElement { --state-color: var(--accent-color); --text-on-state-color: var(--text-primary-color); } - ha-card.group { - max-height: 200px; - } .back-btn { background-color: var(--state-color); @@ -650,9 +651,6 @@ export class HaIntegrationCard extends LitElement { align-items: center; padding: 16px 8px 8px 16px; } - .group.disabled .header { - padding-top: 8px; - } .header img { margin-right: 16px; width: 40px; @@ -706,10 +704,21 @@ export class HaIntegrationCard extends LitElement { --mdc-menu-min-width: 200px; } @media (min-width: 563px) { + ha-card.group { + position: relative; + min-height: 164px; + } paper-listbox { - flex: 1; + position: absolute; + top: 64px; + left: 0; + right: 0; + bottom: 0; overflow: auto; } + .disabled paper-listbox { + top: 100px; + } } paper-item { cursor: pointer; From 179767e9f8054b5f89f5b7ceabde417e6f71e14a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 16 Apr 2021 12:27:01 -0700 Subject: [PATCH 050/106] Align layout of all cards (#8931) * Align layout of all cards * Make ignore card have normal button --- gallery/src/demos/demo-integration-card.ts | 10 +- .../ha-config-integrations-common.ts | 75 -------- .../ha-ignored-config-entry-card.ts | 2 +- .../ha-integration-action-card.ts | 123 +++++-------- .../integrations/ha-integration-card.ts | 131 ++++--------- .../integrations/ha-integration-header.ts | 174 ++++++++++++++++++ 6 files changed, 263 insertions(+), 252 deletions(-) delete mode 100644 src/panels/config/integrations/ha-config-integrations-common.ts create mode 100644 src/panels/config/integrations/ha-integration-header.ts diff --git a/gallery/src/demos/demo-integration-card.ts b/gallery/src/demos/demo-integration-card.ts index 966978ffd1..e8c1694700 100644 --- a/gallery/src/demos/demo-integration-card.ts +++ b/gallery/src/demos/demo-integration-card.ts @@ -44,9 +44,10 @@ const createConfigEntry = ( const createManifest = ( isCustom: boolean, - isCloud: boolean + isCloud: boolean, + name = "ESPHome" ): IntegrationManifest => ({ - name: "ESPHome", + name, domain: "esphome", is_built_in: !isCustom, config_flow: false, @@ -103,7 +104,7 @@ const configFlows: DataEntryFlowProgressExtended[] = [ }, }, step_id: "discovery_confirm", - localized_title: "Roku: Living room Roku", + localized_title: "Living room Roku", }, { flow_id: "adbb401329d8439ebb78ef29837826a8", @@ -234,7 +235,8 @@ export class DemoIntegrationCard extends LitElement { .flow=${flow} .manifest=${createManifest( this.isCustomIntegration, - this.isCloud + this.isCloud, + flow.handler === "roku" ? "Roku" : "Philips Hue" )} > ` diff --git a/src/panels/config/integrations/ha-config-integrations-common.ts b/src/panels/config/integrations/ha-config-integrations-common.ts deleted file mode 100644 index f7e1117ceb..0000000000 --- a/src/panels/config/integrations/ha-config-integrations-common.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { mdiPackageVariant, mdiCloud } from "@mdi/js"; -import "@polymer/paper-tooltip/paper-tooltip"; -import { css, html } from "lit-element"; -import { IntegrationManifest } from "../../../data/integration"; -import { HomeAssistant } from "../../../types"; - -export const haConfigIntegrationsStyles = css` - .banner { - background-color: var(--state-color); - color: var(--text-on-state-color); - text-align: center; - padding: 8px; - } - .icons { - position: absolute; - top: 0px; - right: 16px; - color: var(--text-on-state-color, var(--secondary-text-color)); - background-color: var(--state-color, #e0e0e0); - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - padding: 1px 4px 2px; - } - .icons ha-svg-icon { - width: 20px; - height: 20px; - } - paper-tooltip { - white-space: nowrap; - } -`; - -export const haConfigIntegrationRenderIcons = ( - hass: HomeAssistant, - manifest?: IntegrationManifest -) => { - const icons: [string, string][] = []; - - if (manifest) { - if (!manifest.is_built_in) { - icons.push([ - mdiPackageVariant, - hass.localize( - "ui.panel.config.integrations.config_entry.provided_by_custom_integration" - ), - ]); - } - - if (manifest.iot_class && manifest.iot_class.startsWith("cloud_")) { - icons.push([ - mdiCloud, - hass.localize( - "ui.panel.config.integrations.config_entry.depends_on_cloud" - ), - ]); - } - } - - return icons.length === 0 - ? "" - : html` -
      - ${icons.map( - ([icon, description]) => html` - - - ${description} - - ` - )} -
      - `; -}; diff --git a/src/panels/config/integrations/ha-ignored-config-entry-card.ts b/src/panels/config/integrations/ha-ignored-config-entry-card.ts index e4332bd65e..cbd6c476b7 100644 --- a/src/panels/config/integrations/ha-ignored-config-entry-card.ts +++ b/src/panels/config/integrations/ha-ignored-config-entry-card.ts @@ -31,6 +31,7 @@ export class HaIgnoredConfigEntryCard extends LitElement { "ui.panel.config.integrations.ignore.ignored" )} .domain=${this.entry.domain} + .localizedDomainName=${this.entry.localized_domain_name} .label=${this.entry.title === "Ignored" ? // In 2020.2 we added support for entry.title. All ignored entries before // that have title "Ignored" so we fallback to localized domain name. @@ -38,7 +39,6 @@ export class HaIgnoredConfigEntryCard extends LitElement { : this.entry.title} > - -
      - ${haConfigIntegrationRenderIcons(this.hass, this.manifest)} -
      - -
      -

      ${this.label}

      -
      + +
      `; } - private _onImageLoad(ev) { - ev.target.style.visibility = "initial"; - } - - private _onImageError(ev) { - ev.target.style.visibility = "hidden"; - } - - static get styles(): CSSResult[] { - return [ - haConfigIntegrationsStyles, - css` - ha-card { - display: flex; - flex-direction: column; - height: 100%; - --ha-card-border-color: var(--state-color); - --mdc-theme-primary: var(--state-color); - } - .content { - position: relative; - flex: 1; - } - .image { - height: 60px; - margin-top: 16px; - display: flex; - align-items: center; - justify-content: space-around; - } - img { - max-width: 90%; - max-height: 100%; - } - h2 { - text-align: center; - margin: 16px 8px 0; - } - .attention { - --state-color: var(--error-color); - --text-on-state-color: var(--text-primary-color); - } - .discovered { - --state-color: var(--primary-color); - --text-on-state-color: var(--text-primary-color); - } - .actions { - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 6px 0; - height: 48px; - } - `, - ]; - } + static styles = css` + ha-card { + display: flex; + flex-direction: column; + height: 100%; + --ha-card-border-color: var(--state-color); + --mdc-theme-primary: var(--state-color); + } + .filler { + flex: 1; + } + .attention { + --state-color: var(--error-color); + --text-on-state-color: var(--text-primary-color); + } + .discovered { + --state-color: var(--primary-color); + --text-on-state-color: var(--text-primary-color); + } + .actions { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 6px 0; + height: 48px; + } + `; } declare global { diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index 786b394e7e..5aaf0d31c4 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -31,7 +31,7 @@ import { } from "../../../data/config_entries"; import type { DeviceRegistryEntry } from "../../../data/device_registry"; import type { EntityRegistryEntry } from "../../../data/entity_registry"; -import { domainToName, IntegrationManifest } from "../../../data/integration"; +import type { IntegrationManifest } from "../../../data/integration"; 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 { @@ -40,13 +40,9 @@ import { showPromptDialog, } from "../../../dialogs/generic/show-dialog-box"; import { haStyle } from "../../../resources/styles"; -import { HomeAssistant } from "../../../types"; -import { brandsUrl } from "../../../util/brands-url"; -import { ConfigEntryExtended } from "./ha-config-integrations"; -import { - haConfigIntegrationRenderIcons, - haConfigIntegrationsStyles, -} from "./ha-config-integrations-common"; +import type { HomeAssistant } from "../../../types"; +import type { ConfigEntryExtended } from "./ha-config-integrations"; +import "./ha-integration-header"; const ERROR_STATES: ConfigEntry["state"][] = [ "migration_error", @@ -92,18 +88,6 @@ export class HaIntegrationCard extends LitElement { ); } - let primary: string; - let secondary: string | undefined; - - if (item) { - primary = item.title || item.localized_domain_name || this.domain; - if (primary !== item.localized_domain_name) { - secondary = item.localized_domain_name; - } - } else { - primary = domainToName(this.hass.localize, this.domain, this.manifest); - } - const hasItem = item !== undefined; return html` @@ -120,38 +104,32 @@ export class HaIntegrationCard extends LitElement { })}" .configEntry=${item} > - ${this.disabled - ? html` - - ` - : ""} - ${this.items.length > 1 - ? html` -
      - -
      - ` - : ""} -
      - -
      -
      ${primary}
      - ${secondary ? html`
      ${secondary}
      ` : ""} -
      - ${haConfigIntegrationRenderIcons(this.hass, this.manifest)} -
      + + ${this.items.length > 1 + ? html` +
      + +
      + ` + : ""} +
      + ${item ? this._renderSingleEntry(item) : this._renderGroupedIntegration()} @@ -441,14 +419,6 @@ export class HaIntegrationCard extends LitElement { ); } - 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); } @@ -605,7 +575,6 @@ export class HaIntegrationCard extends LitElement { static get styles(): CSSResult[] { return [ haStyle, - haConfigIntegrationsStyles, css` ha-card { display: flex; @@ -627,7 +596,7 @@ export class HaIntegrationCard extends LitElement { --state-message-color: var(--primary-text-color); } :host(.highlight) ha-card { - --state-color: var(--accent-color); + --state-color: var(--primary-color); --text-on-state-color: var(--text-primary-color); } @@ -645,36 +614,6 @@ export class HaIntegrationCard extends LitElement { height: 0px; } - .header { - display: flex; - position: relative; - align-items: center; - padding: 16px 8px 8px 16px; - } - .header img { - margin-right: 16px; - width: 40px; - height: 40px; - } - .header .info div, - paper-item-body { - word-wrap: break-word; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 2; - overflow: hidden; - text-overflow: ellipsis; - } - .primary { - font-size: 16px; - font-weight: 400; - color: var(--primary-text-color); - } - .secondary { - font-size: 14px; - color: var(--secondary-text-color); - } - .message { font-weight: bold; padding-bottom: 16px; @@ -724,6 +663,14 @@ export class HaIntegrationCard extends LitElement { cursor: pointer; min-height: 35px; } + paper-item-body { + word-wrap: break-word; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + text-overflow: ellipsis; + } mwc-list-item ha-svg-icon { color: var(--secondary-text-color); } diff --git a/src/panels/config/integrations/ha-integration-header.ts b/src/panels/config/integrations/ha-integration-header.ts new file mode 100644 index 0000000000..fefebd5f65 --- /dev/null +++ b/src/panels/config/integrations/ha-integration-header.ts @@ -0,0 +1,174 @@ +import { mdiPackageVariant, mdiCloud } from "@mdi/js"; +import "@polymer/paper-tooltip/paper-tooltip"; +import { + css, + html, + customElement, + property, + LitElement, + TemplateResult, +} from "lit-element"; +import { domainToName, IntegrationManifest } from "../../../data/integration"; +import { HomeAssistant } from "../../../types"; +import { brandsUrl } from "../../../util/brands-url"; + +@customElement("ha-integration-header") +export class HaIntegrationHeader extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public banner!: string; + + @property() public localizedDomainName?: string; + + @property() public domain!: string; + + @property() public label!: string; + + @property() public manifest?: IntegrationManifest; + + protected render(): TemplateResult { + let primary: string; + let secondary: string | undefined; + + const domainName = + this.localizedDomainName || + domainToName(this.hass.localize, this.domain, this.manifest); + + if (this.label) { + primary = this.label; + secondary = primary === domainName ? undefined : domainName; + } else { + primary = domainName; + } + + const icons: [string, string][] = []; + + if (this.manifest) { + if (!this.manifest.is_built_in) { + icons.push([ + mdiPackageVariant, + this.hass.localize( + "ui.panel.config.integrations.config_entry.provided_by_custom_integration" + ), + ]); + } + + if ( + this.manifest.iot_class && + this.manifest.iot_class.startsWith("cloud_") + ) { + icons.push([ + mdiCloud, + this.hass.localize( + "ui.panel.config.integrations.config_entry.depends_on_cloud" + ), + ]); + } + } + + return html` + ${!this.banner + ? "" + : html``} + +
      + +
      +
      ${primary}
      + ${secondary ? html`
      ${secondary}
      ` : ""} +
      + ${icons.length === 0 + ? "" + : html` +
      + ${icons.map( + ([icon, description]) => html` + + + ${description} + + ` + )} +
      + `} +
      + `; + } + + private _onImageLoad(ev) { + ev.target.style.visibility = "initial"; + } + + private _onImageError(ev) { + ev.target.style.visibility = "hidden"; + } + + static styles = css` + .banner { + background-color: var(--state-color); + color: var(--text-on-state-color); + text-align: center; + padding: 8px; + } + .header { + display: flex; + position: relative; + align-items: center; + padding: 16px 8px 8px 16px; + } + .header img { + margin-right: 16px; + width: 40px; + height: 40px; + } + .header .info div { + word-wrap: break-word; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + text-overflow: ellipsis; + } + .primary { + font-size: 16px; + font-weight: 400; + color: var(--primary-text-color); + } + .secondary { + font-size: 14px; + color: var(--secondary-text-color); + } + .icons { + position: absolute; + top: 0px; + right: 16px; + color: var(--text-on-state-color, var(--secondary-text-color)); + background-color: var(--state-color, #e0e0e0); + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + padding: 1px 4px 2px; + } + .icons ha-svg-icon { + width: 20px; + height: 20px; + } + paper-tooltip { + white-space: nowrap; + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "ha-integration-header": HaIntegrationHeader; + } +} From 5493fdfcb7b2125fcd0e08bce4c3ad6533c8b3e9 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 16 Apr 2021 12:27:18 -0700 Subject: [PATCH 051/106] Bumped version to 20210416.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 5502d28283..6345d4de19 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20210407.1", + version="20210416.0", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors", From b518f4b03c5494db90993692ad8844cbd96b70e3 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sat, 17 Apr 2021 00:48:32 +0000 Subject: [PATCH 052/106] Translation update --- translations/frontend/bg.json | 50 +++++++++++++++++++++++++++--- translations/frontend/cs.json | 4 ++- translations/frontend/de.json | 4 ++- translations/frontend/en.json | 15 ++++++++- translations/frontend/es.json | 15 ++++++++- translations/frontend/et.json | 15 ++++++++- translations/frontend/it.json | 19 ++++++++++-- translations/frontend/ko.json | 12 ++++++- translations/frontend/ru.json | 19 ++++++++++-- translations/frontend/zh-Hant.json | 19 ++++++++++-- 10 files changed, 154 insertions(+), 18 deletions(-) diff --git a/translations/frontend/bg.json b/translations/frontend/bg.json index eca046c32a..4ad5e1c313 100644 --- a/translations/frontend/bg.json +++ b/translations/frontend/bg.json @@ -452,6 +452,7 @@ "privileged": "Supervisor не е привилегирован", "systemd": "Systemd" }, + "unsupported_title": "Използвате неподдържана инсталация", "update_supervisor": "Актуализиране на Supervisor", "warning": "ВНИМАНИЕ" } @@ -652,7 +653,13 @@ }, "components": { "addon-picker": { - "addon": "Добавка" + "addon": "Добавка", + "error": { + "no_supervisor": { + "description": "Не е намерен Supervisor, така че добавките не могат да бъдат заредени.", + "title": "Няма Supervisor" + } + } }, "area-picker": { "add_dialog": { @@ -1109,9 +1116,11 @@ "errors": { "config": { "edit_in_yaml_supported": "Все още можете да редактирате вашата конфигурация в YAML.", + "editor_not_supported": "Визуалния редактор не се поддържа за тази конфигурация", "error_detected": "Открити са грешки в конфигурацията", "key_missing": "Липсва задължителният ключ \"{key}\".", - "no_template_editor_support": "Шаблоните не се поддържат във визуалния редактор" + "no_template_editor_support": "Шаблоните не се поддържат във визуалния редактор", + "no_type_provided": "Не е указан тип." }, "supervisor": { "ask": "Помолете за помощ", @@ -1509,6 +1518,7 @@ "thingtalk": { "create": "Създайте автоматизация", "task_selection": { + "error_empty": "Въведете команда или натиснете Пропускане", "for_example": "Например:", "header": "Създайте нова автоматизация", "introduction": "Въведете по-долу какво трябва да направи тази автоматизация и ние ще се опитаме да я преобразуваме в автоматизация на Home Assistant.", @@ -1575,9 +1585,12 @@ "config_documentation": "Документация за конфигурацията", "devices_pin": "ПИН код за Устройства за защита", "enter_pin_hint": "Въведете ПИН за използване на устройства за защита", + "manage_entities": "Управление на обекти", "not_configured_text": "Преди да можете да използвате Google Assistant, трябва да активирате умението Home Assistant Cloud за Google Assistant в приложението Google Home.", "not_configured_title": "Google Assistant не е активиран", "security_devices": "Устройства за защита", + "sync_entities": "Синхронизиране на обекти с Google", + "sync_entities_404_message": "Неуспешно синхронизиране на вашите обекти с Google, помолете Google „Hey Google, sync my devices“, за да синхронизира вашите обекти.", "title": "Google Assistant" }, "integrations": "Интеграции", @@ -1624,6 +1637,7 @@ "expose": "Откриване към Alexa", "expose_entity": "Изложи обекта", "exposed": "{selected} изложен", + "exposed_entities": "Изложени обекти", "follow_domain": "Следван домейн", "manage_domains": "Управление на домейни", "not_exposed": "{selected} неизложен", @@ -1637,7 +1651,7 @@ "certificate_expiration_date": "Дата на изтичане на сертификата:", "certificate_information": "Информация за сертификата", "close": "Затвори", - "will_be_auto_renewed": "ще бъде автоматично подновено" + "will_be_auto_renewed": "ще бъде автоматично подновен" }, "dialog_cloudhook": { "close": "Затвори", @@ -1659,9 +1673,11 @@ "expose": "Откриване към Google Assistant", "expose_entity": "Изложи обекта", "exposed": "{selected} изложен", + "exposed_entities": "Изложени обекти", "follow_domain": "следван домейн", "manage_domains": "Управление на домейни", "not_exposed": "{selected} неизложен", + "not_exposed_entities": "Не изложени обекти", "title": "Google Assistant" }, "login": { @@ -1835,7 +1851,8 @@ "add_entities_lovelace": "Добавете към Lovelace", "disabled_entities": "+{count} {count, plural,\n one {деактивиран обект}\n other {деактивирани обекта}\n}", "entities": "Обекти", - "hide_disabled": "Скриване на деактивираните" + "hide_disabled": "Скриване на деактивираните", + "none": "Това устройство няма обекти" }, "name": "Име", "no_devices": "Няма устройства", @@ -1871,10 +1888,13 @@ "description": "Управление на известните обекти", "picker": { "disable_selected": { + "button": "Деактивиране на избраните", + "confirm_text": "Деактивираните обекти няма да бъдат добавени в Home Assistant.", "confirm_title": "Искате ли да забраните {number} {number, plural,\n one {обект}\n other {обекта}\n}?" }, "enable_selected": { "button": "Активиране на избраните", + "confirm_text": "Това ще ги направи отново достъпни в Home Assistant, ако сега са деактивирани.", "confirm_title": "Искате ли да разрешите {number} {number, plural,\n one {обект}\n other {обекта}\n}?" }, "filter": { @@ -1896,14 +1916,17 @@ "introduction": "Home Assistant поддържа регистър на всички обекти, които някога е виждал, които могат да бъдат идентифицирани уникално. Всеки от тези обекти ще има идентификатор на обект, който ще бъде резервиран само за този обект.", "introduction2": "Използвайте регистъра на обектите, за да промените името, идентификатора на обекта или да премахнете записа от Home Assistant. Моля имайте на предвид, че премахването на записа от регистъра на обектите няма да премахне обекта. За да направите това, следвайте препратката по-долу и я премахнете от страницата за интеграции.", "remove_selected": { + "button": "Премахване на избраните", "confirm_partly_title": "Само {number} {number, plural,\n one {избран обект}\n other {избрани обекта}\n} могат да бъдат премахнати.", "confirm_title": "Искате ли да премахнете {number} {number, plural,\n one {обект}\n other {обекта}\n}?" }, "search": "Търсене на обекти", "selected": "{number} избрани", "status": { + "disabled": "Деактивиран", "ok": "ДА", "readonly": "Само за четене", + "restored": "Възстановен", "unavailable": "Недостъпен" } } @@ -2041,6 +2064,8 @@ "logs": { "caption": "Журнали", "clear": "Изчистване", + "custom_integration": "персонализирана интеграция", + "error_from_custom_integration": "Тази грешка произтича от персонализирана интеграция.", "level": { "critical": "КРИТИЧНО", "debug": "ДЕБЪГ", @@ -2494,7 +2519,8 @@ }, "network_status": { "connected": "Свързан", - "connecting": "Свързване" + "connecting": "Свързване", + "unknown": "Неизвестен" }, "node_config": { "attribution": "Параметрите и описанията на конфигурацията на устройството се предоставят от {device_database}", @@ -2504,6 +2530,9 @@ "introduction": "Управление и настройване на специфични конфигурационни параметри на подбраноto устройството (възел, node)", "parameter_is_read_only": "Този параметър е само за четене.", "zwave_js_device_database": "Z-Wave JS база данни с устройства" + }, + "node_status": { + "unknown": "Неизвестен" } }, "zwave": { @@ -2581,6 +2610,8 @@ "column_parameter": "Параметър", "no_template_ui_support": "Потребителският интерфейс не поддържа шаблони, все още можете да използвате YAML редактора.", "title": "Услуги", + "ui_mode": "Отидете в режим Потребителски интерфейс", + "yaml_mode": "Отидете в YAML режим", "yaml_parameters": "Параметрите са налични само в YAML режим" }, "states": { @@ -2588,11 +2619,14 @@ "current_entities": "Настоящи обекти", "description1": "Задайте представянето на устройство или обект в Home Assistant.", "description2": "Промяната е фиктивна, до следваща актуализация на устройството или обекта.", + "entity": "Обект", "filter_attributes": "Филтриране на атрибути", "last_changed": "Последна промяна", "last_updated": "Последна актуализация", "more_info": "Повече информация", + "no_entities": "Няма обекти", "set_state": "Задаване на състояние", + "state": "Състояние", "state_attributes": "Атрибути на състоянието (YAML, по избор)", "title": "Състояния" }, @@ -2663,6 +2697,9 @@ "toggle": "Превключване на {name}", "url": "Отваряне на прозорец към {url_path}" }, + "safe-mode": { + "header": "Активиран е безопасен режим" + }, "shopping-list": { "add_item": "Добави артикул", "checked_items": "Отметнати артикули", @@ -2791,6 +2828,7 @@ "show_icon": "Показване на иконата?", "show_name": "Показване на името?", "show_state": "Показване на състоянието?", + "state": "Състояние", "state_color": "Да се оцветят ли иконите спрямо състоянието?", "tap_action": "Действие Докосване", "theme": "Тема", @@ -3004,6 +3042,8 @@ }, "unused_entities": { "available_entities": "Това са обектите, които имате на разположение, но все още не са във вашия потребителски интерфейс на Lovelace.", + "domain": "Домейн", + "entity": "Обект", "entity_id": "ID на обекта", "last_changed": "Последна промяна", "no_data": "Не са намерени неизползвани обекти", diff --git a/translations/frontend/cs.json b/translations/frontend/cs.json index a3e86acf5c..59fa0e5ccb 100644 --- a/translations/frontend/cs.json +++ b/translations/frontend/cs.json @@ -2215,7 +2215,7 @@ "configure": "Nastavit", "configured": "Nastaveno", "confirm_new": "Chcete nastavit {integration}?", - "description": "Správa integrací a jejich služeb, zařízení, ...", + "description": "Správa integrací a jejich služeb či zařízení", "details": "Podrobnosti o integraci", "disable": { "disabled_integrations": "{number} zakázáno", @@ -2254,8 +2254,10 @@ "logs": { "caption": "Logy", "clear": "Zrušit", + "custom_integration": "vlastní integrace", "description": "Zobrazení logů Home Assistant", "details": "Detaily protokolu ({level})", + "error_from_custom_integration": "Tato chyba pochází z vlastní integrace.", "level": { "critical": "KRITICKÉ", "debug": "LADĚNÍ", diff --git a/translations/frontend/de.json b/translations/frontend/de.json index 919f9fa46e..a36dc90fed 100644 --- a/translations/frontend/de.json +++ b/translations/frontend/de.json @@ -2216,7 +2216,7 @@ "configure": "Konfigurieren", "configured": "Konfiguriert", "confirm_new": "Möchtest du {integration} einrichten?", - "description": "Integrationen zu Diensten, Geräten, usw. verwalten", + "description": "Verwalte verbundene Geräte und Dienste", "details": "Details zur Integration", "disable": { "disabled_integrations": "{number} deaktiviert", @@ -2255,8 +2255,10 @@ "logs": { "caption": "Logs", "clear": "Löschen", + "custom_integration": "benutzerdefiniert integration", "description": "Home Assistant Logs einsehen", "details": "Protokolldetails ({level})", + "error_from_custom_integration": "benutzerdefinierte", "level": { "critical": "KRITISCH", "debug": "DEBUG", diff --git a/translations/frontend/en.json b/translations/frontend/en.json index 2af8d7bdfc..a2ef44fecc 100644 --- a/translations/frontend/en.json +++ b/translations/frontend/en.json @@ -2156,8 +2156,11 @@ "caption": "Integrations", "config_entry": { "area": "In {area}", + "check_the_logs": "Check the logs", + "configure": "Configure", "delete": "Delete", "delete_confirm": "Are you sure you want to delete this integration?", + "depends_on_cloud": "Depends on the cloud", "device_unavailable": "Device unavailable", "devices": "{count} {count, plural,\n one {device}\n other {devices}\n}", "disable_restart_confirm": "Restart Home Assistant to finish disabling this integration", @@ -2180,14 +2183,24 @@ "logs": "logs", "manuf": "by {manufacturer}", "no_area": "No Area", - "not_loaded": "Not loaded, check the {logs_link}", + "not_loaded": "Not loaded", "options": "Options", + "provided_by_custom_component": "Provided by a custom component", + "provided_by_custom_integration": "Provided by a custom integration", "reload": "Reload", "reload_confirm": "The integration was reloaded", "reload_restart_confirm": "Restart Home Assistant to finish reloading this integration", "rename": "Rename", "restart_confirm": "Restart Home Assistant to finish removing this integration", "services": "{count} {count, plural,\n one {service}\n other {services}\n}", + "state": { + "failed_unload": "Failed to unload", + "loaded": "Loaded", + "migration_error": "Migration error", + "not_loaded": "Not loaded", + "setup_error": "Failed to set up", + "setup_retry": "Retrying to set up" + }, "system_options": "System options", "unnamed_entry": "Unnamed entry" }, diff --git a/translations/frontend/es.json b/translations/frontend/es.json index f3c6f92a4a..b5656e841f 100644 --- a/translations/frontend/es.json +++ b/translations/frontend/es.json @@ -2156,8 +2156,11 @@ "caption": "Integraciones", "config_entry": { "area": "En {area}", + "check_the_logs": "Revisa los registros", + "configure": "Configurar", "delete": "Eliminar", "delete_confirm": "¿Estás seguro de que quieres eliminar esta integración?", + "depends_on_cloud": "Depende de la nube", "device_unavailable": "Dispositivo no disponible", "devices": "{count} {count, plural,\n one {dispositivo}\n other {dispositivos}\n}", "disable_restart_confirm": "Reinicia Home Assistant para terminar de deshabilitar esta integración", @@ -2180,14 +2183,24 @@ "logs": "registros", "manuf": "por {manufacturer}", "no_area": "Ningún área", - "not_loaded": "No se ha cargado, comprueba el {logs_link}", + "not_loaded": "No se ha cargado", "options": "Opciones", + "provided_by_custom_component": "Proporcionada por un componente personalizado", + "provided_by_custom_integration": "Proporcionada por una integración personalizada", "reload": "Recargar", "reload_confirm": "La integración se ha recargado", "reload_restart_confirm": "Reinicia Home Assistant para terminar de recargar esta integración", "rename": "Renombrar", "restart_confirm": "Reinicia Home Assistant para terminar de eliminar esta integración.", "services": "{count} {count, plural,\n one {servicio}\n other {servicios}\n}", + "state": { + "failed_unload": "No se pudo descargar", + "loaded": "Cargada", + "migration_error": "Error de migración", + "not_loaded": "No se ha cargado", + "setup_error": "No se pudo configurar", + "setup_retry": "Volviendo a intentar configurar" + }, "system_options": "Opciones del sistema", "unnamed_entry": "Entrada sin nombre" }, diff --git a/translations/frontend/et.json b/translations/frontend/et.json index e6f10d7c5c..7221044eb7 100644 --- a/translations/frontend/et.json +++ b/translations/frontend/et.json @@ -2156,8 +2156,11 @@ "caption": "Sidumised", "config_entry": { "area": "alas {area}", + "check_the_logs": "Kontrolli logisid", + "configure": "Seadista", "delete": "Kustuta", "delete_confirm": "Oled kindel, et soovid selle sidumise kustutada?", + "depends_on_cloud": "Sõltub pilveteenusest", "device_unavailable": "Seade pole saadaval", "devices": "{count} {count, plural,\n one {seade}\n other {seadet}\n}", "disable_restart_confirm": "Taaskäivita Home Assistant, et lõpetada selle sidumise keelamine", @@ -2180,14 +2183,24 @@ "logs": "Logid", "manuf": "{manufacturer}", "no_area": "Ala puudub", - "not_loaded": "Laadimine nurjus, lisateavet vaata siit {logs_link}", + "not_loaded": "Pole laaditud", "options": "Valikud", + "provided_by_custom_component": "Saadaval välise osise abil", + "provided_by_custom_integration": "Saadaval välise sidumise kaudu", "reload": "Taaslae", "reload_confirm": "Sidumine on taaslaetud", "reload_restart_confirm": "Taaskäivita Home Assistant, et lõpetada selle sidumise taaslaadimine", "rename": "Nimeta ümber", "restart_confirm": "Selle sidumise lõplikuks eemaldamiseks taaskäivita Home Assistant", "services": "{count} {count, plural,\n one {teenus}\n other {teenust}\n}", + "state": { + "failed_unload": "Eemaldamine nurjus", + "loaded": "Laetud", + "migration_error": "Tõrge teisaldamisel", + "not_loaded": "Pole laaditud", + "setup_error": "Häälestamine nurjus", + "setup_retry": "Proovin uuesti seadistada" + }, "system_options": "Süsteemisuvandid", "unnamed_entry": "Nimetu kanne" }, diff --git a/translations/frontend/it.json b/translations/frontend/it.json index c0d6fe6c52..50f40e2da5 100644 --- a/translations/frontend/it.json +++ b/translations/frontend/it.json @@ -2156,8 +2156,11 @@ "caption": "Integrazioni", "config_entry": { "area": "In {area}", + "check_the_logs": "Controlla i registri", + "configure": "Configura", "delete": "Elimina", "delete_confirm": "Sei sicuro di voler eliminare questa integrazione?", + "depends_on_cloud": "Dipende dal cloud", "device_unavailable": "Dispositivo non disponibile", "devices": "{count} {count, plural, \none {dispositivo}\nother {dispositivi}\n}", "disable_restart_confirm": "Riavvia Home Assistant per terminare la disabilitazione di questa integrazione", @@ -2180,14 +2183,24 @@ "logs": "registri", "manuf": "da {manufacturer}", "no_area": "Nessuna area", - "not_loaded": "Non caricato, controlla il {logs_link}", + "not_loaded": "Non caricato", "options": "Opzioni", + "provided_by_custom_component": "Fornito da un componente personalizzato", + "provided_by_custom_integration": "Fornito da un'integrazione personalizzata", "reload": "Ricarica", "reload_confirm": "L'integrazione è stata ricaricata", "reload_restart_confirm": "Riavvia Home Assistant per completare il ricaricamento di questa integrazione", "rename": "Rinomina", "restart_confirm": "Riavvia Home Assistant per completare la rimozione di questa integrazione", "services": "{count} {count, plural,\n one {servizio}\n other {servizi}\n}", + "state": { + "failed_unload": "Impossibile scaricare", + "loaded": "Caricato", + "migration_error": "Errore di migrazione", + "not_loaded": "Non caricato", + "setup_error": "Configurazione non riuscita", + "setup_retry": "Nuovo tentativo di configurazione" + }, "system_options": "Opzioni di sistema", "unnamed_entry": "Voce senza nome" }, @@ -2216,7 +2229,7 @@ "configure": "Configura", "configured": "Configurato", "confirm_new": "Vuoi configurare {integration}?", - "description": "Gestisci le integrazioni con servizi, dispositivi, ...", + "description": "Gestisci le integrazioni con servizi o dispositivi", "details": "Dettagli dell'integrazione", "disable": { "disabled_integrations": "{number} disabilitate", @@ -2255,8 +2268,10 @@ "logs": { "caption": "Registri", "clear": "Pulisci", + "custom_integration": "integrazione personalizzata", "description": "Vedi i registri di Home Assistant", "details": "Dettagli registro ({level})", + "error_from_custom_integration": "Questo errore ha avuto origine da un'integrazione personalizzata.", "level": { "critical": "CRITICO", "debug": "DEBUG", diff --git a/translations/frontend/ko.json b/translations/frontend/ko.json index 2a90f645d9..451d967144 100644 --- a/translations/frontend/ko.json +++ b/translations/frontend/ko.json @@ -2156,6 +2156,8 @@ "caption": "통합 구성요소", "config_entry": { "area": "{area}에 위치", + "check_the_logs": "로그 확인", + "configure": "구성", "delete": "삭제하기", "delete_confirm": "이 통합 구성요소를 제거하시겠습니까?", "device_unavailable": "기기 사용불가", @@ -2180,7 +2182,7 @@ "logs": "로그", "manuf": "{manufacturer} 제조", "no_area": "영역 없음", - "not_loaded": "불러오지 못했습니다. {logs_link}을(를) 확인해주세요.", + "not_loaded": "로드되지 않음", "options": "옵션", "reload": "다시 읽어오기", "reload_confirm": "통합 구성요소를 다시 읽어 들였습니다", @@ -2188,6 +2190,14 @@ "rename": "이름 변경하기", "restart_confirm": "이 통합 구성요소를 제거하려면 Home Assistant를 다시 시작해주세요", "services": "{count} {count, plural,\n one{개의 서비스}\n other{개의 서비스}\n}", + "state": { + "failed_unload": "언로드 실패", + "loaded": "로드 됨", + "migration_error": "마이그레이션 오류", + "not_loaded": "로드되지 않음", + "setup_error": "설정 실패", + "setup_retry": "설정 재시도" + }, "system_options": "시스템 옵션", "unnamed_entry": "이름이 없는 항목" }, diff --git a/translations/frontend/ru.json b/translations/frontend/ru.json index 00655d802c..0cf7ec8a28 100644 --- a/translations/frontend/ru.json +++ b/translations/frontend/ru.json @@ -444,7 +444,7 @@ }, "supervisor": { "beta_backup": "Перед активацией этой функции убедитесь, что у Вас есть резервная копия Ваших данных.", - "beta_join_confirm": "Перейти на бета-версии?", + "beta_join_confirm": "Вы уверены, что хотите перейти на бета-версии?", "beta_release_items": "Канал обновлений включает в себя бета-версии для:", "beta_warning": "Бета-версии предназначены для тестирования и могут содержать нестабильные изменения кода.", "channel": "Канал обновлений", @@ -453,7 +453,7 @@ "failed_to_set_option": "Не удалось настроить параметр Supervisor.", "failed_to_update": "Не удалось обновить Supervisor.", "join_beta_action": "Перейти на бета", - "join_beta_description": "Получать тестовые версии обновлений для Home Assistant, Supervisor и операционной системы хоста", + "join_beta_description": "Получать тестовые версии обновлений для Home Assistant (RC), Supervisor и операционной системы хоста", "leave_beta_action": "Покинуть бета", "leave_beta_description": "Получать стабильные версии обновлений для Home Assistant, Supervisor и операционной системы хоста", "ram_usage": "Использование ОЗУ", @@ -2156,8 +2156,11 @@ "caption": "Интеграции", "config_entry": { "area": "Помещение: {area}", + "check_the_logs": "Проверить журналы", + "configure": "Настроить", "delete": "Удалить", "delete_confirm": "Вы уверены, что хотите удалить эту интеграцию?", + "depends_on_cloud": "Зависящие от облачных сервисов", "device_unavailable": "Устройство недоступно", "devices": "{count, plural,\n one {устройств:}\n other {устройств:}\n} {count}", "disable_restart_confirm": "Перезапустите Home Assistant, чтобы завершить деактивацию этой интеграции.", @@ -2180,14 +2183,24 @@ "logs": "журналы", "manuf": "{manufacturer}", "no_area": "Не указано", - "not_loaded": "Не загружено, проверьте {logs_link}", + "not_loaded": "Не загружено", "options": "Настройки", + "provided_by_custom_component": "Предоставляется кастомным компонентом", + "provided_by_custom_integration": "Предоставляется кастомной интеграцией", "reload": "Перезагрузить", "reload_confirm": "Перезагрузка интеграции выполнена", "reload_restart_confirm": "Перезапустите Home Assistant, чтобы завершить перезагрузку этой интеграции", "rename": "Переименовать", "restart_confirm": "Перезапустите Home Assistant, чтобы завершить удаление этой интеграции", "services": "{count, plural,\n one {служб:}\n other {служб:}\n} {count}", + "state": { + "failed_unload": "Не удалось выгрузить", + "loaded": "Загружено", + "migration_error": "Ошибка при миграции", + "not_loaded": "Не загружено", + "setup_error": "Не удалось настроить", + "setup_retry": "Повторная настройка" + }, "system_options": "Настройки интеграции", "unnamed_entry": "Без названия" }, diff --git a/translations/frontend/zh-Hant.json b/translations/frontend/zh-Hant.json index ae932dd7ed..ae36353362 100644 --- a/translations/frontend/zh-Hant.json +++ b/translations/frontend/zh-Hant.json @@ -242,7 +242,7 @@ "ram_usage": "附加元件 RAM 使用率", "rebuild": "重建", "restart": "重啟", - "start": "開始", + "start": "啟動", "stop": "停止", "uninstall": "移除", "visit_addon_page": "參閱 {name} 頁面以獲得更詳細資訊" @@ -2156,8 +2156,11 @@ "caption": "整合", "config_entry": { "area": "於 {area}", + "check_the_logs": "檢查日誌", + "configure": "設定", "delete": "刪除", "delete_confirm": "確定要刪除此整合?", + "depends_on_cloud": "跟隨雲服務", "device_unavailable": "裝置不可用", "devices": "{count} {count, plural,\n one {個裝置}\n other {個裝置}\n}", "disable_restart_confirm": "重啟 Home Assistant 以完成整合關閉", @@ -2180,14 +2183,24 @@ "logs": "日誌", "manuf": "廠牌:{manufacturer}", "no_area": "無分區", - "not_loaded": "未載入,請檢查 {logs_link}", + "not_loaded": "未載入", "options": "選項", + "provided_by_custom_component": "由自訂元件提供", + "provided_by_custom_integration": "由自訂整合提供", "reload": "重新載入", "reload_confirm": "整合已重新載入", "reload_restart_confirm": "重啟 Home Assistant 以完成整合重新載入", "rename": "重新命名", "restart_confirm": "重啟 Home Assistant 以完成此整合移動", "services": "{count} {count, plural,\n one {項服務}\n other {項服務}\n}", + "state": { + "failed_unload": "卸載失敗", + "loaded": "已載入", + "migration_error": "遷移錯誤", + "not_loaded": "未載入", + "setup_error": "設定失敗", + "setup_retry": "重新設定中" + }, "system_options": "系統選項", "unnamed_entry": "未命名實體" }, @@ -2255,8 +2268,10 @@ "logs": { "caption": "記錄", "clear": "清除", + "custom_integration": "自訂整合", "description": "檢視 Home Assistant 日誌", "details": "記錄詳細資料({level})", + "error_from_custom_integration": "自訂整合產生錯誤。", "level": { "critical": "緊急", "debug": "除錯", From 519988326b9aae2c38c1a26c897ad05eb68c2e68 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 16 Apr 2021 17:59:10 -1000 Subject: [PATCH 053/106] Do not throw warnings when a service calls disconnects the websocket (#8932) --- src/data/service.ts | 3 +++ .../service/developer-tools-service.ts | 15 ++++++++++++++- src/state/connection-mixin.ts | 8 ++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/data/service.ts b/src/data/service.ts index 120d3096c9..5e83fd6741 100644 --- a/src/data/service.ts +++ b/src/data/service.ts @@ -6,3 +6,6 @@ export const callExecuteScript = (hass: HomeAssistant, sequence: Action[]) => type: "execute_script", sequence, }); + +export const serviceCallWillDisconnect = (domain: string, service: string) => + domain === "homeassistant" && ["restart", "stop"].includes(service); diff --git a/src/panels/developer-tools/service/developer-tools-service.ts b/src/panels/developer-tools/service/developer-tools-service.ts index eef7f9ceb2..b72fb01a40 100644 --- a/src/panels/developer-tools/service/developer-tools-service.ts +++ b/src/panels/developer-tools/service/developer-tools-service.ts @@ -1,3 +1,4 @@ +import { ERR_CONNECTION_LOST } from "home-assistant-js-websocket"; import { safeLoad } from "js-yaml"; import { css, @@ -23,7 +24,11 @@ import "../../../components/ha-service-picker"; import "../../../components/ha-yaml-editor"; import type { HaYamlEditor } from "../../../components/ha-yaml-editor"; import { ServiceAction } from "../../../data/script"; -import { callExecuteScript } from "../../../data/service"; +import { forwardHaptic } from "../../../data/haptics"; +import { + callExecuteScript, + serviceCallWillDisconnect, +} from "../../../data/service"; import { haStyle } from "../../../resources/styles"; import "../../../styles/polymer-ha-style"; import { HomeAssistant } from "../../../types"; @@ -275,6 +280,14 @@ class HaPanelDevService extends LitElement { try { await callExecuteScript(this.hass, [this._serviceData]); } catch (err) { + const [domain, service] = this._serviceData.service.split(".", 2); + if ( + err.error.code === ERR_CONNECTION_LOST && + serviceCallWillDisconnect(domain, service) + ) { + return; + } + forwardHaptic("failure"); showToast(this, { message: this.hass.localize( diff --git a/src/state/connection-mixin.ts b/src/state/connection-mixin.ts index 52164b59a0..8785f4dada 100644 --- a/src/state/connection-mixin.ts +++ b/src/state/connection-mixin.ts @@ -3,6 +3,7 @@ import { callService, Connection, ERR_INVALID_AUTH, + ERR_CONNECTION_LOST, HassConfig, subscribeConfig, subscribeEntities, @@ -13,6 +14,7 @@ import { broadcastConnectionStatus } from "../data/connection-status"; import { subscribeFrontendUserData } from "../data/frontend"; import { forwardHaptic } from "../data/haptics"; import { DEFAULT_PANEL } from "../data/panel"; +import { serviceCallWillDisconnect } from "../data/service"; import { NumberFormat } from "../data/translation"; import { subscribePanels } from "../data/ws-panels"; import { translationMetadata } from "../resources/translations-metadata"; @@ -78,6 +80,12 @@ export const connectionMixin = >( target )) as Promise; } catch (err) { + if ( + err.error.code === ERR_CONNECTION_LOST && + serviceCallWillDisconnect(domain, service) + ) { + throw err; + } if (__DEV__) { // eslint-disable-next-line no-console console.error( From c7f4e1152d9d9fca701cf80d6e99b83d5d8c67d0 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 16 Apr 2021 23:02:29 -0700 Subject: [PATCH 054/106] Pass manifest to config flow card (#8933) --- src/panels/config/integrations/ha-config-integrations.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/panels/config/integrations/ha-config-integrations.ts b/src/panels/config/integrations/ha-config-integrations.ts index 845319c01a..3ea886368e 100644 --- a/src/panels/config/integrations/ha-config-integrations.ts +++ b/src/panels/config/integrations/ha-config-integrations.ts @@ -381,6 +381,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { (flow: DataEntryFlowProgressExtended) => html` From 982ab93cdb326ebfc14b503f2d7268968f17568b Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 16 Apr 2021 23:16:20 -0700 Subject: [PATCH 055/106] Do not vertically align integration icon (#8934) --- src/panels/config/integrations/ha-integration-header.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/panels/config/integrations/ha-integration-header.ts b/src/panels/config/integrations/ha-integration-header.ts index fefebd5f65..9c9c49b8d4 100644 --- a/src/panels/config/integrations/ha-integration-header.ts +++ b/src/panels/config/integrations/ha-integration-header.ts @@ -122,7 +122,6 @@ export class HaIntegrationHeader extends LitElement { .header { display: flex; position: relative; - align-items: center; padding: 16px 8px 8px 16px; } .header img { @@ -130,6 +129,9 @@ export class HaIntegrationHeader extends LitElement { width: 40px; height: 40px; } + .header .info { + align-self: center; + } .header .info div { word-wrap: break-word; display: -webkit-box; From b96a70cd551ffd4a906d56430e8999d222a9767e Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 16 Apr 2021 23:51:48 -0700 Subject: [PATCH 056/106] Make the integration header banner smaller (#8935) --- src/panels/config/integrations/ha-integration-card.ts | 6 ++++-- src/panels/config/integrations/ha-integration-header.ts | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index 5aaf0d31c4..ad5b87e3f0 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -608,7 +608,9 @@ export class HaIntegrationCard extends LitElement { overflow: hidden; } .hasMultiple.single .back-btn { - height: 32px; + height: 24px; + display: flex; + align-items: center; } .hasMultiple.group .back-btn { height: 0px; @@ -656,7 +658,7 @@ export class HaIntegrationCard extends LitElement { overflow: auto; } .disabled paper-listbox { - top: 100px; + top: 88px; } } paper-item { diff --git a/src/panels/config/integrations/ha-integration-header.ts b/src/panels/config/integrations/ha-integration-header.ts index 9c9c49b8d4..6ace567a6d 100644 --- a/src/panels/config/integrations/ha-integration-header.ts +++ b/src/panels/config/integrations/ha-integration-header.ts @@ -117,7 +117,7 @@ export class HaIntegrationHeader extends LitElement { background-color: var(--state-color); color: var(--text-on-state-color); text-align: center; - padding: 8px; + padding: 2px; } .header { display: flex; From b76c67fc9b476a35958c2cadfd27af8e3c5c438c Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 18 Apr 2021 00:48:53 +0000 Subject: [PATCH 057/106] Translation update --- translations/frontend/ca.json | 15 ++++++++++++++- translations/frontend/nl.json | 13 +++++++++++++ translations/frontend/zh-Hans.json | 17 ++++++++++++++++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/translations/frontend/ca.json b/translations/frontend/ca.json index 6c2ccced2b..c300fe59ce 100644 --- a/translations/frontend/ca.json +++ b/translations/frontend/ca.json @@ -2156,8 +2156,11 @@ "caption": "Integracions", "config_entry": { "area": "A {area}", + "check_the_logs": "Comprova els registres", + "configure": "Configura", "delete": "Elimina", "delete_confirm": "Estàs segur que vols eliminar aquesta integració?", + "depends_on_cloud": "Depèn del núvol", "device_unavailable": "Dispositiu no disponible", "devices": "{count} {count, plural,\n one {dispositiu}\n other {dispositius}\n}", "disable_restart_confirm": "Reinicia Home Assistant per acabar de desactivar aquesta integració", @@ -2180,14 +2183,24 @@ "logs": "registres", "manuf": "de {manufacturer}", "no_area": "Sense àrea", - "not_loaded": "No carregat, comprova {logs_link}", + "not_loaded": "No carregada", "options": "Opcions", + "provided_by_custom_component": "Proporcionada per un component personalitzat", + "provided_by_custom_integration": "Proporcionada per una integració personalitzada", "reload": "Torna a carregar", "reload_confirm": "La integració s'ha tornat a carregar", "reload_restart_confirm": "Reinicia Home Assistant per acabar de carregar aquesta integració", "rename": "Canvia el nom", "restart_confirm": "Reinicia Home Assistant per acabar d'eliminar aquesta integració", "services": "{count} {count, plural,\n one {servei}\n other {serveis}\n}", + "state": { + "failed_unload": "No s'ha pogut desactivar", + "loaded": "Carregada", + "migration_error": "Error de migració", + "not_loaded": "No carregada", + "setup_error": "No s'ha pogut configurar", + "setup_retry": "S'està tornant a provar de configurar" + }, "system_options": "Opcions de sistema", "unnamed_entry": "Entrada sense nom" }, diff --git a/translations/frontend/nl.json b/translations/frontend/nl.json index ee21974698..32d6142dd1 100644 --- a/translations/frontend/nl.json +++ b/translations/frontend/nl.json @@ -2156,8 +2156,11 @@ "caption": "Integraties", "config_entry": { "area": "In {area}", + "check_the_logs": "Controleer de logboeken", + "configure": "Configureer", "delete": "Verwijder", "delete_confirm": "Weet je zeker dat je deze integratie wilt verwijderen?", + "depends_on_cloud": "Cloud afhankelijk", "device_unavailable": "Apparaat niet beschikbaar", "devices": "{count} {count, plural,\n one {apparaat}\n other {apparaten}\n}", "disable_restart_confirm": "Start Home Assistant opnieuw op om het uitzetten van deze integratie te voltooien", @@ -2182,12 +2185,22 @@ "no_area": "Geen Gebied", "not_loaded": "Niet geladen, controleer de {logs_link}", "options": "Opties", + "provided_by_custom_component": "Geleverd door een aangepaste component", + "provided_by_custom_integration": "Geleverd door een aangepaste integratie", "reload": "Herlaad", "reload_confirm": "De integratie is opnieuw geladen", "reload_restart_confirm": "Start Home Assistant opnieuw om het opnieuw laden van deze integratie te voltooien", "rename": "Naam wijzigen", "restart_confirm": "Herstart Home Assistant om het verwijderen van deze integratie te voltooien", "services": "{count} {count, plural,\n one {service}\n other {services}\n}", + "state": { + "failed_unload": "Uitladen mislukt", + "loaded": "Geladen", + "migration_error": "Migratiefout", + "not_loaded": "Niet geladen", + "setup_error": "Instellen mislukt", + "setup_retry": "Opnieuw proberen in te stellen" + }, "system_options": "Systeeminstellingen", "unnamed_entry": "Naamloze invoer" }, diff --git a/translations/frontend/zh-Hans.json b/translations/frontend/zh-Hans.json index 0dec74815d..885d866b82 100644 --- a/translations/frontend/zh-Hans.json +++ b/translations/frontend/zh-Hans.json @@ -2156,8 +2156,11 @@ "caption": "集成", "config_entry": { "area": "位于:{area}", + "check_the_logs": "检查日志", + "configure": "配置", "delete": "删除", "delete_confirm": "您确定要删除此集成吗?", + "depends_on_cloud": "取决于云端", "device_unavailable": "设备不可用", "devices": "{count} {count, plural,\n one {个设备}\n other {个设备}\n}", "disable_restart_confirm": "重启 Home Assistant 以完成此集成的禁用", @@ -2180,14 +2183,24 @@ "logs": "日志", "manuf": "by {manufacturer}", "no_area": "没有区域", - "not_loaded": "未加载,请检查{logs_link}", + "not_loaded": "未加载", "options": "选项", + "provided_by_custom_component": "由自定义组件提供", + "provided_by_custom_integration": "由自定义集成提供", "reload": "重载", "reload_confirm": "集成已重新加载", "reload_restart_confirm": "重启 Home Assistant 以完成此集成的重载", "rename": "重命名", "restart_confirm": "重启 Home Assistant 以完成此集成的删除", "services": "{count} {count, plural,\n one {个服务}\n other {个服务}\n}", + "state": { + "failed_unload": "卸载失败", + "loaded": "已加载", + "migration_error": "迁移错误", + "not_loaded": "未加载", + "setup_error": "设置失败", + "setup_retry": "正在重试设置" + }, "system_options": "系统选项", "unnamed_entry": "未命名条目" }, @@ -2255,8 +2268,10 @@ "logs": { "caption": "日志", "clear": "清除", + "custom_integration": "自定义集成", "description": "查看 Home Assistant 日志", "details": "日志详细信息( {level} )", + "error_from_custom_integration": "此错误来自自定义集成。", "level": { "critical": "CRITICAL", "debug": "DEBUG", From 97d5e6512dec3d62e48dfdd4dc71f300713e0f48 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Sun, 18 Apr 2021 07:12:07 +0200 Subject: [PATCH 058/106] Fix link to config panels (#8936) --- src/panels/config/integrations/ha-integration-card.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index ad5b87e3f0..d4f64bb232 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -272,9 +272,9 @@ export class HaIntegrationCard extends LitElement {
      ` : item.domain in integrationsWithPanel ? html` ${this.hass.localize( "ui.panel.config.integrations.config_entry.configure" From 51f1ff26f16b84ab7d8afcb536df0e92d3a1344e Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 19 Apr 2021 00:48:51 +0000 Subject: [PATCH 059/106] Translation update --- translations/frontend/bg.json | 28 +++++------ translations/frontend/cs.json | 15 +++++- translations/frontend/hi.json | 88 +++++++++++++++++++++++++++++++++-- translations/frontend/pl.json | 19 ++++++-- 4 files changed, 127 insertions(+), 23 deletions(-) diff --git a/translations/frontend/bg.json b/translations/frontend/bg.json index 4ad5e1c313..fe7ce9984b 100644 --- a/translations/frontend/bg.json +++ b/translations/frontend/bg.json @@ -324,9 +324,9 @@ "text": "Искате ли да рестартирате добавката с вашите промени?" }, "update": { - "create_snapshot": "Създаване на моментна снимка на {name} преди актуализиране", - "snapshot": "Моментна снимка", - "snapshotting": "Създава се моментна снимка на {name}", + "create_snapshot": "Създаване на снапшот на {name} преди актуализиране", + "snapshot": "Снапшот", + "snapshotting": "Създава се снапшот на {name}", "updating": "Актуализиране на {name} до версия {version}" } }, @@ -338,18 +338,18 @@ }, "panel": { "dashboard": "Табло", - "snapshots": "Моментни снимки", + "snapshots": "Снапшоти", "store": "Хранилище за добавки", "system": "Система" }, "snapshot": { "addons": "Добавки", - "available_snapshots": "Налични системни снимки", - "could_not_create": "Не можа да се създаде моментна снимка", + "available_snapshots": "Налични снапшоти", + "could_not_create": "Не можа да се създаде снапшот", "create": "Създаване", - "create_blocked_not_running": "Създаването на моментна снимка в момента не е възможно, тъй като системата е в състояние {state}.", - "create_snapshot": "Създаване на моментна снимка", - "description": "Моментните снимки Ви позволяват лесно да архивирате и възстановявате всички данни от вашия екземпляр на Home Assistant.", + "create_blocked_not_running": "Създаването на снапшот в момента не е възможно, тъй като системата е в състояние {state}.", + "create_snapshot": "Създаване на снапшот", + "description": "Снапшотите ви позволяват лесно да архивирате и възстановявате всички данни от вашия екземпляр на Home Assistant.", "enter_password": "Моля, въведете парола.", "folder": { "addons/local": "Локални добавки", @@ -359,16 +359,16 @@ "ssl": "SSL" }, "folders": "Папки", - "full_snapshot": "Пълена моментна снимка", + "full_snapshot": "Пълен снапшот", "name": "Име", - "no_snapshots": "Все още нямате моментни снимки", - "partial_snapshot": "Частичена моментна снимка", + "no_snapshots": "Все още нямате снапшоти", + "partial_snapshot": "Частичен снапшот", "password": "Парола", "password_protected": "защитен с парола", "password_protection": "Защита с парола", "security": "Сигурност", "type": "Тип", - "upload_snapshot": "Качване на моментна снимка" + "upload_snapshot": "Качване на снапшот" }, "store": { "missing_addons": "Липсват добавки? Активирайте разширения режим в страницата на потребителския си профил", @@ -3238,7 +3238,7 @@ "intro": "Готови ли сте да събудите дома си, да отвоювате независимостта си и да се присъедините към световна общност от хора автоматизиращи домовете си?", "next": "Следващ", "restore": { - "description": "Като алтернатива можете да възстановите от предишна моментна снимка.", + "description": "Като алтернатива можете да възстановите от предишен снапшот.", "hide_log": "Скриване на пълния дневник", "in_progress": "Възстановяването е в ход", "show_log": "Показване на пълния дневник" diff --git a/translations/frontend/cs.json b/translations/frontend/cs.json index 59fa0e5ccb..55466663dd 100644 --- a/translations/frontend/cs.json +++ b/translations/frontend/cs.json @@ -2155,8 +2155,11 @@ "caption": "Integrace", "config_entry": { "area": "V {area}", + "check_the_logs": "Zkontrolujte logy", + "configure": "Nastavit", "delete": "Smazat", "delete_confirm": "Opravdu chcete odstranit tuto integraci?", + "depends_on_cloud": "Závisí na cloudu", "device_unavailable": "Zařízení není dostupné", "devices": "{count} {count, plural,\n one {zařízení}\n other {zařízení}\n}", "disable_restart_confirm": "Restartujte Home Assistant pro dokončení odstranění této integrace", @@ -2179,14 +2182,24 @@ "logs": "logy", "manuf": "od {manufacturer}", "no_area": "Žádná oblast", - "not_loaded": "Není načtena, zkontrolujte {logs_link}", + "not_loaded": "Nenačteno", "options": "Možnosti", + "provided_by_custom_component": "Poskytováno vlastní komponentou", + "provided_by_custom_integration": "Poskytováno vlastní integrací", "reload": "Nově načíst", "reload_confirm": "Integrace byla nově načtena", "reload_restart_confirm": "Restartujte Home Assistant pro nové načtení této integrace", "rename": "Přejmenovat", "restart_confirm": "Restartujte Home Assistant pro odstranění této integrace", "services": "{count} {count, plural,\n one {služba}\n few {služby}\n other {služeb}\n}", + "state": { + "failed_unload": "Zrušení načtení se nezdařilo", + "loaded": "Načteno", + "migration_error": "Chyba migrace", + "not_loaded": "Nenačteno", + "setup_error": "Nastavení se nezdařilo", + "setup_retry": "Opakovaný pokus o nastavení" + }, "system_options": "Více možností", "unnamed_entry": "Nepojmenovaný záznam" }, diff --git a/translations/frontend/hi.json b/translations/frontend/hi.json index e73077b21e..e250279d81 100644 --- a/translations/frontend/hi.json +++ b/translations/frontend/hi.json @@ -14,24 +14,48 @@ "fan_mode": { "off": "बंद", "on": "चालू" + }, + "hvac_action": { + "cooling": "थन्दा", + "drying": "सुखाना", + "fan": "पंखा", + "heating": "गरमाना", + "idle": "खाली", + "off": "बंद" + }, + "preset_mode": { + "away": "बाहर", + "comfort": "पर्याप्त", + "eco": "किफ़ायत", + "home": "घर", + "none": "कुच भि नहि", + "sleep": "निद्रा" + } + }, + "humidifier": { + "mode": { + "normal": "सामान्य" } } }, "state_badge": { "alarm_control_panel": { + "armed_custom_bypass": "सशस्त्र", "pending": "अपूर्ण" }, "default": { "entity_not_found": "Entità non trovata", - "error": "Errore", + "error": "ग़लती", "unavailable": "अनुपलब्ध", "unknown": "अज्ञात" }, "device_tracker": { - "home": "घर" + "home": "घर", + "not_home": "बाहर" }, "person": { - "home": "घर" + "home": "घर", + "not_home": "बाहर" } }, "state": { @@ -57,6 +81,11 @@ "previous": "पिछला", "undo": "पूर्ववत करें" }, + "components": { + "history_charts": { + "no_history_found": "स्थिति के कोइ भि पहले रिकार्ड नहि मिले" + } + }, "dialogs": { "mqtt_device_debug_info": { "entities": "संस्थाएं", @@ -75,6 +104,11 @@ "day": "{count} {count, plural,\n one {दिन}\n other {दिन}\n}", "week": "{count} {count, plural,\n one {हफ़्ता}\n other {हफ़्ते}\n}" }, + "errors": { + "supervisor": { + "system_health": "उप्करन के स्वस्थ्य कि जाँच करे" + } + }, "notification_drawer": { "empty": "सूचनाएँ नहीं हैं", "title": "सूचनाएँ" @@ -163,6 +197,19 @@ "password": "पासवर्ड" } }, + "core": { + "section": { + "core": { + "analytics": { + "preference": { + "usage": { + "title": "उप्योग किये एकीकरण" + } + } + } + } + } + }, "filtering": { "clear": "विशद", "filtering_by": "द्वारा छान रहे हैं" @@ -170,8 +217,17 @@ "integrations": { "add_integration": "एकीकरण जोड़ें", "config_entry": { + "check_the_logs": "अभिलेख जाँच करें", "delete": "हटाएं", + "not_loaded": "तैयार नहीं हैं", + "provided_by_custom_integration": "विशेष एकीकरण से उप्लब्ध", "rename": "नाम बदलें", + "state": { + "failed_unload": "खाली करने मे असफल", + "loaded": "तैयार", + "migration_error": "प्रवसन दोष", + "not_loaded": "तैयार नहीं हैं" + }, "system_options": "सिस्टम विकल्प" }, "integration": "एकीकरण", @@ -180,6 +236,10 @@ "rename_input_label": "प्रवेश का नाम" }, "introduction": "In questa schermata è possibile configurare Home Assistant e i suoi componenti. Non è ancora possibile configurare tutto tramite l'interfaccia, ma ci stiamo lavorando.", + "logs": { + "custom_integration": "िशेष एकीकरण", + "error_from_custom_integration": "ये दोश िशेष एकीकरण की वजह से है" + }, "mqtt": { "title": "MQTT" }, @@ -229,6 +289,11 @@ "services": { "title": "सेवाएं" }, + "states": { + "filter_states": "स्थिति छन्नी", + "set_state": "स्थिति निर्धारित करे", + "state": "स्थिति" + }, "templates": { "title": "टेम्पलेट्स" } @@ -236,6 +301,9 @@ }, "lovelace": { "cards": { + "empty_state": { + "title": "स्वागत है घर मै" + }, "starting": { "description": "होम असिस्टेंट शुरू हो रहा है, कृपया प्रतीक्षा करें ..." } @@ -245,11 +313,21 @@ }, "editor": { "card": { + "alarm-panel": { + "available_states": "उप्लब्दह स्थिति" + }, + "conditional": { + "current_state": "वरतमान", + "state_equal": "स्थिति इस के बराबर है", + "state_not_equal": "स्थिति इस के बराबर नहि है" + }, "entity": { - "description": "एंटिटी कार्ड आपको अपनी इकाई की स्थिति का त्वरित अवलोकन देता है।" + "description": "स्थिति कार्ड आपको अपनी इकाई की स्थिति का संक्षेप देता है।" }, "generic": { - "double_tap_action": "डबल टैप एक्शन" + "double_tap_action": "डबल टैप एक्शन", + "show_state": "स्थिति दिखाएं?", + "state": "स्थिति" }, "map": { "hours_to_show": "hours to show" diff --git a/translations/frontend/pl.json b/translations/frontend/pl.json index 395b3675b5..3725be380f 100644 --- a/translations/frontend/pl.json +++ b/translations/frontend/pl.json @@ -2156,8 +2156,11 @@ "caption": "Integracje", "config_entry": { "area": "obszar: {area}", + "check_the_logs": "Sprawdź logi", + "configure": "Konfiguruj", "delete": "Usuń", "delete_confirm": "Czy na pewno chcesz usunąć tę integrację?", + "depends_on_cloud": "Zależy od chmury", "device_unavailable": "Urządzenie niedostępne", "devices": "{count} {count, plural,\n one {urządzenie}\n few {urządzenia}\n many {urządzeń}\n other {urządzeń}\n}", "disable_restart_confirm": "Zrestartuj Home Assistanta, aby zakończyć wyłączanie tej integracji", @@ -2180,21 +2183,31 @@ "logs": "logi", "manuf": "producent: {manufacturer}", "no_area": "brak", - "not_loaded": "Nie załadowano, sprawdź {logs_link}", + "not_loaded": "Nie załadowano", "options": "Opcje", + "provided_by_custom_component": "Dostarczone przez niestandardowy komponent", + "provided_by_custom_integration": "Dostarczone przez niestandardowy komponent", "reload": "Wczytaj ponownie", "reload_confirm": "Integracja została ponownie wczytana", "reload_restart_confirm": "Uruchom ponownie Home Assistanta, aby dokończyć ponowne wczytywanie tej integracji", "rename": "Zmień nazwę", "restart_confirm": "Zrestartuj Home Assistanta, aby zakończyć usuwanie tej integracji", "services": "{count} {count, plural,\n one {usługa}\n few {usługi}\n many {usług}\n other {usług}\n}", + "state": { + "failed_unload": "Nie udało się rozładować", + "loaded": "Załadowano", + "migration_error": "Błąd migracji", + "not_loaded": "Nie załadowano", + "setup_error": "Nie udało się skonfigurować", + "setup_retry": "Próbuję ponownie skonfigurować" + }, "system_options": "Opcje systemowe", "unnamed_entry": "Nienazwany wpis" }, "config_flow": { "aborted": "Przerwano", "close": "Zamknij", - "could_not_load": "Nie można wczytać interfejsu konfiguracji", + "could_not_load": "Nie udało się wczytać interfejsu konfiguracji", "created_config": "Utworzono konfigurację dla {name}.", "dismiss": "Okno dialogowe odrzucenia", "error": "Błąd", @@ -2216,7 +2229,7 @@ "configure": "Konfiguruj", "configured": "Skonfigurowane", "confirm_new": "Czy chcesz skonfigurować {integration}?", - "description": "Zarządzaj integracjami z usługami, urządzeniami, ...", + "description": "Zarządzaj integracjami z usługami lub urządzeniami", "details": "Szczegóły integracji", "disable": { "disabled_integrations": "Wyłączonych: {number}", From 9bc2ab29a1662bf7b766b0b19cd2775a87bd7b64 Mon Sep 17 00:00:00 2001 From: uvjustin <46082645+uvjustin@users.noreply.github.com> Date: Mon, 19 Apr 2021 23:25:19 +0800 Subject: [PATCH 060/106] Version bump hls.js to v1.0.1 (#8951) Co-authored-by: Bram Kragten --- package.json | 3 +-- src/components/ha-hls-player.ts | 15 +++++++-------- yarn.lock | 26 ++++---------------------- 3 files changed, 12 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 67964e7bf3..39a6c837e3 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "fecha": "^4.2.0", "fuse.js": "^6.0.0", "google-timezones-json": "^1.0.2", - "hls.js": "^0.13.2", + "hls.js": "^1.0.1", "home-assistant-js-websocket": "^5.9.0", "idb-keyval": "^3.2.0", "intl-messageformat": "^8.3.9", @@ -167,7 +167,6 @@ "@types/chromecast-caf-receiver": "^5.0.11", "@types/chromecast-caf-sender": "^1.0.3", "@types/codemirror": "^0.0.97", - "@types/hls.js": "^0.12.3", "@types/js-yaml": "^3.12.1", "@types/leaflet": "^1.4.3", "@types/leaflet-draw": "^1.0.1", diff --git a/src/components/ha-hls-player.ts b/src/components/ha-hls-player.ts index 777684d187..e841993c1b 100644 --- a/src/components/ha-hls-player.ts +++ b/src/components/ha-hls-player.ts @@ -1,3 +1,4 @@ +import type HlsType from "hls.js"; import { css, CSSResult, @@ -15,8 +16,6 @@ import { nextRender } from "../common/util/render-status"; import { getExternalConfig } from "../external_app/external_config"; import type { HomeAssistant } from "../types"; -type HLSModule = typeof import("hls.js"); - @customElement("ha-hls-player") class HaHLSPlayer extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -43,7 +42,7 @@ class HaHLSPlayer extends LitElement { @internalProperty() private _attached = false; - private _hlsPolyfillInstance?: Hls; + private _hlsPolyfillInstance?: HlsType; private _useExoPlayer = false; @@ -107,8 +106,8 @@ class HaHLSPlayer extends LitElement { const useExoPlayerPromise = this._getUseExoPlayer(); const masterPlaylistPromise = fetch(this.url); - const hls = ((await import("hls.js")) as any).default as HLSModule; - let hlsSupported = hls.isSupported(); + const Hls = (await import("hls.js")).default; + let hlsSupported = Hls.isSupported(); if (!hlsSupported) { hlsSupported = @@ -144,8 +143,8 @@ class HaHLSPlayer extends LitElement { // If codec is HEVC and ExoPlayer is supported, use ExoPlayer. if (this._useExoPlayer && match !== null && match[1] !== undefined) { this._renderHLSExoPlayer(playlist_url); - } else if (hls.isSupported()) { - this._renderHLSPolyfill(videoEl, hls, playlist_url); + } else if (Hls.isSupported()) { + this._renderHLSPolyfill(videoEl, Hls, playlist_url); } else { this._renderHLSNative(videoEl, playlist_url); } @@ -182,7 +181,7 @@ class HaHLSPlayer extends LitElement { private async _renderHLSPolyfill( videoEl: HTMLVideoElement, - Hls: HLSModule, + Hls: typeof HlsType, url: string ) { const hls = new Hls({ diff --git a/yarn.lock b/yarn.lock index 5abd1ee959..8d389e3cf9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3649,11 +3649,6 @@ resolved "https://registry.yarnpkg.com/@types/har-format/-/har-format-1.2.4.tgz#3275842095abb60d14b47fa798cc9ff708dab6d4" integrity sha512-iUxzm1meBm3stxUMzRqgOVHjj4Kgpgu5w9fm4X7kPRfSgVRzythsucEN7/jtOo8SQzm+HfcxWWzJS0mJDH/3DQ== -"@types/hls.js@^0.12.3": - version "0.12.3" - resolved "https://registry.yarnpkg.com/@types/hls.js/-/hls.js-0.12.3.tgz#09d5d1dbcd78d7dd46deff6db02bd2af9721a4cf" - integrity sha512-1QbxVTp7v9bn8MjvbMXV4YbMntC9Dv8v9bI9LgWxfg9Mgib0/jI2XITUEKGgG5Cde48ktyA1UHTSWld7QKKNnQ== - "@types/http-assert@*": version "1.5.1" resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.1.tgz#d775e93630c2469c2f980fc27e3143240335db3b" @@ -7182,11 +7177,6 @@ event-target-shim@^5.0.1: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter3@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" - integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== - eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -8323,13 +8313,10 @@ he@1.2.0, he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hls.js@^0.13.2: - version "0.13.2" - resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-0.13.2.tgz#3e7dd28e3787c69c6aba42b64b11eb2c3c8c29f1" - integrity sha512-sIg2t4uGpWQLzuK1Iid9614WOKqxj4OYg+EbFbhhTDCsxpENBN+Du3yBFnoi+a83DuOOHdiQd1ydnti9loSGXw== - dependencies: - eventemitter3 "3.1.0" - url-toolkit "^2.1.6" +hls.js@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-1.0.1.tgz#d92bd0a9c78760f0f0e90d53c60192800ebc629f" + integrity sha512-ElPUW9VMY2uXdX07N872BSrVUcVd4jZGav4nqlY3vinpdMpW8esmdpUaeVA5vv3oIRSmiC/XtL9K+mSt6rlBpA== hmac-drbg@^1.0.1: version "1.0.1" @@ -13642,11 +13629,6 @@ url-parse@^1.4.7: querystringify "^2.1.1" requires-port "^1.0.0" -url-toolkit@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/url-toolkit/-/url-toolkit-2.1.6.tgz#6d03246499e519aad224c44044a4ae20544154f2" - integrity sha512-UaZ2+50am4HwrV2crR/JAf63Q4VvPYphe63WGeoJxeu8gmOm0qxPt+KsukfakPNrX9aymGNEkkaoICwn+OuvBw== - url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" From b39872741335b8ccb5c7d9db8e509f2afa9ff192 Mon Sep 17 00:00:00 2001 From: Aaron Godfrey Date: Mon, 19 Apr 2021 09:51:55 -0700 Subject: [PATCH 061/106] Allow falsey values for attribute value in a picture-elements card element. (#8943) --- src/panels/lovelace/elements/hui-state-label-element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/lovelace/elements/hui-state-label-element.ts b/src/panels/lovelace/elements/hui-state-label-element.ts index be5a114d7a..8b78064d82 100644 --- a/src/panels/lovelace/elements/hui-state-label-element.ts +++ b/src/panels/lovelace/elements/hui-state-label-element.ts @@ -57,7 +57,7 @@ class HuiStateLabelElement extends LitElement implements LovelaceElement { if ( this._config.attribute && - !stateObj.attributes[this._config.attribute] + !(this._config.attribute in stateObj.attributes) ) { return html` Date: Tue, 20 Apr 2021 00:48:22 +0000 Subject: [PATCH 062/106] Translation update --- translations/frontend/bg.json | 4 +++ translations/frontend/ca.json | 1 - translations/frontend/cs.json | 1 - translations/frontend/en.json | 1 - translations/frontend/es.json | 1 - translations/frontend/et.json | 1 - translations/frontend/it.json | 1 - translations/frontend/nb.json | 14 ++++++++- translations/frontend/nl.json | 1 - translations/frontend/pl.json | 49 +++++++++++++++--------------- translations/frontend/ro.json | 10 ++++++ translations/frontend/ru.json | 1 - translations/frontend/zh-Hans.json | 1 - translations/frontend/zh-Hant.json | 1 - 14 files changed, 51 insertions(+), 36 deletions(-) diff --git a/translations/frontend/bg.json b/translations/frontend/bg.json index fe7ce9984b..cfdfd6e5e9 100644 --- a/translations/frontend/bg.json +++ b/translations/frontend/bg.json @@ -1678,6 +1678,7 @@ "manage_domains": "Управление на домейни", "not_exposed": "{selected} неизложен", "not_exposed_entities": "Не изложени обекти", + "sync_to_google": "Синхронизиране на промените с Google.", "title": "Google Assistant" }, "login": { @@ -2434,6 +2435,9 @@ "spinner": "Търсене на ZHA Zigbee устройства..." }, "button": "Конфигуриране", + "cluster_attributes": { + "attributes_of_cluster": "Атрибути на избрания клъстер" + }, "clusters": { "header": "Клъстери", "introduction": "Клъстерите са градивните елементи за функционалността на Zigbee. Те разделят функционалността на логически единици. Има типове клиенти и сървъри, състоящи се от атрибути и команди." diff --git a/translations/frontend/ca.json b/translations/frontend/ca.json index c300fe59ce..7b4925368c 100644 --- a/translations/frontend/ca.json +++ b/translations/frontend/ca.json @@ -2185,7 +2185,6 @@ "no_area": "Sense àrea", "not_loaded": "No carregada", "options": "Opcions", - "provided_by_custom_component": "Proporcionada per un component personalitzat", "provided_by_custom_integration": "Proporcionada per una integració personalitzada", "reload": "Torna a carregar", "reload_confirm": "La integració s'ha tornat a carregar", diff --git a/translations/frontend/cs.json b/translations/frontend/cs.json index 55466663dd..647a8915d7 100644 --- a/translations/frontend/cs.json +++ b/translations/frontend/cs.json @@ -2184,7 +2184,6 @@ "no_area": "Žádná oblast", "not_loaded": "Nenačteno", "options": "Možnosti", - "provided_by_custom_component": "Poskytováno vlastní komponentou", "provided_by_custom_integration": "Poskytováno vlastní integrací", "reload": "Nově načíst", "reload_confirm": "Integrace byla nově načtena", diff --git a/translations/frontend/en.json b/translations/frontend/en.json index a2ef44fecc..bbb1c2814c 100644 --- a/translations/frontend/en.json +++ b/translations/frontend/en.json @@ -2185,7 +2185,6 @@ "no_area": "No Area", "not_loaded": "Not loaded", "options": "Options", - "provided_by_custom_component": "Provided by a custom component", "provided_by_custom_integration": "Provided by a custom integration", "reload": "Reload", "reload_confirm": "The integration was reloaded", diff --git a/translations/frontend/es.json b/translations/frontend/es.json index b5656e841f..35bc19a4a8 100644 --- a/translations/frontend/es.json +++ b/translations/frontend/es.json @@ -2185,7 +2185,6 @@ "no_area": "Ningún área", "not_loaded": "No se ha cargado", "options": "Opciones", - "provided_by_custom_component": "Proporcionada por un componente personalizado", "provided_by_custom_integration": "Proporcionada por una integración personalizada", "reload": "Recargar", "reload_confirm": "La integración se ha recargado", diff --git a/translations/frontend/et.json b/translations/frontend/et.json index 7221044eb7..17078d07e3 100644 --- a/translations/frontend/et.json +++ b/translations/frontend/et.json @@ -2185,7 +2185,6 @@ "no_area": "Ala puudub", "not_loaded": "Pole laaditud", "options": "Valikud", - "provided_by_custom_component": "Saadaval välise osise abil", "provided_by_custom_integration": "Saadaval välise sidumise kaudu", "reload": "Taaslae", "reload_confirm": "Sidumine on taaslaetud", diff --git a/translations/frontend/it.json b/translations/frontend/it.json index 50f40e2da5..51eac4c452 100644 --- a/translations/frontend/it.json +++ b/translations/frontend/it.json @@ -2185,7 +2185,6 @@ "no_area": "Nessuna area", "not_loaded": "Non caricato", "options": "Opzioni", - "provided_by_custom_component": "Fornito da un componente personalizzato", "provided_by_custom_integration": "Fornito da un'integrazione personalizzata", "reload": "Ricarica", "reload_confirm": "L'integrazione è stata ricaricata", diff --git a/translations/frontend/nb.json b/translations/frontend/nb.json index c653c4efa0..323e7cc569 100644 --- a/translations/frontend/nb.json +++ b/translations/frontend/nb.json @@ -2156,8 +2156,11 @@ "caption": "Integrasjoner", "config_entry": { "area": "I {area}", + "check_the_logs": "Kontroller loggene", + "configure": "Konfigurer", "delete": "Slett", "delete_confirm": "Er du sikker på at du vil slette denne integrasjonen?", + "depends_on_cloud": "Avhenger av skyen", "device_unavailable": "Enheten er utilgjengelig", "devices": "{count} {count, plural,\n one {enhet}\n other {enheter}\n}", "disable_restart_confirm": "Start Home Assistant på nytt for å fullføre deaktiveringen av denne integreringen", @@ -2180,14 +2183,23 @@ "logs": "Logger", "manuf": "av {manufacturer}", "no_area": "Intet område", - "not_loaded": "Ikke lastet inn, sjekk {logs_link}", + "not_loaded": "Ikke lastet", "options": "Alternativer", + "provided_by_custom_integration": "Levert av en tilpasset integrasjon", "reload": "Last inn på nytt", "reload_confirm": "Integrasjonen ble lastet på nytt", "reload_restart_confirm": "Start Home Assistant på nytt for å fullføre omlastingen av denne integrasjonen", "rename": "Gi nytt navn", "restart_confirm": "Start Home Assistant på nytt for å fullføre fjerningen av denne integrasjonen", "services": "{count} {count, plural,\n one {tjeneste}\n other {tjenester}\n}", + "state": { + "failed_unload": "Kan ikke laste ut", + "loaded": "Lastet", + "migration_error": "Migrasjonsfeil", + "not_loaded": "Ikke lastet", + "setup_error": "Kunne ikke konfigurere", + "setup_retry": "Prøver på nytt for å sette opp" + }, "system_options": "Systemalternativer", "unnamed_entry": "Ikke navngitt oppføring" }, diff --git a/translations/frontend/nl.json b/translations/frontend/nl.json index 32d6142dd1..a7f7995152 100644 --- a/translations/frontend/nl.json +++ b/translations/frontend/nl.json @@ -2185,7 +2185,6 @@ "no_area": "Geen Gebied", "not_loaded": "Niet geladen, controleer de {logs_link}", "options": "Opties", - "provided_by_custom_component": "Geleverd door een aangepaste component", "provided_by_custom_integration": "Geleverd door een aangepaste integratie", "reload": "Herlaad", "reload_confirm": "De integratie is opnieuw geladen", diff --git a/translations/frontend/pl.json b/translations/frontend/pl.json index 3725be380f..077fbb4cff 100644 --- a/translations/frontend/pl.json +++ b/translations/frontend/pl.json @@ -667,7 +667,7 @@ "enable": "Włącz", "error_required": "To pole jest wymagane", "leave": "Wyjdź", - "loading": "Ładowanie", + "loading": "Wczytywanie", "menu": "Menu", "next": "Dalej", "no": "Nie", @@ -694,7 +694,7 @@ "title": "Błąd podczas pobierania dodatków" }, "no_supervisor": { - "description": "Nie znaleziono Supervisora, więc nie można załadować dodatków.", + "description": "Nie znaleziono Supervisora, więc nie można wczytać dodatków.", "title": "Brak Supervisora" } } @@ -758,7 +758,7 @@ }, "history_charts": { "history_disabled": "Integracja historia wyłączona", - "loading_history": "Ładowanie historii...", + "loading_history": "Wczytywanie historii...", "no_history_found": "Nie znaleziono historii." }, "logbook": { @@ -1001,7 +1001,7 @@ "pattern": "Wyrażenie regularne do sprawdzania poprawności po stronie klienta", "text": "Pole tekstowe" }, - "platform_not_loaded": "Komponent {platform} nie jest załadowany, dodaj go do swojej konfiguracji dodając 'default_config:' lub ''{platform}:''.", + "platform_not_loaded": "Komponent {platform} nie jest wczytany, dodaj go do swojej konfiguracji dodając 'default_config:' lub ''{platform}:''.", "required_error_msg": "To pole jest wymagane", "timer": { "duration": "Czas" @@ -1220,7 +1220,7 @@ "observer": "Sprawdź obserwatora", "reboot": "Spróbuj ponownie uruchomić hosta", "system_health": "Sprawdź kondycję systemu", - "title": "Nie można załadować panelu Supervisora!", + "title": "Nie można wczytać panelu Supervisora!", "wait": "Jeśli właśnie uruchomiłeś system, upewnij się, że dałeś Supervisorowi wystarczająco dużo czasu na start." } }, @@ -1481,7 +1481,7 @@ "enable_disable": "Włącz/wyłącz automatyzację", "introduction": "Użyj automatyzacji, aby ożywić swój dom", "load_error_not_editable": "Tylko automatyzacje zdefiniowane w pliku automations.yaml są edytowalne", - "load_error_unknown": "Wystąpił błąd podczas ładowania automatyzacji ({err_no})", + "load_error_unknown": "Wystąpił błąd podczas wczytywania automatyzacji ({err_no})", "max": { "parallel": "Maksymalna liczba równoległych uruchomień", "queued": "Długość kolejki" @@ -1873,15 +1873,15 @@ "core": { "analytics": { "documentation": "Zanim to włączysz, odwiedź stronę z dokumentacją analityczną {link}, aby zrozumieć, co wysyłasz i jak to jest przechowywane.", - "header": "Analityka", + "header": "Dane analityczne", "instance_id": "Identyfikator instancji: {huuid}", "introduction": "Udostępnij informacje o instalacji, aby ulepszyć Home Assistant i pomóż nam przekonać producentów do dodania lokalnych funkcji sterowania i prywatności.", "learn_more": "Jak przetwarzamy Twoje dane", - "needs_base": "Aby ta opcja była dostępna, musisz włączyć podstawowe analityki", + "needs_base": "Aby ta opcja była dostępna, musisz włączyć podstawowe dane analityczne", "preference": { "base": { "description": "Identyfikator instancji, wersja i typ instalacji.", - "title": "Podstawowe analityki" + "title": "Podstawowe dane analityczne" }, "diagnostics": { "description": "Udostępniaj raporty o awariach, gdy wystąpią nieoczekiwane błędy.", @@ -2139,7 +2139,7 @@ "path_configuration": "Ścieżka do pliku configuration.yaml: {path}", "server": "serwer", "source": "Źródło:", - "system_health_error": "Komponent kondycji systemu nie jest załadowany. Dodaj 'system_health:' do pliku configuration.yaml", + "system_health_error": "Komponent kondycji systemu nie jest wczytany. Dodaj 'system_health:' do pliku configuration.yaml", "system_health": { "manage": "Zarządzaj", "more_info": "więcej info" @@ -2160,7 +2160,7 @@ "configure": "Konfiguruj", "delete": "Usuń", "delete_confirm": "Czy na pewno chcesz usunąć tę integrację?", - "depends_on_cloud": "Zależy od chmury", + "depends_on_cloud": "Zależny od chmury", "device_unavailable": "Urządzenie niedostępne", "devices": "{count} {count, plural,\n one {urządzenie}\n few {urządzenia}\n many {urządzeń}\n other {urządzeń}\n}", "disable_restart_confirm": "Zrestartuj Home Assistanta, aby zakończyć wyłączanie tej integracji", @@ -2183,9 +2183,8 @@ "logs": "logi", "manuf": "producent: {manufacturer}", "no_area": "brak", - "not_loaded": "Nie załadowano", + "not_loaded": "Nie wczytano", "options": "Opcje", - "provided_by_custom_component": "Dostarczone przez niestandardowy komponent", "provided_by_custom_integration": "Dostarczone przez niestandardowy komponent", "reload": "Wczytaj ponownie", "reload_confirm": "Integracja została ponownie wczytana", @@ -2194,11 +2193,11 @@ "restart_confirm": "Zrestartuj Home Assistanta, aby zakończyć usuwanie tej integracji", "services": "{count} {count, plural,\n one {usługa}\n few {usługi}\n many {usług}\n other {usług}\n}", "state": { - "failed_unload": "Nie udało się rozładować", - "loaded": "Załadowano", + "failed_unload": "Błąd usuwania", + "loaded": "Wczytano", "migration_error": "Błąd migracji", - "not_loaded": "Nie załadowano", - "setup_error": "Nie udało się skonfigurować", + "not_loaded": "Nie wczytano", + "setup_error": "Błąd konfiguracji", "setup_retry": "Próbuję ponownie skonfigurować" }, "system_options": "Opcje systemowe", @@ -2219,7 +2218,7 @@ "finish": "Zakończ", "loading_first_time": "Proszę czekać, trwa instalowanie integracji...", "not_all_required_fields": "Nie wszystkie wymagane pola są wypełnione.", - "not_loaded": "Nie udało się załadować integracji, spróbuj ponownie uruchomić Home Assistanta.", + "not_loaded": "Nie udało się wczytać integracji, spróbuj ponownie uruchomić Home Assistanta.", "pick_flow_step": { "new_flow": "Nie, skonfiguruj inną instancję integracji {integration}", "title": "Odkryliśmy je, chcesz je skonfigurować?" @@ -2279,8 +2278,8 @@ "info": "INFO", "warning": "OSTRZEŻENIE" }, - "load_full_log": "Załaduj cały log Home Assistanta", - "loading_log": "Ładowanie loga błędów…", + "load_full_log": "Wczytaj cały log Home Assistanta", + "loading_log": "Wczytywanie loga błędów…", "multiple_messages": "wiadomość pojawiła się po raz pierwszy {time} i powtarzała się {counter} razy", "no_errors": "Nie zgłoszono żadnych błędów", "no_issues": "Nie ma nowych problemów!", @@ -2439,7 +2438,7 @@ }, "node_query_stages": { "associations": "Odświeżanie grup skojarzeń i członkostwa", - "cacheload": "Ładowanie informacji z pliku pamięci podręcznej OpenZWave. Węzły baterii pozostaną na tym etapie, dopóki węzeł się nie wybudzi.", + "cacheload": "Wczytywanie informacji z pliku pamięci podręcznej OpenZWave. Węzły baterii pozostaną na tym etapie, dopóki węzeł się nie wybudzi.", "complete": "Proces odpytywania jest zakończony", "configuration": "Pobieranie wartości konfiguracyjnych z węzła", "dynamic": "Pobieranie często zmieniających się wartości z węzła", @@ -2547,7 +2546,7 @@ "icon": "Ikona", "introduction": "Użyj scen, aby ożywić swój dom.", "load_error_not_editable": "Tylko sceny zdefiniowane w pliku scenes.yaml są edytowalne", - "load_error_unknown": "Błąd ładowania sceny ({err_no})", + "load_error_unknown": "Błąd wczytywania sceny ({err_no})", "name": "Nazwa", "save": "Zapisz", "unsaved_confirm": "Masz niezapisane zmiany. Na pewno chcesz wyjść?" @@ -3126,7 +3125,7 @@ "observer": "Sprawdź obserwatora", "reboot": "Spróbuj ponownie uruchomić hosta", "system_health": "Sprawdź kondycję systemu", - "title": "Nie można załadować panelu Supervisora!", + "title": "Nie można wczytać panelu Supervisora!", "wait": "Jeśli właśnie uruchomiłeś system, upewnij się, że dałeś Supervisorowi wystarczająco dużo czasu na start." } }, @@ -3180,7 +3179,7 @@ "url": "Otwórz okno do {url_path}" }, "safe-mode": { - "description": "Podczas ładowania konfiguracji Home Assistant napotkał problemy i działa teraz w trybie awaryjnym. Zajrzyj do loga, aby sprawdzić, co poszło nie tak.", + "description": "Podczas wczytywania konfiguracji Home Assistant napotkał problemy i działa teraz w trybie awaryjnym. Zajrzyj do loga, aby sprawdzić, co poszło nie tak.", "header": "Tryb awaryjny aktywny" }, "shopping-list": { @@ -3535,7 +3534,7 @@ "error_remove": "Nie można usunąć konfiguracji: {error}", "error_save_yaml": "Nie można zapisać YAML: {error}", "header": "Edytuj konfigurację", - "lovelace_changed": "Konfiguracja Lovelace została zaktualizowana, czy chcesz załadować zaktualizowaną konfigurację do edytora i stracić obecne zmiany?", + "lovelace_changed": "Konfiguracja Lovelace została zaktualizowana, czy chcesz wczytać zaktualizowaną konfigurację do edytora i stracić obecne zmiany?", "reload": "Wczytaj ponownie", "resources_moved": "Zasoby nie powinny być już dodawane do konfiguracji Lovelace, można je dodawać w panelu konfiguracji Lovelace.", "save": "Zapisz", diff --git a/translations/frontend/ro.json b/translations/frontend/ro.json index 1278b240fd..554218de45 100644 --- a/translations/frontend/ro.json +++ b/translations/frontend/ro.json @@ -1451,6 +1451,14 @@ "description": "Sistemul de unități, locația, fusul orar și alți parametri generali", "section": { "core": { + "analytics": { + "documentation": "Inainte de activare acestuia asigurați-va ca vizitați pagina de documentare {link} pentru a înțelege ce trimiteți si cum este stocată", + "preference": { + "statistics": { + "title": "Statistici de utilizare" + } + } + }, "core_config": { "edit_requires_storage": "Editorul a fost dezactivat deoarece configurația a fost stocata în configuration.yaml.", "elevation": "Altitudine", @@ -3169,12 +3177,14 @@ "location_name": "Numele instalării Home Assistant", "location_name_default": "Acasă" }, + "finish": "Finalizare", "integration": { "finish": "Finalizați", "intro": "Dispozitivele și serviciile sunt reprezentate în Home Assistant ca integrări. Aveți posibilitatea să le configurați acum sau să le faceți mai târziu din ecranul de configurare.", "more_integrations": "Mai Mult" }, "intro": "Sunteți gata să vă treziți casa, să vă recuperați intimitatea și să vă alăturați unei comunități mondiale de creatori?", + "next": "Următorul", "restore": { "hide_log": "Ascundeți jurnalul complet", "in_progress": "Restaurare în curs", diff --git a/translations/frontend/ru.json b/translations/frontend/ru.json index 0cf7ec8a28..14e0e1b776 100644 --- a/translations/frontend/ru.json +++ b/translations/frontend/ru.json @@ -2185,7 +2185,6 @@ "no_area": "Не указано", "not_loaded": "Не загружено", "options": "Настройки", - "provided_by_custom_component": "Предоставляется кастомным компонентом", "provided_by_custom_integration": "Предоставляется кастомной интеграцией", "reload": "Перезагрузить", "reload_confirm": "Перезагрузка интеграции выполнена", diff --git a/translations/frontend/zh-Hans.json b/translations/frontend/zh-Hans.json index 885d866b82..2e9f631552 100644 --- a/translations/frontend/zh-Hans.json +++ b/translations/frontend/zh-Hans.json @@ -2185,7 +2185,6 @@ "no_area": "没有区域", "not_loaded": "未加载", "options": "选项", - "provided_by_custom_component": "由自定义组件提供", "provided_by_custom_integration": "由自定义集成提供", "reload": "重载", "reload_confirm": "集成已重新加载", diff --git a/translations/frontend/zh-Hant.json b/translations/frontend/zh-Hant.json index ae36353362..555061c6ff 100644 --- a/translations/frontend/zh-Hant.json +++ b/translations/frontend/zh-Hant.json @@ -2185,7 +2185,6 @@ "no_area": "無分區", "not_loaded": "未載入", "options": "選項", - "provided_by_custom_component": "由自訂元件提供", "provided_by_custom_integration": "由自訂整合提供", "reload": "重新載入", "reload_confirm": "整合已重新載入", From f21ed24a49f86f9b5bdc50d42d4049e3e529cd8f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 19 Apr 2021 22:58:39 -1000 Subject: [PATCH 063/106] Make error optional in connection lost service check (#8937) --- src/panels/developer-tools/service/developer-tools-service.ts | 2 +- src/state/connection-mixin.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/panels/developer-tools/service/developer-tools-service.ts b/src/panels/developer-tools/service/developer-tools-service.ts index b72fb01a40..69c6a84c43 100644 --- a/src/panels/developer-tools/service/developer-tools-service.ts +++ b/src/panels/developer-tools/service/developer-tools-service.ts @@ -282,7 +282,7 @@ class HaPanelDevService extends LitElement { } catch (err) { const [domain, service] = this._serviceData.service.split(".", 2); if ( - err.error.code === ERR_CONNECTION_LOST && + err.error?.code === ERR_CONNECTION_LOST && serviceCallWillDisconnect(domain, service) ) { return; diff --git a/src/state/connection-mixin.ts b/src/state/connection-mixin.ts index 8785f4dada..51406ad3d4 100644 --- a/src/state/connection-mixin.ts +++ b/src/state/connection-mixin.ts @@ -81,7 +81,7 @@ export const connectionMixin = >( )) as Promise; } catch (err) { if ( - err.error.code === ERR_CONNECTION_LOST && + err.error?.code === ERR_CONNECTION_LOST && serviceCallWillDisconnect(domain, service) ) { throw err; From a07220f38349dcfa41f45abc767f4eaecc6c64eb Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Tue, 20 Apr 2021 12:37:59 +0200 Subject: [PATCH 064/106] Update GitHub issue form (#8954) --- .github/ISSUE_TEMPLATE/bug_report.yml | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 2737b9a696..4a7a93564f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,8 +1,6 @@ name: Report a bug with the UI, Frontend or Lovelace -about: Report an issue related to the Home Assistant frontend. +description: Report an issue related to the Home Assistant frontend. labels: bug -title: "" -issue_body: true body: - type: markdown attributes: @@ -126,13 +124,10 @@ body: # Paste your logs here. ``` - - type: markdown + - type: textarea attributes: - value: | - ## Additional information - - type: markdown - attributes: - value: | + label: Additional information + description: > If you have any additional information for us, use the field below. - Please note, you can attach screenshots or screen recordings here, - by dragging and dropping files in the field below. + Please note, you can attach screenshots or screen recordings here, by + dragging and dropping files in the field below. From 07ce07c4a579e6776c86d5f7811b5760e69bd71d Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 21 Apr 2021 00:48:45 +0000 Subject: [PATCH 065/106] Translation update --- translations/frontend/es-419.json | 18 ++++++++++++-- translations/frontend/es.json | 12 +++++----- translations/frontend/he.json | 22 +++++++++++++---- translations/frontend/hi.json | 38 ++++++++++++++++++++++++++---- translations/frontend/lt.json | 3 ++- translations/frontend/zh-Hans.json | 2 +- 6 files changed, 76 insertions(+), 19 deletions(-) diff --git a/translations/frontend/es-419.json b/translations/frontend/es-419.json index 0ddb609097..7425cff854 100644 --- a/translations/frontend/es-419.json +++ b/translations/frontend/es-419.json @@ -2156,8 +2156,11 @@ "caption": "Integraciones", "config_entry": { "area": "En {area}", + "check_the_logs": "Compruebe los registros", + "configure": "Configurar", "delete": "Eliminar", "delete_confirm": "¿Estás seguro de que quieres eliminar esta integración?", + "depends_on_cloud": "Depende de la nube", "device_unavailable": "Dispositivo no disponible", "devices": "{count} {count, plural,\n one {dispositivo}\n other {dispositivos}\n}", "disable_restart_confirm": "Reinicie Home Assistant para terminar de deshabilitar esta integración", @@ -2180,14 +2183,23 @@ "logs": "Registros", "manuf": "por {manufacturer}", "no_area": "Ninguna área", - "not_loaded": "No se ha cargado, consulte en {logs_link}", + "not_loaded": "No cargado", "options": "Opciones", + "provided_by_custom_integration": "Proporcionado por una integración personalizada", "reload": "Recargar", "reload_confirm": "La integración se recargó", "reload_restart_confirm": "Reinicie Home Assistant para terminar de recargar esta integración", "rename": "Renombrar", "restart_confirm": "Reinicie Home Assistant para terminar de eliminar esta integración.", "services": "{count} {count, plural,\n one {service}\n other {services}\n}", + "state": { + "failed_unload": "No se pudo descargar", + "loaded": "Cargado", + "migration_error": "Error de migración", + "not_loaded": "No cargado", + "setup_error": "No se pudo configurar", + "setup_retry": "Reintentando configurar" + }, "system_options": "Opciones de Sistema", "unnamed_entry": "Entrada sin nombre" }, @@ -2255,8 +2267,10 @@ "logs": { "caption": "Registros", "clear": "Limpiar", + "custom_integration": "integración personalizada", "description": "Ver los registros de Home Assistant", "details": "Detalles del registro ({level})", + "error_from_custom_integration": "Este error se originó en una integración personalizada.", "level": { "critical": "CRÍTICO", "debug": "DEPURAR", @@ -2636,7 +2650,7 @@ "script": "Recargar scripts", "smtp": "Recargar servicios de notificación SMTP", "statistics": "Recargar entidades de estadísticas", - "telegram": "Recargar servicios de notificación de telegram", + "telegram": "Recargar servicios de notificación de Telegram", "template": "Recargar las entidades de plantilla", "trend": "Recargar entidades de tendencia", "universal": "Recargar entidades de reproductor multimedia universal", diff --git a/translations/frontend/es.json b/translations/frontend/es.json index 35bc19a4a8..1c896fdff1 100644 --- a/translations/frontend/es.json +++ b/translations/frontend/es.json @@ -287,7 +287,7 @@ "reset_defaults": "Restablecer los valores predeterminados", "reset_options": "Restablecer opciones", "restart": "Reiniciar", - "restart_name": "Reiniciar {name}", + "restart_name": "Reiniciar el {name}", "running_version": "Actualmente estás ejecutando la versión {version}", "save": "Guardar", "show_more": "Mostrar más información sobre esto", @@ -303,7 +303,7 @@ }, "restart": { "text": "¿Estás seguro de que deseas reiniciar {name}?", - "title": "Reiniciar {name}" + "title": "Reiniciar el {name}" }, "update": { "text": "¿Estás seguro de que deseas actualizar {name} a la versión {version}?", @@ -412,8 +412,8 @@ }, "system": { "core": { - "cpu_usage": "Uso de CPU principal", - "ram_usage": "Uso de RAM principal" + "cpu_usage": "Uso de CPU del core", + "ram_usage": "Uso de RAM del core" }, "host": { "change": "Cambiar", @@ -731,7 +731,7 @@ "search": "Buscar" }, "date-range-picker": { - "end_date": "Fecha de finalización", + "end_date": "Fecha de fin", "select": "Seleccionar", "start_date": "Fecha de inicio" }, @@ -2630,7 +2630,7 @@ "generic": "Entidades de cámara IP genéricas", "generic_thermostat": "Entidades de termostato genéricas", "group": "Grupos, entidades de grupo, y notificar servicios", - "heading": "Recargando la configuración YAML", + "heading": "Recarga de la configuración YAML", "history_stats": "Entidades de estadísticas del historial", "homekit": "HomeKit", "input_boolean": "Campos booleanos", diff --git a/translations/frontend/he.json b/translations/frontend/he.json index f526bcc088..679f63b41f 100644 --- a/translations/frontend/he.json +++ b/translations/frontend/he.json @@ -21,6 +21,7 @@ "logbook": "יומן אירועים", "mailbox": "תיבת דואר", "map": "מפה", + "media_browser": "סייר המדיה", "profile": "פרופיל", "shopping_list": "רשימת קניות", "states": "ראשי" @@ -505,11 +506,11 @@ }, "never": "אף פעם לא", "past_duration": { - "day": "לפני {count} {count, plural,\n one {day}\n other {days}\n}", + "day": "לפני {count} {count, plural,\n one {יום}\n other {ימים}\n}", "hour": "לפני {count} {count, plural,\n one {שעה}\n other {שעות}\n}", - "minute": "לפני {count} {count, plural,\n one {minute}\n other {minutes}\n}", - "second": "לפני {count} {count, plural,\n one {second}\n other {seconds}\n}", - "week": "לפני {count} {count, plural,\n one {week}\n other {weeks}\n}" + "minute": "לפני {count} {count, plural,\n one {דקה}\n other {דקות}\n}", + "second": "לפני {count} {count, plural,\n one {שניה}\n other {שניות}\n}", + "week": "לפני {count} {count, plural,\n one {שבוע}\n other {שבועות}\n}" } }, "service-control": { @@ -1137,6 +1138,8 @@ "unsupported_blueprint": "שרטוט זה לא נתמך", "url": "כתובת URL של השרטוט" }, + "caption": "שרטוטים", + "description": "ניהול שרטוטים", "overview": { "add_blueprint": "יבוא שרטוט", "confirm_delete_text": "האם אתה בטוח שברצונך למחוק שרטוט זה?", @@ -1600,6 +1603,13 @@ "delete_confirm": "האם אתה בטוח שברצונך למחוק אינטגרציה זו?", "device_unavailable": "מכשיר אינו זמין", "devices": "{count} {count, plural,\n one {device}\n other {devices}\n}", + "disable": { + "disabled_by": { + "device": "מכשיר", + "integration": "אינטגרציה", + "user": "משתמש" + } + }, "documentation": "תיעוד", "entities": "{count} {count, plural,\n one {entity}\n other {entities}\n}", "entity_unavailable": "ישות לא זמינה", @@ -2673,7 +2683,7 @@ "delete": "מחק תצוגה", "edit": "ערוך תצוגה", "header": "הצג הגדרות", - "header_name": "{name} הצג את תצורת", + "header_name": "הצג את תצורת {name}", "move_left": "הזז את התצוגה שמאלה", "move_right": "הזז את התצוגה ימינה", "tab_badges": "תגים", @@ -3036,9 +3046,11 @@ "header": "מודלי אימות מרובה גורמים" }, "number_format": { + "description": "בחר כיצד מוצגים מספרים.", "formats": { "comma_decimal": "1,234,567.89", "decimal_comma": "1.234.567,89", + "language": "אוטומטי (השתמש בהגדרות השפה)", "none": "לא נבחר", "space_comma": "1 234 567,89", "system": "השתמש ב System Locale" diff --git a/translations/frontend/hi.json b/translations/frontend/hi.json index e250279d81..5e66dd1958 100644 --- a/translations/frontend/hi.json +++ b/translations/frontend/hi.json @@ -106,6 +106,9 @@ }, "errors": { "supervisor": { + "ask": "मदद के लिए पूछें", + "observer": "प्रेक्षक (Observer) की जाँच करें", + "reboot": "मशीन पुनः आरंभ करने का प्रयास करें", "system_health": "उप्करन के स्वस्थ्य कि जाँच करे" } }, @@ -167,12 +170,15 @@ "picker": { "headers": { "name": "नाम" - } + }, + "no_automations": "हमें कोई AUTOMATION नहीं मिला" } }, "cloud": { "account": { "google": { + "enable_ha_skill": "Home Assistant Cloud कौशल सक्रिय करे Google Assistant के लिय", + "not_configured_title": "Google Assistant सक्रिय नहीं है", "title": "Google Assistant" }, "thank_you_note": "होम असिस्टेंट क्लाउड का हिस्सा बनने के लिए धन्यवाद। यह आप जैसे लोगों की वजह से है कि हम हर किसी के लिए एक शानदार होम ऑटोमेशन अनुभव बनाने में सक्षम हैं। धन्यवाद!" @@ -201,8 +207,16 @@ "section": { "core": { "analytics": { + "learn_more": "हम आपके जानकारी को कैसे संसाधित करते हैं", "preference": { + "diagnostics": { + "description": "अप्रत्याशित त्रुटि होने पर क्रैश रिपोर्ट साझा करें" + }, + "usage_supervisor": { + "description": "नाम, संस्करण और क्षमताएं" + }, "usage": { + "description": "नाम और संस्करण जानकारी", "title": "उप्योग किये एकीकरण" } } @@ -226,7 +240,9 @@ "failed_unload": "खाली करने मे असफल", "loaded": "तैयार", "migration_error": "प्रवसन दोष", - "not_loaded": "तैयार नहीं हैं" + "not_loaded": "तैयार नहीं हैं", + "setup_error": "एकीकरण करने में विफल", + "setup_retry": "एकीकरण के लिय पुन: प्रयास जारी है" }, "system_options": "सिस्टम विकल्प" }, @@ -238,7 +254,15 @@ "introduction": "In questa schermata è possibile configurare Home Assistant e i suoi componenti. Non è ancora possibile configurare tutto tramite l'interfaccia, ma ci stiamo lavorando.", "logs": { "custom_integration": "िशेष एकीकरण", - "error_from_custom_integration": "ये दोश िशेष एकीकरण की वजह से है" + "error_from_custom_integration": "ये दोश िशेष एकीकरण की वजह से है", + "level": { + "critical": "अभिलेख स्तर CRITICAL", + "debug": "अभिलेख स्तर DEBUG", + "error": "अभिलेख स्तर ERROR", + "info": "अभिलेख स्तर INFO", + "warning": "अभिलेख स्तर WARNING" + }, + "no_errors": "कोई त्रुटी नहीं बताई गई है" }, "mqtt": { "title": "MQTT" @@ -248,11 +272,17 @@ "unknown": "अनजान" } }, + "scene": { + "picker": { + "no_scenes": "हमें कोई SCENE नहीं मिला" + } + }, "script": { "picker": { "headers": { "name": "नाम" - } + }, + "no_scripts": "हमें कोई SCRIPT नहीं मिला" } }, "users": { diff --git a/translations/frontend/lt.json b/translations/frontend/lt.json index 8cb0fa7ce1..fef434b079 100644 --- a/translations/frontend/lt.json +++ b/translations/frontend/lt.json @@ -658,7 +658,8 @@ "integrations": { "config_entry": { "hub": "Prijungtas per", - "no_area": "Nėra srities" + "no_area": "Nėra srities", + "provided_by_custom_integration": "Teikiama naudojant pasirinktinę integraciją" }, "config_flow": { "aborted": "Nutraukta", diff --git a/translations/frontend/zh-Hans.json b/translations/frontend/zh-Hans.json index 2e9f631552..1d18ed0e2a 100644 --- a/translations/frontend/zh-Hans.json +++ b/translations/frontend/zh-Hans.json @@ -2157,7 +2157,7 @@ "config_entry": { "area": "位于:{area}", "check_the_logs": "检查日志", - "configure": "配置", + "configure": "选项", "delete": "删除", "delete_confirm": "您确定要删除此集成吗?", "depends_on_cloud": "取决于云端", From e8d1318a5b598d1b75ba2d1775eb9c40a1d2ca07 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 21 Apr 2021 19:22:56 +0200 Subject: [PATCH 066/106] Bump codemirror (#8953) Fixes #8557 --- yarn.lock | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8d389e3cf9..7b278290e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1918,9 +1918,9 @@ lezer-tree "^0.13.0" "@codemirror/gutter@^0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@codemirror/gutter/-/gutter-0.18.0.tgz#b6fb340f7cc7b4ed1a67687e145489b3ed93098d" - integrity sha512-9hcKzBM5EjhWwrau5Xiv0ll/yOvkgiyLnH7DTsjFCUvuyfbS45WVEMhQ6C+HfsoRVR4TJqRVLJjaIktZqaAqnw== + version "0.18.1" + resolved "https://registry.yarnpkg.com/@codemirror/gutter/-/gutter-0.18.1.tgz#65657be98d8c7183d23c03038a32df22dd631cc2" + integrity sha512-OJXT3giUPtMOLKmr3hHoLekEUHjLoGFA+1fIQUw7/39t4UZJr3S/1EQGI3NEPhyCg4+NCEHZJWS33x6dz5oOiA== dependencies: "@codemirror/rangeset" "^0.18.0" "@codemirror/state" "^0.18.0" @@ -2011,16 +2011,16 @@ crelt "^1.0.5" "@codemirror/state@^0.18.0", "@codemirror/state@^0.18.3": - version "0.18.5" - resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-0.18.5.tgz#db936f80c40f329fb803bd284cbb5aa556dafb88" - integrity sha512-lHR+yE08jEz7MqA5hgNvK4/ksF2mQsJJ/pedKKfB94CUobMX20tsFQ27lZbXCxZDQcz5lO0AZuFuRqrbDlRtKA== + version "0.18.6" + resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-0.18.6.tgz#46f4cabd7e635dd0f229d0ff1136d79b071354f8" + integrity sha512-jBY4KFY6RGPkuRUFXSZtgxpKebju8CJq7SkKYf+NsD8OZzDSauxPPYAL7V2z8ubvw74qLPIKIX2hERvY6WBdbg== dependencies: "@codemirror/text" "^0.18.0" "@codemirror/stream-parser@^0.18.0": - version "0.18.1" - resolved "https://registry.yarnpkg.com/@codemirror/stream-parser/-/stream-parser-0.18.1.tgz#20248b79d0fb9243a1431437dba79112c025058e" - integrity sha512-Q7HXbZRbAg5SboM0/3Hw9bKX7UxRWVsrtFjeQXzti2be/VHfMUAykidqWwWHe1SSn3Me3izpw9vLNEoGCm7tBw== + version "0.18.2" + resolved "https://registry.yarnpkg.com/@codemirror/stream-parser/-/stream-parser-0.18.2.tgz#d96ac5724650719c4a7784f2b94449366b22130e" + integrity sha512-3RTRmhIixcC2ps/G8So+BL0qJkwaspjyYt4smVYlSn4eNbxGK9K2RCnSmOPRv0SkuQMu3oUFbprFI/SbtZrPKg== dependencies: "@codemirror/highlight" "^0.18.0" "@codemirror/language" "^0.18.0" @@ -2035,9 +2035,9 @@ integrity sha512-HMzHNIAbjCiCf3tEJMRg6ul01KPuXxQGNiHlHgAnqPguq/CX+L4Nvj5JlWQAI91Pupk18zhmM1c6eaazX4YeTg== "@codemirror/view@^0.18.0": - version "0.18.6" - resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-0.18.6.tgz#3598e72658e37b30e3260e4e623a81599b67a9a0" - integrity sha512-j0TtJbV+41g/0eGH7Pgx9wtO7Y3Rg0s9shLFGvUtJ4jMIimkCelQsEBtUmfEbNxAVXOsN+CbmsKg8M9p0ISeCA== + version "0.18.8" + resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-0.18.8.tgz#e8e6b26adf427ce65356b9f1020876d7947d7953" + integrity sha512-vzP8oUBiLMbl5OCWUMGQdYtonk0tt9eUzi/xEDpYmo8Ao48/49fxPQUqBpUwy5Rcce9kUnkTi6r44iJKsEHpmg== dependencies: "@codemirror/rangeset" "^0.18.0" "@codemirror/state" "^0.18.0" @@ -9425,14 +9425,7 @@ lezer-tree@^0.13.0, lezer-tree@^0.13.2: resolved "https://registry.yarnpkg.com/lezer-tree/-/lezer-tree-0.13.2.tgz#00f4671309b15c27b131f637e430ce2d4d5f7065" integrity sha512-15ZxW8TxVNAOkHIo43Iouv4zbSkQQ5chQHBpwXcD2bBFz46RB4jYLEEww5l1V0xyIx9U2clSyyrLes+hAUFrGQ== -lezer@^0.13.0: - version "0.13.3" - resolved "https://registry.yarnpkg.com/lezer/-/lezer-0.13.3.tgz#520033a8f8be32872af1030e99ede6d9d3c6c023" - integrity sha512-DKYaqt52qx9wjxk+q+CqMMn5InqdwLrSCMqtNs+zYkl/VoTUgU8/BdmB6w/b/u7L5FCwdNybVvDS5t+1AvsD5g== - dependencies: - lezer-tree "^0.13.2" - -lezer@^0.13.4: +lezer@^0.13.0, lezer@^0.13.4: version "0.13.4" resolved "https://registry.yarnpkg.com/lezer/-/lezer-0.13.4.tgz#f0396a3447c7a8f40391623f3f47a4d95559c42f" integrity sha512-cLQxUVY28VBBqKBt/R8CYeH57KQnIvscAnoahzvhlZTK8qxMkIyGExR6ecEpYYDX06ZhROZrEm1IiPvjLAsTig== From 0b8d3568652d497fd2317839ebba880a899a6689 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 22 Apr 2021 09:46:15 -0700 Subject: [PATCH 067/106] Clean up HUI-VIEW (#8967) --- src/panels/lovelace/hui-root.ts | 2 +- src/panels/lovelace/views/hui-panel-view.ts | 5 + src/panels/lovelace/views/hui-view.ts | 189 ++++++++++---------- 3 files changed, 101 insertions(+), 95 deletions(-) diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index 2ccfc6ccc9..2dd95ba627 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -613,7 +613,7 @@ class HUIRoot extends LitElement { } if (!force && huiView) { - huiView.lovelace = this.lovelace; + huiView.lovelace = this.lovelace!; } } diff --git a/src/panels/lovelace/views/hui-panel-view.ts b/src/panels/lovelace/views/hui-panel-view.ts index 7cf3a2dc8d..515673759c 100644 --- a/src/panels/lovelace/views/hui-panel-view.ts +++ b/src/panels/lovelace/views/hui-panel-view.ts @@ -101,6 +101,11 @@ export class PanelView extends LitElement implements LovelaceViewElement { } private _createCard(): void { + if (this.cards.length === 0) { + this._card = undefined; + return; + } + const card: LovelaceCard = this.cards[0]; card.isPanel = true; diff --git a/src/panels/lovelace/views/hui-view.ts b/src/panels/lovelace/views/hui-view.ts index 666e47e1f0..100d5ef1f1 100644 --- a/src/panels/lovelace/views/hui-view.ts +++ b/src/panels/lovelace/views/hui-view.ts @@ -39,13 +39,13 @@ declare global { @customElement("hui-view") export class HUIView extends UpdatingElement { - @property({ attribute: false }) public hass?: HomeAssistant; + @property({ attribute: false }) public hass!: HomeAssistant; - @property({ attribute: false }) public lovelace?: Lovelace; + @property({ attribute: false }) public lovelace!: Lovelace; @property({ type: Boolean }) public narrow!: boolean; - @property({ type: Number }) public index?: number; + @property({ type: Number }) public index!: number; @internalProperty() private _cards: Array = []; @@ -89,127 +89,128 @@ export class HUIView extends UpdatingElement { protected updated(changedProperties: PropertyValues): void { super.updated(changedProperties); - const hass = this.hass!; - const lovelace = this.lovelace!; + /* + We need to handle the following use cases: + - initialization: create layout element, populate + - config changed to view with same layout element + - config changed to view with different layout element + - forwarded properties hass/narrow/lovelace/cards/badges change + - cards/badges change if one is rebuild when it was loaded later + - lovelace changes if edit mode is enabled or config has changed + */ - const hassChanged = changedProperties.has("hass"); - const oldLovelace = changedProperties.get("lovelace") as Lovelace; - - let editModeChanged = false; - let configChanged = false; - - if (changedProperties.has("index")) { - configChanged = true; - } else if (changedProperties.has("lovelace")) { - editModeChanged = - oldLovelace && lovelace.editMode !== oldLovelace.editMode; - configChanged = !oldLovelace || lovelace.config !== oldLovelace.config; - } - - let viewConfig: LovelaceViewConfig | undefined; + const oldLovelace = changedProperties.get("lovelace") as this["lovelace"]; + const configChanged = + changedProperties.has("index") || + (changedProperties.has("lovelace") && + (!oldLovelace || + this.lovelace.config.views[this.index] !== + oldLovelace.config.views[this.index])); + // If config has changed, create element if necessary and set all values. if (configChanged) { - viewConfig = lovelace.config.views[this.index!]; + let viewConfig = this.lovelace.config.views[this.index]; viewConfig = { ...viewConfig, type: viewConfig.panel ? PANEL_VIEW_LAYOUT : viewConfig.type || DEFAULT_VIEW_LAYOUT, }; - } - let replace = false; - - if ( - configChanged && - (!this._layoutElement || this._layoutElementType !== viewConfig!.type) - ) { - replace = true; - this._layoutElement = createViewElement(viewConfig!); - this._layoutElementType = viewConfig!.type; - this._layoutElement.addEventListener("ll-create-card", () => { - showCreateCardDialog(this, { - lovelaceConfig: this.lovelace!.config, - saveConfig: this.lovelace!.saveConfig, - path: [this.index!], - }); - }); - this._layoutElement.addEventListener("ll-edit-card", (ev) => { - showEditCardDialog(this, { - lovelaceConfig: this.lovelace!.config, - saveConfig: this.lovelace!.saveConfig, - path: ev.detail.path, - }); - }); - this._layoutElement.addEventListener("ll-delete-card", (ev) => { - confDeleteCard(this, this.hass!, this.lovelace!, ev.detail.path); - }); - } - - if (configChanged) { this._createBadges(viewConfig!); this._createCards(viewConfig!); + // Create a new layout element if necessary. + let addLayoutElement = false; + + if ( + !this._layoutElement || + this._layoutElementType !== viewConfig!.type + ) { + addLayoutElement = true; + this._createLayoutElement(viewConfig!); + } + this._layoutElement!.hass = this.hass; this._layoutElement!.narrow = this.narrow; - this._layoutElement!.lovelace = lovelace; + this._layoutElement!.lovelace = this.lovelace; this._layoutElement!.index = this.index; - } - - if (hassChanged) { - this._badges.forEach((badge) => { - badge.hass = hass; - }); - - this._cards.forEach((element) => { - element.hass = hass; - }); - - this._layoutElement!.hass = this.hass; - } - - if (changedProperties.has("narrow")) { - this._layoutElement!.narrow = this.narrow; - } - - if (editModeChanged) { - this._layoutElement!.lovelace = lovelace; - } - - if ( - configChanged || - hassChanged || - editModeChanged || - changedProperties.has("_cards") || - changedProperties.has("_badges") - ) { this._layoutElement!.cards = this._cards; this._layoutElement!.badges = this._badges; + + if (addLayoutElement) { + while (this.lastChild) { + this.removeChild(this.lastChild); + } + this.appendChild(this._layoutElement!); + } + } else { + // Config has not changed. Just props + if (changedProperties.has("hass")) { + this._badges.forEach((badge) => { + badge.hass = this.hass; + }); + + this._cards.forEach((element) => { + element.hass = this.hass; + }); + + this._layoutElement!.hass = this.hass; + } + if (changedProperties.has("narrow")) { + this._layoutElement!.narrow = this.narrow; + } + if (changedProperties.has("lovelace")) { + this._layoutElement!.lovelace = this.lovelace; + } + if (changedProperties.has("_cards")) { + this._layoutElement!.cards = this._cards; + } + if (changedProperties.has("_badges")) { + this._layoutElement!.badges = this._badges; + } } const oldHass = changedProperties.get("hass") as this["hass"] | undefined; + // Update theme if necessary: + // - If config changed, the theme could have changed + // - if hass themes preferences have changed if ( configChanged || - editModeChanged || - (hassChanged && - oldHass && - (hass.themes !== oldHass.themes || - hass.selectedTheme !== oldHass.selectedTheme)) + (changedProperties.has("hass") && + (!oldHass || + this.hass.themes !== oldHass.themes || + this.hass.selectedTheme !== oldHass.selectedTheme)) ) { applyThemesOnElement( this, - hass.themes, - lovelace.config.views[this.index!].theme + this.hass.themes, + this.lovelace.config.views[this.index].theme ); } + } - if (this._layoutElement && replace) { - while (this.lastChild) { - this.removeChild(this.lastChild); - } - this.appendChild(this._layoutElement); - } + private _createLayoutElement(config: LovelaceViewConfig): void { + this._layoutElement = createViewElement(config); + this._layoutElementType = config.type; + this._layoutElement.addEventListener("ll-create-card", () => { + showCreateCardDialog(this, { + lovelaceConfig: this.lovelace!.config, + saveConfig: this.lovelace!.saveConfig, + path: [this.index], + }); + }); + this._layoutElement.addEventListener("ll-edit-card", (ev) => { + showEditCardDialog(this, { + lovelaceConfig: this.lovelace!.config, + saveConfig: this.lovelace!.saveConfig, + path: ev.detail.path, + }); + }); + this._layoutElement.addEventListener("ll-delete-card", (ev) => { + confDeleteCard(this, this.hass!, this.lovelace!, ev.detail.path); + }); } private _createBadges(config: LovelaceViewConfig): void { From 5f78f18cb4d3b708a329aa400e1a358d14853459 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 22 Apr 2021 12:01:09 -0700 Subject: [PATCH 068/106] Fix rendering of a choose without any action taken (#8952) --- src/components/trace/hat-trace-timeline.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/trace/hat-trace-timeline.ts b/src/components/trace/hat-trace-timeline.ts index a17cb3c81e..49898be86f 100644 --- a/src/components/trace/hat-trace-timeline.ts +++ b/src/components/trace/hat-trace-timeline.ts @@ -314,16 +314,18 @@ class ActionRenderer { if (defaultExecuted) { this._renderEntry(choosePath, `${name}: Default action executed`); - } else { + } else if (chooseTrace.result) { const choiceConfig = this._getDataFromPath( - `${this.keys[index]}/choose/${chooseTrace.result?.choice}` + `${this.keys[index]}/choose/${chooseTrace.result.choice}` ) as ChooseActionChoice | undefined; const choiceName = choiceConfig ? `${ - choiceConfig.alias || `Choice ${chooseTrace.result?.choice}` + choiceConfig.alias || `Choice ${chooseTrace.result.choice}` } executed` : `Error: ${chooseTrace.error}`; this._renderEntry(choosePath, `${name}: ${choiceName}`); + } else { + this._renderEntry(choosePath, `${name}: No action taken`); } let i; From c296a60babaefd691b724e1d5f4df9b7261cc5f0 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 23 Apr 2021 00:48:28 +0000 Subject: [PATCH 069/106] Translation update --- translations/frontend/bg.json | 11 +++- translations/frontend/he.json | 108 ++++++++++++++++++++++++++++++++-- 2 files changed, 114 insertions(+), 5 deletions(-) diff --git a/translations/frontend/bg.json b/translations/frontend/bg.json index cfdfd6e5e9..e68d0280bc 100644 --- a/translations/frontend/bg.json +++ b/translations/frontend/bg.json @@ -180,6 +180,7 @@ "new_update_available": "{name} {version} е налично", "not_available_arch": "Тази добавка не е съвместима с процесора на вашето устройство или операционната система, която сте инсталирали на вашето устройство.", "not_available_version": "Изпълнявате Home Assistant {core_version_installed}, за да актуализирате до тази версия на добавката ви е необходима поне версия {core_version_needed} на Home Assistant", + "open_web_ui": "Отваряне на потребителския WEB интерфейс", "option": { "auto_update": { "description": "Автоматично актуализиране на добавката, когато има налична нова версия", @@ -1967,6 +1968,8 @@ "copy_github": "За GitHub", "description": "Версия, състояние на системата и връзки към документация", "documentation": "Документация", + "frontend": "Интерфейс", + "frontend_version": "Версия на интерфейса: {version} - {type}", "home_assistant_logo": "Лого на Home Assistant", "icons_by": "Икони от", "integrations": "Интеграции", @@ -2017,6 +2020,9 @@ "rename": "Преименуване", "restart_confirm": "Рестартирайте Home Assistant за да завършите премахването на интеграцията", "services": "{count} {count, plural,\n one {услуга}\n other {услуги}\n}", + "state": { + "migration_error": "Грешка при миграцията" + }, "system_options": "Системни настройки", "unnamed_entry": "Запис без име" }, @@ -2077,6 +2083,7 @@ "load_full_log": "Зареждане на пълния журнал на Home Assistant", "loading_log": "Зарежда се журнала за грешки...", "multiple_messages": "съобщението е възникнало за първи път в {time} и се показва {counter} пъти", + "no_issues": "Няма нови проблеми!", "refresh": "Опресняване" }, "lovelace": { @@ -2507,8 +2514,10 @@ "zwave_js": { "button": "Конфигуриране", "common": { + "add_node": "Добавяне на възел", "close": "Затвори", - "network": "Мрежа" + "network": "Мрежа", + "remove_node": "Премахване на възел" }, "dashboard": { "driver_version": "Версия на драйвера", diff --git a/translations/frontend/he.json b/translations/frontend/he.json index 679f63b41f..94063e9b06 100644 --- a/translations/frontend/he.json +++ b/translations/frontend/he.json @@ -105,14 +105,34 @@ "supervisor": { "addon": { "dashboard": { + "action_error": { + "get_changelog": "קבלת יומן שינויים של התוסף נכשלה", + "validate_config": "אימות תצורת התוסף נכשל" + }, "not_available_version": "אתה מפעיל את Home Assistant {core_version_installed} , כדי לעדכן לגרסה זו של התוסף אתה זקוק לפחות לגרסה {core_version_needed} של Home Assistant", "visit_addon_page": "בקר בדף {name} לפרטים נוספים" + }, + "documentation": { + "get_documentation": "קבלת תיעוד התוסף נכשלה, {error}" + }, + "logs": { + "get_logs": "קבלת יומני התוסף נכשלה, {error}" } }, "common": { "cancel": "בטל", "close": "סגור", - "save": "שמור" + "description": "תיאור", + "failed_to_restart_name": "אתחול {name} נכשל.", + "failed_to_update_name": "עדכון {name} נכשל.", + "learn_more": "למד עוד", + "new_version_available": "גרסה חדשה זמינה", + "no": "לא", + "refresh": "רענן", + "reload": "טען מחדש", + "reset_defaults": "אפס לברירות מחדל", + "save": "שמור", + "yes": "כן" }, "confirm": { "update": { @@ -170,23 +190,66 @@ "error_addon_not_found": "התוסף לא נמצא" }, "snapshot": { + "addons": "תוספים", + "available_snapshots": "גיבויים זמינים", + "could_not_create": "לא ניתן ליצור גיבוי", + "create": "צור", + "create_blocked_not_running": "יצירת גיבוי אינה אפשרית כרגע מכיוון שהמערכת במצב {state} .", + "create_snapshot": "צור גיבוי", + "enter_password": "נא הזן סיסמה.", "folder": { "addons/local": "תוספות מקומיות", + "homeassistant": "תצורת Home Assistant", "media": "תוכן", "share": "שיתוף", "ssl": "SSL" - } + }, + "folders": "תיקיות", + "full_snapshot": "גיבוי מלא", + "name": "שם", + "no_snapshots": "אין לך גיבויים כרגע.", + "partial_snapshot": "גיבוי חלקי", + "password": "סיסמה", + "password_protected": "מוגן באמצעות סיסמה", + "password_protection": "הגנה באמצעות סיסמה", + "security": "אבטחה", + "type": "סוּג", + "upload_snapshot": "טען גיבוי" }, "system": { + "host": { + "change_hostname": "שנה שם מכונה", + "failed_to_get_hardware_list": "קבלת רשימת החומרה נכשלה", + "failed_to_import_from_usb": "ייבוא מ- USB נכשל", + "failed_to_reboot": "אתחול המכונה נכשל", + "failed_to_set_hostname": "הגדרת שם המכונה נכשלה", + "failed_to_shutdown": "כיבוי המכונה נכשל", + "hostname": "שם מכונה", + "ip_address": "כתובת IP", + "new_hostname": "אנא הזן שם מכונה חדש:", + "used_space": "שטח בשימוש" + }, "supervisor": { "beta_backup": "ודא שיש לך גיבויים של הנתונים לפני הפעלת תכונה זו.", "beta_join_confirm": "האם אתה רוצה להצטרף לערוץ הבטא?", "beta_release_items": "זה כולל גרסאות בטא עבור:", "beta_warning": "גרסאות בטא מיועדות לבודקים ומאמצים מוקדמים ויכולות להכיל שינויי קוד לא יציבים", + "channel": "עָרוּץ", + "join_beta_action": "הצטרף לערוץ בטא", + "join_beta_description": "קבל עדכוני בטא עבור Home Assistant, Supervisor ומערכת ההפעלה", + "leave_beta_action": "עזוב את ערוץ הבטא", + "leave_beta_description": "קבל עדכונים יציבים עבור Home Assistant, Supervisor ומערכת ההפעלה", "reload_supervisor": "טען מחדש את ה Supervisor", + "share_diagnostics": "שתף מידע אבחוני", + "share_diagnostics_description": "שתף דוחות קריסה ומידע אבחוני.", "share_diagonstics_description": "האם ברצונך לשתף באופן אוטומטי דוחות קריסה ומידע אבחון כאשר ה Supervisor נתקל בשגיאות בלתי צפויות? {line_break} זה יאפשר לנו לתקן את הבעיות, המידע נגיש רק לצוות הליבה של Home Assistant ולא ישותף עם אחרים. {line_break} הנתונים אינם כוללים מידע פרטי/רגיש ובאפשרותך להפוך מידע זה ללא זמין בהגדרות בכל עת שתרצה.", "share_diagonstics_title": "עזור לשפר את Home Assistant", + "unhealthy_description": "הפעלת התקנה לא בריאה תגרום לבעיות. להלן רשימת הבעיות שנמצאו בהתקנה שלך, לחץ על הקישורים כדי ללמוד כיצד תוכל לפתור את הבעיות.", "unhealthy_reason": { + "docker": "סביבת ה- Docker אינה פועלת כראוי", + "privileged": "ל Supervisor אין הרשאות", + "setup": "הגדרת ה Supervisor נכשלה", + "supervisor": "עדכון ה Supervisor לא הצליח", "untrusted": "זוהה תוכן לא מהימן" }, "unsupported_reason": { @@ -194,8 +257,16 @@ "container": "ה Container ידוע כבעייתי", "content-trust": "אימות אמון תוכן מושבת", "dbus": "DBUS", - "docker_configuration": "תצורת Docker" + "docker_configuration": "תצורת Docker", + "docker_version": "גרסת Docker", + "job_conditions": "התעלם מתנאי ה Job", + "lxc": "LXC", + "network_manager": "מנהל רשת", + "os": "מערכת הפעלה", + "privileged": "ל Supervisor אין הרשאות", + "systemd": "Systemd" }, + "update_supervisor": "עדכן את ה Supervisor", "warning": "אזהרה" } } @@ -399,6 +470,9 @@ "today": "היום" }, "data-table": { + "clear": "נקה", + "filtering_by": "סינון לפי", + "hidden": "{number} חבוי", "no-data": "אין נתונים", "search": "חיפוש" }, @@ -686,6 +760,11 @@ "perform_action": "{action} שרת", "restart": "הפעל מחדש", "stop": "עצור" + }, + "types": { + "navigation": "ניווט", + "reload": "טען מחדש", + "server_control": "שרת" } }, "filter_placeholder": "מסנן ישויות" @@ -1599,8 +1678,11 @@ "caption": "אינטגרציות", "config_entry": { "area": "ב-{area}", + "check_the_logs": "בדוק את היומנים", + "configure": "הגדר", "delete": "מחק", "delete_confirm": "האם אתה בטוח שברצונך למחוק אינטגרציה זו?", + "depends_on_cloud": "תלוי בענן", "device_unavailable": "מכשיר אינו זמין", "devices": "{count} {count, plural,\n one {device}\n other {devices}\n}", "disable": { @@ -1620,8 +1702,17 @@ "no_area": "ללא אזור", "not_loaded": "לא נטען, בדוק את {logs_link}", "options": "אפשרויות", + "provided_by_custom_integration": "מסופק על ידי אינטגרציה מותאמת אישית", "rename": "שנה שם", "restart_confirm": "הפעל מחדש את Home Assistant כדי להשלים את הסרת האינטגרציה", + "state": { + "failed_unload": "ביטול הטעינה נכשל", + "loaded": "טעון", + "migration_error": "שגיאת המרה", + "not_loaded": "לא טעון", + "setup_error": "ההגדרה נכשלה", + "setup_retry": "מנסה להגדיר מחדש" + }, "system_options": "אפשרויות מערכת", "unnamed_entry": "ערך ללא שם" }, @@ -1645,6 +1736,9 @@ "configured": "הוגדר", "description": "ניהול והגדרת אינטגרציות", "details": "פרטי האינטגרציה", + "disable": { + "show": "הצג" + }, "discovered": "זוהו", "home_assistant_website": "אתר Home Assistant", "ignore": { @@ -1675,8 +1769,10 @@ "logs": { "caption": "יומנים", "clear": "נקה", + "custom_integration": "אינטגרציה מותאמת אישית", "description": "צפה ביומני Home Assistant", "details": "פרטי יומן האירועים ({level})", + "error_from_custom_integration": "מקור השגיאה הזו הוא אינטגרציה מותאמת אישית.", "level": { "critical": "CRITICAL", "debug": "DEBUG", @@ -2195,6 +2291,7 @@ "node_config": { "attribution": "פרמטרים ותיאורי תצורת המכשיר מסופקים על ידי {device_database}", "battery_device_notice": "התקני סוללה חייבים להיות ערים כדי לעדכן את תצורתם. נא עיין במדריך למשתמש לקבלת הוראות כיצד להעיר את ההתקן.", + "error_device_not_found": "ההתקן לא נמצא", "header": "תצורת מכשיר Z-Wave", "introduction": "נהל והתאם פרמטרי תצורה ספציפיים למכשיר (צומת) עבור ההתקן שנבחר", "parameter_is_read_only": "פרמטר זה מוגדר לקריאה בלבד.", @@ -2321,6 +2418,7 @@ "column_parameter": "פרמטר", "description": "כלי הפיתוח של השירותים מאפשר לך לקרוא לכל שירות ב Home Assistant.", "fill_example_data": "מלא נתונים לדוגמה", + "no_template_ui_support": "ממשק המשתמש אינו תומך בתבניות, עדיין תוכל להשתמש בעורך ה YAML.", "title": "שירותים" }, "states": { @@ -3047,6 +3145,7 @@ }, "number_format": { "description": "בחר כיצד מוצגים מספרים.", + "dropdown_label": "פורמט מספר", "formats": { "comma_decimal": "1,234,567.89", "decimal_comma": "1.234.567,89", @@ -3054,7 +3153,8 @@ "none": "לא נבחר", "space_comma": "1 234 567,89", "system": "השתמש ב System Locale" - } + }, + "header": "פורמט מספר" }, "push_notifications": { "add_device_prompt": { From 3f21c87a3d9063a7923828f4b5d64ce24d42be8c Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 23 Apr 2021 00:25:09 -0700 Subject: [PATCH 070/106] Allow config entries to show the reason (#8974) --- gallery/src/demos/demo-integration-card.ts | 6 ++++++ src/data/config_entries.ts | 1 + .../config/integrations/ha-integration-card.ts | 18 ++++++++++-------- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/gallery/src/demos/demo-integration-card.ts b/gallery/src/demos/demo-integration-card.ts index e8c1694700..35c6b46b3b 100644 --- a/gallery/src/demos/demo-integration-card.ts +++ b/gallery/src/demos/demo-integration-card.ts @@ -39,6 +39,7 @@ const createConfigEntry = ( supports_options: false, supports_unload: true, disabled_by: null, + reason: null, ...override, }); @@ -76,6 +77,10 @@ const migrationErrorEntry = createConfigEntry("Migration Error", { const setupRetryEntry = createConfigEntry("Setup Retry", { state: "setup_retry", }); +const setupRetryReasonEntry = createConfigEntry("Setup Retry", { + state: "setup_retry", + reason: "Unable to connect", +}); const failedUnloadEntry = createConfigEntry("Failed Unload", { state: "failed_unload", }); @@ -135,6 +140,7 @@ const configEntries: Array<{ { items: [setupErrorEntry] }, { items: [migrationErrorEntry] }, { items: [setupRetryEntry] }, + { items: [setupRetryReasonEntry] }, { items: [failedUnloadEntry] }, { items: [notLoadedEntry] }, { diff --git a/src/data/config_entries.ts b/src/data/config_entries.ts index 603aab6d06..9bb203c942 100644 --- a/src/data/config_entries.ts +++ b/src/data/config_entries.ts @@ -16,6 +16,7 @@ export interface ConfigEntry { supports_options: boolean; supports_unload: boolean; disabled_by: "user" | null; + reason: string | null; } export interface ConfigEntryMutableParams { diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index d4f64bb232..934a2f4f11 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -199,14 +199,16 @@ export class HaIntegrationCard extends LitElement { stateText = [ `ui.panel.config.integrations.config_entry.state.${item.state}`, ]; - stateTextExtra = html` -
      -
      ${this.hass.localize( - "ui.panel.config.integrations.config_entry.check_the_logs" - )} - `; + stateTextExtra = item.reason + ? html`: ${item.reason}` + : html` +
      + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.check_the_logs" + )} + `; } return html` From 899eab4e5c9b306d785cb5ed7945edcc78c4e1aa Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Fri, 23 Apr 2021 09:29:03 +0200 Subject: [PATCH 071/106] Ensure 0 does not get formatted to empty string (#8971) --- src/common/string/format_number.ts | 2 +- test-mocha/common/string/format_number.ts | 50 +++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/common/string/format_number.ts b/src/common/string/format_number.ts index 0f171bd0ea..da8af2798a 100644 --- a/src/common/string/format_number.ts +++ b/src/common/string/format_number.ts @@ -58,7 +58,7 @@ export const formatNumber = ( ).format(Number(num)); } } - return num ? num.toString() : ""; + return num.toString(); }; /** diff --git a/test-mocha/common/string/format_number.ts b/test-mocha/common/string/format_number.ts index efd1461bc8..903be54cb0 100644 --- a/test-mocha/common/string/format_number.ts +++ b/test-mocha/common/string/format_number.ts @@ -15,6 +15,56 @@ describe("formatNumber", () => { ); }); + it("Test format 'none' (keep dot despite language 'de')", () => { + assert.strictEqual( + formatNumber(1.23, { + language: "de", + number_format: NumberFormat.none, + }), + "1.23" + ); + }); + + it("Ensure zero is kept for format 'language'", () => { + assert.strictEqual( + formatNumber(0, { + language: "en", + number_format: NumberFormat.language, + }), + "0" + ); + }); + + it("Ensure zero is kept for format 'none'", () => { + assert.strictEqual( + formatNumber(0, { + language: "en", + number_format: NumberFormat.none, + }), + "0" + ); + }); + + it("Test empty string input for format 'none'", () => { + assert.strictEqual( + formatNumber("", { + language: "en", + number_format: NumberFormat.none, + }), + "" + ); + }); + + it("Test empty string input for format 'language'", () => { + assert.strictEqual( + formatNumber("", { + language: "en", + number_format: NumberFormat.language, + }), + "0" + ); + }); + it("Formats number with options", () => { assert.strictEqual( formatNumber( From b599417a37a7095f4260c68731a8d3225955e1c0 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 23 Apr 2021 00:30:17 -0700 Subject: [PATCH 072/106] Improve rendering status text on integration cards (#8973) --- .../integrations/ha-integration-card.ts | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index 934a2f4f11..55687a48d2 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -212,14 +212,17 @@ export class HaIntegrationCard extends LitElement { } return html` -
      - ${stateText - ? html` -
      + ${stateText + ? html` +
      + +
      ${this.hass.localize(...stateText)}${stateTextExtra}
      - ` - : ""} +
      + ` + : ""} +
      ${devices.length || services.length || entities.length ? html`
      @@ -621,8 +624,17 @@ export class HaIntegrationCard extends LitElement { .message { font-weight: bold; padding-bottom: 16px; + display: flex; + margin-left: 40px; + } + .message ha-svg-icon { color: var(--state-message-color); } + .message div { + flex: 1; + margin-left: 8px; + padding-top: 2px; + } .content { flex: 1; From 63e10314bd17b0cf8f713ac8c1cb066a171693ee Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 23 Apr 2021 09:36:45 -0700 Subject: [PATCH 073/106] Sketch out strategies (#8959) Co-authored-by: Zack Arnett --- cast/src/receiver/layout/hc-lovelace.ts | 1 + cast/src/receiver/layout/hc-main.ts | 12 +- src/data/lovelace.ts | 9 + src/panels/lovelace/cards/hui-error-card.ts | 15 +- .../common/generate-lovelace-config.ts | 177 +----------------- .../create-element/create-view-element.ts | 3 +- .../lovelace/editor/hui-dialog-save-config.ts | 33 +++- .../editor/show-save-config-dialog.ts | 1 + src/panels/lovelace/ha-panel-lovelace.ts | 111 +++++++++-- src/panels/lovelace/hui-editor.ts | 2 +- src/panels/lovelace/hui-root.ts | 20 +- .../lovelace/strategies/get-strategy.ts | 158 ++++++++++++++++ .../strategies/original-states-strategy.ts | 94 ++++++++++ src/panels/lovelace/types.ts | 2 + src/panels/lovelace/views/hui-masonry-view.ts | 4 +- src/panels/lovelace/views/hui-panel-view.ts | 4 +- src/panels/lovelace/views/hui-view.ts | 141 +++++++------- src/types.ts | 9 + 18 files changed, 509 insertions(+), 287 deletions(-) create mode 100644 src/panels/lovelace/strategies/get-strategy.ts create mode 100644 src/panels/lovelace/strategies/original-states-strategy.ts diff --git a/cast/src/receiver/layout/hc-lovelace.ts b/cast/src/receiver/layout/hc-lovelace.ts index be23073207..ba94b42394 100644 --- a/cast/src/receiver/layout/hc-lovelace.ts +++ b/cast/src/receiver/layout/hc-lovelace.ts @@ -35,6 +35,7 @@ class HcLovelace extends LitElement { } const lovelace: Lovelace = { config: this.lovelaceConfig, + rawConfig: this.lovelaceConfig, editMode: false, urlPath: this.urlPath!, enableFullEditMode: () => undefined, diff --git a/cast/src/receiver/layout/hc-main.ts b/cast/src/receiver/layout/hc-main.ts index e035d5dd4e..e8623dfa65 100644 --- a/cast/src/receiver/layout/hc-main.ts +++ b/cast/src/receiver/layout/hc-main.ts @@ -221,11 +221,17 @@ export class HcMain extends HassElement { } private async _generateLovelaceConfig() { - const { generateLovelaceConfigFromHass } = await import( - "../../../../src/panels/lovelace/common/generate-lovelace-config" + const { generateLovelaceDashboardStrategy } = await import( + "../../../../src/panels/lovelace/strategies/get-strategy" ); this._handleNewLovelaceConfig( - await generateLovelaceConfigFromHass(this.hass!) + await generateLovelaceDashboardStrategy( + { + hass: this.hass!, + narrow: false, + }, + "original-states" + ) ); } diff --git a/src/data/lovelace.ts b/src/data/lovelace.ts index 89611b44ef..48bff25ffb 100644 --- a/src/data/lovelace.ts +++ b/src/data/lovelace.ts @@ -19,6 +19,10 @@ export interface LovelacePanelConfig { export interface LovelaceConfig { title?: string; + strategy?: { + name: string; + options?: Record; + }; views: LovelaceViewConfig[]; background?: string; } @@ -77,6 +81,10 @@ export interface LovelaceViewConfig { index?: number; title?: string; type?: string; + strategy?: { + name: string; + options?: Record; + }; badges?: Array; cards?: LovelaceCardConfig[]; path?: string; @@ -94,6 +102,7 @@ export interface LovelaceViewElement extends HTMLElement { index?: number; cards?: Array; badges?: LovelaceBadge[]; + isStrategy: boolean; setConfig(config: LovelaceViewConfig): void; } diff --git a/src/panels/lovelace/cards/hui-error-card.ts b/src/panels/lovelace/cards/hui-error-card.ts index 7739390717..1e9b0fc779 100644 --- a/src/panels/lovelace/cards/hui-error-card.ts +++ b/src/panels/lovelace/cards/hui-error-card.ts @@ -31,11 +31,18 @@ export class HuiErrorCard extends LitElement implements LovelaceCard { return html``; } + let dumped: string | undefined; + + if (this._config.origConfig) { + try { + dumped = safeDump(this._config.origConfig); + } catch (err) { + dumped = `[Error dumping ${this._config.origConfig}]`; + } + } + return html` - ${this._config.error} - ${this._config.origConfig - ? html`
      ${safeDump(this._config.origConfig)}
      ` - : ""} + ${this._config.error}${dumped ? html`
      ${dumped}
      ` : ""} `; } diff --git a/src/panels/lovelace/common/generate-lovelace-config.ts b/src/panels/lovelace/common/generate-lovelace-config.ts index 4251172c82..e07ac79bc5 100644 --- a/src/panels/lovelace/common/generate-lovelace-config.ts +++ b/src/panels/lovelace/common/generate-lovelace-config.ts @@ -1,41 +1,16 @@ -import { - HassEntities, - HassEntity, - STATE_NOT_RUNNING, -} from "home-assistant-js-websocket"; -import { isComponentLoaded } from "../../../common/config/is_component_loaded"; -import { DEFAULT_VIEW_ENTITY_ID } from "../../../common/const"; +import { HassEntities, HassEntity } from "home-assistant-js-websocket"; import { computeDomain } from "../../../common/entity/compute_domain"; -import { computeObjectId } from "../../../common/entity/compute_object_id"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateName } from "../../../common/entity/compute_state_name"; -import { extractViews } from "../../../common/entity/extract_views"; -import { getViewEntities } from "../../../common/entity/get_view_entities"; import { splitByGroups } from "../../../common/entity/split_by_groups"; import { compare } from "../../../common/string/compare"; import { LocalizeFunc } from "../../../common/translations/localize"; -import { subscribeOne } from "../../../common/util/subscribe-one"; -import { - AreaRegistryEntry, - subscribeAreaRegistry, -} from "../../../data/area_registry"; -import { - DeviceRegistryEntry, - subscribeDeviceRegistry, -} from "../../../data/device_registry"; -import { - EntityRegistryEntry, - subscribeEntityRegistry, -} from "../../../data/entity_registry"; -import { GroupEntity } from "../../../data/group"; +import type { AreaRegistryEntry } from "../../../data/area_registry"; +import type { DeviceRegistryEntry } from "../../../data/device_registry"; +import type { EntityRegistryEntry } from "../../../data/entity_registry"; import { domainToName } from "../../../data/integration"; -import { - LovelaceCardConfig, - LovelaceConfig, - LovelaceViewConfig, -} from "../../../data/lovelace"; +import { LovelaceCardConfig, LovelaceViewConfig } from "../../../data/lovelace"; import { SENSOR_DEVICE_CLASS_BATTERY } from "../../../data/sensor"; -import { HomeAssistant } from "../../../types"; import { AlarmPanelCardConfig, EntitiesCardConfig, @@ -57,8 +32,6 @@ const HIDE_DOMAIN = new Set([ const HIDE_PLATFORM = new Set(["mobile_app"]); -let subscribedRegistries = false; - interface SplittedByAreas { areasWithEntities: Array<[AreaRegistryEntry, HassEntity[]]>; otherEntities: HassEntities; @@ -239,7 +212,7 @@ const computeDefaultViewStates = ( return states; }; -const generateViewConfig = ( +export const generateViewConfig = ( localize: LocalizeFunc, path: string, title: string | undefined, @@ -373,141 +346,3 @@ export const generateDefaultViewConfig = ( return config; }; - -export const generateLovelaceConfigFromData = async ( - hass: HomeAssistant, - areaEntries: AreaRegistryEntry[], - deviceEntries: DeviceRegistryEntry[], - entityEntries: EntityRegistryEntry[], - entities: HassEntities, - localize: LocalizeFunc -): Promise => { - if (hass.config.safe_mode) { - return { - title: hass.config.location_name, - views: [ - { - cards: [{ type: "safe-mode" }], - }, - ], - }; - } - - const viewEntities = extractViews(entities); - - const views = viewEntities.map((viewEntity: GroupEntity) => { - const states = getViewEntities(entities, viewEntity); - - // In the case of a normal view, we use group order as specified in view - const groupOrders = {}; - Object.keys(states).forEach((entityId, idx) => { - groupOrders[entityId] = idx; - }); - - return generateViewConfig( - localize, - computeObjectId(viewEntity.entity_id), - computeStateName(viewEntity), - viewEntity.attributes.icon, - states, - groupOrders - ); - }); - - let title = hass.config.location_name; - - // User can override default view. If they didn't, we will add one - // that contains all entities. - if ( - viewEntities.length === 0 || - viewEntities[0].entity_id !== DEFAULT_VIEW_ENTITY_ID - ) { - views.unshift( - generateDefaultViewConfig( - areaEntries, - deviceEntries, - entityEntries, - entities, - localize - ) - ); - - // Add map of geo locations to default view if loaded - if (isComponentLoaded(hass, "geo_location")) { - if (views[0] && views[0].cards) { - views[0].cards.push({ - type: "map", - geo_location_sources: ["all"], - }); - } - } - - // Make sure we don't have Home as title and first tab. - if (views.length > 1 && title === "Home") { - title = "Home Assistant"; - } - } - - // User has no entities - if (views.length === 1 && views[0].cards!.length === 0) { - views[0].cards!.push({ - type: "empty-state", - }); - } - - return { - title, - views, - }; -}; - -export const generateLovelaceConfigFromHass = async ( - hass: HomeAssistant, - localize?: LocalizeFunc -): Promise => { - if (hass.config.state === STATE_NOT_RUNNING) { - return { - title: hass.config.location_name, - views: [ - { - cards: [{ type: "starting" }], - }, - ], - }; - } - - if (hass.config.safe_mode) { - return { - title: hass.config.location_name, - views: [ - { - cards: [{ type: "safe-mode" }], - }, - ], - }; - } - - // We want to keep the registry subscriptions alive after generating the UI - // so that we don't serve up stale data after changing areas. - if (!subscribedRegistries) { - subscribedRegistries = true; - subscribeAreaRegistry(hass.connection, () => undefined); - subscribeDeviceRegistry(hass.connection, () => undefined); - subscribeEntityRegistry(hass.connection, () => undefined); - } - - const [areaEntries, deviceEntries, entityEntries] = await Promise.all([ - subscribeOne(hass.connection, subscribeAreaRegistry), - subscribeOne(hass.connection, subscribeDeviceRegistry), - subscribeOne(hass.connection, subscribeEntityRegistry), - ]); - - return generateLovelaceConfigFromData( - hass, - areaEntries, - deviceEntries, - entityEntries, - hass.states, - localize || hass.localize - ); -}; diff --git a/src/panels/lovelace/create-element/create-view-element.ts b/src/panels/lovelace/create-element/create-view-element.ts index d8cec5fa48..3e5b69b612 100644 --- a/src/panels/lovelace/create-element/create-view-element.ts +++ b/src/panels/lovelace/create-element/create-view-element.ts @@ -2,6 +2,7 @@ import { LovelaceViewConfig, LovelaceViewElement, } from "../../../data/lovelace"; +import { HuiErrorCard } from "../cards/hui-error-card"; import "../views/hui-masonry-view"; import { createLovelaceElement } from "./create-element-base"; @@ -13,7 +14,7 @@ const LAZY_LOAD_LAYOUTS = { export const createViewElement = ( config: LovelaceViewConfig -): LovelaceViewElement => { +): LovelaceViewElement | HuiErrorCard => { return createLovelaceElement( "view", config, diff --git a/src/panels/lovelace/editor/hui-dialog-save-config.ts b/src/panels/lovelace/editor/hui-dialog-save-config.ts index 3cf9fae524..acf32993e4 100644 --- a/src/panels/lovelace/editor/hui-dialog-save-config.ts +++ b/src/panels/lovelace/editor/hui-dialog-save-config.ts @@ -19,13 +19,15 @@ import "../../../components/ha-formfield"; import "../../../components/ha-svg-icon"; import "../../../components/ha-switch"; import "../../../components/ha-yaml-editor"; +import type { LovelaceConfig } from "../../../data/lovelace"; import type { HassDialog } from "../../../dialogs/make-dialog-manager"; import { haStyleDialog } from "../../../resources/styles"; import type { HomeAssistant } from "../../../types"; import { documentationUrl } from "../../../util/documentation-url"; +import { expandLovelaceConfigStrategies } from "../strategies/get-strategy"; import type { SaveDialogParams } from "./show-save-config-dialog"; -const EMPTY_CONFIG = { views: [] }; +const EMPTY_CONFIG: LovelaceConfig = { views: [{ title: "Home" }] }; @customElement("hui-dialog-save-config") export class HuiSaveConfig extends LitElement implements HassDialog { @@ -125,14 +127,17 @@ export class HuiSaveConfig extends LitElement implements HassDialog {
      ${this._params.mode === "storage" ? html` - ${this.hass!.localize( - "ui.common.cancel" - )} - + ${this._saving @@ -148,11 +153,13 @@ export class HuiSaveConfig extends LitElement implements HassDialog { ` : html` - ${this.hass!.localize( + + @click=${this.closeDialog} + > `} `; @@ -177,7 +184,13 @@ export class HuiSaveConfig extends LitElement implements HassDialog { try { const lovelace = this._params!.lovelace; await lovelace.saveConfig( - this._emptyConfig ? EMPTY_CONFIG : lovelace.config + this._emptyConfig + ? EMPTY_CONFIG + : await expandLovelaceConfigStrategies({ + config: lovelace.config, + hass: this.hass!, + narrow: this._params!.narrow, + }) ); lovelace.setEditMode(true); this._saving = false; diff --git a/src/panels/lovelace/editor/show-save-config-dialog.ts b/src/panels/lovelace/editor/show-save-config-dialog.ts index a1be39ddcf..cda486ef15 100644 --- a/src/panels/lovelace/editor/show-save-config-dialog.ts +++ b/src/panels/lovelace/editor/show-save-config-dialog.ts @@ -14,6 +14,7 @@ const dialogTag = "hui-dialog-save-config"; export interface SaveDialogParams { lovelace: Lovelace; mode: "yaml" | "storage"; + narrow: boolean; } let registeredDialog = false; diff --git a/src/panels/lovelace/ha-panel-lovelace.ts b/src/panels/lovelace/ha-panel-lovelace.ts index 0d6b38716a..a499aa54e0 100644 --- a/src/panels/lovelace/ha-panel-lovelace.ts +++ b/src/panels/lovelace/ha-panel-lovelace.ts @@ -7,6 +7,11 @@ import { property, TemplateResult, } from "lit-element"; +import { constructUrlCurrentPath } from "../../common/url/construct-url"; +import { + addSearchParam, + removeSearchParam, +} from "../../common/url/search-params"; import { domainToName } from "../../data/integration"; import { deleteConfig, @@ -21,14 +26,16 @@ import "../../layouts/hass-error-screen"; import "../../layouts/hass-loading-screen"; import { HomeAssistant, PanelInfo, Route } from "../../types"; import { showToast } from "../../util/toast"; -import { generateLovelaceConfigFromHass } from "./common/generate-lovelace-config"; import { loadLovelaceResources } from "./common/load-resources"; import { showSaveDialog } from "./editor/show-save-config-dialog"; import "./hui-root"; +import { generateLovelaceDashboardStrategy } from "./strategies/get-strategy"; import { Lovelace } from "./types"; (window as any).loadCardHelpers = () => import("./custom-card-helpers"); +const DEFAULT_STRATEGY = "original-states"; + interface LovelacePanelConfig { mode: "yaml" | "storage"; } @@ -71,7 +78,11 @@ class LovelacePanel extends LitElement { this.lovelace.locale !== this.hass.locale ) { // language has been changed, rebuild UI - this._setLovelaceConfig(this.lovelace.config, this.lovelace.mode); + this._setLovelaceConfig( + this.lovelace.config, + this.lovelace.rawConfig, + this.lovelace.mode + ); } else if (this.lovelace && this.lovelace.mode === "generated") { // When lovelace is generated, we re-generate each time a user goes // to the states panel to make sure new entities are shown. @@ -139,7 +150,9 @@ class LovelacePanel extends LitElement { `; } - protected firstUpdated() { + protected firstUpdated(changedProps) { + super.firstUpdated(changedProps); + this._fetchConfig(false); if (!this._unsubUpdates) { this._subscribeUpdates(); @@ -153,8 +166,14 @@ class LovelacePanel extends LitElement { } private async _regenerateConfig() { - const conf = await generateLovelaceConfigFromHass(this.hass!); - this._setLovelaceConfig(conf, "generated"); + const conf = await generateLovelaceDashboardStrategy( + { + hass: this.hass!, + narrow: this.narrow, + }, + DEFAULT_STRATEGY + ); + this._setLovelaceConfig(conf, undefined, "generated"); this._state = "loaded"; } @@ -202,6 +221,7 @@ class LovelacePanel extends LitElement { private async _fetchConfig(forceDiskRefresh: boolean) { let conf: LovelaceConfig; + let rawConf: LovelaceConfig | undefined; let confMode: Lovelace["mode"] = this.panel!.config.mode; let confProm: Promise | undefined; const llWindow = window as WindowWithLovelaceProm; @@ -236,7 +256,18 @@ class LovelacePanel extends LitElement { } try { - conf = await confProm!; + rawConf = await confProm!; + + // If strategy defined, apply it here. + if (rawConf.strategy) { + conf = await generateLovelaceDashboardStrategy({ + config: rawConf, + hass: this.hass!, + narrow: this.narrow, + }); + } else { + conf = rawConf; + } } catch (err) { if (err.code !== "config_not_found") { // eslint-disable-next-line @@ -245,8 +276,13 @@ class LovelacePanel extends LitElement { this._errorMsg = err.message; return; } - const localize = await this.hass!.loadBackendTranslation("title"); - conf = await generateLovelaceConfigFromHass(this.hass!, localize); + conf = await generateLovelaceDashboardStrategy( + { + hass: this.hass!, + narrow: this.narrow, + }, + DEFAULT_STRATEGY + ); confMode = "generated"; } finally { // Ignore updates for another 2 seconds. @@ -258,7 +294,7 @@ class LovelacePanel extends LitElement { } this._state = this._state === "yaml-editor" ? this._state : "loaded"; - this._setLovelaceConfig(conf, confMode); + this._setLovelaceConfig(conf, rawConf, confMode); } private _checkLovelaceConfig(config: LovelaceConfig) { @@ -277,11 +313,16 @@ class LovelacePanel extends LitElement { return checkedConfig ? deepFreeze(checkedConfig) : config; } - private _setLovelaceConfig(config: LovelaceConfig, mode: Lovelace["mode"]) { + private _setLovelaceConfig( + config: LovelaceConfig, + rawConfig: LovelaceConfig | undefined, + mode: Lovelace["mode"] + ) { config = this._checkLovelaceConfig(config); const urlPath = this.urlPath; this.lovelace = { config, + rawConfig, mode, urlPath: this.urlPath, editMode: this.lovelace ? this.lovelace.editMode : false, @@ -294,22 +335,39 @@ class LovelacePanel extends LitElement { this._state = "yaml-editor"; }, setEditMode: (editMode: boolean) => { + // If we use a strategy for dashboard, we cannot show the edit UI + // So go straight to the YAML editor + if ( + this.lovelace!.rawConfig && + this.lovelace!.rawConfig !== this.lovelace!.config + ) { + this.lovelace!.enableFullEditMode(); + return; + } + if (!editMode || this.lovelace!.mode !== "generated") { this._updateLovelace({ editMode }); return; } + showSaveDialog(this, { lovelace: this.lovelace!, mode: this.panel!.config.mode, + narrow: this.narrow!, }); }, saveConfig: async (newConfig: LovelaceConfig): Promise => { - const { config: previousConfig, mode: previousMode } = this.lovelace!; + const { + config: previousConfig, + rawConfig: previousRawConfig, + mode: previousMode, + } = this.lovelace!; newConfig = this._checkLovelaceConfig(newConfig); try { // Optimistic update this._updateLovelace({ config: newConfig, + rawConfig: undefined, mode: "storage", }); this._ignoreNextUpdateEvent = true; @@ -320,18 +378,30 @@ class LovelacePanel extends LitElement { // Rollback the optimistic update this._updateLovelace({ config: previousConfig, + rawConfig: previousRawConfig, mode: previousMode, }); throw err; } }, deleteConfig: async (): Promise => { - const { config: previousConfig, mode: previousMode } = this.lovelace!; + const { + config: previousConfig, + rawConfig: previousRawConfig, + mode: previousMode, + } = this.lovelace!; try { // Optimistic update - const localize = await this.hass!.loadBackendTranslation("title"); + const generatedConf = await generateLovelaceDashboardStrategy( + { + hass: this.hass!, + narrow: this.narrow, + }, + DEFAULT_STRATEGY + ); this._updateLovelace({ - config: await generateLovelaceConfigFromHass(this.hass!, localize), + config: generatedConf, + rawConfig: undefined, mode: "generated", editMode: false, }); @@ -343,6 +413,7 @@ class LovelacePanel extends LitElement { // Rollback the optimistic update this._updateLovelace({ config: previousConfig, + rawConfig: previousRawConfig, mode: previousMode, }); throw err; @@ -356,6 +427,18 @@ class LovelacePanel extends LitElement { ...this.lovelace!, ...props, }; + + if ("editMode" in props) { + window.history.replaceState( + null, + "", + constructUrlCurrentPath( + props.editMode + ? addSearchParam({ edit: "1" }) + : removeSearchParam("edit") + ) + ); + } } } diff --git a/src/panels/lovelace/hui-editor.ts b/src/panels/lovelace/hui-editor.ts index 9766279d3d..eb0a8805e7 100644 --- a/src/panels/lovelace/hui-editor.ts +++ b/src/panels/lovelace/hui-editor.ts @@ -106,7 +106,7 @@ class LovelaceFullConfigEditor extends LitElement { protected firstUpdated(changedProps: PropertyValues) { super.firstUpdated(changedProps); - this.yamlEditor.value = safeDump(this.lovelace!.config); + this.yamlEditor.value = safeDump(this.lovelace!.rawConfig); } protected updated(changedProps: PropertyValues) { diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index 2dd95ba627..199c979e66 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -43,9 +43,7 @@ import { navigate } from "../../common/navigate"; import { addSearchParam, extractSearchParam, - removeSearchParam, } from "../../common/url/search-params"; -import { constructUrlCurrentPath } from "../../common/url/construct-url"; import { computeRTLDirection } from "../../common/util/compute_rtl"; import { debounce } from "../../common/util/debounce"; import { afterNextRender } from "../../common/util/render-status"; @@ -539,7 +537,7 @@ class HUIRoot extends LitElement { protected firstUpdated() { // Check for requested edit mode if (extractSearchParam("edit") === "1") { - this._enableEditMode(); + this.lovelace!.setEditMode(true); } } @@ -715,25 +713,11 @@ class HUIRoot extends LitElement { }); return; } - this._enableEditMode(); - } - - private _enableEditMode(): void { this.lovelace!.setEditMode(true); - window.history.replaceState( - null, - "", - constructUrlCurrentPath(addSearchParam({ edit: "1" })) - ); } private _editModeDisable(): void { this.lovelace!.setEditMode(false); - window.history.replaceState( - null, - "", - constructUrlCurrentPath(removeSearchParam("edit")) - ); } private _editLovelace() { @@ -837,7 +821,7 @@ class HUIRoot extends LitElement { const viewConfig = this.config.views[viewIndex]; if (!viewConfig) { - this._enableEditMode(); + this.lovelace!.setEditMode(true); return; } diff --git a/src/panels/lovelace/strategies/get-strategy.ts b/src/panels/lovelace/strategies/get-strategy.ts new file mode 100644 index 0000000000..72271daf5c --- /dev/null +++ b/src/panels/lovelace/strategies/get-strategy.ts @@ -0,0 +1,158 @@ +import { LovelaceConfig, LovelaceViewConfig } from "../../../data/lovelace"; +import { AsyncReturnType, HomeAssistant } from "../../../types"; +import { OriginalStatesStrategy } from "./original-states-strategy"; + +const MAX_WAIT_STRATEGY_LOAD = 5000; +const CUSTOM_PREFIX = "custom:"; + +export interface LovelaceDashboardStrategy { + generateDashboard(info: { + config?: LovelaceConfig; + hass: HomeAssistant; + narrow: boolean | undefined; + }): Promise; +} + +export interface LovelaceViewStrategy { + generateView(info: { + view: LovelaceViewConfig; + config: LovelaceConfig; + hass: HomeAssistant; + narrow: boolean | undefined; + }): Promise; +} + +const strategies: Record< + string, + LovelaceDashboardStrategy & LovelaceViewStrategy +> = { + "original-states": OriginalStatesStrategy, +}; + +const getLovelaceStrategy = async < + T extends LovelaceDashboardStrategy | LovelaceViewStrategy +>( + name: string +): Promise => { + if (name in strategies) { + return strategies[name] as T; + } + + if (!name.startsWith(CUSTOM_PREFIX)) { + throw new Error("Unknown strategy"); + } + + const tag = `ll-strategy-${name.substr(CUSTOM_PREFIX.length)}`; + + if ( + (await Promise.race([ + customElements.whenDefined(tag), + new Promise((resolve) => + setTimeout(() => resolve(true), MAX_WAIT_STRATEGY_LOAD) + ), + ])) === true + ) { + throw new Error( + `Timeout waiting for strategy element ${tag} to be registered` + ); + } + + return customElements.get(tag); +}; + +interface GenerateMethods { + generateDashboard: LovelaceDashboardStrategy["generateDashboard"]; + generateView: LovelaceViewStrategy["generateView"]; +} + +const generateStrategy = async ( + generateMethod: T, + renderError: (err: string | Error) => AsyncReturnType, + info: Parameters[0], + name: string | undefined +): Promise> => { + if (!name) { + return renderError("No strategy name found"); + } + + try { + const strategy = (await getLovelaceStrategy(name)) as any; + return await strategy[generateMethod](info); + } catch (err) { + if (err.message !== "timeout") { + // eslint-disable-next-line + console.error(err); + } + + return renderError(err); + } +}; + +export const generateLovelaceDashboardStrategy = async ( + info: Parameters[0], + name?: string +): ReturnType => + generateStrategy( + "generateDashboard", + (err) => ({ + views: [ + { + title: "Error", + cards: [ + { + type: "markdown", + content: `Error loading the dashboard strategy:\n> ${err}`, + }, + ], + }, + ], + }), + info, + name || info.config?.strategy?.name + ); + +export const generateLovelaceViewStrategy = async ( + info: Parameters[0], + name?: string +): ReturnType => + generateStrategy( + "generateView", + (err) => ({ + cards: [ + { + type: "markdown", + content: `Error loading the view strategy:\n> ${err}`, + }, + ], + }), + info, + name || info.view?.strategy?.name + ); + +/** + * Find all references to strategies and replaces them with the generated output + */ +export const expandLovelaceConfigStrategies = async ( + info: Parameters[0] & { + config: LovelaceConfig; + } +): Promise => { + const config = info.config.strategy + ? await generateLovelaceDashboardStrategy(info) + : { ...info.config }; + + config.views = await Promise.all( + config.views.map((view) => + view.strategy + ? generateLovelaceViewStrategy({ + hass: info.hass, + narrow: info.narrow, + config, + view, + }) + : view + ) + ); + + return config; +}; diff --git a/src/panels/lovelace/strategies/original-states-strategy.ts b/src/panels/lovelace/strategies/original-states-strategy.ts new file mode 100644 index 0000000000..0762bedabe --- /dev/null +++ b/src/panels/lovelace/strategies/original-states-strategy.ts @@ -0,0 +1,94 @@ +import { STATE_NOT_RUNNING } from "home-assistant-js-websocket"; +import { subscribeOne } from "../../../common/util/subscribe-one"; +import { subscribeAreaRegistry } from "../../../data/area_registry"; +import { subscribeDeviceRegistry } from "../../../data/device_registry"; +import { subscribeEntityRegistry } from "../../../data/entity_registry"; +import { generateDefaultViewConfig } from "../common/generate-lovelace-config"; +import { + LovelaceViewStrategy, + LovelaceDashboardStrategy, +} from "./get-strategy"; + +let subscribedRegistries = false; + +export class OriginalStatesStrategy { + static async generateView( + info: Parameters[0] + ): ReturnType { + const hass = info.hass; + + if (hass.config.state === STATE_NOT_RUNNING) { + return { + cards: [{ type: "starting" }], + }; + } + + if (hass.config.safe_mode) { + return { + cards: [{ type: "safe-mode" }], + }; + } + + // We leave this here so we always have the freshest data. + if (!subscribedRegistries) { + subscribedRegistries = true; + subscribeAreaRegistry(hass.connection, () => undefined); + subscribeDeviceRegistry(hass.connection, () => undefined); + subscribeEntityRegistry(hass.connection, () => undefined); + } + + const [ + areaEntries, + deviceEntries, + entityEntries, + localize, + ] = await Promise.all([ + subscribeOne(hass.connection, subscribeAreaRegistry), + subscribeOne(hass.connection, subscribeDeviceRegistry), + subscribeOne(hass.connection, subscribeEntityRegistry), + hass.loadBackendTranslation("title"), + ]); + + // User can override default view. If they didn't, we will add one + // that contains all entities. + const view = generateDefaultViewConfig( + areaEntries, + deviceEntries, + entityEntries, + hass.states, + localize + ); + + // Add map of geo locations to default view if loaded + if (hass.config.components.includes("geo_location")) { + if (view && view.cards) { + view.cards.push({ + type: "map", + geo_location_sources: ["all"], + }); + } + } + + // User has no entities + if (view.cards!.length === 0) { + view.cards!.push({ + type: "empty-state", + }); + } + + return view; + } + + static async generateDashboard( + info: Parameters[0] + ): ReturnType { + return { + views: [ + { + strategy: { name: "original-states" }, + title: info.hass.config.location_name, + }, + ], + }; + } +} diff --git a/src/panels/lovelace/types.ts b/src/panels/lovelace/types.ts index 17bd8bc465..f9763be955 100644 --- a/src/panels/lovelace/types.ts +++ b/src/panels/lovelace/types.ts @@ -18,6 +18,8 @@ declare global { export interface Lovelace { config: LovelaceConfig; + // If not set, a strategy was used to generate everything + rawConfig: LovelaceConfig | undefined; editMode: boolean; urlPath: string | null; mode: "generated" | "yaml" | "storage"; diff --git a/src/panels/lovelace/views/hui-masonry-view.ts b/src/panels/lovelace/views/hui-masonry-view.ts index 42914224af..0e7e49d21f 100644 --- a/src/panels/lovelace/views/hui-masonry-view.ts +++ b/src/panels/lovelace/views/hui-masonry-view.ts @@ -53,6 +53,8 @@ export class MasonryView extends LitElement implements LovelaceViewElement { @property({ type: Number }) public index?: number; + @property({ type: Boolean }) public isStrategy = false; + @property({ attribute: false }) public cards: Array< LovelaceCard | HuiErrorCard > = []; @@ -228,7 +230,7 @@ export class MasonryView extends LitElement implements LovelaceViewElement { private _addCardToColumn(columnEl, index, editMode) { const card: LovelaceCard = this.cards[index]; - if (!editMode) { + if (!editMode || this.isStrategy) { card.editMode = false; columnEl.appendChild(card); } else { diff --git a/src/panels/lovelace/views/hui-panel-view.ts b/src/panels/lovelace/views/hui-panel-view.ts index 515673759c..23898074aa 100644 --- a/src/panels/lovelace/views/hui-panel-view.ts +++ b/src/panels/lovelace/views/hui-panel-view.ts @@ -31,6 +31,8 @@ export class PanelView extends LitElement implements LovelaceViewElement { @property({ type: Number }) public index?: number; + @property({ type: Boolean }) public isStrategy = false; + @property({ attribute: false }) public cards: Array< LovelaceCard | HuiErrorCard > = []; @@ -109,7 +111,7 @@ export class PanelView extends LitElement implements LovelaceViewElement { const card: LovelaceCard = this.cards[0]; card.isPanel = true; - if (!this.lovelace?.editMode) { + if (this.isStrategy || !this.lovelace?.editMode) { card.editMode = false; this._card = card; return; diff --git a/src/panels/lovelace/views/hui-view.ts b/src/panels/lovelace/views/hui-view.ts index 100d5ef1f1..938662e24a 100644 --- a/src/panels/lovelace/views/hui-view.ts +++ b/src/panels/lovelace/views/hui-view.ts @@ -23,6 +23,7 @@ import { createViewElement } from "../create-element/create-view-element"; import { showCreateCardDialog } from "../editor/card-editor/show-create-card-dialog"; import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog"; import { confDeleteCard } from "../editor/delete-card"; +import { generateLovelaceViewStrategy } from "../strategies/get-strategy"; import type { Lovelace, LovelaceBadge, LovelaceCard } from "../types"; const DEFAULT_VIEW_LAYOUT = "masonry"; @@ -55,6 +56,8 @@ export class HUIView extends UpdatingElement { private _layoutElement?: LovelaceViewElement; + private _viewConfigTheme?: string; + // Public to make demo happy public createCardElement(cardConfig: LovelaceCardConfig) { const element = createCardElement(cardConfig) as LovelaceCard; @@ -100,51 +103,21 @@ export class HUIView extends UpdatingElement { */ const oldLovelace = changedProperties.get("lovelace") as this["lovelace"]; - const configChanged = + + // If config has changed, create element if necessary and set all values. + if ( changedProperties.has("index") || (changedProperties.has("lovelace") && (!oldLovelace || this.lovelace.config.views[this.index] !== - oldLovelace.config.views[this.index])); + oldLovelace.config.views[this.index])) + ) { + this._initializeConfig(); + return; + } - // If config has changed, create element if necessary and set all values. - if (configChanged) { - let viewConfig = this.lovelace.config.views[this.index]; - viewConfig = { - ...viewConfig, - type: viewConfig.panel - ? PANEL_VIEW_LAYOUT - : viewConfig.type || DEFAULT_VIEW_LAYOUT, - }; - - this._createBadges(viewConfig!); - this._createCards(viewConfig!); - - // Create a new layout element if necessary. - let addLayoutElement = false; - - if ( - !this._layoutElement || - this._layoutElementType !== viewConfig!.type - ) { - addLayoutElement = true; - this._createLayoutElement(viewConfig!); - } - - this._layoutElement!.hass = this.hass; - this._layoutElement!.narrow = this.narrow; - this._layoutElement!.lovelace = this.lovelace; - this._layoutElement!.index = this.index; - this._layoutElement!.cards = this._cards; - this._layoutElement!.badges = this._badges; - - if (addLayoutElement) { - while (this.lastChild) { - this.removeChild(this.lastChild); - } - this.appendChild(this._layoutElement!); - } - } else { + // If no layout element, we're still creating one + if (this._layoutElement) { // Config has not changed. Just props if (changedProperties.has("hass")) { this._badges.forEach((badge) => { @@ -155,56 +128,98 @@ export class HUIView extends UpdatingElement { element.hass = this.hass; }); - this._layoutElement!.hass = this.hass; + this._layoutElement.hass = this.hass; } if (changedProperties.has("narrow")) { - this._layoutElement!.narrow = this.narrow; + this._layoutElement.narrow = this.narrow; } if (changedProperties.has("lovelace")) { - this._layoutElement!.lovelace = this.lovelace; + this._layoutElement.lovelace = this.lovelace; } if (changedProperties.has("_cards")) { - this._layoutElement!.cards = this._cards; + this._layoutElement.cards = this._cards; } if (changedProperties.has("_badges")) { - this._layoutElement!.badges = this._badges; + this._layoutElement.badges = this._badges; } } const oldHass = changedProperties.get("hass") as this["hass"] | undefined; - // Update theme if necessary: - // - If config changed, the theme could have changed - // - if hass themes preferences have changed if ( - configChanged || - (changedProperties.has("hass") && - (!oldHass || - this.hass.themes !== oldHass.themes || - this.hass.selectedTheme !== oldHass.selectedTheme)) + changedProperties.has("hass") && + (!oldHass || + this.hass.themes !== oldHass.themes || + this.hass.selectedTheme !== oldHass.selectedTheme) ) { - applyThemesOnElement( - this, - this.hass.themes, - this.lovelace.config.views[this.index].theme - ); + applyThemesOnElement(this, this.hass.themes, this._viewConfigTheme); + } + } + + private async _initializeConfig() { + let viewConfig = this.lovelace.config.views[this.index]; + let isStrategy = false; + + if (viewConfig.strategy) { + isStrategy = true; + viewConfig = await generateLovelaceViewStrategy({ + hass: this.hass, + config: this.lovelace.config, + narrow: this.narrow, + view: viewConfig, + }); + } + + viewConfig = { + ...viewConfig, + type: viewConfig.panel + ? PANEL_VIEW_LAYOUT + : viewConfig.type || DEFAULT_VIEW_LAYOUT, + }; + + // Create a new layout element if necessary. + let addLayoutElement = false; + + if (!this._layoutElement || this._layoutElementType !== viewConfig.type) { + addLayoutElement = true; + this._createLayoutElement(viewConfig); + } + + this._createBadges(viewConfig); + this._createCards(viewConfig); + this._layoutElement!.isStrategy = isStrategy; + this._layoutElement!.hass = this.hass; + this._layoutElement!.narrow = this.narrow; + this._layoutElement!.lovelace = this.lovelace; + this._layoutElement!.index = this.index; + this._layoutElement!.cards = this._cards; + this._layoutElement!.badges = this._badges; + + applyThemesOnElement(this, this.hass.themes, viewConfig.theme); + this._viewConfigTheme = viewConfig.theme; + + if (addLayoutElement) { + while (this.lastChild) { + this.removeChild(this.lastChild); + } + this.appendChild(this._layoutElement!); } } private _createLayoutElement(config: LovelaceViewConfig): void { - this._layoutElement = createViewElement(config); + this._layoutElement = createViewElement(config) as LovelaceViewElement; this._layoutElementType = config.type; this._layoutElement.addEventListener("ll-create-card", () => { showCreateCardDialog(this, { - lovelaceConfig: this.lovelace!.config, - saveConfig: this.lovelace!.saveConfig, + lovelaceConfig: this.lovelace.config, + saveConfig: this.lovelace.saveConfig, path: [this.index], }); }); this._layoutElement.addEventListener("ll-edit-card", (ev) => { showEditCardDialog(this, { - lovelaceConfig: this.lovelace!.config, - saveConfig: this.lovelace!.saveConfig, + lovelaceConfig: this.lovelace.config, + saveConfig: this.lovelace.saveConfig, path: ev.detail.path, }); }); diff --git a/src/types.ts b/src/types.ts index 5b9b6ed980..7c6d699ce1 100644 --- a/src/types.ts +++ b/src/types.ts @@ -256,3 +256,12 @@ export interface LocalizeMixin { hass?: HomeAssistant; localize: LocalizeFunc; } + +// https://www.jpwilliams.dev/how-to-unpack-the-return-type-of-a-promise-in-typescript +export type AsyncReturnType any> = T extends ( + ...args: any +) => Promise + ? U + : T extends (...args: any) => infer U + ? U + : never; From 393ae9e5dc7e5197b1bfab916e1cd7e3de7336e9 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 23 Apr 2021 15:23:32 -0700 Subject: [PATCH 074/106] Bumped version to 20210423.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 6345d4de19..7e7e6cb523 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20210416.0", + version="20210423.0", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors", From 9572a58764bcb90dbe6a0bb9ec30274f57189766 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sat, 24 Apr 2021 00:48:31 +0000 Subject: [PATCH 075/106] Translation update --- translations/frontend/he.json | 13 +++++++++++++ translations/frontend/lb.json | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/translations/frontend/he.json b/translations/frontend/he.json index 94063e9b06..a90af9161c 100644 --- a/translations/frontend/he.json +++ b/translations/frontend/he.json @@ -123,6 +123,9 @@ "cancel": "בטל", "close": "סגור", "description": "תיאור", + "error": { + "unknown": "בעיה לא ידועה" + }, "failed_to_restart_name": "אתחול {name} נכשל.", "failed_to_update_name": "עדכון {name} נכשל.", "learn_more": "למד עוד", @@ -219,14 +222,22 @@ "system": { "host": { "change_hostname": "שנה שם מכונה", + "confirm_reboot": "האם אתה בטוח שאתה מעוניין לאתחל שרת מארח?", + "confirm_shutdown": "האם אתה בטוח שאתה מעוניין לכבות שרת מארח?", + "docker_version": "גרסת Docker", "failed_to_get_hardware_list": "קבלת רשימת החומרה נכשלה", "failed_to_import_from_usb": "ייבוא מ- USB נכשל", "failed_to_reboot": "אתחול המכונה נכשל", "failed_to_set_hostname": "הגדרת שם המכונה נכשלה", "failed_to_shutdown": "כיבוי המכונה נכשל", + "hardware": "חומרה", "hostname": "שם מכונה", + "import_from_usb": "יבא מרכיב USB", "ip_address": "כתובת IP", "new_hostname": "אנא הזן שם מכונה חדש:", + "operating_system": "מערכת הפעלה", + "reboot_host": "אתחל שרת", + "shutdown_host": "כבה שרת מארח", "used_space": "שטח בשימוש" }, "supervisor": { @@ -252,6 +263,8 @@ "supervisor": "עדכון ה Supervisor לא הצליח", "untrusted": "זוהה תוכן לא מהימן" }, + "unhealthy_title": "ההתקנה שלך אינה תקינה", + "unsupported_description": "למטה רשימת נושאים שנימצאו במהלך ההתקנה, לחץ על קישור על מנת ללמוד איך לפתור את הנושא", "unsupported_reason": { "apparmor": "AppArmor אינו זמין במחשב המארח", "container": "ה Container ידוע כבעייתי", diff --git a/translations/frontend/lb.json b/translations/frontend/lb.json index 39829025fe..29201c41aa 100644 --- a/translations/frontend/lb.json +++ b/translations/frontend/lb.json @@ -749,6 +749,9 @@ "label": "Bild", "unsupported_format": "Net ënnerstëtzte Format, wiel e JPEG, PNG oder GIF Bild." }, + "related-filter-menu": { + "filter_by_entity": "Der Entitéit no filteren" + }, "related-items": { "area": "Beräich", "automation": "Deel vun de folgenden Automatismen", @@ -1055,6 +1058,9 @@ "zha_device_card": { "device_name_placeholder": "Numm vum Apparat änneren" } + }, + "zha_reconfigure_device": { + "heading": "Apparat frësch konfiguréieren" } }, "duration": { @@ -1075,6 +1081,10 @@ "key_wrong_type": "De Wäert fir \"{key}\" ass net vum visuelle Editeur ënnerstëtzt. Mir ënnerstëtzen ({type_correct}) mee mir kruuten ({type_wrong}).", "no_template_editor_support": "Modeller net ënnerstëtzt am Visuellen Editeur", "no_type_provided": "Keen Typ uginn." + }, + "supervisor": { + "ask": "No Hëllef froen", + "system_health": "System Zoustand iwwerpréiwen" } }, "login-form": { @@ -1889,6 +1899,9 @@ "filtering_by": "Filteren anhand vun", "show": "Uweisen" }, + "hassio": { + "button": "Astellen" + }, "header": "Home Assistant astellen", "helpers": { "caption": "Helper", @@ -1954,8 +1967,11 @@ "caption": "Integratiounen", "config_entry": { "area": "An {area}", + "check_the_logs": "Logs iwwerpréifen", + "configure": "Astellen", "delete": "Läschen", "delete_confirm": "Sécher fir dës Integratioun ze läsche?", + "depends_on_cloud": "Cloud ofhängeg", "device_unavailable": "Apparat net erreechbar", "devices": "{count} {count, plural,\n one {Apparat}\n other {Apparaten}\n}", "disable": { @@ -1973,12 +1989,21 @@ "hub": "Verbonnen via", "manuf": "vun {manufacturer}", "no_area": "Kee Beräich", + "not_loaded": "Net gelueden", "options": "Optiounen", "reload": "Nei lueden", "reload_confirm": "Integratioun gouf frësch gelueden", "reload_restart_confirm": "Start Home Assistant nei fir dës Integratioun fäerdeg ze lueden", "rename": "Ëmbenennen", "restart_confirm": "Start Home Assistant nei fir dës Integratioun ze läschen", + "state": { + "failed_unload": "Feeler beim entlueden", + "loaded": "Gelueden", + "migration_error": "Feeler bei der Migratioun", + "not_loaded": "Net gelueden", + "setup_error": "Feeler beim ariichten", + "setup_retry": "Probéiert nach emol anzeriichten" + }, "system_options": "System Optiounen", "unnamed_entry": "Entrée ouni Numm" }, @@ -2038,6 +2063,11 @@ "clear": "Läschen", "description": "Home Assistant Logbicher ukucken", "details": "Detailler vum Log ({level})", + "level": { + "error": "FEELER", + "info": "INFO", + "warning": "WARNUNG" + }, "load_full_log": "Kompletten Home Assistant Log lueden", "loading_log": "Feeler Log gëtt gelueden...", "multiple_messages": "Noriicht als éischt opgetrueden um {time} a säit deem {counter} mol opgetrueden", @@ -3446,6 +3476,9 @@ } }, "page-onboarding": { + "analytics": { + "finish": "Nächst" + }, "core-config": { "button_detect": "Entdecken", "finish": "Nächst", @@ -3455,12 +3488,14 @@ "location_name": "Numm vun denger Home Assistant Installatioun", "location_name_default": "Doheem" }, + "finish": "Ofschléissen", "integration": { "finish": "Ofschléissen", "intro": "Apparaten a Servicë ginn am Home Assistant als Integratioune representéiert. Dir kënnt si elo astellen, oder méi spéit vun der Konfiguratioun's Säit aus.", "more_integrations": "Méi" }, "intro": "Sidd Dir prett fir Äert Heem interessant ze maachen, Är Privatsphär ze garantéieren an enger weltwäiter Gemeinschaft bei ze trieden?", + "next": "Nächst", "restore": { "description": "Alternativ kanns Du aus engem fréiere Snapshot restauréieren.", "hide_log": "Komplette Log verstoppen", From 959f7ae0468435abb5578071d331a03e25911b0e Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 25 Apr 2021 00:48:30 +0000 Subject: [PATCH 076/106] Translation update --- translations/frontend/tr.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/translations/frontend/tr.json b/translations/frontend/tr.json index b9a766daf2..f54dbe9f2f 100644 --- a/translations/frontend/tr.json +++ b/translations/frontend/tr.json @@ -1594,7 +1594,7 @@ "dev_automation": "Hata ayıklama otomasyonu", "dev_only_editable": "Yalnızca automations.yaml'de tanımlanan otomasyonlarda hata ayıklama yapılabilir.", "duplicate": "Çiftleme", - "duplicate_automation": "Yinelenen otomasyon", + "duplicate_automation": "Otomasyonu çiftleme", "edit_automation": "Otomasyonu düzenle", "header": "Otomasyon Düzenleyici", "headers": { @@ -2136,6 +2136,7 @@ "caption": "Entegrasyonlar", "config_entry": { "area": "{area} içinde", + "check_the_logs": "Günlükleri kontrol edin", "delete": "Sil", "delete_confirm": "Bu entegrasyonu silmek istediğinizden emin misiniz?", "device_unavailable": "Cihaz kullanılamıyor", @@ -2168,6 +2169,13 @@ "rename": "Yeniden adlandır", "restart_confirm": "Bu entegrasyonu kaldırmaya devam etmek için Home Assistant'ı yeniden başlatın", "services": "{count} {count, plural,\n one {hizmet}\n other {hizmetler}\n}", + "state": { + "failed_unload": "Kaldırılamadı", + "loaded": "Yüklendi", + "migration_error": "Taşıma hatası", + "not_loaded": "Yüklenmedi", + "setup_error": "Kurulum başarısız oldu" + }, "system_options": "Sistem seçenekleri", "unnamed_entry": "Adsız giriş" }, From 96d6e337be827728bd571804b563b0347cba6635 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 26 Apr 2021 03:02:56 -0700 Subject: [PATCH 077/106] Document last step (#8979) Co-authored-by: Philip Allgaier --- src/data/data_entry_flow.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/data/data_entry_flow.ts b/src/data/data_entry_flow.ts index d1447b1c74..5a7d8088a8 100644 --- a/src/data/data_entry_flow.ts +++ b/src/data/data_entry_flow.ts @@ -28,6 +28,7 @@ export interface DataEntryFlowStepForm { data_schema: HaFormSchema[]; errors: Record; description_placeholders: Record; + last_step: boolean | null; } export interface DataEntryFlowStepExternal { From cba3992d2bfd74d6a5cc962d447bd70c536c2cfa Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Mon, 26 Apr 2021 12:09:50 +0200 Subject: [PATCH 078/106] Make "Events" dev tools use screen space better (#7449) --- .../src/addon-view/hassio-addon-dashboard.ts | 5 +-- .../src/addon-view/info/hassio-addon-info.ts | 14 +++++--- src/panels/config/info/integrations-card.ts | 5 +-- .../zha/dialog-zha-device-children.ts | 4 +-- .../event/developer-tools-event.js | 33 ++++++++++++------- .../event/event-subscribe-card.ts | 10 ++++-- .../components/hui-generic-entity-row.ts | 3 +- src/translations/en.json | 22 ++++++------- 8 files changed, 57 insertions(+), 39 deletions(-) diff --git a/hassio/src/addon-view/hassio-addon-dashboard.ts b/hassio/src/addon-view/hassio-addon-dashboard.ts index 4e11853aca..6287c7907d 100644 --- a/hassio/src/addon-view/hassio-addon-dashboard.ts +++ b/hassio/src/addon-view/hassio-addon-dashboard.ts @@ -177,8 +177,9 @@ class HassioAddonDashboard extends LitElement { const requestedAddon = extractSearchParam("addon"); if (requestedAddon) { const addonsInfo = await fetchHassioAddonsInfo(this.hass); - const validAddon = addonsInfo.addons - .some((addon) => addon.slug === requestedAddon); + const validAddon = addonsInfo.addons.some( + (addon) => addon.slug === requestedAddon + ); if (!validAddon) { this._error = this.supervisor.localize("my.error_addon_not_found"); } else { diff --git a/hassio/src/addon-view/info/hassio-addon-info.ts b/hassio/src/addon-view/info/hassio-addon-info.ts index e4161971bb..b0f10392fa 100644 --- a/hassio/src/addon-view/info/hassio-addon-info.ts +++ b/hassio/src/addon-view/info/hassio-addon-info.ts @@ -242,14 +242,18 @@ class HassioAddonInfo extends LitElement { ? html` Current version: ${this.addon.version}
      - (${ - this.supervisor.localize("addon.dashboard.changelog")}${this.supervisor.localize( + "addon.dashboard.changelog" + )})
      ` - : html`${ - this.supervisor.localize("addon.dashboard.changelog") - }`} + : html`${this.supervisor.localize( + "addon.dashboard.changelog" + )}`}
      diff --git a/src/panels/config/info/integrations-card.ts b/src/panels/config/info/integrations-card.ts index d078524f1e..9ac154d716 100644 --- a/src/panels/config/info/integrations-card.ts +++ b/src/panels/config/info/integrations-card.ts @@ -30,8 +30,9 @@ class IntegrationsCard extends LitElement { private _sortedIntegrations = memoizeOne((components: string[]) => { return Array.from( new Set( - components - .map((comp) => (comp.includes(".") ? comp.split(".")[1] : comp)) + components.map((comp) => + comp.includes(".") ? comp.split(".")[1] : comp + ) ) ).sort(); }); diff --git a/src/panels/config/integrations/integration-panels/zha/dialog-zha-device-children.ts b/src/panels/config/integrations/integration-panels/zha/dialog-zha-device-children.ts index 31869775cc..135776a74a 100644 --- a/src/panels/config/integrations/integration-panels/zha/dialog-zha-device-children.ts +++ b/src/panels/config/integrations/integration-panels/zha/dialog-zha-device-children.ts @@ -76,9 +76,7 @@ class DialogZHADeviceChildren extends LitElement { }, }; - public showDialog( - params: ZHADeviceChildrenDialogParams - ): void { + public showDialog(params: ZHADeviceChildrenDialogParams): void { this._device = params.device; this._fetchData(); } diff --git a/src/panels/developer-tools/event/developer-tools-event.js b/src/panels/developer-tools/event/developer-tools-event.js index 7da723ee44..163c034b2b 100644 --- a/src/panels/developer-tools/event/developer-tools-event.js +++ b/src/panels/developer-tools/event/developer-tools-event.js @@ -24,17 +24,21 @@ class HaPanelDevEvent extends EventsMixin(LocalizeMixin(PolymerElement)) { return html` diff --git a/src/html/index.html.template b/src/html/index.html.template index 747c8c102c..dfad967ad1 100644 --- a/src/html/index.html.template +++ b/src/html/index.html.template @@ -51,6 +51,7 @@ @media (prefers-color-scheme: dark) { html { background-color: #111111; + color: #e1e1e1; } #ha-init-skeleton::before { background-color: #1c1c1c; diff --git a/src/html/onboarding.html.template b/src/html/onboarding.html.template index 55b4144b6c..8ab6264be1 100644 --- a/src/html/onboarding.html.template +++ b/src/html/onboarding.html.template @@ -34,17 +34,8 @@ @media (prefers-color-scheme: dark) { html { - color: #e1e1e1; - } - ha-onboarding { - --primary-text-color: #e1e1e1; - --secondary-text-color: #9b9b9b; - --disabled-text-color: #6f6f6f; - --mdc-theme-surface: #1e1e1e; - --ha-card-background: #1e1e1e; - } - .content { background-color: #111111; + color: #e1e1e1; } } diff --git a/src/onboarding/ha-onboarding.ts b/src/onboarding/ha-onboarding.ts index a6177099be..64ff66bf5a 100644 --- a/src/onboarding/ha-onboarding.ts +++ b/src/onboarding/ha-onboarding.ts @@ -32,6 +32,7 @@ import { registerServiceWorker } from "../util/register-service-worker"; import "./onboarding-create-user"; import "./onboarding-loading"; import "./onboarding-analytics"; +import { applyThemesOnElement } from "../common/dom/apply_themes_on_element"; type OnboardingEvent = | { @@ -137,6 +138,19 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { if (window.innerWidth > 450) { import("./particles"); } + if (matchMedia("(prefers-color-scheme: dark)").matches) { + applyThemesOnElement( + document.documentElement, + { + default_theme: "default", + default_dark_theme: null, + themes: {}, + darkMode: false, + }, + "default", + { dark: true } + ); + } } protected updated(changedProps: PropertyValues) { diff --git a/src/state/themes-mixin.ts b/src/state/themes-mixin.ts index 4ed2b560b8..0c9e64e7ce 100644 --- a/src/state/themes-mixin.ts +++ b/src/state/themes-mixin.ts @@ -32,6 +32,19 @@ export default >(superClass: T) => storeState(this.hass!); }); mql.addListener((ev) => this._applyTheme(ev.matches)); + if (mql.matches) { + applyThemesOnElement( + document.documentElement, + { + default_theme: "default", + default_dark_theme: null, + themes: {}, + darkMode: false, + }, + "default", + { dark: true } + ); + } } protected hassConnected() { From b7a4f97ecacd6e6e4e9d48f31ac387ab2fbfdb49 Mon Sep 17 00:00:00 2001 From: Charles Garwood Date: Mon, 26 Apr 2021 18:19:48 -0400 Subject: [PATCH 087/106] Add opt-in toggle for zwave-js telemetry to config panel (#8958) --- src/data/zwave_js.ts | 25 +++++++ .../zwave_js/zwave_js-config-dashboard.ts | 71 ++++++++++++++++++- 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/src/data/zwave_js.ts b/src/data/zwave_js.ts index d6db70bd21..b34338a150 100644 --- a/src/data/zwave_js.ts +++ b/src/data/zwave_js.ts @@ -56,6 +56,11 @@ export interface ZWaveJSSetConfigParamData { value: string | number; } +export interface ZWaveJSDataCollectionStatus { + enabled: boolean; + opted_in: boolean; +} + export enum NodeStatus { Unknown, Asleep, @@ -75,6 +80,26 @@ export const fetchNetworkStatus = ( entry_id, }); +export const fetchDataCollectionStatus = ( + hass: HomeAssistant, + entry_id: string +): Promise => + hass.callWS({ + type: "zwave_js/data_collection_status", + entry_id, + }); + +export const setDataCollectionPreference = ( + hass: HomeAssistant, + entry_id: string, + opted_in: boolean +): Promise => + hass.callWS({ + type: "zwave_js/update_data_collection_preference", + entry_id, + opted_in, + }); + export const fetchNodeStatus = ( hass: HomeAssistant, entry_id: string, diff --git a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts index bc219081a4..eb53eeafba 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts @@ -17,9 +17,11 @@ import "../../../../../components/ha-svg-icon"; import "../../../../../components/ha-icon-next"; import { getSignedPath } from "../../../../../data/auth"; import { + fetchDataCollectionStatus, fetchNetworkStatus, fetchNodeStatus, NodeStatus, + setDataCollectionPreference, ZWaveJSNetwork, ZWaveJSNode, } from "../../../../../data/zwave_js"; @@ -55,6 +57,8 @@ class ZWaveJSConfigDashboard extends LitElement { @internalProperty() private _icon = mdiCircle; + @internalProperty() private _dataCollectionOptIn?: boolean; + protected firstUpdated() { if (this.hass) { this._fetchData(); @@ -167,6 +171,39 @@ class ZWaveJSConfigDashboard extends LitElement {
      + +
      +

      Third-Party Data Reporting

      + ${this._dataCollectionOptIn !== undefined + ? html` + + ` + : html` + + `} +
      +
      +

      + Enable the reporting of anonymized telemetry and + statistics to the Z-Wave JS organization. This + data will be used to focus development efforts and improve + the user experience. Information about the data that is + collected and how it is used, including an example of the + data collected, can be found in the + Z-Wave JS data collection documentation. +

      +
      +
      ` : ``}