From 3606b8077f941a7eb5801aa8cbb411d1363bfbd1 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Fri, 21 Feb 2020 00:34:40 +0000 Subject: [PATCH 01/33] [ci skip] Translation update --- translations/lb.json | 9 +++++++++ translations/pl.json | 10 +++++----- translations/sk.json | 2 +- translations/sv.json | 5 +++++ translations/uk.json | 29 ++++++++++++++++++++++++++++- 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/translations/lb.json b/translations/lb.json index 1c9de75892..a91fd4d67d 100644 --- a/translations/lb.json +++ b/translations/lb.json @@ -581,6 +581,7 @@ "entity": "Entitéiten a Relatioun", "group": "Deel vun de folgende Gruppen", "integration": "Integratioun", + "no_related_found": "Keng ähnlech Objeten fonnt.", "scene": "Deel vun de folgende Zeenen", "script": "Deel vun de folgende Skripten" }, @@ -1346,6 +1347,7 @@ "status": { "disabled": "Deaktivéiert", "ok": "Ok", + "readonly": "Nëmme liesen", "unavailable": "Net erreechbar" }, "unavailable": "(net verfügbar)" @@ -1702,6 +1704,8 @@ "update": "Aktualiséieren" }, "edit_home_zone": "De Standuert vun Ärem Doheem kann an der allgemenger Konfiguratioun geännert ginn.", + "go_to_core_config": "Zur genereller Konfiguratioun wiesselen?", + "home_zone_core_config": "De Standuert vun Ärer Heemzon kann vun der allgemenger Konfiguratiounssäit aus geännert ginn. De Radius vun der Home Zone kann nach net am Frontend geännert ginn. Wëllt Dir op d'allgemeng Konfiguratioun goen?", "introduction": "Zonen erlaben Iech verschidde Regiounen op der Äerd ze spezifizéieren. Wann eng Persoun an enger Zone ass, hëlt de Status den Numm aus der Zone. Zonë kënnen och als Ausléiser oder als Konditioun an Automatisme benotzt ginn.", "no_zones_created_yet": "Et gesäit sou aus wéi wann nach keng Zone erstallt goufen." }, @@ -1909,6 +1913,11 @@ "toggle": "{name} ëmschalten", "url": "Fënster opmaachen mat {url_path}" }, + "safe-mode": { + "description": "Home Assistant konnt Konfiguratioun net richteg lueden an leeft elo am Sécherheetsmodus. Kuck Logbicher fir de Feeler ze fannen.", + "header": "Sécherheetsmodus aktivéiert", + "show_errors": "Feeler uweisen" + }, "shopping-list": { "add_item": "Element dobäisetzen", "checked_items": "Markéiert Elementer", diff --git a/translations/pl.json b/translations/pl.json index 1e33d72593..e3907b074f 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -1985,9 +1985,9 @@ "minimum": "Minimum", "name": "Nazwa", "refresh_interval": "Częstotliwość odświeżania", - "show_icon": "Pokaż ikonę?", - "show_name": "Pokaż nazwę?", - "show_state": "Pokaż stan?", + "show_icon": "Wyświetlanie ikony", + "show_name": "Wyświetlanie nazwy", + "show_state": "Wyświetlanie stanu", "tap_action": "Akcja dotknięcia", "theme": "Motyw", "title": "Tytuł", @@ -2011,7 +2011,7 @@ "name": "Światło" }, "map": { - "dark_mode": "Tryb ciemny?", + "dark_mode": "Tryb ciemny", "default_zoom": "Domyślne powiększenie", "geo_location_sources": "Źródła geolokalizacji", "name": "Mapa", @@ -2375,7 +2375,7 @@ "learn_auth_requests": "Dowiedz się, jak tworzyć uwierzytelnione żądania.", "not_used": "Nigdy nie był używany", "prompt_copy_token": "Skopiuj token. Nie będzie on już ponownie wyświetlany.", - "prompt_name": "Nazwa?" + "prompt_name": "Nazwa" }, "mfa_setup": { "close": "Zamknij", diff --git a/translations/sk.json b/translations/sk.json index d4c12e091e..e31480fe8f 100644 --- a/translations/sk.json +++ b/translations/sk.json @@ -585,7 +585,7 @@ "last_action": "Posledná akcia" }, "sun": { - "elevation": "Nadmorská výška", + "elevation": "Výška nad horizontom", "rising": "Vychádzajúce", "setting": "Zapadajúce" }, diff --git a/translations/sv.json b/translations/sv.json index 1224c6182a..ca295eee57 100644 --- a/translations/sv.json +++ b/translations/sv.json @@ -1916,6 +1916,11 @@ "toggle": "Växla {name}", "url": "Öppna fönster till {url_path}" }, + "safe-mode": { + "description": "Home Assistant stötte på problem när din konfiguration laddades och körs nu i felsäkert läge. Ta en titt i felloggen för att se vad som gick fel.", + "header": "Felsäkert läge aktiverat", + "show_errors": "Visa fel" + }, "shopping-list": { "add_item": "Lägg till objekt", "checked_items": "Markerade objekt", diff --git a/translations/uk.json b/translations/uk.json index 235cca3453..ee21f8abd7 100644 --- a/translations/uk.json +++ b/translations/uk.json @@ -556,6 +556,9 @@ "loading_history": "Завантаження історії стану ...", "no_history_found": "Немає історії станів." }, + "related-items": { + "no_related_found": "Не знайдено пов'язаних елементів" + }, "relative_time": { "duration": { "day": "{count} {count, plural,\n one {д.}\n other {д.}\n}", @@ -576,7 +579,8 @@ "config_entry_system_options": { "enable_new_entities_description": "Якщо вимкнено, нововиявлені об'єкти для {integration} не будуть автоматично додані до Home Assistant.", "enable_new_entities_label": "Додавати нові об'єкти.", - "title": "Параметри системи для {integration}" + "title": "Параметри системи для {integration}", + "update": "Оновити" }, "confirmation": { "cancel": "Скасувати", @@ -589,6 +593,9 @@ "more_info_control": { "dismiss": "Відхилити", "edit": "Редагувати об'єкт", + "person": { + "create_zone": "Створити зону з поточного місця розташування" + }, "script": { "last_action": "Остання дія" }, @@ -602,6 +609,7 @@ "title": "Інструкції по оновленню" }, "vacuum": { + "return_home": "Повернутися додому", "start_pause": "Початок/Пауза", "stop": "Зупинити" } @@ -820,6 +828,7 @@ }, "edit_ui": "Редагувати за допомогою інтерфейсу користувача", "edit_yaml": "Редагувати як YAML", + "enable_disable": "Увімкнути / Вимкнути автоматизацію", "introduction": "Використовуйте автоматизацію, щоб оживити ваш будинок", "load_error_not_editable": "Можна редагувати лише секцію automations у файлі automations.yaml", "load_error_unknown": "Помилка під час завантаження автоматизації ({err_no}).", @@ -1203,6 +1212,9 @@ "update": "ОНОВИТИ" }, "picker": { + "filter": { + "show_readonly": "Показати об'єкти лише для читання" + }, "header": "Реєстр об'єктів", "headers": { "enabled": "Увімкнено", @@ -1217,6 +1229,9 @@ "button": "Видалити вибране" }, "show_disabled": "Показати відключені об’єкти", + "status": { + "readonly": "Лише для читання" + }, "unavailable": "(недоступно)" } }, @@ -1514,6 +1529,10 @@ "updateDeviceName": "Встановіть зручну назву для цього пристрою у реєстрі." } }, + "zone": { + "go_to_core_config": "Перейти до загальних налаштувань?", + "home_zone_core_config": "Місцезнаходження вашої домашньої зони можна редагувати на сторінці загальних налаштувань. На даний час, радіус зони \"Головна\" не можна редагувати з адміністративної панелі. Ви хочете перейти до загальних налаштувань?" + }, "zwave": { "caption": "Z-Wave", "common": { @@ -1710,6 +1729,11 @@ "toggle": "Переключити {name}", "url": "Відкрити вікно для {url_path}" }, + "safe-mode": { + "description": "Home Assistant зіткнувся з проблемою під час завантаження конфігурації і тепер працює в безпечному режимі. Погляньте на журнал помилок, щоб побачити, що пішло не так.", + "header": "Активовано безпечний режим", + "show_errors": "Показати помилки" + }, "shopping-list": { "add_item": "Додати елемент", "checked_items": "Позначені елементи", @@ -1729,6 +1753,9 @@ "available_states": "Доступні стани", "name": "Панель сигналізації" }, + "button": { + "name": "Кнопка" + }, "conditional": { "name": "Умова" }, From 22e4c0512e881e0306e2af31c37ac85507481946 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Fri, 21 Feb 2020 13:59:09 +0100 Subject: [PATCH 02/33] Add GitHub Actions (#4952) --- .github/workflows/ci.yaml | 119 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 .github/workflows/ci.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000000..cbb95228fd --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,119 @@ +name: CI + +on: [push, pull_request] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Check out files from GitHub + uses: actions/checkout@v2 + - name: Setting up Node.js + uses: actions/setup-node@v1 + with: + node-version: 12.x + - name: Get yarn cache path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + - name: Fetching Yarn cache + uses: actions/cache@v1 + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + - name: Install dependencies + run: yarn install + env: + CI: true + - name: Build icons + run: ./node_modules/.bin/gulp gen-icons-hassio gen-icons-mdi gen-icons-app + - name: Build translations + run: ./node_modules/.bin/gulp build-translations + - name: Run eslint + run: ./node_modules/.bin/eslint src hassio/src gallery/src + - name: Run tslint + run: ./node_modules/.bin/tslint 'src/**/*.ts' 'hassio/src/**/*.ts' 'gallery/src/**/*.ts' 'cast/src/**/*.ts' 'test-mocha/**/*.ts' + - name: Run tsc + run: ./node_modules/.bin/tsc + test: + runs-on: ubuntu-latest + steps: + - name: Check out files from GitHub + uses: actions/checkout@v2 + - name: Setting up Node.js + uses: actions/setup-node@v1 + with: + node-version: 12.x + - name: Get yarn cache path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + - name: Fetching Yarn cache + uses: actions/cache@v1 + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + - name: Install dependencies + run: yarn install + env: + CI: true + - name: Run Mocha + run: npm run mocha + build: + runs-on: ubuntu-latest + needs: [lint, test] + steps: + - name: Check out files from GitHub + uses: actions/checkout@v2 + - name: Setting up Node.js + uses: actions/setup-node@v1 + with: + node-version: 12.x + - name: Get yarn cache path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + - name: Fetching Yarn cache + uses: actions/cache@v1 + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + - name: Install dependencies + run: yarn install + env: + CI: true + - name: Build Application + run: ./node_modules/.bin/gulp build-app + env: + TRAVIS: "true" + supervisor: + runs-on: ubuntu-latest + needs: [lint, test] + steps: + - name: Check out files from GitHub + uses: actions/checkout@v2 + - name: Setting up Node.js + uses: actions/setup-node@v1 + with: + node-version: 12.x + - name: Get yarn cache path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + - name: Fetching Yarn cache + uses: actions/cache@v1 + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + - name: Install dependencies + run: yarn install + env: + CI: true + - name: Build Application + run: ./node_modules/.bin/gulp build-hassio + env: + TRAVIS: "true" From 6e35c79c141f946dd6fbafb7ae5aa872a550c3e2 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Sat, 22 Feb 2020 00:32:31 +0000 Subject: [PATCH 03/33] [ci skip] Translation update --- translations/ko.json | 16 ++++++++++++++-- translations/pt-BR.json | 4 ++++ translations/ru.json | 7 ++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/translations/ko.json b/translations/ko.json index 63da61b68b..a5e1c6d61a 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -581,6 +581,7 @@ "entity": "관련된 구성요소", "group": "관련된 그룹", "integration": "통합 구성요소", + "no_related_found": "관련 항목을 찾을 수 없습니다.", "scene": "관련된 씬", "script": "관련된 스크립트" }, @@ -630,6 +631,7 @@ "unavailable": "이 구성요소는 현재 사용할 수 없습니다.", "update": "업데이트" }, + "no_unique_id": "이 구성요소는 고유한 ID 가 없으므로 설정을 UI에서 관리할 수 없습니다.", "related": "관련 내용", "settings": "설정" }, @@ -1323,6 +1325,7 @@ "filter": { "filter": "필터", "show_disabled": "비활성화 된 구성요소 표시", + "show_readonly": "읽기 전용 구성요소 표시", "show_unavailable": "사용할 수 없는 구성요소 표시" }, "header": "구성요소", @@ -1346,6 +1349,7 @@ "status": { "disabled": "비활성화", "ok": "확인", + "readonly": "읽기 전용", "unavailable": "사용불가" }, "unavailable": "(사용불가)" @@ -1690,7 +1694,7 @@ "create": "만들기", "delete": "삭제", "icon": "아이콘", - "icon_error_msg": "아이콘은 접두사:아이콘이름 형식이어야 합니다, 예: mdi:home", + "icon_error_msg": "아이콘은 접두사:아이콘이름 형식이어야 합니다. 예: mdi:home", "latitude": "위도", "longitude": "경도", "name": "이름", @@ -1701,7 +1705,10 @@ "required_error_msg": "이 입력란은 필수 요소입니다", "update": "업데이트" }, - "edit_home_zone": "집의 위치는 일반 설정에서 변경할 수 있습니다.", + "edit_home_zone": "집 지역의 반경은 아직 프런트엔드에서 편집할 수 없습니다. 집 지역을 이동하려면 지도에서 마커를 끌어놓아 주세요.", + "edit_home_zone_narrow": "집 지역의 반경은 아직 프런트엔드에서 편집할 수 없습니다. 위치는 일반 구성에서 변경할 수 있습니다.", + "go_to_core_config": "일반 구성으로 이동하시겠습니까?", + "home_zone_core_config": "집 지역의 위치는 일반 구성 페이지에서 편집할 수 있습니다. 집 지역의 반경은 아직 프런트엔드에서 편집할 수 없습니다. 일반 구성으로 이동하시겠습니까?", "introduction": "지역을 사용하면 지구 상의 특정 지역을 지정할 수 있습니다. 구성원이 지역 내에 있으면 구성요소 상태에서 지역의 이름을 가져옵니다. 자동화 설정 내에서 지역을 트리거 또는 조건으로 사용할 수도 있습니다.", "no_zones_created_yet": "아직 설정한 지역이 없는 것 같습니다." }, @@ -1909,6 +1916,11 @@ "toggle": "{name} 토글", "url": "{url_path} 창 열기" }, + "safe-mode": { + "description": "구성 내용을 읽어오는 중에 Home Assistant 에서 문제가 발생하여 안전 모드에서 실행 중입니다. 오류 로그를 참고하여 무엇이 잘못되었는지 확인해주세요.", + "header": "안전 모드 활성화", + "show_errors": "오류 표시" + }, "shopping-list": { "add_item": "항목 추가", "checked_items": "선택한 항목", diff --git a/translations/pt-BR.json b/translations/pt-BR.json index 2a21621f90..e3909e7a10 100644 --- a/translations/pt-BR.json +++ b/translations/pt-BR.json @@ -1872,6 +1872,10 @@ "toggle": "Alternar {name}", "url": "Abrir janela para {url_path}" }, + "safe-mode": { + "description": "O Home Assistant teve problemas ao carregar sua configuração e agora está sendo executado no modo de segurança. Dê uma olhada no log de erros para ver o que deu errado.", + "show_errors": "Mostrar erros" + }, "shopping-list": { "add_item": "Adicionar item", "checked_items": "Itens marcados", diff --git a/translations/ru.json b/translations/ru.json index 8dc780aaae..ec9ca43a4e 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -16,7 +16,7 @@ "domain": { "alarm_control_panel": "Панель сигнализации", "automation": "Автоматизация", - "binary_sensor": "Бинарный датчик", + "binary_sensor": "Бинарный сенсор", "calendar": "Календарь", "camera": "Камера", "climate": "Климат", @@ -47,7 +47,7 @@ "remote": "Пульт ДУ", "scene": "Сцена", "script": "Сценарий", - "sensor": "Датчик", + "sensor": "Сенсор", "sun": "Солнце", "switch": "Выключатель", "system_health": "Статус системы", @@ -581,6 +581,7 @@ "entity": "Связанные объекты", "group": "Используется в группах", "integration": "Интеграция", + "no_related_found": "Не найдено связей с другими элементами.", "scene": "Используется в сценах", "script": "Используется в сценариях" }, @@ -2034,7 +2035,7 @@ "sensor": { "graph_detail": "Детализация графика", "graph_type": "Тип графика", - "name": "Датчик" + "name": "Сенсор" }, "shopping-list": { "integration_not_loaded": "Для работы этой карточки необходимо настроить интеграцию `shopping_list`.", From b41369a2ad0171e0327d8371731aba934562b9e1 Mon Sep 17 00:00:00 2001 From: Tomasz Date: Sat, 22 Feb 2020 15:00:01 +0100 Subject: [PATCH 04/33] Localize tabs names in view editor (#4954) * Localize tabs * remove Polish localization --- .../lovelace/editor/view-editor/hui-edit-view.ts | 12 ++++++++++-- src/translations/en.json | 4 +++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/panels/lovelace/editor/view-editor/hui-edit-view.ts b/src/panels/lovelace/editor/view-editor/hui-edit-view.ts index 5750a1e261..1c44cc168a 100644 --- a/src/panels/lovelace/editor/view-editor/hui-edit-view.ts +++ b/src/panels/lovelace/editor/view-editor/hui-edit-view.ts @@ -142,8 +142,16 @@ export class HuiEditView extends LitElement { .selected="${this._curTabIndex}" @selected-item-changed="${this._handleTabSelected}" > - Settings - Badges + ${this.hass!.localize( + "ui.panel.lovelace.editor.edit_view.tab_settings" + )} + ${this.hass!.localize( + "ui.panel.lovelace.editor.edit_view.tab_badges" + )} ${content}
diff --git a/src/translations/en.json b/src/translations/en.json index 9173c28233..797078805e 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1773,7 +1773,9 @@ "edit": "Edit view", "delete": "Delete view", "move_left": "Move view left", - "move_right": "Move view right" + "move_right": "Move view right", + "tab_settings": "Settings", + "tab_badges": "Badges" }, "edit_card": { "header": "Card Configuration", From 12234de20e04a8eb17793e49e616288528109919 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Sun, 23 Feb 2020 00:32:34 +0000 Subject: [PATCH 05/33] [ci skip] Translation update --- translations/en.json | 4 +- translations/hu.json | 12 ++ translations/lv.json | 255 +++++++++++++++++++++++++++----------- translations/pl.json | 4 +- translations/zh-Hans.json | 115 ++++++++++++----- translations/zh-Hant.json | 4 +- 6 files changed, 288 insertions(+), 106 deletions(-) diff --git a/translations/en.json b/translations/en.json index 1a09f9519f..6f000a2908 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2084,7 +2084,9 @@ "header": "View Configuration", "header_name": "{name} View Configuration", "move_left": "Move view left", - "move_right": "Move view right" + "move_right": "Move view right", + "tab_badges": "Badges", + "tab_settings": "Settings" }, "header": "Edit UI", "menu": { diff --git a/translations/hu.json b/translations/hu.json index 2ebc091b6a..bcb5649d5f 100644 --- a/translations/hu.json +++ b/translations/hu.json @@ -581,6 +581,7 @@ "entity": "Kapcsolódó entitások", "group": "A következő csoportok része", "integration": "Integráció", + "no_related_found": "Nem található kapcsolódó elem.", "scene": "A következő jelenetek része", "script": "A következő szkriptek része" }, @@ -630,6 +631,7 @@ "unavailable": "Ez az entitás jelenleg nem elérhető.", "update": "FRISSÍTÉS" }, + "no_unique_id": "Ez az entitás nem rendelkezik egyedi azonosítóval, ezért a beállítások nem kezelhetők a felhasználói felületről.", "related": "Kapcsolatok", "settings": "Beállítások" }, @@ -1323,6 +1325,7 @@ "filter": { "filter": "Szűrő", "show_disabled": "Letiltott entitások megjelenítése", + "show_readonly": "Csak olvasható entitások megjelenítése", "show_unavailable": "Nem elérhető entitások megjelenítése" }, "header": "Entitások", @@ -1346,6 +1349,7 @@ "status": { "disabled": "Letiltott", "ok": "Ok", + "readonly": "Csak olvasható", "unavailable": "Nem elérhető" }, "unavailable": "(nem elérhető)" @@ -1702,6 +1706,9 @@ "update": "Frissítés" }, "edit_home_zone": "Az otthona címét az általános konfigurációnál változtathatja meg.", + "edit_home_zone_narrow": "A otthoni zóna sugara még nem szerkeszthető a frontendről. A hely az általános konfigurációtól módosítható.", + "go_to_core_config": "Ugrás az általános konfigurációra?", + "home_zone_core_config": "Az otthoni zóna helye szerkeszthető az általános konfigurációs lapon. A Főzóna sugara még nem szerkeszthető a frontendről. Szeretné az általános konfigurációt?", "introduction": "A zónák lehetővé teszik a Föld bizonyos területeinek megadását. Ha egy személy egy zónán belül van, az állapota felveszi a zóna nevét. A zónák eseményindítóként vagy feltételként is használhatók az automatizálási beállításokon belül.", "no_zones_created_yet": "Úgy tűnik, még nem hoztál létre zónákat." }, @@ -1909,6 +1916,11 @@ "toggle": "Váltás {name}", "url": "Ablak megnyitása: {url_path}" }, + "safe-mode": { + "description": "A Home Assistant a konfiguráció betöltése közben bajba került, és most csökkentett módban fut. Vessen egy pillantást a hibanaplóra, hogy lássa, mi romlott el.", + "header": "Biztonsági mód aktiválva", + "show_errors": "Hibák megjelenítése" + }, "shopping-list": { "add_item": "Tétel hozzáadása", "checked_items": "Bejelölt tételek", diff --git a/translations/lv.json b/translations/lv.json index 10e09dea7b..24d50483fc 100644 --- a/translations/lv.json +++ b/translations/lv.json @@ -50,7 +50,6 @@ "sensor": "Sensors", "sun": "Saule", "switch": "Slēdzis", - "system_health": "Sistēmas Veselība", "updater": "Atjauninātājs", "vacuum": "Putekļsūcējs", "weblink": "Weblink", @@ -116,7 +115,7 @@ "triggered": "Trig" }, "default": { - "entity_not_found": "Vienība Nav Atrasta", + "entity_not_found": "Vienība nav atrasta", "error": "Kļūda", "unavailable": "Nepie", "unknown": "Nez" @@ -549,19 +548,27 @@ "future": "Pēc {time}", "never": "Nekad", "past": "{time} atpakaļ" - }, - "service-picker": { - "service": "Pakalpojums" } }, "dialogs": { "config_entry_system_options": { - "enable_new_entities_description": "Ja atspējots, jaunatklātās vienības priekš {integration} netiks automātiski pievienotas Home Assistant.", + "enable_new_entities_description": "Ja atspējots, jaunatklātās {integration} integrācijas vienības netiks automātiski pievienotas Home Assistant.", "enable_new_entities_label": "Iespējot tikko pievienotās vienības.", - "title": "Sistēmas Opcijas priekš {integration}" + "title": "Sistēmas opcijas {integration} integrācijai", + "update": "Atjaunināt" + }, + "entity_registry": { + "editor": { + "name": "Nosaukuma pārlabošana", + "note": "Ievērībai: pašlaik tas var nedarboties ar visām integrācijām.", + "unavailable": "Šī vienība pašlaik nav pieejama." + } }, "more_info_control": { "dismiss": "Aizvērt dialogu", + "person": { + "create_zone": "Izveidot zonu no pašreizējās atrašanās vietas" + }, "script": { "last_action": "Pēdējā Darbība" }, @@ -578,7 +585,7 @@ "more_info_settings": { "back": "Atgriezties", "entity_id": "Vienības ID", - "name": "Piesķirt nosaukumu", + "name": "Nosaukuma pārlabošana", "save": "Saglabāt" }, "options_flow": { @@ -642,21 +649,21 @@ "areas": { "caption": "Apgabali", "create_area": "IZVEIDOT APGABALU", - "description": "Pārskats par visām vietām jūsu mājās.", + "description": "Pārskats par visiem jūsu mājās apgabaliem.", "editor": { "create": "IZVEIDOT", - "default_name": "Jauns Apgabals", + "default_name": "Jauns apgabals", "delete": "DZĒST", "update": "ATJAUNINĀT" }, - "no_areas": "Izskatās, ka jums vēl nav apgabalu!", + "no_areas": "Izskatās, ka vēl neesat izveidojis nevienu apgabalu.", "picker": { "create_area": "IZVEIDOT APGABALU", "header": "Apgabali", "integrations_page": "Integrāciju lapa", - "introduction": "Apgabali tiek izmantoti, lai organizētu ierīces atrašanās vietu. Šī informācija tiks izmantota visā Home Assistant, lai palīdzētu organizēt Jūsu saskarni, atļaujas un integrāciju ar citām sistēmām.", - "introduction2": "Lai novietotu ierīces apgabalā, izmantojiet zemāk esošo saiti, lai pārietu uz integrācijas lapu un pēc tam noklikšķiniet uz konfigurētas integrācijas, lai iegūtu ierīces kartiņu.", - "no_areas": "Izskatās, ka jums vēl nav apgabalu!" + "introduction": "Apgabali tiek izmantoti, lai organizētu ierīces atrašanās vietu. Šī informācija tiks izmantota daudzviet Home Assistant, lai palīdzētu organizēt lietotāja saskarni, atļaujas un integrācijas ar citām sistēmām.", + "introduction2": "Lai piesaistītu ierīces noteiktam apgabalam, izmantojiet zemāk esošo saiti, lai pārietu uz integrāciju lapu un tad noklikšķiniet uz konfigurētas integrācijas, lai nonāktu pie ierīču kartiņu saraksta.", + "no_areas": "Izskatās, ka vēl neesat izveidojis nevienu apgabalu." } }, "automation": { @@ -920,12 +927,16 @@ }, "customize": { "attributes_not_set": "Šie atribūti netika iestatīti. Iestatiet tos, ja vēlaties.", + "attributes_override": "Varat pārlabot pēc savas patikas.", "caption": "Pielāgojumi", "description": "Pielāgojiet jūsu iekārtas", - "pick_attribute": "Izvēlieties atribūtu, kuru neievērot", + "pick_attribute": "Izvēlieties atribūtu, kuru pārlabot", "picker": { "header": "Pielāgojumi", - "introduction": "Korekcijas atribūti vienai vienībai. Pievienotās / labotās pielāgošanas stāsies spēkā nekavējoties. Noņemtie pielāgojumi stāsies spēkā, kad vienība tiks atjaunināta." + "introduction": "Uzlabojiet atribūtus katrai vienībai. Pievienotie jeb mainīties pielāgojumi stāsies spēkā nekavējoties. Noņemtie pielāgojumi stāsies spēkā, kad vienība tiks atjaunināta." + }, + "warning": { + "not_applied": "Veiktās izmaiņas ir saglabātas, bet netiks piemērotas veicot konfigurācijas pārlādēšanu, ja vien tajā include." } }, "devices": { @@ -952,20 +963,60 @@ "caption": "Vienības", "description": "Pārskats par visām zināmajām vienībām.", "editor": { - "default_name": "Jauns Apgabals", + "confirm_delete": "Vai tiešām vēlaties dzēst šo ierakstu?", + "confirm_delete2": "Dzēšot ierakstu, Home Assistant vienība netiks noņemta. Lai to izdarītu, no Home Assistant jānoņem '{platform}' integrācija.", + "default_name": "Jauns apgabals", "delete": "DZĒST", "enabled_cause": "Atspējots dēļ {cause}.", "enabled_description": "Atspējotās vienības netiks pievienotas Home Assistant.", "enabled_label": "Iespējot vienību", - "note": "Piezīme: tas var vēl nedarboties ar visām integrācijām.", + "entity_id": "Vienības ID", + "name": "Nosaukuma pārlabošana", + "note": "Ievērībai: pašlaik tas var nedarboties ar visām integrācijām.", "unavailable": "Šī vienība pašlaik nav pieejama.", "update": "ATJAUNINĀT" }, "picker": { + "disable_selected": { + "button": "Atspējot atlasītās", + "confirm_text": "Atspējotās vienības netiks pievienotas Home Assistant.", + "confirm_title": "Vai vēlaties atspējot {number} vienības?" + }, + "enable_selected": { + "button": "Iespējot atlasītās", + "confirm_text": "Tas atkārtoti padarīs tās pieejamas Home Assistant, ja tās šobrīd ir atspējotas.", + "confirm_title": "Vai vēlaties iespējot {number} vienības?" + }, + "filter": { + "filter": "Filtrēt", + "show_disabled": "Rādīt atspējotās vienības", + "show_readonly": "Rādīt tikai lasāmās vienības", + "show_unavailable": "Rādīt nepieejamās vienības" + }, "header": "Vienības", + "headers": { + "enabled": "Iespējota", + "entity_id": "Vienības ID", + "integration": "Integrācija", + "name": "Nosaukums", + "status": "Statuss" + }, "integrations_page": "Integrāciju lapa", - "introduction": "Home Assistant uztur katras vienības reģistru, kuru var unikāli identificēt. Katrai no šīm vienībām tiks piešķirts vienības ID, kas tiks rezervēts tikai šai vienībai.", - "introduction2": "Izmantojiet vienību reģistru, lai piešķirtu vārdu, mainītu vienību ID vai noņemtu ierakstu no Home Assistant. Ņemiet vērā: noņemot vienības reģistra ierakstu, vienība netiks noņemta. Lai to izdarītu, sekojiet zemāk esošajai saitei un noņemiet to no integrācijas lapas.", + "introduction": "Home Assistant uztur visu vienību reģistru, kuras jebkad parādījušās un kuras var unikāli identificēt. Katrai no šīm vienībām piešķirts vienības ID, kas tiks rezervēts tikai šai vienībai.", + "introduction2": "Izmantojiet vienību reģistru, lai pārlabotu nosaukumu, mainītu vienības ID vai noņemtu ierakstu no Home Assistant.", + "remove_selected": { + "button": "Noņemt atlasītās", + "confirm_text": "Vienības var noņemt tikai tad, kad tās vairs nerada attiecīgā integrācija.", + "confirm_title": "Vai vēlaties noņemt {number} vienības?" + }, + "selected": "{numurs} atlasītas", + "show_disabled": "Rādīt atspējotās vienības", + "status": { + "disabled": "Atspējota", + "ok": "Ok", + "readonly": "Tikai lasāma", + "unavailable": "Nepieejama" + }, "unavailable": "(nav pieejams)" } }, @@ -973,27 +1024,32 @@ "integrations": { "caption": "Integrācijas", "config_entry": { + "area": "Apgabalā {area}", + "delete_button": "Dzēst {integration}", "delete_confirm": "Vai tiešām vēlaties dzēst šo integrāciju?", "device_unavailable": "ierīce nav pieejama", "entity_unavailable": "vienība nav pieejama", "firmware": "Programmaparatūra: {version}", "hub": "Savienots caur", "manuf": "{manufacturer}", - "no_area": "Nav Apgabala", - "no_device": "Vienības, bez ierīcēm", + "no_area": "Nav apgabala", + "no_device": "Vienības bez ierīcēm", "no_devices": "Šai integrācijai nav ierīču.", "restart_confirm": "Restartēt Home Assistant, lai pabeigtu šīs integrācijas noņemšanu", + "settings_button": "Rediģēt {integration} integrācijas iestatījumus", + "system_options_button": "Sistēmas opcijas {integration} integrācijai", "via": "Savienots ar" }, "config_flow": { "aborted": "Pārtraukts", - "add_area": "Pievienot Apgabalu", + "add_area": "Pievienot apgabalu", "area_picker_label": "Apgabals", "close": "Aizvērt", - "created_config": "Tika izveidota konfigurācija {name}.", + "created_config": "Tika izveidota {name} integrācijas konfigurācija.", + "dismiss": "Aizvērt dialogu", "error_saving_area": "Kļūda saglabājot apgabalu: {error}", "external_step": { - "description": "Šajā solī ir nepieciešams, lai jūs apmeklētu ārēju tīmekļa vietni, lai pabeigtu.", + "description": "Šī soļa pabeigšanai ir nepieciešams apmeklēt ārēju tīmekļa vietni.", "open_site": "Atvērt tīmekļa vietni" }, "failed_create_area": "Neizdevās izveidot apgabalu.", @@ -1003,35 +1059,54 @@ "submit": "Iesniegt" }, "configure": "Konfigurēt", - "configured": "Konfigurēts", + "configured": "Nokonfigurētās", "description": "Pārvaldīt un iestatīt integrācijas", "details": "Integrācijas detaļas", - "discovered": "Atklāts", + "discovered": "Atklātās", + "home_assistant_website": "Home Assistant tīmekļa vietne", "ignore": { - "confirm_delete_ignore": "Tas ļaus integrācijai atkal parādīties jūsu atklātajās integrācijās, kad tā tiks atklāta. Tam var būt nepieciešama restartēšana vai nepieciešams ilgāks laiks.", + "confirm_delete_ignore": "Tas ļaus integrācijai atkal parādīties starp atklātajām integrācijām. Atklāšanai var būt nepieciešama restartēšana vai nepieciešams ilgāks laiks.", "confirm_delete_ignore_title": "Pārtraukt ignorēt {name}?", "confirm_ignore": "Vai tiešām nevēlaties iestatīt šo integrāciju? To varat atsaukt, augšējā labajā stūrī noklikšķinot uz “Rādīt ignorētās integrācijas” pārpildes izvēlnē.", "confirm_ignore_title": "Ignorēt {name} atklāšanu?", "hide_ignored": "Slēpt ignorētās integrācijas", "ignore": "Ignorēt", - "ignored": "Ignorēts", + "ignored": "Ignorētās", "show_ignored": "Rādīt ignorētās integrācijas", - "stop_ignore": "Pārtraukt ignorēt" + "stop_ignore": "Pārtraukt ignorēšanu" }, "integration_not_found": "Integrācija nav atrasta.", "new": "Izveidot jaunu integrāciju", - "none": "Nekas vēl nav konfigurēts" + "none": "Pagaidām nekas nav nokonfigurēts", + "note_about_integrations": "Pagaidām ne visas integrācijas var nokonfigurēt, izmantojot lietotāja saskarni.", + "note_about_website_reference": "Vairāk informācijas vietnē " }, "introduction": "Šeit iespējams konfigurēt Jūsu komponentus un pašu Home Assistant. Pagaidām ne visu ir iespējams konfigurēt no lietotāja saskarnes, bet mēs strādājam pie tā.", "person": { + "add_person": "Pievienot personu", "caption": "Personas", + "confirm_delete": "Vai tiešām vēlaties dzēst šo personu?", + "confirm_delete2": "Visas šai personai piederošās ierīces kļus par nepiesaistītām.", + "create_person": "Izveidot personu", "description": "Pārvaldīt personas, kuras izseko Home Assistant.", "detail": { + "create": "Izveidot", + "delete": "Dzēst", "device_tracker_intro": "Atlasiet ierīces, kas pieder šai personai.", "device_tracker_pick": "Izvēlieties izsekojamo ierīci", "device_tracker_picked": "Izsekot Ierīci", - "name": "Nosaukums" - } + "link_integrations_page": "Integrāciju lapa", + "link_presence_detection_integrations": "Klātbūtnes noteikšanas integrācijas", + "linked_user": "Saistītais lietotājs", + "name": "Vārds", + "name_error_msg": "Nepieciešams vārds", + "new_person": "Jauna persona", + "no_device_tracker_available_intro": "Ja jums ir ierīces, kas norāda uz personas klātbūtni, jūs šeit varēsit tās piesaistīt personai. Pirmo ierīci varat pievienot, integrāciju lapā pievienojot klātbūtnes noteikšanas integrāciju.", + "update": "Atjaunināt" + }, + "introduction": "Šeit jūs varat definēt personas izmantošanai Home Assistant.", + "no_persons_created_yet": "Izskatās, ka vēl neesat izveidojis nevienu personu.", + "note_about_persons_configured_in_yaml": "Ievērībai: configuration.yaml konfigurētās personas nevar rediģēt, izmantojot lietotāja saskarni." }, "scene": { "activated": "Aktivizēta aina {name}.", @@ -1079,20 +1154,29 @@ "description": "Veidojiet un rediģējiet skriptus", "editor": { "alias": "Nosaukums", + "default_name": "Jauns skripts", + "delete_confirm": "Vai tiešām vēlaties dzēst šo skriptu?", "delete_script": "Dzēst skriptu", + "header": "Skripts: {name}", "introduction": "Izmantojiet skriptus, lai izpildītu darbību secību.", "link_available_actions": "Uzzināt vairāk par pieejamām darbībām.", + "load_error_not_editable": "Rediģējami ir tikai scripts.yaml esošie skripti.", "sequence": "Secība", "sequence_sentence": "Šī skripta darbību secība." }, "picker": { + "add_script": "Pievienot skriptu", "edit_script": "Rediģēt skriptu", - "trigger_script": "Izsaukšanas skripts" + "header": "Skriptu redaktors", + "introduction": "Skriptu redaktors ļauj jums izveidot un rediģēt skriptus. Lūdzu, izmantojiet zemāk esošo saiti, lai izlasītu instrukcijas, lai pārliecinātos, ka esat pareizi konfigurējis Home Assistant.", + "learn_more": "Uzziniet vairāk par skriptiem", + "no_scripts": "Rediģējami skripti nav atrasti", + "trigger_script": "Izpildīt skriptu" } }, "server_control": { - "caption": "Servera Pārvaldība", - "description": "Restartēt un apturēt Home Assistant serveri", + "caption": "Servera vadība", + "description": "Home Assistant servera restartēšana un apturēšana", "section": { "reloading": { "automation": "Pārlādēt automatizācijas", @@ -1100,8 +1184,10 @@ "group": "Pārlādēt grupas", "heading": "Konfigurācijas pārlādēšana", "introduction": "Atsevišķas Home Assistant daļas var pārlādēt bez nepieciešamības restartēt. Veicot pārlādēšanu iepriekšējā konfigurācija tiks atiestatīta un tiks ielādēta jaunā.", + "person": "Pārlādēt personas", "scene": "Pārlādēt ainas", - "script": "Pārlādēt skriptus" + "script": "Pārlādēt skriptus", + "zone": "Pārlādēt zonas" }, "server_management": { "confirm_restart": "Vai tiešām vēlaties restartēt Home Assistant?", @@ -1132,13 +1218,25 @@ "description": "Pārvaldīt lietotājus", "editor": { "activate_user": "Aktivizēt lietotāju", + "active": "Aktīvs", "caption": "Skatīt lietotāju", "change_password": "Mainīt paroli", + "confirm_user_deletion": "Vai tiešām vēlaties dzēst {name}?", "deactivate_user": "Deaktivizēt lietotāju", "delete_user": "Dzēst lietotāju", - "rename_user": "Pārdēvēt lietotāju" + "enter_new_name": "Ievadiet jauno vārdu", + "group": "Grupa", + "group_update_failed": "Grupas atjaunināšana neizdevās:", + "id": "ID", + "owner": "Īpašnieks", + "rename_user": "Pārdēvēt lietotāju", + "system_generated": "Sistēmas ģenerēts", + "system_generated_users_not_removable": "Nevar noņemt sistēmas ģenerētos lietotājus.", + "unnamed_user": "Lietotājs bez vārda", + "user_rename_failed": "Lietotāja pārdēvēšana neizdevās:" }, "picker": { + "system_generated": "Sistēmas ģenerēts", "title": "Lietotāji" } }, @@ -1146,6 +1244,7 @@ "add_device_page": { "discovery_text": "Šeit tiks parādītas atklātās ierīces. Izpildiet ierīces (-ču) instrukcijas un iestatiet ierīci (-es) pārī savienošanas režīmā.", "header": "Zigbee Home Automation - Pievienot ierīces", + "search_again": "Atkārtot meklēšanu", "spinner": "Meklē ZHA Zigbee ierīces..." }, "caption": "ZHA", @@ -1161,6 +1260,35 @@ "updateDeviceName": "Ierīču reģistrā iestatiet šai ierīcei pielāgotu nosaukumu." } }, + "zone": { + "add_zone": "Pievienot zonu", + "caption": "Zonas", + "configured_in_yaml": "configuration.yaml konfigurētās zonas nevar rediģēt, izmantojot lietotāja saskarni.", + "confirm_delete": "Vai tiešām vēlaties dzēst šo zonu?", + "create_zone": "Izveidot zonu", + "description": "Pārvaldiet zonas, kurās vēlaties izsekot personām.", + "detail": { + "create": "Izveidot", + "delete": "Dzēst", + "icon": "Ikona", + "icon_error_msg": "Ikonai jābūt formātā prefikss:nosaukums, piemēram: mdi:home", + "latitude": "Platums", + "longitude": "Garums", + "name": "Nosaukums", + "new_zone": "Jauna zona", + "passive": "Pasīva", + "passive_note": "Pasīvās zonas netiek rādītas lietotāja saskarnē un netiek izmantotas kā atrašanās vieta ierīču izsekošanai. Tas ir noderīgi, ja vēlaties tās izmantot tikai automatizācijai.", + "radius": "Rādiuss", + "required_error_msg": "Šis lauks ir obligāts", + "update": "Atjaunināt" + }, + "edit_home_zone": "Mājas zonas rādiusu pagaidām nevar rediģēt, izmantojot lietotāja saskarni. Velciet marķieri kartē, lai pārvietotu mājas zonu.", + "edit_home_zone_narrow": "Mājas zonas rādiusu pagaidām nevar rediģēt, izmantojot lietotāja saskarni. Atrašanās vietu var mainīt no vispārējās konfigurācijas.", + "go_to_core_config": "Doties uz vispārējo konfigurāciju?", + "home_zone_core_config": "Jūsu mājas zonas atrašanās vietu var rediģēt no vispārējās konfigurācijas lapas. Mājas zonas rādiusu pagaidām nevar rediģēt, izmantojot lietotāja saskarni. Vai vēlaties pāriet uz vispārīgo konfigurāciju?", + "introduction": "Zonas ļauj norādīt noteiktus reģionus uz zemes. Kad cilvēks atrodas zonā, vienības stāvoklim tiks izmantots zonas nosaukums. Zonas var izmantotas kā aktivators vai nosacījums automatizācijās.", + "no_zones_created_yet": "Izskatās, ka vēl neesat izveidojis nevienu zonu." + }, "zwave": { "caption": "Z-Wave", "common": { @@ -1217,35 +1345,6 @@ "question_trust": "Vai Jūs uzticaties ārējam panelim {name} uz {link}?" } }, - "developer-tools": { - "tabs": { - "events": { - "title": "Notikumi" - }, - "info": { - "title": "Informācija" - }, - "logs": { - "title": "Žurnāli" - }, - "mqtt": { - "title": "MQTT" - }, - "services": { - "title": "Pakalpojumi" - }, - "states": { - "copied": "Kopēts starpliktuvē", - "copy_entity_attribute": "Kopēt atribūtus", - "copy_entity_id": "Kopēt ID", - "copy_entity_state": "Kopēt stāvokli", - "title": "Stāvokļi" - }, - "templates": { - "title": "Veidne" - } - } - }, "history": { "period": "Periods", "showing_entries": "Rāda ierakstus par" @@ -1284,6 +1383,9 @@ "card": { "entities": { "toggle": "Pārslēgt vienības." + }, + "map": { + "default_zoom": "Noklusējuma mērogs" } }, "edit_card": { @@ -1352,7 +1454,7 @@ "domain": "Domēns", "entity": "Vienība", "entity_id": "Vienības ID", - "last_changed": "Pēdējo reizi Mainīts", + "last_changed": "Pēdējo reizi mainīts", "select_to_add": "Izvēlieties vienību, kuru vēlaties pievienot kartei, un pēc tam noklikšķiniet uz pogu pievienot karti.", "title": "Neizmantotās vienības" }, @@ -1538,6 +1640,11 @@ } }, "profile": { + "advanced_mode": { + "description": "Dod piekļuvi papildu funcionalitātei", + "link_promo": "Uzziniet vairāk", + "title": "Detalizētais režīms" + }, "change_password": { "confirm_new_password": "Apstipriniet jauno paroli", "current_password": "Pašreizējā parole", @@ -1548,7 +1655,7 @@ }, "current_user": "Jūs šobrīd esat pieteicies kā {fullName}.", "force_narrow": { - "description": "Tas pēc noklusējuma slēps sānjoslu, līdzīgi kā mobilajās ierīcēs.", + "description": "Sānjosla pēc noklusējuma tiks slēpta, līdzīgi kā mobilajās ierīcēs.", "header": "Vienmēr slēpt sānjoslu" }, "is_owner": "Jūs esat īpašnieks.", @@ -1564,7 +1671,7 @@ "create_failed": "Neizdevās izveidot piekļuves pilnvaru.", "created_at": "Izveidots {date}", "delete_failed": "Neizdevās dzēst piekļuves pilnvaru.", - "description": "Izveidojiet ilgtermiņa piekļuves pilnvaras, lai ļautu jūsu skriptiem mijiedarboties ar jūsu Home Assistant instanci. Katra pilnvara būs derīga 10 gadus pēc tās radīšanas. Pašlaik ir aktīvas sekojošas ilgstošas piekļuves pilvaras.", + "description": "Izveidojiet ilgtermiņa piekļuves pilnvaras, lai ļautu jūsu skriptiem mijiedarboties ar jūsu Home Assistant instanci. Katra pilnvara būs derīga 10 gadus pēc tās izveidošanas. Pašlaik ir aktīvas sekojošas ilgtermiņa piekļuves pilvaras.", "empty_state": "Jums vēl nav ilgtermiņa piekļuves pilnvaru.", "header": "Ilgtermiņas piekļuves pilnvaras", "last_used": "Pēdējoreiz izmantots {date} no {location}", @@ -1589,7 +1696,7 @@ "push_notifications": { "description": "Sūtīt paziņojumus uz šo ierīci.", "error_load_platform": "Konfigurēt notify.html5.", - "error_use_https": "Nepieciešama SSL iespējošana priekšpusei.", + "error_use_https": "Nepieciešama SSL iespējošana priekšgalsistēmai.", "header": "Pašpiegādes paziņojumi", "link_promo": "Uzziniet vairāk", "push_notifications": "Pašpiegādes paziņojumi" @@ -1599,7 +1706,7 @@ "created_at": "Izveidots {date}", "current_token_tooltip": "Nevar izdzēst pašreizējo atsvaidzināšanas pilnvaru", "delete_failed": "Neizdevās dzēst atsvaidzināšanas pilnvaru.", - "description": "Katra atsvaidzināšanas pilvara pārstāv pieteikšanās sesiju. Atsvaidzināšanas pilvaras tiks automātiski noņemtas, kad Jūs izrakstīsieties. Šāda atsvaidzināšanas pilvaras ir pašreiz aktīvas Jūsu kontā.", + "description": "Katra atsvaidzināšanas pilvara apzīmē pieteikšanās sesiju. Atsvaidzināšanas pilvaras tiks automātiski noņemtas, kad Jūs izrakstīsieties. Jūsu kontam šobrīd aktīvas ir sekojošas atsvaidzināšanas pilvaras.", "header": "Atsvaidzināšanas pilnvaras", "last_used": "Pēdējoreiz izmantots {date} no {location}", "not_used": "Nekad nav izmantots", @@ -1610,6 +1717,10 @@ "error_no_theme": "Nav nevienas tēmas", "header": "Tēma", "link_promo": "Uzziniet par tēmām" + }, + "vibrate": { + "description": "Iespējot vai atspējot vibrāciju šajā ierīcē, kontrolējot ierīces.", + "header": "Vibrācija" } }, "shopping-list": { diff --git a/translations/pl.json b/translations/pl.json index e3907b074f..5725ea88ed 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -1515,7 +1515,7 @@ "section": { "reloading": { "automation": "Automatyzacje", - "core": "Lokacje i dostosowywanie", + "core": "Lokalizacja i dostosowywanie", "group": "Grupy", "heading": "Ponowne wczytanie konfiguracji", "introduction": "Niektóre części konfiguracji można wczytać od nowa bez konieczności ponownego uruchamiania Home Assistant'a. Naciśnięcie poniższych przycisków wczyta ponownie daną część konfiguracji.", @@ -1952,7 +1952,7 @@ }, "entities": { "name": "Encje", - "show_header_toggle": "Pokaż przełącznik w nagłówku?", + "show_header_toggle": "Pokaż przełącznik w nagłówku", "toggle": "Przełącz encje" }, "entity-button": { diff --git a/translations/zh-Hans.json b/translations/zh-Hans.json index 37ff0c2ca3..6d095b0e55 100644 --- a/translations/zh-Hans.json +++ b/translations/zh-Hans.json @@ -503,7 +503,7 @@ "currently": "当前", "on_off": "开/关", "operation": "操作", - "target_temperature": "设定温度" + "target_temperature": "目标温度" }, "weather": { "attributes": { @@ -581,6 +581,7 @@ "entity": "相关实体", "group": "以下群组的一部分", "integration": "集成", + "no_related_found": "找不到相关项目。", "scene": "以下场景的一部分", "script": "以下脚本的一部分" }, @@ -604,7 +605,7 @@ "config_entry_system_options": { "enable_new_entities_description": "如果禁用,从 {integration} 新发现的实体将不会自动添加到 Home Assistant。", "enable_new_entities_label": "启用新添加的实体。", - "title": "{integration}的系统选项", + "title": "{integration} 系统选项", "update": "更新" }, "confirmation": { @@ -630,6 +631,7 @@ "unavailable": "该实体暂不可用。", "update": "更新" }, + "no_unique_id": "该实体没有唯一的ID,因此无法由UI进行管理设置。", "related": "关联", "settings": "设置" }, @@ -666,7 +668,7 @@ }, "vacuum": { "clean_spot": "清理污渍", - "commands": "扫地机指令:", + "commands": "吸尘器清扫指令:", "fan_speed": "风扇转速", "locate": "定位", "pause": "暂停", @@ -697,7 +699,7 @@ "found": "为您找到以下结果:", "how_can_i_help": "请问需要什么帮助?", "label": "输入问题,然后按回车", - "label_voice": "输入后按回车,或点击麦克风图标后讲话" + "label_voice": "输入后按「Enter」或点击麦克风图标后进行语音命令" }, "zha_device_info": { "buttons": { @@ -712,7 +714,7 @@ "manuf": "制造商:{manufacturer}", "no_area": "没有区域", "power_source": "电源", - "quirk": "怪癖", + "quirk": "Quirk", "services": { "reconfigure": "这将重新配置 ZHA 设备(复原设备)。如果您的设备遇到问题,请使用此项。如果有问题的设备是由电池供电的,请确保在使用此服务时它处于唤醒状态并可以接受指令。", "remove": "从 Zigbee 网络中删除设备。", @@ -1107,7 +1109,7 @@ "email": "电子邮件", "email_error_msg": "无效电子邮件", "instructions": "输入您的电子邮件地址,我们将向您发送一个链接以重置密码。", - "send_reset_email": "发送重置电子邮件", + "send_reset_email": "发送重置邮件", "subtitle": "忘记密码", "title": "忘记密码" }, @@ -1249,7 +1251,7 @@ }, "create": "通过设备创建自动化", "no_automations": "没有自动化", - "no_device_automations": "该设备没有可用的自动化。", + "no_device_automations": "该设备没有任何自动化可使用。", "triggers": { "caption": "当以下事件发生时:" } @@ -1270,7 +1272,7 @@ "details": "这是设备的所有详细信息。", "device_not_found": "未找到设备。", "entities": { - "add_entities_lovelace": "添加设备的所有实体到 Lovelace", + "add_entities_lovelace": "添加设备的所有实体到 Lovelace UI", "entities": "实体", "none": "这个设备没有实体" }, @@ -1323,6 +1325,7 @@ "filter": { "filter": "筛选", "show_disabled": "显示已禁用的实体", + "show_readonly": "显示只读实体", "show_unavailable": "显示不可用的实体" }, "header": "实体", @@ -1338,6 +1341,7 @@ "introduction2": "使用本实体注册工具重写名称,修改实体 ID 或者从 Home Assistant 删除实体。注意,删除实体注册信息并不会删除实体本身。如果要删除实体,请点击下面的链接进入集成页面进行操作。", "remove_selected": { "button": "删除所选实体", + "confirm_text": "仅当集成不再提供实体时才能进行删除。", "confirm_title": "您要删除这 {number} 个实体吗?" }, "selected": "选择了 {number} 项", @@ -1345,6 +1349,7 @@ "status": { "disabled": "已禁用", "ok": "确定", + "readonly": "只读", "unavailable": "不可用" }, "unavailable": "(不可用)" @@ -1375,7 +1380,7 @@ "add_area": "新建区域", "area_picker_label": "区域", "close": "关闭", - "created_config": "为{name}创建了配置。", + "created_config": "新增 {name} 设置。", "dismiss": "关闭对话框", "error_saving_area": "保存区域时发生错误:{error}", "external_step": { @@ -1573,10 +1578,14 @@ "zha": { "add_device_page": { "discovery_text": "发现的设备将显示在此处。按照设备的说明进行操作,并将设备置于配对模式。", - "header": "Zigbee家庭自动化 - 添加设备", + "header": "Zigbee 家庭自动化 - 添加设备", "search_again": "再次搜索", "spinner": "正在寻找ZHA Zigbee设备......" }, + "add": { + "caption": "添加设备", + "description": "将设备添加到Zigbee网络" + }, "caption": "ZHA", "cluster_attributes": { "attributes_of_cluster": "所选集群的属性", @@ -1596,7 +1605,9 @@ "issue_zigbee_command": "发出Zigbee命令" }, "clusters": { - "help_cluster_dropdown": "选择一个集群以查看属性和命令。" + "header": "集群", + "help_cluster_dropdown": "选择一个集群以查看属性和命令。", + "introduction": "集群是Zigbee功能的构建基础,它们将功能分成逻辑单元。 有客户端和服务器类型,由属性和命令组成。" }, "common": { "add_devices": "添加设备", @@ -1611,17 +1622,49 @@ "device_name_placeholder": "用户指定的名称", "update_name_button": "更新名称" }, + "devices": { + "header": "Zigbee 家庭自动化 - 设备" + }, "group_binding": { - "bind_button_help": "将选定的组绑定到所选的设备集群。", - "bind_button_label": "绑定组", + "bind_button_help": "将选定的群组绑定到所选的设备集群。", + "bind_button_label": "绑定群组", "cluster_selection_help": "选择要绑定到所选组的集群。", "group_picker_help": "选择一个组来进行绑定。", "group_picker_label": "可绑定的组", - "header": "组绑定", - "introduction": "绑定和取消绑定组。", - "unbind_button_help": "从选定的设备集群中取消绑定选定的组。", - "unbind_button_label": "取消绑定组" + "header": "群组绑定", + "introduction": "绑定和取消绑定群组。", + "unbind_button_help": "从选定的设备集群中取消绑定选定的群组。", + "unbind_button_label": "取消绑定群组" }, + "groups": { + "add_members": "添加成员", + "adding_members": "添加成员中", + "caption": "群组", + "create": "创建群组", + "create_group": "Zigbee 家庭自动化 - 新增群组", + "create_group_details": "输入所需的详细信息以创建新的zigbee组", + "creating_group": "创建群组中", + "description": "创建和修改Zigbee组", + "group_details": "以下是所选Zigbee组的所有详细信息。", + "group_id": "组号", + "group_info": "群组信息", + "group_name_placeholder": "群组名", + "group_not_found": "找不到群组!", + "group-header": "Zigbee 家庭自动化 - 群组资讯", + "groups": "组", + "groups-header": "Zigbee 家庭自动化 - 群组管理", + "header": "Zigbee 家庭自动化 - 群组管理", + "introduction": "创建和修改zigbee组", + "manage_groups": "管理Zigbee组", + "members": "成员", + "remove_groups": "删除群组", + "remove_members": "删除成员", + "removing_groups": "删除群组中", + "removing_members": "删除成员中", + "zha_zigbee_groups": "ZHA Zigbee组" + }, + "header": "配置 Zigbee 家庭自动化", + "introduction": "在这里可以配置ZHA组件。 目前尚未支持在UI中进行所有的配置,但我们正在努力啦。", "network_management": { "header": "网络管理", "introduction": "影响整个网络的命令" @@ -1637,7 +1680,8 @@ "reconfigure": "重新配置ZHA设备(唤醒设备)。如果您的设备遇到问题,请使用此项。如果有问题的设备是电池供电的,请确保在使用此服务时它处于唤醒状态并可以接受指令。", "remove": "从 Zigbee 网络中删除设备。", "updateDeviceName": "在设备注册表中为此设备设置自定义名称。" - } + }, + "title": "Zigbee 家庭自动化" }, "zone": { "add_zone": "添加地点", @@ -1645,7 +1689,7 @@ "configured_in_yaml": "通过 configuration.yaml 配置的地点不能通过 UI 编辑。", "confirm_delete": "您确定要删除此地点吗?", "create_zone": "创建地点", - "description": "管理要跟踪的人员所在的区域。", + "description": "管理要跟踪人员的区域。", "detail": { "create": "创建", "delete": "删除", @@ -1661,7 +1705,10 @@ "required_error_msg": "此字段为必填字段", "update": "更新" }, - "edit_home_zone": "家所在的位置可以在通用配置中更改。", + "edit_home_zone": "住址的半径尚无法由前端进行设定、于地图上拖拉标示以移动住址位置。", + "edit_home_zone_narrow": "住址的半径尚无法由前端进行设定、但可以于一般设定中变更其位置。", + "go_to_core_config": "转换至常规配置?", + "home_zone_core_config": "住址的位置可以于一般设定页面中进行编辑、但半径尚无法编辑。是否要切换至一般设定?", "introduction": "地点用于定义世界的某个地方。若某人位于一个地点,则其状态的名称就取自该地点。地点也可用作自动化配置中的触发条件和环境条件。", "no_zones_created_yet": "看来您还没有建立地点。" }, @@ -1694,7 +1741,7 @@ "false": "False", "header": "节点配置选项", "seconds": "秒", - "set_config_parameter": "设置配置参数", + "set_config_parameter": "设置参数", "set_wakeup": "设置唤醒间隔", "true": "True" }, @@ -1723,7 +1770,7 @@ "external_panel": { "complete_access": "它将有权访问 Home Assistant 中的所有数据。", "hide_message": "查看有关 panel_custom 的文档以隐藏此消息", - "question_trust": "您是否信任{link}处的外部面板{name}?" + "question_trust": "您是否信任 {link} 处的外部面板 {name}?" } }, "developer-tools": { @@ -1846,8 +1893,8 @@ }, "lovelace": { "add_entities": { - "generated_unsupported": "只有在自行编辑 Lovelace 时才能使用此功能。", - "saving_failed": "保存 Lovelace 配置失败。", + "generated_unsupported": "只有在自行编辑 Lovelace UI 时才能使用此功能。", + "saving_failed": "保存 Lovelace UI 设置失败。", "yaml_unsupported": "在 YAML 模式下使用 Lovelace 时不能使用此功能。" }, "cards": { @@ -1869,6 +1916,11 @@ "toggle": "切换{name}", "url": "打开窗口前往 {url_path}" }, + "safe-mode": { + "description": "Home Assistant 在加载配置时遇到问题,正以安全模式执行中。请查看错误日志,以找出问题。", + "header": "安全模式已开启", + "show_errors": "显示错误" + }, "shopping-list": { "add_item": "新增项目", "checked_items": "已完成项目", @@ -1900,7 +1952,7 @@ }, "entities": { "name": "实体", - "show_header_toggle": "显示页眉切换?", + "show_header_toggle": "显示名称切换?", "toggle": "切换实体。" }, "entity-button": { @@ -2036,7 +2088,7 @@ }, "header": "编辑 UI", "menu": { - "open": "打开 Lovelace 菜单", + "open": "打开 Lovelace UI 菜单", "raw_editor": "原始配置编辑器" }, "migrate": { @@ -2046,11 +2098,11 @@ "para_no_id": "此元素没有 ID。请在 'ui-lovelace.yaml' 中为此元素添加 ID。" }, "raw_editor": { - "confirm_remove_config_text": "如果您删除了 Lovelace 配置,我们将通过您的区域和设备自动生成 Lovelace 视图。", - "confirm_remove_config_title": "您确定要删除 Lovelace 配置吗?我们将通过您的区域和设备自动生成 Lovelace 视图。", + "confirm_remove_config_text": "如果您删除了 Lovelace UI 设置的话,我们将通过您的区域和设备自动生成 Lovelace UI 面板。", + "confirm_remove_config_title": "您确定要删除 Lovelace UI 设置吗?我们将通过您的区域和设备自动生成 Lovelace UI 面板。", "confirm_unsaved_changes": "您有未保存的更改,确定要退出吗?", "confirm_unsaved_comments": "您的配置包含注释,这些注释将不会保存。是否继续?", - "error_invalid_config": "您的配置无效: {error}", + "error_invalid_config": "您的配置无效:{error}", "error_parse_yaml": "无法解析YAML:{error}", "error_remove": "无法删除配置:{error}", "error_save_yaml": "无法保存YAML:{error}", @@ -2066,6 +2118,11 @@ "para_sure": "您确定要自行编辑用户界面吗?", "save": "自行编辑" }, + "suggest_card": { + "add": "添加至 Lovelace UI", + "create_own": "选择其他卡", + "header": "我们为您提出了一条建议" + }, "view": { "panel_mode": { "description": "这将使第一张卡片全屏显示。此视图中的其他卡将不会呈现。", diff --git a/translations/zh-Hant.json b/translations/zh-Hant.json index 433a60b07e..728ddf4b72 100644 --- a/translations/zh-Hant.json +++ b/translations/zh-Hant.json @@ -1046,7 +1046,7 @@ }, "integrations": "整合", "integrations_introduction": "Home Assistant Cloud 雲服務整合可連線至其他雲服務、而不需將您的 Home Assistant 暴露在整個網際網路上。", - "integrations_introduction2": "開啟網站 ", + "integrations_introduction2": "開啟網站", "integrations_link_all_features": " 所有可用功能", "manage_account": "管理帳號", "nabu_casa_account": "Nabu Casa 帳號", @@ -1071,7 +1071,7 @@ "no_hooks_yet": "看起來您尚未建立 Webhook,可藉由設定 ", "no_hooks_yet_link_automation": "Webhook 自動化", "no_hooks_yet_link_integration": "Webhook 整合", - "no_hooks_yet2": " 或新增一組 ", + "no_hooks_yet2": "或新增一組", "title": "Webhooks" } }, From de8bca69677249a873e4219f55776edae3dc2045 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Mon, 24 Feb 2020 00:32:30 +0000 Subject: [PATCH 06/33] [ci skip] Translation update --- translations/ca.json | 4 +- translations/da.json | 4 +- translations/de.json | 5 +- translations/el.json | 5 ++ translations/hu.json | 4 +- translations/nl.json | 9 ++- translations/pl.json | 4 +- translations/ro.json | 159 ++++++++++++++++++++++++++++++++++---- translations/ru.json | 4 +- translations/zh-Hans.json | 2 +- translations/zh-Hant.json | 4 +- 11 files changed, 180 insertions(+), 24 deletions(-) diff --git a/translations/ca.json b/translations/ca.json index 21f48285ca..caec1db5bc 100644 --- a/translations/ca.json +++ b/translations/ca.json @@ -2084,7 +2084,9 @@ "header": "Configuració de la visualització", "header_name": "Configuració de la visualització {name}", "move_left": "Desplaça la visualització cap a l'esquerra", - "move_right": "Desplaça la visualització cap a la dreta" + "move_right": "Desplaça la visualització cap a la dreta", + "tab_badges": "Etiquetes", + "tab_settings": "Configuració" }, "header": "Editar la interfície d'usuari (UI)", "menu": { diff --git a/translations/da.json b/translations/da.json index 8f7cef85f7..ffa62acfa0 100644 --- a/translations/da.json +++ b/translations/da.json @@ -2084,7 +2084,9 @@ "header": "Vis konfiguration", "header_name": "{name}-visningskonfiguration", "move_left": "Flyt visningen til venstre", - "move_right": "Flyt visningen til højre" + "move_right": "Flyt visningen til højre", + "tab_badges": "Badges", + "tab_settings": "Indstillinger" }, "header": "Rediger brugerflade", "menu": { diff --git a/translations/de.json b/translations/de.json index 6c481e6f29..7772606e61 100644 --- a/translations/de.json +++ b/translations/de.json @@ -631,6 +631,7 @@ "unavailable": "Diese Entität ist derzeit nicht verfügbar.", "update": "AKTUALISIEREN" }, + "no_unique_id": "Diese Entität hat keine eindeutige ID, daher können die Einstellungen nicht über die UI verwaltet werden.", "related": "Verwandte", "settings": "Einstellungen" }, @@ -1324,6 +1325,7 @@ "filter": { "filter": "Filter", "show_disabled": "Anzeigen deaktivierter Entitäten", + "show_readonly": "Anzeigen schreibgeschützter Entitäten", "show_unavailable": "Anzeigen nicht verfügbarer Entitäten" }, "header": "Entitäten", @@ -2079,7 +2081,8 @@ "header": "Konfiguration anzeigen", "header_name": "{name} Konfiguration anzeigen", "move_left": "Ansicht nach links verschieben", - "move_right": "Ansicht nach rechts verschieben" + "move_right": "Ansicht nach rechts verschieben", + "tab_settings": "Einstellungen" }, "header": "Benutzeroberfläche bearbeiten", "menu": { diff --git a/translations/el.json b/translations/el.json index 1d6d9aa145..0b07c10b3f 100644 --- a/translations/el.json +++ b/translations/el.json @@ -536,6 +536,7 @@ }, "common": { "cancel": "Ακύρωση", + "close": "Κλείστε", "loading": "Φόρτωση", "no": "Όχι", "save": "Αποθήκευση", @@ -1217,6 +1218,9 @@ "description": "Διαχείριση συνδεδεμένων συσκευών", "details": "Δείτε όλες τις λεπτομέρειες της συσκευής σας.", "device_not_found": "Η συσκευή δε βρέθηκε.", + "entities": { + "add_entities_lovelace": "Προσθήκη στο Lovelace" + }, "info": "Πληροφορίες συσκευής", "name": "Όνομα", "scene": { @@ -1502,6 +1506,7 @@ "issue_zigbee_command": "Έκδοση εντολής Zigbee" }, "clusters": { + "header": "Συστοιχίες", "help_cluster_dropdown": "Επιλέξτε μια συστοιχία για να προβάλετε τα χαρακτηριστικά και τις εντολές." }, "common": { diff --git a/translations/hu.json b/translations/hu.json index bcb5649d5f..05bd034ae9 100644 --- a/translations/hu.json +++ b/translations/hu.json @@ -2084,7 +2084,9 @@ "header": "Nézet konfigurálása", "header_name": "{name} Konfiguráció megtekintése", "move_left": "Nézet mozgatása balra", - "move_right": "Nézet mozgatása jobbra" + "move_right": "Nézet mozgatása jobbra", + "tab_badges": "Kitűzők", + "tab_settings": "Beállítások" }, "header": "Felhasználói felület szerkesztése", "menu": { diff --git a/translations/nl.json b/translations/nl.json index c966c8dd2f..dc7021e29c 100644 --- a/translations/nl.json +++ b/translations/nl.json @@ -1916,6 +1916,11 @@ "toggle": "Omschakelen {name}", "url": "Open venster naar {url_path}" }, + "safe-mode": { + "description": "Home Assistant heeft problemen ondervonden tijdens het laden van uw configuratie en werkt nu in de veilige modus. Bekijk het foutenlogboek om te zien wat er mis is gegaan.", + "header": "Veilige modus geactiveerd", + "show_errors": "Foutmeldingen weergeven" + }, "shopping-list": { "add_item": "Item toevoegen", "checked_items": "Geselecteerde items", @@ -2079,7 +2084,9 @@ "header": "Bekijk de configuratie", "header_name": "{name} Bekijk de configuratie", "move_left": "Verplaats weergave naar links", - "move_right": "Verplaats weergave naar rechts" + "move_right": "Verplaats weergave naar rechts", + "tab_badges": "Badges", + "tab_settings": "instellingen" }, "header": "Bewerk UI", "menu": { diff --git a/translations/pl.json b/translations/pl.json index 5725ea88ed..2f925d9069 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -2084,7 +2084,9 @@ "header": "Konfiguracja widoku", "header_name": "Konfiguracja widoku {name}", "move_left": "Przesuń widok w lewo", - "move_right": "Przesuń widok w prawo" + "move_right": "Przesuń widok w prawo", + "tab_badges": "Odznaki", + "tab_settings": "Ustawienia" }, "header": "Edycja interfejsu użytkownika", "menu": { diff --git a/translations/ro.json b/translations/ro.json index 75d0091dec..eacf65649e 100644 --- a/translations/ro.json +++ b/translations/ro.json @@ -522,6 +522,7 @@ }, "common": { "cancel": "Revocare", + "close": "Închide", "loading": "Se încarcă", "save": "Salvați", "successfully_saved": "Opțiunile salvate cu succes." @@ -564,6 +565,7 @@ "entity": "Entități conexe", "group": "Parte din următoarele grupuri", "integration": "Integrare", + "no_related_found": "Nu s-au găsit elemente corelate.", "scene": "Parte din următoarele scenarii", "script": "Parte din următoarele scripturi" }, @@ -587,7 +589,8 @@ "config_entry_system_options": { "enable_new_entities_description": "Dacă sunt dezactivate, entitățile recent descoperite pentru {integration} nu vor fi adăugate automat la Home Assistant.", "enable_new_entities_label": "Activează entitățile nou adăugate", - "title": "Opțiuni de sistem pentru {integration}" + "title": "Opțiuni de sistem pentru {integration}", + "update": "Actualizare" }, "entity_registry": { "control": "Control", @@ -604,6 +607,7 @@ "unavailable": "Această entitate nu este disponibilă momentan.", "update": "ACTUALIZARE" }, + "no_unique_id": "Această entitate nu are un ID unic, prin urmare, setările sale nu pot fi gestionate de la interfața cu utilizatorul.", "related": "În legătură cu", "settings": "Setări" }, @@ -614,6 +618,16 @@ }, "more_info_control": { "edit": "Editează entitatea", + "person": { + "create_zone": "Creare zonă din locația curentă" + }, + "restored": { + "confirm_remove_text": "Sigur doriți să eliminați această entitate?", + "confirm_remove_title": "Ștergeți entitatea?", + "not_provided": "Această entitate este momentan indisponibilă și este orfană pentru o integrare sau dispozitiv eliminat, modificat sau disfuncțional.", + "remove_action": "Eliminați entitatea", + "remove_intro": "Dacă entitatea nu mai este utilizată, aveți posibilitatea să o curățați eliminând-o." + }, "script": { "last_action": "Ultima acțiune", "last_triggered": "Ultima declanșare" @@ -627,10 +641,15 @@ "title": "Actualizați instrucțiunile" }, "vacuum": { + "clean_spot": "Loc curat", + "commands": "Comenzi aspirator:", + "fan_speed": "Viteza ventilatorului", + "locate": "Localizaţi", "pause": "Pauza", "return_home": "Návrat domov", "start": "Štart", "start_pause": "Štart/Pouza", + "status": "Stare", "stop": "Stop" } }, @@ -823,6 +842,7 @@ "label": "Descriere", "placeholder": "Descriere opțională" }, + "enable_disable": "Activare/Dezactivare automatizare", "introduction": "Utilizați automatizări pentru a vă aduce casa în viață", "load_error_not_editable": "Numai automatizările din automations.yaml pot fi editate.", "load_error_unknown": "Eroare la încărcarea automatizării ({err_no}).", @@ -925,6 +945,15 @@ } }, "cloud": { + "account": { + "alexa": { + "config_documentation": "Documentație de configurare" + }, + "google": { + "config_documentation": "Documentație de configurare", + "sync_entities_404_message": "Sincronizarea entităților cu Google nu a reușit, cereți Google \"Hey Google, sync my devices\" să vă sincronizeze entitățile." + } + }, "caption": "Home Assistant Cloud", "description_features": "Controlați-vă casa de la distanta, integrați-vă cu Alexa și Asistentul Google.", "description_login": "Logat ca {email}", @@ -1006,6 +1035,11 @@ "cant_edit": "Poți edita numai elementele create în UI.", "caption": "Dispozitive", "description": "Gestionați dispozitivele conectate", + "entities": { + "add_entities_lovelace": "Adăugați la Lovelace", + "entities": "Entități", + "none": "Acest dispozitiv nu are entități" + }, "name": "Nume", "scene": { "create": "Creează un scenariu cu dispozitivul", @@ -1036,11 +1070,42 @@ "update": "ACTUALIZAȚI" }, "picker": { + "disable_selected": { + "button": "Dezactivați selecția", + "confirm_text": "Entitățile dezactivate nu vof fi adăugate in Home Assistant", + "confirm_title": "Doriți să dezactivați {number} entități?" + }, + "enable_selected": { + "button": "Activați selectarea", + "confirm_text": "Acest lucru le va face disponibile în Home Assistant din nou, dacă acestea sunt acum dezactivate.", + "confirm_title": "Doriți să activați {number} entități?" + }, + "filter": { + "filter": "Filtru", + "show_disabled": "Afișare entități dezactivate", + "show_readonly": "Afișare entități doar în citire", + "show_unavailable": "Afișare entități indisponibile" + }, "header": "Entități", + "headers": { + "status": "Stare" + }, "integrations_page": "Pagina de integrari", "introduction": "Home Assistant păstrează un registru al fiecărei entități pe care a văzut-o vreodată, care poate fi identificată în mod unic. Fiecare dintre aceste entități va avea un ID de entitate atribuit care va fi rezervat doar pentru această entitate.", "introduction2": "Utilizați registrul de entități pentru a înlocui numele, schimba identitatea entității sau a elimina înregistrarea din Home Assistant. Rețineți că eliminarea intrării din registrul entității nu va elimina entitatea. Pentru aceasta, urmați linkul de mai jos și eliminați-l din pagina de integrare.", + "remove_selected": { + "button": "Sterge selectia", + "confirm_text": "Entitățile pot fi eliminate numai atunci când integrarea nu mai oferă entitățile.", + "confirm_title": "Doriți să eliminați {number} entități?" + }, + "selected": "{number} selectate", "show_disabled": "Afișare entități dezactivate", + "status": { + "disabled": "Dezactivat", + "ok": "In regula", + "readonly": "Mod doar citire", + "unavailable": "Indisponibil" + }, "unavailable": "(indisponibil)" } }, @@ -1076,6 +1141,16 @@ "configured": "Configurat", "description": "Gestionați și configurați integrările", "discovered": "Descoperit", + "ignore": { + "confirm_delete_ignore": "Acest lucru va face ca integrarea să apară din nou în integrările descoperite atunci când este descoperită. Acest lucru ar putea necesita o repornire sau să dureze ceva timp.", + "confirm_delete_ignore_title": "Încetați să ignorați {name} ?", + "confirm_ignore": "Sunteți sigur că nu doriți să configurați această integrare? Puteți anula acest lucru făcând clic pe „Afișați integrări ignorate” din meniul de preaplin din partea dreaptă sus.", + "confirm_ignore_title": "Ignorați descoperirea {name} ?", + "hide_ignored": "Ascundeți integrările ignorate", + "ignored": "Ignorat", + "show_ignored": "Afișați integrări ignorate", + "stop_ignore": "Nu mai ignorați" + }, "new": "Configurați o nouă integrare", "none": "Nimic nu a fost configurat încă" }, @@ -1099,6 +1174,9 @@ "devices": { "header": "Dispozitive" }, + "entities": { + "introduction": "Entitățile care nu aparțin unui dispozitiv pot fi setate aici." + }, "load_error_not_editable": "Numai scenele din scene.yaml sunt editabile.", "name": "Nume", "save": "Salvează", @@ -1134,8 +1212,8 @@ "automation": "Reîncarcă automatizările", "core": "Reîncărcați locația și personalizările", "group": "Reîncărcați grupurile", - "heading": "Reîncărcarea configurației", - "introduction": "Unele părți din Home Assistant se pot reîncărca fără a necesita o repornire. Apăsarea reîncărcării va dezactiva configurația actuală și va încărca noua configurație.", + "heading": "Reîncărcarea configurației YAML", + "introduction": "Unele părți din Home Assistant se pot reîncărca fără a necesita o repornire. Apăsarea reîncărcării va descărca configurația actuală și va încărca noua configurație.", "person": "Reîncărcare persoane", "scene": "Reîncărca scenarii", "script": "Reîncărcați script-uri", @@ -1216,16 +1294,40 @@ "unbind_button_label": "Deconectează grupul" }, "groups": { + "add_members": "Adăugați membri", + "adding_members": "Adăugarea membrilor", "caption": "Grupuri", + "create": "Creare Grup", + "create_group": "Zigbee Home Automation - Creare grup", + "create_group_details": "Introduceți detaliile necesare pentru a crea un nou grup zigbee", + "creating_group": "Crearea grupului", "description": "Creează și modifică grupurile Zigbee", + "group_details": "Iată toate detaliile pentru grupul Zigbee selectat.", + "group_id": "ID de grup", + "group_info": "Informații de grup", + "group_name_placeholder": "Numele Grupului", + "group_not_found": "Grupul nu a fost găsit!", "group-header": "Zigbee Home Automation - Detalii despre grup", - "groups-header": "Zigbee Home Automation - Managementul grupului" + "groups": "Grupuri", + "groups-header": "Zigbee Home Automation - Managementul grupului", + "header": "Zigbee Home Automation - Managementul grupului", + "introduction": "Crearea și modificarea grupurilor zigbee", + "manage_groups": "Gestionați grupurile Zigbee", + "members": "Membri", + "remove_groups": "Eliminare grupuri", + "remove_members": "Eliminați membrii", + "removing_groups": "Eliminarea Grupuri", + "removing_members": "Eliminarea Membrilor", + "zha_zigbee_groups": "Grupuri ZHA Zigbee" }, + "header": "Configurați automatizarea Zigbee Home", + "introduction": "Aici este posibil să configurați componenta ZHA. Nu totul este posibil pentru a configura de la UI încă, dar lucrăm la ea.", "services": { "reconfigure": "Reconfigurați dispozitivul ZHA (dispozitiv de vindecare). Utilizați acest lucru dacă aveți probleme cu dispozitivul. Dacă dispozitivul în cauză este un dispozitiv alimentat cu baterii, asigurați-vă că este treaz și accepta comenzi atunci când utilizați acest serviciu.", "remove": "Eliminați un dispozitiv din rețeaua Zigbee.", "updateDeviceName": "Setați un nume personalizat pentru acest dispozitiv în registrul de dispozitive." - } + }, + "title": "Automatizare Zigbee Home" }, "zone": { "add_zone": "Adăugare zonă", @@ -1249,7 +1351,10 @@ "required_error_msg": "Acest câmp este obligatoriu", "update": "Actualizează" }, - "edit_home_zone": "Locația casei tale poate fi modificată în configurarea generală.", + "edit_home_zone": "Raza zonei Acasă nu poate fi încă editată din frontend. Trageți marcatorul pe hartă pentru a muta zona de origine.", + "edit_home_zone_narrow": "Raza zonei Acasă nu poate fi editată încă de pe frontend. Locația poate fi modificată din configurația generală.", + "go_to_core_config": "Mergeți la configurația generală?", + "home_zone_core_config": "Locația zonei de domiciliu este editabilă din pagina de configurare generală. Raza zonei Acasă nu poate fi editată încă de pe frontend. Doriți să accesați configurația generală?", "introduction": "Zonele vă permit să specificați anumite regiuni de pe pământ. Când o persoană se află într-o zonă, identificatorul va lua numele din zonă. Zonele pot fi de asemenea utilizate ca declanșator sau condiție în cadrul setărilor de automatizare.", "no_zones_created_yet": "Se pare că nu ai creat încă nici o zonă." }, @@ -1291,7 +1396,7 @@ "cancel_command": "Anulați comanda", "heal_network": "Heal Network", "remove_node": "Eliminare nod", - "save_config": "Salvați Configurația", + "save_config": "Salvați configurația", "soft_reset": "Resetare soft", "start_network": "Porniți rețeaua", "stop_network": "Opriți rețeaua", @@ -1394,6 +1499,11 @@ "showing_entries": "Arată intrări pentru" }, "lovelace": { + "add_entities": { + "generated_unsupported": "Puteți utiliza această funcție numai atunci când ați preluat controlul asupra UI Lovelace.", + "saving_failed": "Salvarea configurației UI Lovelace a eșuat.", + "yaml_unsupported": "Nu se poate utiliza această funcție atunci când utilizați Lovelace UI în modul YAML." + }, "cards": { "empty_state": { "go_to_integrations_page": "Du-te la pagina integrări.", @@ -1411,6 +1521,11 @@ "tap": "Atingeți:", "toggle": "Comutați {name}" }, + "safe-mode": { + "description": "Home Assistant a avut probleme în timpul încărcării configurației și rulează acum în modul de siguranță. Aruncati o privire la jurnalul de erori pentru a vedea ce a mers prost.", + "header": "Mod de siguranță activat", + "show_errors": "Arată erori" + }, "shopping-list": { "add_item": "Adaugare element", "checked_items": "Elementele selectate", @@ -1418,11 +1533,14 @@ } }, "changed_toast": { - "message": "Configurația Lovelace a fost actualizată, doriți să reîmprospătați?", + "message": "Configurația Lovelace UI a fost actualizată, reîmprospătați pentru a vedea modificările?", "refresh": "Reîmprospătare" }, "editor": { "card": { + "button": { + "name": "Buton" + }, "entities": { "toggle": "Schimbati entitatile" }, @@ -1443,7 +1561,7 @@ }, "edit_lovelace": { "edit_title": "Editează titlul", - "explanation": "Acest titlu este arătat mai sus toate punctele de vedere în Lovelace.", + "explanation": "Acest titlu este arătat mai sus de toate punctele de vedere în Lovelace.", "header": "Titlul interfeței dvs. Lovelace" }, "edit_view": { @@ -1452,12 +1570,14 @@ "edit": "Editați vizualizarea", "header": "Vizualizați configurația", "move_left": "Mutare vizualizare la stânga", - "move_right": "Mutare vizualizare dreapta" + "move_right": "Mutare vizualizare dreapta", + "tab_badges": "Insigne", + "tab_settings": "Setări" }, "header": "Editați interfața utilizator", "menu": { - "open": "Deschideti meniul Lovelace", - "raw_editor": "Raw config editor" + "open": "Deschideți meniul Lovelace UI", + "raw_editor": "Editor de configurare brut" }, "migrate": { "header": "Configurație Incompatibilă", @@ -1466,10 +1586,13 @@ "para_no_id": "Acest element nu are un ID. Adăugați un ID la acest element în \"ui-lovelace.yaml\"." }, "raw_editor": { + "confirm_remove_config_text": "Vom genera automat vizualizările UI Lovelace cu zonele și dispozitivele dvs., dacă eliminați configurația UI Lovelace.", + "confirm_remove_config_title": "Sigur eliminați configurația Ui Lovelace? Vom genera automat vizualizările UI Lovelace cu zonele și dispozitivele dvs.", "confirm_unsaved_changes": "Aveți modificări nesalvate, sunteți sigur că doriți să ieșiți?", "confirm_unsaved_comments": "Configurația dvs. conține comentarii, acestea nu vor fi salvate. Doriți să continuați?", "error_invalid_config": "Configurația dvs. nu este validă: {error}", "error_parse_yaml": "Eroare de parsare YAML: {error}", + "error_remove": "Imposibil de eliminat configurația: {error}", "error_save_yaml": "Imposibil de salvat YAML: {error}", "header": "Editați configurația", "save": "Salvați", @@ -1479,9 +1602,14 @@ "save_config": { "cancel": "Nu contează", "header": "Preia controlul asupra interfața dvs. Lovelace", - "para": "În mod implicit, Home Assistant va menține interfața dvs. de utilizator, actualizându-l atunci când entitățile noi sau componente Lovelace devin disponibile. Dacă preluați controlul, nu vom mai face automat modificări pentru dvs.", + "para": "În mod implicit, Home Assistant va menține interfața dvs. de utilizator, actualizând-o atunci când entitățile noi sau componente Lovelace devin disponibile. Dacă preluați controlul, nu vom mai face automat modificări pentru dvs.", "para_sure": "Sigur doriți să preluați controlul asupra interfeței dvs. de utilizator?", "save": "Preia controlul" + }, + "suggest_card": { + "add": "Adăugați la Lovelace UI", + "create_own": "Alege alt card", + "header": "Am creat o sugestie pentru dumneavoastră" } }, "menu": { @@ -1491,7 +1619,7 @@ "refresh": "Reîmprospătare", "unused_entities": "Entități neutilizate" }, - "reload_lovelace": "Reîncarcă Lovelace", + "reload_lovelace": "Reîncarcă Lovelace UI", "unused_entities": { "available_entities": "Acestea sunt entitățile pe care le aveți disponibile, dar nu sunt încă în UI dvs. Lovelace.", "domain": "Domeniu", @@ -1577,7 +1705,7 @@ "data": { "password": "Parola API" }, - "description": "Introduceti parola API in http config:" + "description": "Vă rugăm să introduceți parola API în configurația http:" }, "mfa": { "data": { @@ -1684,6 +1812,7 @@ }, "profile": { "advanced_mode": { + "description": "Deblochează funcțiile avansate.", "link_promo": "Află mai multe" }, "change_password": { diff --git a/translations/ru.json b/translations/ru.json index ec9ca43a4e..9b7ca5b284 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -2077,7 +2077,9 @@ "header": "Настройки вкладки", "header_name": "Настройки вкладки \"{name}\"", "move_left": "Переместить вкладку влево", - "move_right": "Переместить вкладку вправо" + "move_right": "Переместить вкладку вправо", + "tab_badges": "Значки", + "tab_settings": "Настройки" }, "header": "Редактирование интерфейса", "menu": { diff --git a/translations/zh-Hans.json b/translations/zh-Hans.json index 6d095b0e55..15aeb71101 100644 --- a/translations/zh-Hans.json +++ b/translations/zh-Hans.json @@ -1705,7 +1705,7 @@ "required_error_msg": "此字段为必填字段", "update": "更新" }, - "edit_home_zone": "住址的半径尚无法由前端进行设定、于地图上拖拉标示以移动住址位置。", + "edit_home_zone": "住址的半径目前不能在前端设定。请在地图上拖动标示以移动家的区域。", "edit_home_zone_narrow": "住址的半径尚无法由前端进行设定、但可以于一般设定中变更其位置。", "go_to_core_config": "转换至常规配置?", "home_zone_core_config": "住址的位置可以于一般设定页面中进行编辑、但半径尚无法编辑。是否要切换至一般设定?", diff --git a/translations/zh-Hant.json b/translations/zh-Hant.json index 728ddf4b72..d7ad3880a2 100644 --- a/translations/zh-Hant.json +++ b/translations/zh-Hant.json @@ -2084,7 +2084,9 @@ "header": "檢視設定", "header_name": "{name} 檢視設定", "move_left": "向左移動視圖", - "move_right": "向右移動視圖" + "move_right": "向右移動視圖", + "tab_badges": "園標圖示", + "tab_settings": "設定" }, "header": "編輯 UI", "menu": { From 5d2242dd16ac8cd9cf540e3d3b6ba04d6cab5f8b Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 24 Feb 2020 02:29:40 -0800 Subject: [PATCH 07/33] Add a smarter default value for entity card show header toggle (#4964) --- .../lovelace/cards/hui-entities-card.ts | 25 ++++++++++++++++--- .../common/generate-lovelace-config.ts | 1 - 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/panels/lovelace/cards/hui-entities-card.ts b/src/panels/lovelace/cards/hui-entities-card.ts index 2f6dea1af7..f4fc025b7a 100644 --- a/src/panels/lovelace/cards/hui-entities-card.ts +++ b/src/panels/lovelace/cards/hui-entities-card.ts @@ -25,6 +25,8 @@ import { EntitiesCardConfig, EntitiesCardEntityConfig } from "./types"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { createHeaderFooterElement } from "../create-element/create-header-footer-element"; import { LovelaceHeaderFooterConfig } from "../header-footer/types"; +import { DOMAINS_TOGGLE } from "../../../common/const"; +import { computeDomain } from "../../../common/entity/compute_domain"; @customElement("hui-entities-card") class HuiEntitiesCard extends LitElement implements LovelaceCard { @@ -44,6 +46,7 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard { private _hass?: HomeAssistant; private _configEntities?: EntitiesCardEntityConfig[]; + private _showHeaderToggle?: boolean; set hass(hass: HomeAssistant) { this._hass = hass; @@ -78,6 +81,22 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard { this._config = { theme: "default", ...config }; this._configEntities = entities; + if (config.show_header_toggle === undefined) { + // Default value is show toggle if we can at least toggle 2 entities. + let toggleable = 0; + for (const rowConf of entities) { + if (!rowConf.entity) { + continue; + } + toggleable += Number(DOMAINS_TOGGLE.has(computeDomain(rowConf.entity))); + if (toggleable === 2) { + break; + } + } + this._showHeaderToggle = toggleable === 2; + } else { + this._showHeaderToggle = config.show_header_toggle; + } } protected updated(changedProps: PropertyValues): void { @@ -110,9 +129,7 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard { ${this._config.header ? this.renderHeaderFooter(this._config.header, "header") : ""} - ${!this._config.title && - !this._config.show_header_toggle && - !this._config.icon + ${!this._config.title && !this._showHeaderToggle && !this._config.icon ? "" : html`
@@ -127,7 +144,7 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard { : ""} ${this._config.title}
- ${this._config.show_header_toggle === false + ${!this._showHeaderToggle ? html`` : html` [entity.entity_id, entity]), { title: area.name, - show_header_toggle: true, } ) ); From 95aa29d6cafe1db0f036a326b7a3f1c0c57dfd97 Mon Sep 17 00:00:00 2001 From: Ruslan Sayfutdinov Date: Mon, 24 Feb 2020 10:38:05 +0000 Subject: [PATCH 08/33] Fix layout of history and logbook filters (#4963) --- src/panels/history/ha-panel-history.js | 5 ++++- src/panels/logbook/ha-panel-logbook.js | 10 ++++++++-- src/resources/ha-date-picker-style.js | 6 +++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/panels/history/ha-panel-history.js b/src/panels/history/ha-panel-history.js index 70f8ee2d03..432f24d247 100644 --- a/src/panels/history/ha-panel-history.js +++ b/src/panels/history/ha-panel-history.js @@ -41,7 +41,10 @@ class HaPanelHistory extends LocalizeMixin(PolymerElement) { margin-right: 16px; margin-top: 5px; --paper-input-container-label-floating: { - padding-bottom: 10px; + padding-bottom: 11px; + } + --paper-input-suffix: { + height: 24px; } } diff --git a/src/panels/logbook/ha-panel-logbook.js b/src/panels/logbook/ha-panel-logbook.js index c0a1a66133..3c2c0d0f85 100644 --- a/src/panels/logbook/ha-panel-logbook.js +++ b/src/panels/logbook/ha-panel-logbook.js @@ -52,7 +52,7 @@ class HaPanelLogbook extends LocalizeMixin(PolymerElement) { .filters { display: flex; - align-items: center; + align-items: flex-end; } :host([narrow]) .filters { @@ -73,7 +73,10 @@ class HaPanelLogbook extends LocalizeMixin(PolymerElement) { max-width: 100px; margin-right: 16px; --paper-input-container-label-floating: { - padding-bottom: 10px; + padding-bottom: 11px; + } + --paper-input-suffix: { + height: 24px; } } @@ -92,6 +95,9 @@ class HaPanelLogbook extends LocalizeMixin(PolymerElement) { display: inline-block; flex-grow: 1; max-width: 400px; + --paper-input-suffix: { + height: 24px; + } } :host([narrow]) ha-entity-picker { diff --git a/src/resources/ha-date-picker-style.js b/src/resources/ha-date-picker-style.js index 61d8d80b7e..185b29d453 100644 --- a/src/resources/ha-date-picker-style.js +++ b/src/resources/ha-date-picker-style.js @@ -6,7 +6,8 @@ documentContainer.innerHTML = ` From 18abc6adf7525ea07aa3d514beea167b246f0bbf Mon Sep 17 00:00:00 2001 From: Sergey Avdeev Date: Mon, 24 Feb 2020 13:43:58 +0300 Subject: [PATCH 09/33] Update icon_color_css.ts (#4962) --- src/common/style/icon_color_css.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/common/style/icon_color_css.ts b/src/common/style/icon_color_css.ts index 565fd065e2..8f868e000a 100644 --- a/src/common/style/icon_color_css.ts +++ b/src/common/style/icon_color_css.ts @@ -29,6 +29,10 @@ export const iconColorCSS = css` color: var(--heat-color, #ff8100); } + ha-icon[data-domain="climate"][data-state="drying"] { + color: var(--dry-color, #efbd07); + } + ha-icon[data-domain="alarm_control_panel"] { color: var(--alarm-color-armed, var(--label-badge-red)); } From 028b370ead58e96d8478ab7261917ed6661e8c67 Mon Sep 17 00:00:00 2001 From: Ruslan Sayfutdinov Date: Mon, 24 Feb 2020 12:50:22 +0000 Subject: [PATCH 10/33] [logbook] fix scrolling on iOS (#4950) * [logbook] fix scrolling on iOS * Update styling * Update ha-logbook.ts Co-authored-by: Bram Kragten --- src/panels/logbook/ha-logbook.ts | 33 ++++++--- src/panels/logbook/ha-panel-logbook.js | 92 ++++++++++++-------------- 2 files changed, 67 insertions(+), 58 deletions(-) diff --git a/src/panels/logbook/ha-logbook.ts b/src/panels/logbook/ha-logbook.ts index f72edab10c..91a2890b54 100644 --- a/src/panels/logbook/ha-logbook.ts +++ b/src/panels/logbook/ha-logbook.ts @@ -15,7 +15,7 @@ import { } from "lit-element"; import { HomeAssistant } from "../../types"; import { fireEvent } from "../../common/dom/fire_event"; -import "lit-virtualizer"; +import { scroll } from "lit-virtualizer"; import { LogbookEntry } from "../../data/logbook"; class HaLogbook extends LitElement { @@ -44,19 +44,23 @@ class HaLogbook extends LitElement { } return html` - - this._renderLogbookItem(item, index)} - style="height: 100%;" - > +
+ ${scroll({ + items: this.entries, + renderItem: (item: LogbookEntry, index?: number) => + this._renderLogbookItem(item, index), + })} +
`; } private _renderLogbookItem( item: LogbookEntry, - index: number + index?: number ): TemplateResult { + if (!index) { + return html``; + } const previous = this.entries[index - 1]; const state = item.entity_id ? this.hass.states[item.entity_id] : undefined; return html` @@ -149,6 +153,19 @@ class HaLogbook extends LitElement { a { color: var(--primary-color); } + + .uni-virtualizer-host { + display: block; + position: relative; + contain: strict; + height: 100%; + overflow: auto; + padding: 0 16px; + } + + .uni-virtualizer-host > * { + box-sizing: border-box; + } `; } } diff --git a/src/panels/logbook/ha-panel-logbook.js b/src/panels/logbook/ha-panel-logbook.js index 3c2c0d0f85..2deaf83a67 100644 --- a/src/panels/logbook/ha-panel-logbook.js +++ b/src/panels/logbook/ha-panel-logbook.js @@ -27,10 +27,6 @@ class HaPanelLogbook extends LocalizeMixin(PolymerElement) { static get template() { return html` - `; + `, + ]; } } diff --git a/src/panels/lovelace/cards/hui-stack-card.ts b/src/panels/lovelace/cards/hui-stack-card.ts index bcd165470c..3d0a1b5fa7 100644 --- a/src/panels/lovelace/cards/hui-stack-card.ts +++ b/src/panels/lovelace/cards/hui-stack-card.ts @@ -1,18 +1,34 @@ -import { html, LitElement, TemplateResult, CSSResult, css } from "lit-element"; +import { + html, + LitElement, + TemplateResult, + CSSResult, + css, + property, +} from "lit-element"; import { createCardElement } from "../create-element/create-card-element"; -import { LovelaceCard } from "../types"; +import { LovelaceCard, LovelaceCardEditor } from "../types"; import { LovelaceCardConfig } from "../../../data/lovelace"; import { HomeAssistant } from "../../../types"; import { StackCardConfig } from "./types"; export abstract class HuiStackCard extends LitElement implements LovelaceCard { - static get properties() { - return { - _config: {}, - }; + public static async getConfigElement(): Promise { + await import( + /* webpackChunkName: "hui-stack-card-editor" */ "../editor/config-elements/hui-stack-card-editor" + ); + return document.createElement("hui-stack-card-editor"); } + public static getStubConfig(): object { + return { cards: [] }; + } + + @property() protected _cards?: LovelaceCard[]; + @property() private _config?: StackCardConfig; + private _hass?: HomeAssistant; + set hass(hass: HomeAssistant) { this._hass = hass; @@ -24,9 +40,6 @@ export abstract class HuiStackCard extends LitElement implements LovelaceCard { element.hass = this._hass; } } - protected _cards?: LovelaceCard[]; - private _config?: StackCardConfig; - private _hass?: HomeAssistant; public abstract getCardSize(): number; @@ -42,12 +55,11 @@ export abstract class HuiStackCard extends LitElement implements LovelaceCard { } protected render(): TemplateResult { - if (!this._config) { + if (!this._config || !this._cards) { return html``; } return html` - ${this.renderStyle()} ${this._config.title ? html`
${this._config.title}
@@ -57,9 +69,7 @@ export abstract class HuiStackCard extends LitElement implements LovelaceCard { `; } - protected abstract renderStyle(): TemplateResult; - - static get styles(): CSSResult { + static get sharedStyles(): CSSResult { return css` .card-header { color: var(--ha-card-header-color, --primary-text-color); diff --git a/src/panels/lovelace/cards/hui-vertical-stack-card.ts b/src/panels/lovelace/cards/hui-vertical-stack-card.ts index a36c37ea6b..c4107ef721 100644 --- a/src/panels/lovelace/cards/hui-vertical-stack-card.ts +++ b/src/panels/lovelace/cards/hui-vertical-stack-card.ts @@ -1,4 +1,4 @@ -import { html, TemplateResult } from "lit-element"; +import { CSSResult, css } from "lit-element"; import { computeCardSize } from "../common/compute-card-size"; import { HuiStackCard } from "./hui-stack-card"; @@ -18,9 +18,10 @@ class HuiVerticalStackCard extends HuiStackCard { return totalSize; } - protected renderStyle(): TemplateResult { - return html` - - `; + `, + ]; } } diff --git a/src/panels/lovelace/cards/types.ts b/src/panels/lovelace/cards/types.ts index a80103fcf9..3ad79336b0 100644 --- a/src/panels/lovelace/cards/types.ts +++ b/src/panels/lovelace/cards/types.ts @@ -243,6 +243,7 @@ export interface ShoppingListCardConfig extends LovelaceCardConfig { export interface StackCardConfig extends LovelaceCardConfig { cards: LovelaceCardConfig[]; + title?: string; } export interface ThermostatCardConfig extends LovelaceCardConfig { diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts index 1223354fdd..f594d313c5 100644 --- a/src/panels/lovelace/components/hui-card-options.ts +++ b/src/panels/lovelace/components/hui-card-options.ts @@ -93,6 +93,10 @@ export class HuiCardOptions extends LitElement { static get styles(): CSSResult { return css` + :host(:hover) { + outline: 2px solid var(--primary-color); + } + ha-card { border-top-right-radius: 0; border-top-left-radius: 0; diff --git a/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts new file mode 100644 index 0000000000..ee9d8e7392 --- /dev/null +++ b/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts @@ -0,0 +1,201 @@ +import { + html, + LitElement, + TemplateResult, + customElement, + property, + CSSResult, + css, +} from "lit-element"; +import "@polymer/paper-tabs"; + +import { struct } from "../../common/structs/struct"; +import { HomeAssistant } from "../../../../types"; +import { LovelaceCardEditor } from "../../types"; +import { StackCardConfig } from "../../cards/types"; +import { fireEvent } from "../../../../common/dom/fire_event"; + +const cardConfigStruct = struct({ + type: "string", + cards: ["any"], + title: "string?", +}); + +@customElement("hui-stack-card-editor") +export class HuiStackCardEditor extends LitElement + implements LovelaceCardEditor { + @property() public hass?: HomeAssistant; + @property() private _config?: StackCardConfig; + @property() private _selectedCard: number = 0; + + public setConfig(config: StackCardConfig): void { + this._config = cardConfigStruct(config); + } + + protected render(): TemplateResult { + if (!this.hass || !this._config) { + return html``; + } + const selected = this._selectedCard!; + const numcards = this._config.cards.length; + + return html` +
+
+ + ${this._config.cards.map((_card, i) => { + return html` + + ${i + 1} + + `; + })} + + + + + + +
+ +
+ ${ + selected < numcards + ? html` +
+ + + + + +
+ + + ` + : html` + + ` + } +
+
+ `; + } + + private _handleSelectedCard(ev) { + this._selectedCard = + ev.target.id === "add-card" + ? this._config!.cards.length + : parseInt(ev.target.selected, 10); + } + + private _handleConfigChanged(ev) { + ev.stopPropagation(); + if (!this._config) { + return; + } + this._config.cards[this._selectedCard] = ev.detail.config; + fireEvent(this, "config-changed", { config: this._config }); + } + + private _handleCardPicked(ev) { + ev.stopPropagation(); + if (!this._config) { + return; + } + const config = ev.detail.config; + this._config.cards.push(config); + fireEvent(this, "config-changed", { config: this._config }); + } + + private _handleDeleteCard() { + if (!this._config) { + return; + } + this._config.cards.splice(this._selectedCard, 1); + this._selectedCard = Math.max(0, this._selectedCard - 1); + fireEvent(this, "config-changed", { config: this._config }); + } + + private _handleMove(ev) { + if (!this._config) { + return; + } + const source = this._selectedCard; + const target = ev.target.id === "move-before" ? source - 1 : source + 1; + const card = this._config.cards.splice(this._selectedCard, 1)[0]; + this._config.cards.splice(target, 0, card); + this._selectedCard = target; + fireEvent(this, "config-changed", { config: this._config }); + } + + static get styles(): CSSResult { + return css` + .toolbar { + display: flex; + --paper-tabs-selection-bar-color: var(--primary-color); + --paper-tab-ink: var(--primary-color); + } + paper-tabs { + display: flex; + font-size: 14px; + flex-grow: 1; + } + #add-card { + max-width: 32px; + padding: 0; + } + + #card-options { + display: flex; + justify-content: flex-end; + width: 100%; + } + + #editor { + border: 1px solid var(--divider-color); + padding: 12px; + } + @media (max-width: 450px) { + #editor { + margin: 0 -12px; + } + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-stack-card-editor": HuiStackCardEditor; + } +} From 33d65bcefc40c020552d4877c6f3a857573701df Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Fri, 28 Feb 2020 00:32:34 +0000 Subject: [PATCH 28/33] [ci skip] Translation update --- translations/en.json | 2 +- translations/fr.json | 36 +++++++ translations/lv.json | 205 +++++++++++++++++++++++++++++++++++++- translations/nb.json | 64 ++++++++++++ translations/ru.json | 63 ++++++++++++ translations/sk.json | 189 +++++++++++++++++++++++++++++++++-- translations/zh-Hant.json | 64 ++++++++++++ 7 files changed, 609 insertions(+), 14 deletions(-) diff --git a/translations/en.json b/translations/en.json index 21ccc72848..ef333b5aaf 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1992,7 +1992,7 @@ } }, "changed_toast": { - "message": "The Lovelace UI configuration was updated, refresh to see changes?", + "message": "The Lovelace UI configuration for this dashboard was updated, refresh to see changes?", "refresh": "Refresh" }, "editor": { diff --git a/translations/fr.json b/translations/fr.json index eb41026872..f5790d0f84 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -640,6 +640,23 @@ "default_confirmation_title": "Êtes-vous sûr ?", "ok": "OK" }, + "helper_settings": { + "input_datetime": { + "has_date": "Date" + }, + "input_select": { + "add": "Ajouter", + "add_option": "Ajouter une option", + "options": "Options" + }, + "input_text": { + "max": "Longueur maximale", + "min": "Longueur minimum", + "mode": "Mode d'affichage", + "password": "Mot de passe", + "text": "Texte" + } + }, "more_info_control": { "dismiss": "Fermer la fenêtre de dialogue", "edit": "Modifier l'entité", @@ -1356,6 +1373,25 @@ } }, "header": "Configurer Home Assistant", + "helpers": { + "caption": "Aides", + "dialog": { + "add_helper": "Ajouter une aide", + "create": "Créer" + }, + "picker": { + "add_helper": "Ajouter une aide", + "headers": { + "editable": "Modifiable", + "name": "Nom", + "type": "Type" + } + }, + "types": { + "input_number": "Nombre", + "input_text": "Texte" + } + }, "integrations": { "caption": "Intégrations", "config_entry": { diff --git a/translations/lv.json b/translations/lv.json index 24d50483fc..f04745b203 100644 --- a/translations/lv.json +++ b/translations/lv.json @@ -420,6 +420,8 @@ "away_mode": "Prombūtnes režīms", "currently": "Pašlaik", "fan_mode": "Ventilatora režīms", + "high": "augsts", + "low": "zems", "on_off": "Ieslēgts / Izslēgts", "operation": "Darbība", "preset_mode": "Iestatījums", @@ -427,6 +429,13 @@ "target_humidity": "Mērķa mitrums", "target_temperature": "Mērķa temperatūra" }, + "counter": { + "actions": { + "decrement": "samazināt", + "increment": "palielināt", + "reset": "atiestatīt" + } + }, "cover": { "position": "Pozīcija", "tilt_position": "Slīpuma pozīcija" @@ -525,11 +534,20 @@ "yes": "Jā" }, "components": { + "area-picker": { + "add_dialog": { + "add": "Pievienot", + "name": "Nosaukums" + }, + "clear": "Notīrīt" + }, "device-picker": { + "clear": "Notīrīt", "device": "Ierīce" }, "entity": { "entity-picker": { + "clear": "Notīrīt", "entity": "Vienība" } }, @@ -537,6 +555,10 @@ "loading_history": "Vēsturiskie ieraksti par stāvokli tiek ielādēti.", "no_history_found": "Vēsturiskie ieraksti par stāvokli netika atrasti." }, + "related-items": { + "device": "Ierīce", + "integration": "Integrācija" + }, "relative_time": { "duration": { "day": "{count} {count, plural,\n one {diena}\n other {dienas}\n}", @@ -557,12 +579,41 @@ "title": "Sistēmas opcijas {integration} integrācijai", "update": "Atjaunināt" }, + "confirmation": { + "cancel": "Atcelt", + "ok": "Labi" + }, "entity_registry": { "editor": { + "delete": "DZĒST", "name": "Nosaukuma pārlabošana", "note": "Ievērībai: pašlaik tas var nedarboties ar visām integrācijām.", "unavailable": "Šī vienība pašlaik nav pieejama." - } + }, + "settings": "Iestatījumi" + }, + "generic": { + "cancel": "Atcelt", + "ok": "Labi" + }, + "helper_settings": { + "generic": { + "icon": "Ikona" + }, + "input_datetime": { + "has_time": "Laiks" + }, + "input_select": { + "add": "Pievienot", + "add_option": "Pievienot iespēju", + "options": "Iespējas" + }, + "input_text": { + "password": "Parole", + "text": "Teksts" + }, + "not_editable": "Nav labojams", + "required_error_msg": "Šis lauks ir obligāts" }, "more_info_control": { "dismiss": "Aizvērt dialogu", @@ -580,6 +631,11 @@ }, "updater": { "title": "Atjaunināt Instrukcijas" + }, + "vacuum": { + "commands": "Putekļsūcēja komandas:", + "fan_speed": "Ventilatora ātrums", + "status": "Statuss" } }, "more_info_settings": { @@ -597,10 +653,16 @@ } }, "voice_command": { + "how_can_i_help": "Kā es varu palīdzēt?", "label": "Uzrakstiet jautājumu un nospiediet 'Enter'", "label_voice": "Ievadiet tekstu un nospiediet 'Enter' vai pieskarieties mikrofonam, lai runātu" }, "zha_device_info": { + "buttons": { + "add": "Pievienot ierīces", + "reconfigure": "Pārkonfigurēt ierīci", + "remove": "Noņemt ierīci" + }, "manuf": "autors {manufacturer}", "no_area": "Nav Apgabala", "services": { @@ -689,6 +751,9 @@ "label": "Atlikt" }, "device_id": { + "extra_fields": { + "code": "Kods" + }, "label": "Ierīce" }, "event": { @@ -724,6 +789,11 @@ "type_select": "Nosacījuma tips", "type": { "device": { + "extra_fields": { + "above": "Virs", + "below": "Zem", + "for": "Ilgums" + }, "label": "Ierīce" }, "numeric_state": { @@ -763,6 +833,10 @@ "unsupported_condition": "Neatbalstīts nosacījums: {condition}" }, "default_name": "Jauna automatizācija", + "description": { + "label": "Apraksts", + "placeholder": "Neobligāts apraksts" + }, "edit_ui": "Rediģēt, izmantojot UI", "edit_yaml": "Rediģēt kā YAML", "introduction": "Lietojiet automatizācijas, lai iedzīvinātu Jūsu mājās", @@ -872,10 +946,31 @@ } }, "cloud": { + "account": { + "alexa": { + "title": "Alexa" + }, + "webhooks": { + "loading": "Ielādē..." + } + }, + "alexa": { + "title": "Alexa" + }, "caption": "Home Assistant Cloud", "description_features": "Kontrolējiet prom no mājām, integrējieties ar Alexa un Google Assistant.", "description_login": "Pieteikts kā {email}", - "description_not_login": "Neesat pieteicies" + "description_not_login": "Neesat pieteicies", + "dialog_certificate": { + "close": "Aizvērt" + }, + "register": { + "create_account": "Izveidot kontu", + "email_address": "E-pasta adrese", + "email_error_msg": "Nederīgs e-pasts", + "link_privacy_policy": "Privātuma politika", + "password": "Parole" + } }, "core": { "caption": "Vispārīgi", @@ -885,6 +980,7 @@ "core_config": { "edit_requires_storage": "Redaktors ir atspējots, jo konfigurācija ir definēta configuration.yaml.", "elevation": "Augstums", + "elevation_feet": "pēdas", "elevation_meters": "metri", "imperial_example": "Fārenheita, mārciņas", "latitude": "Platums", @@ -957,7 +1053,8 @@ "device_not_found": "Ierīce nav atrasta.", "info": "Informācija par ierīci", "unknown_error": "Nezināma kļūda", - "unnamed_device": "Nenosaukta ierīce" + "unnamed_device": "Nenosaukta ierīce", + "update": "Atjaunināt" }, "entities": { "caption": "Vienības", @@ -1021,6 +1118,19 @@ } }, "header": "Home Assistant konfigurēšana", + "helpers": { + "dialog": { + "create": "Izveidot" + }, + "picker": { + "headers": { + "type": "Veids" + } + }, + "types": { + "input_text": "Teksts" + } + }, "integrations": { "caption": "Integrācijas", "config_entry": { @@ -1247,13 +1357,36 @@ "search_again": "Atkārtot meklēšanu", "spinner": "Meklē ZHA Zigbee ierīces..." }, + "add": { + "caption": "Pievienot ierīces" + }, "caption": "ZHA", + "clusters": { + "header": "Kopas" + }, + "common": { + "add_devices": "Pievienot ierīces", + "clusters": "Kopas", + "devices": "Ierīces", + "value": "Vērtība" + }, "description": "Zigbee Home Automation tīkla pārvaldība", "device_card": { "area_picker_label": "Apgabals", "device_name_placeholder": "Lietotāja dots nosaukums", "update_name_button": "Atjaunināt Nosaukumu" }, + "groups": { + "caption": "Grupas", + "group_id": "Grupas ID", + "group_name_placeholder": "Grupas nosaukums" + }, + "network_management": { + "header": "Tīkla pārvaldība" + }, + "node_management": { + "header": "Ierīču pārvaldība" + }, "services": { "reconfigure": "Pārkonfigurējiet ZHA ierīci (heal device). Izmantojiet to, ja rodas problēmas ar ierīci. Ja attiecīgā ierīce ir ar akumulatoru darbināma ierīce, lūdzu, pārliecinieties, ka tā ir nomodā un pieņem komandas, kad izmantojat šo pakalpojumu.", "remove": "Noņemt ierīci no Zigbee tīkla.", @@ -1345,6 +1478,40 @@ "question_trust": "Vai Jūs uzticaties ārējam panelim {name} uz {link}?" } }, + "developer-tools": { + "tabs": { + "events": { + "title": "Notikumi" + }, + "info": { + "server": "serveris", + "source": "Avots:", + "title": "Informācija" + }, + "logs": { + "clear": "Notīrīt", + "refresh": "Atsvaidzināt" + }, + "mqtt": { + "publish": "Publicēt", + "title": "MQTT", + "topic": "temats" + }, + "services": { + "column_description": "Apraksts", + "column_example": "Piemērs", + "column_parameter": "Parametrs" + }, + "states": { + "attributes": "Atribūti", + "copied": "Kopēts starpliktuvē", + "copy_entity_attribute": "Kopēt atribūtus", + "copy_entity_id": "Kopēt ID", + "copy_entity_state": "Kopēt stāvokli", + "title": "Stāvokļi" + } + } + }, "history": { "period": "Periods", "showing_entries": "Rāda ierakstus par" @@ -1369,6 +1536,9 @@ "tap": "Pieskarties:", "toggle": "Pārslēgt {name}" }, + "safe-mode": { + "show_errors": "Rādīt kļūdas" + }, "shopping-list": { "add_item": "Pievienot vienumu", "checked_items": "Atzīmētie vienumi", @@ -1381,11 +1551,35 @@ }, "editor": { "card": { + "button": { + "name": "Poga" + }, "entities": { "toggle": "Pārslēgt vienības." }, + "generic": { + "icon": "Ikona" + }, + "iframe": { + "name": "iFrame" + }, + "light": { + "name": "Gaisma" + }, "map": { - "default_zoom": "Noklusējuma mērogs" + "default_zoom": "Noklusējuma mērogs", + "name": "Karte", + "source": "Avots" + }, + "markdown": { + "content": "Saturs", + "name": "Markdown" + }, + "picture": { + "name": "Attēls" + }, + "sensor": { + "name": "Sensors" } }, "edit_card": { @@ -1409,7 +1603,8 @@ "edit": "Rediģēt skatu", "header": "Skatīt konfigurāciju", "move_left": "Pārvietot skatu pa kreisi", - "move_right": "Pārvietot skatu pa labi" + "move_right": "Pārvietot skatu pa labi", + "tab_settings": "Iestatījumi" }, "header": "Rediģēt lietotāja saskarni", "menu": { diff --git a/translations/nb.json b/translations/nb.json index 3511e4e7b7..9c14ba1933 100644 --- a/translations/nb.json +++ b/translations/nb.json @@ -626,6 +626,8 @@ "enabled_description": "Deaktiverte entiteter vil ikke bli lagt til i Home Assistant.", "enabled_label": "Aktiver entitet", "entity_id": "Entitets-ID", + "icon": "Overstyring av ikon", + "icon_error": "Ikoner bør være i formatet 'prefix:iconname', f.eks .", "name": "Overstyr Navn", "note": "Merk: dette fungerer kanskje ikke ennå med alle integrasjoner.", "unavailable": "Denne entiteten er ikke tilgjengelig for øyeblikket.", @@ -640,6 +642,44 @@ "default_confirmation_title": "Er du sikker?", "ok": "OK" }, + "helper_settings": { + "generic": { + "icon": "Ikon", + "initial_value": "Startverdi ved start", + "initial_value_explain": "Verdien elementet vil ha når Home Assistant starter. Når den er tom, gjenopprettes verdien til den forrige verdien.", + "name": "Navn" + }, + "input_datetime": { + "has_date": "Dato", + "has_time": "Tid" + }, + "input_number": { + "box": "Inntastingsfelt", + "max": "Maksimal verdi", + "min": "Minimum verdi", + "mode": "Visningsmodus", + "slider": "Glidebryter", + "step": "Trinnstørrelse på glidebryteren", + "unit_of_measurement": "Måleenhet" + }, + "input_select": { + "add": "Legg til", + "add_option": "Legg til alternativ", + "no_options": "Det er ingen alternativer ennå.", + "options": "Alternativer" + }, + "input_text": { + "max": "Maksimal lengde", + "min": "Minimum lengde", + "mode": "Visningsmodus", + "password": "Passord", + "pattern": "Regex-mønster for validering på klientsiden", + "text": "Tekst" + }, + "not_editable": "Kan ikke redigeres", + "not_editable_text": "Denne enheten kan ikke endres fra brukergrensesnittet fordi den er definert i configuration.yaml.", + "required_error_msg": "Dette feltet er påkrevd" + }, "more_info_control": { "dismiss": "Avvis dialogboksen", "edit": "Redigér entitet", @@ -1356,6 +1396,30 @@ } }, "header": "Konfigurer Home Assistant", + "helpers": { + "caption": "Hjelpere", + "description": "Elementer som kan bidra til å bygge automatiseringer.", + "dialog": { + "add_helper": "Legg hjelper", + "add_platform": "Legg til {platform}", + "create": "Opprett" + }, + "picker": { + "add_helper": "Legg hjelper", + "headers": { + "editable": "Redigerbare", + "name": "Navn", + "type": "Type" + } + }, + "types": { + "input_boolean": "Veksle", + "input_datetime": "Dato og/eller klokkeslett", + "input_number": "Nummer", + "input_select": "Fall ned", + "input_text": "Tekst" + } + }, "integrations": { "caption": "Integrasjoner", "config_entry": { diff --git a/translations/ru.json b/translations/ru.json index 9b7ca5b284..b19e68a292 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -626,6 +626,7 @@ "enabled_description": "Отключенные объекты не будут доступны в Home Assistant.", "enabled_label": "Включить объект", "entity_id": "ID объекта", + "icon_error": "Параметр значка должен быть указан в формате \"префикс:имя-значка\" (например: mdi:home)", "name": "Название", "note": "Примечание: это может не работать со всеми интеграциями.", "unavailable": "Этот объект в настоящее время недоступен.", @@ -640,6 +641,44 @@ "default_confirmation_title": "Вы уверены?", "ok": "ОК" }, + "helper_settings": { + "generic": { + "icon": "Значок", + "initial_value": "Исходное значение при запуске", + "initial_value_explain": "Значение, которое элемент будет иметь при запуске Home Assistant. Если оставить пустым, будет восстановлено предыдущее значение элемента.", + "name": "Название" + }, + "input_datetime": { + "has_date": "Дата", + "has_time": "Время" + }, + "input_number": { + "box": "Поле ввода", + "max": "Максимальное значение", + "min": "Минимальное значение", + "mode": "Режим отображения", + "slider": "Слайдер", + "step": "Шаг слайдера", + "unit_of_measurement": "Единица измерения" + }, + "input_select": { + "add": "Добавить", + "add_option": "Добавить опцию", + "no_options": "Добавьте доступные для выбора опции.", + "options": "Опции" + }, + "input_text": { + "max": "Максимальная длина", + "min": "Минимальная длина", + "mode": "Режим отображения", + "password": "Пароль", + "pattern": "Шаблон регулярного выражения для проверки на стороне клиента", + "text": "Текст" + }, + "not_editable": "Только для чтения", + "not_editable_text": "Этот объект нельзя изменить из пользовательского интерфейса, поскольку он был создан в файле configuration.yaml.", + "required_error_msg": "Обязательное поле" + }, "more_info_control": { "dismiss": "Закрыть диалог", "edit": "Изменить объект", @@ -1356,6 +1395,30 @@ } }, "header": "Настройка Home Assistant", + "helpers": { + "caption": "Вспомогательное", + "description": "Элементы, которые могут помочь в создании автоматизации.", + "dialog": { + "add_helper": "Добавить вспомогательный элемент", + "add_platform": "Добавить \"{platform}\"", + "create": "Создать" + }, + "picker": { + "add_helper": "Добавить вспомогательный элемент", + "headers": { + "editable": "Редактируемый", + "name": "Название", + "type": "Тип" + } + }, + "types": { + "input_boolean": "Переключатель", + "input_datetime": "Дата и время", + "input_number": "Число", + "input_select": "Выпадающий список", + "input_text": "Текст" + } + }, "integrations": { "caption": "Интеграции", "config_entry": { diff --git a/translations/sk.json b/translations/sk.json index e31480fe8f..13e3e1b946 100644 --- a/translations/sk.json +++ b/translations/sk.json @@ -537,6 +537,19 @@ "successfully_saved": "Úspešne uložené" }, "components": { + "area-picker": { + "add_dialog": { + "add": "Pridať", + "failed_create_area": "Nepodarilo sa vytvoriť oblasť.", + "name": "Názov", + "text": "Zadajte názov novej oblasti.", + "title": "Pridať novú oblasť" + }, + "add_new": "Pridať novú oblasť ...", + "area": "Oblasť", + "clear": "Vyčistiť", + "show_areas": "Zobraziť oblasti" + }, "device-picker": { "clear": "Vyčistiť", "device": "Zariadenie", @@ -553,6 +566,13 @@ "loading_history": "Načítavam históriu stavov", "no_history_found": "Nenašla sa žiadna história stavov" }, + "related-items": { + "area": "Oblasť", + "automation": "Súčasťou nasledujúcich automatizácií", + "device": "Zariadenie", + "integration": "Integrácia", + "scene": "Súčasťou nasledujúcich scén" + }, "relative_time": { "duration": { "day": "{count} {count, plural,\none {deň}\nother {dní}\n}", @@ -580,7 +600,22 @@ "ok": "OK", "title": "Ste si istý?" }, + "entity_registry": { + "editor": { + "confirm_delete": "Naozaj chcete odstrániť túto entitu?", + "icon": "Zmeniť ikonu", + "name": "Prepísať názov", + "note": "Poznámka: toto nemusí zatiaľ fungovať so všetkými integráciami." + } + }, + "generic": { + "default_confirmation_title": "Ste si istý?" + }, "more_info_control": { + "restored": { + "confirm_remove_text": "Naozaj chcete odstrániť túto entitu?", + "not_provided": "Táto entita je momentálne nedostupná a je ojedinelou pre odstránenú, zmenenú alebo nefunkčnú integráciu alebo zariadenie." + }, "script": { "last_action": "Posledná akcia" }, @@ -611,6 +646,9 @@ "add": "Pridať zariadenia", "reconfigure": "Prekonfigurovať zariadenie" }, + "confirmations": { + "remove": "Naozaj chcete odstrániť zariadenie?" + }, "last_seen": "Naposledy videný", "manuf": "od {manufacturer}", "no_area": "Žiadna oblasť", @@ -687,6 +725,7 @@ "header": "Akcie", "introduction": "Akcie, ktoré vykoná Home Assistant, sa aktivujú po spustení automatizácie. \n\n [Viac informácií o akciách.](https://home-assistant.io/docs/automation/action/)", "learn_more": "Získajte viac informácií o akciách", + "name": "Akcia", "type_select": "Typ akcie", "type": { "condition": { @@ -731,6 +770,7 @@ "header": "Podmienky", "introduction": "Podmienky sú voliteľnou súčasťou pravidla automatizácie a môžu sa použiť na zabránenie tomu, aby sa akcia vykonala pri spustení. Podmienky vyzerajú veľmi podobne ako spúšťače, ale sú veľmi odlišné. Spúšťač sa zameria na udalosti, ktoré sa dejú v systéme, zatiaľ čo podmienka sa zameriava iba na to, ako systém práve vyzerá. Spúšťač môže pozorovať, že je zapnutý spínač. Podmienkou je iba to, či je vypínač v súčasnosti zapnutý alebo vypnutý. \n\n [Viac informácií o podmienkach.](https://home-assistant.io/docs/scripts/conditions/)", "learn_more": "Získajte viac informácií o podmienkach", + "name": "Podmienka", "type_select": "Typ podmienky", "type": { "and": { @@ -788,6 +828,9 @@ "label": "Popis", "placeholder": "Voliteľný popis" }, + "edit_ui": "Upraviť pomocou používateľského rozhrania", + "edit_yaml": "Upraviť pomocou YAML", + "enable_disable": "Povoliť/zakázať automatizáciu", "introduction": "Použite automatizácie, aby váš domov ožil", "load_error_not_editable": "Len automatizácie v automations.yaml je možné upravovať.", "load_error_unknown": "Chyba pri načítaní automatizácie ({err_no}).", @@ -800,6 +843,7 @@ "header": "Spúšťače", "introduction": "Spúšťače spúšťajú spracovanie pravidla automatizácie. Pre rovnaké pravidlo je možné určiť viac spúšťačov. Po spustení spúšťača aplikácia Home Assistant overí prípadné podmienky a zavolá akciu. \n\n [Viac informácií o spúšťačov.](https://home-assistant.io/docs/automation/trigger/)", "learn_more": "Získajte viac informácií o spúšťačoch", + "name": "Spúšťač", "type_select": "Typ spúšťača", "type": { "device": { @@ -886,11 +930,16 @@ }, "picker": { "add_automation": "Pridať automatizáciu", + "delete_automation": "Odstrániť automatizáciu", + "delete_confirm": "Naozaj chcete odstrániť túto automatizáciu?", + "edit_automation": "Upraviť automatizáciu", "header": "Editor automatizácií", "introduction": "Editor automatizácií vám umožňuje vytvárať a upravovať automatizácie. Prečítajte si prosím [pokyny](https://home-assistant.io/docs/automation/editor/), aby ste sa uistili, že ste nakonfigurovali Home Assistant správne.", "learn_more": "Získajte viac informácií o automatizáciách", "no_automations": "Nepodarilo sa nájsť žiadne editovateľné automatizácie", - "pick_automation": "Vyberte automatizáciu, ktorú chcete upraviť" + "only_editable": "Iba automatizácie definované v automations.yaml je možné upravovať.", + "pick_automation": "Vyberte automatizáciu, ktorú chcete upraviť", + "show_info_automation": "Zobraziť informácie o automatizácii" } }, "cloud": { @@ -953,6 +1002,7 @@ "dialog_cloudhook": { "available_at": "Webhook je k dispozícii na tejto webovej adrese:", "close": "Zavrieť", + "confirm_disable": "Naozaj chcete zakázať tento webhook?", "copied_to_clipboard": "Skopírované do schránky", "managed_by_integration": "Tento webhook je riadený integráciou a nemožno ho zakázať.", "webhook_for": "Webhook pre {name}" @@ -1039,8 +1089,14 @@ } }, "customize": { + "attributes_customize": "Nasledujúce atribúty sú už nastavené v customize.yaml", + "attributes_not_set": "Nasledujúce atribúty neboli nastavené. Ak chcete, nastavte ich.", + "attributes_outside": "Nasledujúce atribúty sú prispôsobené mimo customize.yaml", + "attributes_override": "Ak chcete, môžete ich prepísať.", + "attributes_set": "Nasledujúce atribúty entity sa nastavujú programovo.", "caption": "Prispôsobenie", "description": "Prispôsobte svoje entity", + "pick_attribute": "Vyberte atribút, ktorý chcete prepísať", "picker": { "header": "Prispôsobenie", "introduction": "Upravujte atribúty v rámci entity. Pridané / upravené prispôsobenia sa prejavia okamžite. Odstránené prispôsobenia sa prejavia po aktualizácii entity." @@ -1051,15 +1107,36 @@ "actions": { "caption": "Keď sa niečo spustí..." }, + "automations": "Automatizácie", "conditions": { "caption": "Urob niečo len vtedy, ak ..." }, + "create": "Vytvorte automatizáciu so zariadením", + "no_automations": "Žiadne automatizácie", + "no_device_automations": "Pre toto zariadenie nie sú k dispozícii žiadne automatizácie.", "triggers": { "caption": "Urob niečo, keď ..." } }, + "automations": "Automatizácie", "caption": "Zariadenia", - "description": "Spravovať pripojené zariadenia" + "data_table": { + "battery": "Batérie", + "device": "Zariadenie", + "integration": "Integrácia", + "manufacturer": "Výrobca" + }, + "description": "Spravovať pripojené zariadenia", + "scene": { + "create": "Vytvorte scénu pomocou zariadenia", + "no_scenes": "Žiadne scény", + "scenes": "Scény" + }, + "scenes": "Scény", + "script": { + "no_scripts": "Žiadne skripty" + }, + "scripts": "Skripty" }, "entities": { "caption": "Register entít", @@ -1072,6 +1149,7 @@ "enabled_cause": "Zakázané {cause}", "enabled_description": "Zakázané entity nebudú pridané do Home Assistanta", "enabled_label": "Povoliť entitu", + "name": "Prepísať názov", "unavailable": "Táto entita nie je momentálne k dispozícii.", "update": "AKTUALIZOVAŤ" }, @@ -1085,11 +1163,20 @@ "integrations_page": "Stránka Integrácie", "introduction": "Home Assistant vedie register všetkých subjektov, ktoré kedy videl a ktoré môžu byť jednoznačne identifikované. Každá z týchto entít bude mať pridelené ID, ktoré bude vyhradené len pre tento subjekt.", "introduction2": "Použite register entít na prepísanie mena, zmenu ID entity alebo odstránenie položky z Home Assistant. Poznámka: Odstránenie položky databázy entít neodstráni entitu. Postupujte podľa nižšie uvedeného odkazu a odstráňte ho z integračnej stránky.", + "remove_selected": { + "confirm_text": "Entity je možné odstrániť, iba ak ich integrácia už neposkytuje." + }, "show_disabled": "Zobraziť zakázané entity", "unavailable": "(nedostupné)" } }, "header": "Konfigurovať Home Assistant", + "helpers": { + "description": "Prvky, ktoré môžu pomôcť pri vytváraní automatizácií.", + "dialog": { + "create": "Vytvoriť" + } + }, "integrations": { "caption": "Integrácie", "config_entry": { @@ -1110,17 +1197,29 @@ "via": "Pripojené cez" }, "config_flow": { + "add_area": "Pridať oblasť", + "area_picker_label": "Oblasť", + "dismiss": "Zrušiť dialógové okno", + "error_saving_area": "Chyba pri ukladaní oblasti: {error}", "external_step": { "description": "Tento krok vyžaduje, aby ste navštívili externú webovú stránku, ktorá dokončí proces.", "open_site": "Otvoriť webovú stránku" - } + }, + "failed_create_area": "Nepodarilo sa vytvoriť oblasť.", + "name_new_area": "Názov novej oblasti?" }, "configure": "Konfigurovať", "configured": "Nakonfigurovaný", "description": "Spravujte a nastavujte integrácie", "discovered": "Objavené", + "ignore": { + "confirm_ignore": "Naozaj nechcete nastaviť túto integráciu? Túto akciu môžete vrátiť späť kliknutím na položku „Zobraziť ignorované integrácie“ v ponuke v pravom hornom rohu.", + "show_ignored": "Zobraziť ignorované integrácie", + "stop_ignore": "Zastaviť ignorovanie" + }, "new": "Nastaviť novú integráciu", - "none": "Nič zatiaľ nebolo nakonfigurované" + "none": "Nič zatiaľ nebolo nakonfigurované", + "note_about_integrations": "Nie všetky integrácie je možné nakonfigurovať pomocou používateľského rozhrania." }, "introduction": "Tu je možné konfigurovať vaše komponenty a Home Assistant. Aktuálne sa z používateľského rozhrania nedá konfigurovať všetko, ale pracujeme na tom.", "person": { @@ -1143,8 +1242,45 @@ "introduction": "Tu môžete definovať každú osobu, ktorá vás zaujíma v Home Assistant." }, "scene": { + "activated": "Aktivovaná scéna {name}.", "caption": "Scény", - "description": "Vytvárajte a upravujte scény" + "description": "Vytvárajte a upravujte scény", + "editor": { + "default_name": "Nová scéna", + "devices": { + "add": "Pridať zariadenie", + "delete": "Odstrániť zariadenie", + "header": "Zariadenia", + "introduction": "Pridajte zariadenia, ktoré chcete zahrnúť do svojej scény. Nastavte všetky zariadenia do stavu, ktorý chcete pre túto scénu." + }, + "entities": { + "add": "Pridať entitu", + "delete": "Odstrániť entitu", + "device_entities": "Ak pridáte entitu, ktorá patrí k zariadeniu, zariadenie sa pridá.", + "header": "Entity", + "introduction": "Entity, ktoré nepatria zariadeniu, môžete nastaviť tu.", + "without_device": "Entity bez zariadenia" + }, + "introduction": "Využite scény na oživenie vášho domova.", + "load_error_not_editable": "Upraviť je možné iba scény zo scenes.yaml.", + "load_error_unknown": "Chyba pri načítaní scény ({err_no}).", + "name": "Názov", + "save": "Uložiť", + "unsaved_confirm": "Máte neuložené zmeny. Naozaj chcete odísť?" + }, + "picker": { + "add_scene": "Pridať scénu", + "delete_confirm": "Naozaj chcete odstrániť túto scénu?", + "delete_scene": "Odstrániť scénu", + "edit_scene": "Upraviť scénu", + "header": "Editor scén", + "introduction": "Editor scén vám umožňuje vytvárať a upravovať scény. Postupujte podľa odkazu nižšie a prečítajte si pokyny, aby ste sa uistili, že ste Home Assistant nakonfigurovali správne.", + "learn_more": "Získajte viac informácií o scénach", + "no_scenes": "Nemohli sme nájsť žiadne editovateľné scény", + "only_editable": "Upraviť je možné iba scény zo scenes.yaml.", + "pick_scene": "Vyberte scénu, ktorú chcete upraviť", + "show_info_scene": "Zobraziť informácie o scéne" + } }, "script": { "caption": "Skripty", @@ -1153,7 +1289,11 @@ "default_name": "Nový skript", "delete_confirm": "Naozaj chcete odstrániť tento skript?", "header": "Skript: {name}", - "load_error_not_editable": "Iba skripty zo súboru scripts.yaml sú editovateľné." + "introduction": "Na vykonanie sledu akcií použite skripty.", + "link_available_actions": "Získajte viac informácií o dostupných akciách.", + "load_error_not_editable": "Iba skripty zo súboru scripts.yaml sú editovateľné.", + "sequence": "Sekvencia", + "sequence_sentence": "Sled akcií tohto skriptu" }, "picker": { "add_script": "Pridať skript", @@ -1172,8 +1312,10 @@ "group": "Znovu načítať skupiny", "heading": "Načítavanie novej konfigurácie", "introduction": "Niektoré časti aplikácie Home Assistant sa môžu načítať bez nutnosti reštartovania. Opätovným načítaním sa zahodí aktuálna konfigurácia a načíta sa nová.", + "person": "Znovu načítať osoby", "scene": "Znovu načítať scény", - "script": "Znovu načítať skripty" + "script": "Znovu načítať skripty", + "zone": "Znovu načítať zóny" }, "server_management": { "confirm_restart": "Naozaj chcete reštartovať Home Assistanta?", @@ -1206,6 +1348,7 @@ "activate_user": "Aktivovať používateľa", "caption": "Zobraziť používateľa", "change_password": "Zmeniť heslo", + "confirm_user_deletion": "Naozaj chcete odstrániť {name}?", "deactivate_user": "Deaktivovať používateľa", "delete_user": "Vymazať používateľa", "rename_user": "Premenovať používateľa", @@ -1219,6 +1362,7 @@ "add_device_page": { "discovery_text": "Tu sa zobrazia objavené zariadenia. Postupujte podľa pokynov pre zariadenie (zariadenia) a umiestnite zariadenie (zariadenia) do režimu párovania.", "header": "Zigbee Home Automation - Pridať zariadenia", + "search_again": "Hľadať znova", "spinner": "Vyhľadávanie ZHA Zigbee zariadení ..." }, "caption": "ZHA", @@ -1251,6 +1395,16 @@ "device_name_placeholder": "Meno používateľa", "update_name_button": "Aktualizovať názov" }, + "devices": { + "header": "Zigbee Home Automation - Zariadenie" + }, + "groups": { + "create_group": "Zigbee Home Automation - Vytvoriť skupinu", + "group-header": "Zigbee Home Automation - Podrobnosti o skupine", + "groups-header": "Zigbee Home Automation - Správa skupiny", + "header": "Zigbee Home Automation - Správa skupiny" + }, + "header": "Konfigurácia Zigbee Home Automation", "node_management": { "help_node_dropdown": "Vyberte zariadenie na zobrazenie možností zariadenia.", "hint_battery_devices": "Poznámka: Spiace (napájané z batérie) zariadenia musia byť pri vykonávaní príkazov zobudené. Spiace zariadenie môžete zvyčajne prebudiť jeho spustením.", @@ -1261,7 +1415,19 @@ "reconfigure": "Znovu nakonfigurujte zariadenie ZHA (oprava zariadenia). Použite, len ak máte problémy so zariadením. Ak sa jedná o zariadenie s batériovým napájaním, uistite sa, že pri používaní tejto služby, nebolo zariadenie v režime spánku a prijímalo príkazy.", "remove": "Odstráňte zariadenie zo siete Zigbee.", "updateDeviceName": "Nastavte vlastný názov pre toto zariadenie v registri zariadenia." - } + }, + "title": "Zigbee Home Automation" + }, + "zone": { + "caption": "Zóny", + "configured_in_yaml": "Zóny vytvorené prostredníctvom configuration.yaml nie je možné upravovať pomocou používateľského rozhrania.", + "confirm_delete": "Naozaj chcete odstrániť túto zónu?", + "description": "Spravujte zóny, v ktorých chcete sledovať osoby.", + "detail": { + "passive_note": "Pasívne zóny sú skryté vo frontende a nie sú používané ako umiestnenia pre sledovacie zariadenia. Toto je užitočné, ak chcete používať zóny len pre automatizácie." + }, + "introduction": "Zóny vám umožňujú vybrať špecifické oblasti na mape. Ak sa osoba nachádza v nejakej zóne, v stavoch sa zobrazí názov konkrétnej zóny. Zóny môžu byť tiež použité ako spúšťač alebo podmienka v rámci automatizácií.", + "no_zones_created_yet": "Zdá sa, že ste ešte nevytvorili žiadne zóny." }, "zwave": { "caption": "Z-Wave", @@ -1425,6 +1591,7 @@ }, "lovelace": { "cards": { + "confirm_delete": "Naozaj chcete odstrániť túto kartu?", "empty_state": { "go_to_integrations_page": "Prejsť na stránku integrácií", "no_devices": "Táto stránka vám umožňuje ovládať vaše zariadenia, zdá sa však, že ešte nemáte nastavené žiadne zariadenia. Ak chcete začať, choďte na stránku integrácií.", @@ -1537,6 +1704,7 @@ "name": "Snímač" }, "shopping-list": { + "integration_not_loaded": "Táto karta vyžaduje nastavenie integrácie \"shopping_list\".", "name": "Zoznam nákupov" }, "thermostat": { @@ -1585,6 +1753,10 @@ "para_no_id": "Tento prvok nemá žiadne ID. Doplňte, prosím, ID pre tento prvok v súbore 'ui-lovelace.yaml'." }, "raw_editor": { + "confirm_remove_config_title": "Naozaj chcete odstrániť konfiguráciu používateľského rozhrania Lovelace? Vaše zobrazenia používateľské rozhranie Lovelace automaticky vygenerujeme s vašimi oblasťami a zariadeniami.", + "confirm_unsaved_changes": "Máte neuložené zmeny. Naozaj chcete odísť?", + "confirm_unsaved_comments": "Vaša konfigurácia obsahuje komentáre, ktoré sa neuložia. Chcete pokračovať?", + "error_save_yaml": "Nepodarilo sa uložiť YAML: {error}", "header": "Upraviť konfiguráciu", "save": "Uložiť", "saved": "Uložené", @@ -1821,6 +1993,7 @@ "link_promo": "Pomôžte s prekladom" }, "logout": "Odhlásiť sa", + "logout_text": "Naozaj sa chcete odhlásiť?", "long_lived_access_tokens": { "confirm_delete": "Naozaj chcete odstrániť prístupový token pre {name}?", "create": "Vytvoriť Token", diff --git a/translations/zh-Hant.json b/translations/zh-Hant.json index 716cf94288..3ccbb90a53 100644 --- a/translations/zh-Hant.json +++ b/translations/zh-Hant.json @@ -626,6 +626,8 @@ "enabled_description": "關閉的物件將不會新增至 Home Assistant。", "enabled_label": "啟用物件", "entity_id": "物件 ID", + "icon": "圖示覆寫", + "icon_error": "圖示必須按照格式「prefix:iconname」設定,例如「mdi:home」", "name": "名稱覆寫", "note": "注意:可能無法適用所有整合。", "unavailable": "該物件目前不可用。", @@ -640,6 +642,44 @@ "default_confirmation_title": "確認?", "ok": "好" }, + "helper_settings": { + "generic": { + "icon": "圖示", + "initial_value": "初始值", + "initial_value_explain": "Home Assistant 啟動初始值。空白時、將會回覆至之前的數值。", + "name": "名稱" + }, + "input_datetime": { + "has_date": "日期", + "has_time": "時間" + }, + "input_number": { + "box": "輸入欄位", + "max": "最大值", + "min": "最小值", + "mode": "顯示模式", + "slider": "滑桿", + "step": "滑桿刻度", + "unit_of_measurement": "單位" + }, + "input_select": { + "add": "新增", + "add_option": "新增選項", + "no_options": "尚無選項。", + "options": "選項" + }, + "input_text": { + "max": "最大長度", + "min": "最小長度", + "mode": "顯示模式", + "password": "密碼", + "pattern": "客戶端驗證模式", + "text": "文字" + }, + "not_editable": "不可編輯", + "not_editable_text": "由於 configuration.yaml 內已定義,物件編輯功能已關閉。", + "required_error_msg": "必填欄位" + }, "more_info_control": { "dismiss": "忽略對話", "edit": "編輯物件", @@ -1356,6 +1396,30 @@ } }, "header": "設定 Home Assistant", + "helpers": { + "caption": "助手", + "description": "可協助建立自動化的元素。", + "dialog": { + "add_helper": "新增助手", + "add_platform": "新增 {platform}", + "create": "新增" + }, + "picker": { + "add_helper": "新增助手", + "headers": { + "editable": "可編輯", + "name": "名稱", + "type": "類別" + } + }, + "types": { + "input_boolean": "開關", + "input_datetime": "日期及/或時間", + "input_number": "數字", + "input_select": "下拉選單", + "input_text": "文字" + } + }, "integrations": { "caption": "整合", "config_entry": { From 5646045e9e380cbbcbeb003311814506d029e49e Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 28 Feb 2020 21:58:50 +0100 Subject: [PATCH 29/33] Add UI to create and manage Lovelace dashboards and resources (#5012) * Add UI to create and manage Lovelace dashboards and resources * update, comments, fixes * Align icons with seach icon and checkboxes * Fix * Remove js and html resource types * Allow it for existing ones --- src/components/data-table/ha-data-table.ts | 48 ++- src/components/ha-dialog.ts | 24 +- src/data/lovelace.ts | 106 ++++++- src/layouts/hass-tabs-subpage.ts | 100 ++++--- .../config/dashboard/ha-config-navigation.ts | 2 +- .../ha-device-automation-dialog.ts | 13 +- .../config/devices/ha-config-devices.ts | 2 - src/panels/config/ha-panel-config.ts | 17 +- .../config/helpers/dialog-helper-detail.ts | 40 +-- .../dialog-lovelace-dashboard-detail.ts | 262 +++++++++++++++++ .../ha-config-lovelace-dashboards.ts | 276 ++++++++++++++++++ .../show-dialog-lovelace-dashboard-detail.ts | 31 ++ .../config/lovelace/ha-config-lovelace.ts | 63 ++++ .../dialog-lovelace-resource-detail.ts | 228 +++++++++++++++ .../resources/ha-config-lovelace-resources.ts | 209 +++++++++++++ .../show-dialog-lovelace-resource-detail.ts | 30 ++ .../config/person/dialog-person-detail.ts | 45 +-- src/panels/config/zone/dialog-zone-detail.ts | 49 +--- src/panels/lovelace/common/load-resources.ts | 4 +- src/resources/styles.ts | 23 ++ src/translations/en.json | 73 ++++- 21 files changed, 1465 insertions(+), 180 deletions(-) create mode 100644 src/panels/config/lovelace/dashboards/dialog-lovelace-dashboard-detail.ts create mode 100644 src/panels/config/lovelace/dashboards/ha-config-lovelace-dashboards.ts create mode 100644 src/panels/config/lovelace/dashboards/show-dialog-lovelace-dashboard-detail.ts create mode 100644 src/panels/config/lovelace/ha-config-lovelace.ts create mode 100644 src/panels/config/lovelace/resources/dialog-lovelace-resource-detail.ts create mode 100644 src/panels/config/lovelace/resources/ha-config-lovelace-resources.ts create mode 100644 src/panels/config/lovelace/resources/show-dialog-lovelace-resource-detail.ts diff --git a/src/components/data-table/ha-data-table.ts b/src/components/data-table/ha-data-table.ts index 28b657cd1c..73188403e6 100644 --- a/src/components/data-table/ha-data-table.ts +++ b/src/components/data-table/ha-data-table.ts @@ -571,6 +571,18 @@ export class HaDataTable extends BaseElement { width: 24px; } + .mdc-data-table__header-cell--icon { + text-align: center; + } + + .mdc-data-table__cell--icon:first-child ha-icon { + margin-left: 8px; + } + + .mdc-data-table__cell--icon:first-child state-badge { + margin-right: -8px; + } + .mdc-data-table__header-cell { font-family: Roboto, sans-serif; -moz-osx-font-smoothing: grayscale; @@ -598,10 +610,6 @@ export class HaDataTable extends BaseElement { text-align: left; } - .mdc-data-table__header-cell--icon { - text-align: center; - } - /* custom from here */ :host { @@ -615,27 +623,39 @@ export class HaDataTable extends BaseElement { } .mdc-data-table__header-cell { overflow: hidden; + position: relative; } + .mdc-data-table__header-cell span { + position: relative; + left: 0px; + } + .mdc-data-table__header-cell.sortable { cursor: pointer; } - .mdc-data-table__header-cell.not-sorted:not(.mdc-data-table__header-cell--numeric):not(.mdc-data-table__header-cell--icon) - span { - position: relative; - left: -24px; - } - .mdc-data-table__header-cell.not-sorted > * { + .mdc-data-table__header-cell > * { transition: left 0.2s ease 0s; } + .mdc-data-table__header-cell ha-icon { + top: 15px; + position: absolute; + } .mdc-data-table__header-cell.not-sorted ha-icon { - left: -36px; + left: -20px; } - .mdc-data-table__header-cell.not-sorted:not(.mdc-data-table__header-cell--numeric):not(.mdc-data-table__header-cell--icon):hover + .mdc-data-table__header-cell:not(.not-sorted) span, + .mdc-data-table__header-cell.not-sorted:hover span { + left: 24px; + } + .mdc-data-table__header-cell.mdc-data-table__header-cell--numeric:not(.not-sorted) + span, + .mdc-data-table__header-cell.mdc-data-table__header-cell--numeric.not-sorted:hover span { - left: 0px; + left: 12px; } + .mdc-data-table__header-cell:not(.not-sorted) ha-icon, .mdc-data-table__header-cell:hover.not-sorted ha-icon { - left: 0px; + left: 12px; } .table-header { border-bottom: 1px solid rgba(var(--rgb-primary-text-color), 0.12); diff --git a/src/components/ha-dialog.ts b/src/components/ha-dialog.ts index ff770e7bb7..290f5ad22f 100644 --- a/src/components/ha-dialog.ts +++ b/src/components/ha-dialog.ts @@ -1,12 +1,23 @@ -import { customElement, CSSResult, css } from "lit-element"; +import { customElement, CSSResult, css, html } from "lit-element"; +import "@polymer/paper-icon-button/paper-icon-button"; import "@material/mwc-dialog"; import { style } from "@material/mwc-dialog/mwc-dialog-css"; // tslint:disable-next-line import { Dialog } from "@material/mwc-dialog"; -import { Constructor } from "../types"; +import { Constructor, HomeAssistant } from "../types"; // tslint:disable-next-line const MwcDialog = customElements.get("mwc-dialog") as Constructor; +export const createCloseHeading = (hass: HomeAssistant, title: string) => html` + ${title} + +`; + @customElement("ha-dialog") export class HaDialog extends MwcDialog { protected static get styles(): CSSResult[] { @@ -19,6 +30,15 @@ export class HaDialog extends MwcDialog { .mdc-dialog__container { align-items: var(--vertial-align-dialog, center); } + .mdc-dialog__title::before { + display: block; + height: 20px; + } + .close_button { + position: absolute; + right: 16px; + top: 12px; + } `, ]; } diff --git a/src/data/lovelace.ts b/src/data/lovelace.ts index 618c146f5f..cde4dda192 100644 --- a/src/data/lovelace.ts +++ b/src/data/lovelace.ts @@ -12,10 +12,47 @@ export interface LovelaceConfig { background?: string; } -export type LovelaceResources = Array<{ +export interface LovelaceResource { + id: string; type: "css" | "js" | "module" | "html"; url: string; -}>; +} + +export interface LovelaceResourcesMutableParams { + res_type: "css" | "js" | "module" | "html"; + url: string; +} + +export type LovelaceDashboard = + | LovelaceYamlDashboard + | LovelaceStorageDashboard; + +interface LovelaceGenericDashboard { + id: string; + url_path: string; + require_admin: boolean; + sidebar?: { icon: string; title: string }; +} + +export interface LovelaceYamlDashboard extends LovelaceGenericDashboard { + mode: "yaml"; + filename: string; +} + +export interface LovelaceStorageDashboard extends LovelaceGenericDashboard { + mode: "storage"; +} + +export interface LovelaceDashboardMutableParams { + require_admin: boolean; + sidebar: { icon: string; title: string } | null; +} + +export interface LovelaceDashboardCreateParams + extends LovelaceDashboardMutableParams { + url_path: string; + mode: "storage"; +} export interface LovelaceViewConfig { index?: number; @@ -111,10 +148,70 @@ type LovelaceUpdatedEvent = HassEventBase & { }; }; -export const fetchResources = (conn: Connection): Promise => +export const fetchResources = (conn: Connection): Promise => conn.sendMessagePromise({ type: "lovelace/resources", }); + +export const createResource = ( + hass: HomeAssistant, + values: LovelaceResourcesMutableParams +) => + hass.callWS({ + type: "lovelace/resources/create", + ...values, + }); + +export const updateResource = ( + hass: HomeAssistant, + id: string, + updates: Partial +) => + hass.callWS({ + type: "lovelace/resources/update", + resource_id: id, + ...updates, + }); + +export const deleteResource = (hass: HomeAssistant, id: string) => + hass.callWS({ + type: "lovelace/resources/delete", + resource_id: id, + }); + +export const fetchDashboards = ( + hass: HomeAssistant +): Promise => + hass.callWS({ + type: "lovelace/dashboards/list", + }); + +export const createDashboard = ( + hass: HomeAssistant, + values: LovelaceDashboardCreateParams +) => + hass.callWS({ + type: "lovelace/dashboards/create", + ...values, + }); + +export const updateDashboard = ( + hass: HomeAssistant, + id: string, + updates: Partial +) => + hass.callWS({ + type: "lovelace/dashboards/update", + dashboard_id: id, + ...updates, + }); + +export const deleteDashboard = (hass: HomeAssistant, id: string) => + hass.callWS({ + type: "lovelace/dashboards/delete", + dashboard_id: id, + }); + export const fetchConfig = ( conn: Connection, urlPath: string | null, @@ -125,6 +222,7 @@ export const fetchConfig = ( url_path: urlPath, force, }); + export const saveConfig = ( hass: HomeAssistant, urlPath: string | null, @@ -174,7 +272,7 @@ export const getLovelaceCollection = ( export interface WindowWithLovelaceProm extends Window { llConfProm?: Promise; - llResProm?: Promise; + llResProm?: Promise; } export interface ActionHandlerOptions { diff --git a/src/layouts/hass-tabs-subpage.ts b/src/layouts/hass-tabs-subpage.ts index a3130916df..7d904c1a5f 100644 --- a/src/layouts/hass-tabs-subpage.ts +++ b/src/layouts/hass-tabs-subpage.ts @@ -15,6 +15,7 @@ import { Route, HomeAssistant } from "../types"; import { navigate } from "../common/navigate"; import "@material/mwc-ripple"; import { isComponentLoaded } from "../common/config/is_component_loaded"; +import memoizeOne from "memoize-one"; export interface PageNavigation { path: string; @@ -22,7 +23,7 @@ export interface PageNavigation { component?: string; name?: string; core?: boolean; - exportOnly?: boolean; + advancedOnly?: boolean; icon?: string; info?: any; } @@ -33,12 +34,57 @@ class HassTabsSubpage extends LitElement { @property({ type: String, attribute: "back-path" }) public backPath?: string; @property() public backCallback?: () => void; @property({ type: Boolean }) public hassio = false; - @property({ type: Boolean }) public showAdvanced = false; @property() public route!: Route; @property() public tabs!: PageNavigation[]; @property({ type: Boolean, reflect: true }) public narrow = false; @property() private _activeTab: number = -1; + private _getTabs = memoizeOne( + ( + tabs: PageNavigation[], + activeTab: number, + showAdvanced: boolean | undefined, + _components, + _language + ) => { + const shownTabs = tabs.filter( + (page) => + (!page.component || + page.core || + isComponentLoaded(this.hass, page.component)) && + (!page.advancedOnly || showAdvanced) + ); + + return shownTabs.map( + (page, index) => html` +
+ ${this.narrow + ? html` + + ` + : ""} + ${!this.narrow || index === activeTab + ? html` + ${page.translationKey + ? this.hass.localize(page.translationKey) + : name} + ` + : ""} + +
+ ` + ); + } + ); + protected updated(changedProperties: PropertyValues) { super.updated(changedProperties); if (changedProperties.has("route")) { @@ -49,6 +95,14 @@ class HassTabsSubpage extends LitElement { } protected render(): TemplateResult { + const tabs = this._getTabs( + this.tabs, + this._activeTab, + this.hass.userData?.showAdvanced, + this.hass.config.components, + this.hass.language + ); + return html`
` : ""} -
- ${this.tabs.map((page, index) => - (!page.component || - page.core || - isComponentLoaded(this.hass, page.component)) && - (!page.exportOnly || this.showAdvanced) - ? html` -
- ${this.narrow - ? html` - - ` - : ""} - ${!this.narrow || index === this._activeTab - ? html` - ${page.translationKey - ? this.hass.localize(page.translationKey) - : name} - ` - : ""} - -
- ` - : "" - )} -
- + ${tabs.length > 1 || !this.narrow + ? html` +
+ ${tabs} +
+ ` + : ""}
diff --git a/src/panels/config/dashboard/ha-config-navigation.ts b/src/panels/config/dashboard/ha-config-navigation.ts index 3af4194ac9..2d0116daf1 100644 --- a/src/panels/config/dashboard/ha-config-navigation.ts +++ b/src/panels/config/dashboard/ha-config-navigation.ts @@ -31,7 +31,7 @@ class HaConfigNavigation extends LitElement { (!page.component || page.core || isComponentLoaded(this.hass, page.component)) && - (!page.exportOnly || this.showAdvanced) + (!page.advancedOnly || this.showAdvanced) ? html` + import( + /* webpackChunkName: "panel-config-lovelace" */ "./lovelace/ha-config-lovelace" + ), + }, person: { tag: "ha-config-person", load: () => diff --git a/src/panels/config/helpers/dialog-helper-detail.ts b/src/panels/config/helpers/dialog-helper-detail.ts index 2ede201a0b..2b2ad20508 100644 --- a/src/panels/config/helpers/dialog-helper-detail.ts +++ b/src/panels/config/helpers/dialog-helper-detail.ts @@ -25,6 +25,7 @@ import "./forms/ha-input_select-form"; import "./forms/ha-input_number-form"; import { domainIcon } from "../../../common/entity/domain_icon"; import { classMap } from "lit-html/directives/class-map"; +import { haStyleDialog } from "../../../resources/styles"; const HELPERS = { input_boolean: createInputBoolean, @@ -156,37 +157,18 @@ export class DialogHelperDetail extends LitElement { this._platform = undefined; } - static get styles(): CSSResult { - return css` - ha-dialog { - --mdc-dialog-title-ink-color: var(--primary-text-color); - --justify-action-buttons: space-between; - } - ha-dialog.button-left { - --justify-action-buttons: flex-start; - } - @media only screen and (min-width: 600px) { - ha-dialog { - --mdc-dialog-min-width: 600px; + static get styles(): CSSResult[] { + return [ + haStyleDialog, + css` + ha-dialog.button-left { + --justify-action-buttons: flex-start; } - } - - /* make dialog fullscreen on small screens */ - @media all and (max-width: 450px), all and (max-height: 500px) { - ha-dialog { - --mdc-dialog-min-width: 100vw; - --mdc-dialog-max-height: 100vh; - --mdc-dialog-shape-radius: 0px; - --vertial-align-dialog: flex-end; + paper-icon-item { + cursor: pointer; } - } - .error { - color: var(--google-red-500); - } - paper-icon-item { - cursor: pointer; - } - `; + `, + ]; } } diff --git a/src/panels/config/lovelace/dashboards/dialog-lovelace-dashboard-detail.ts b/src/panels/config/lovelace/dashboards/dialog-lovelace-dashboard-detail.ts new file mode 100644 index 0000000000..9698c6a9fa --- /dev/null +++ b/src/panels/config/lovelace/dashboards/dialog-lovelace-dashboard-detail.ts @@ -0,0 +1,262 @@ +import { + css, + CSSResult, + customElement, + html, + LitElement, + property, + TemplateResult, +} from "lit-element"; +import "../../../../components/ha-icon-input"; +import { HomeAssistant } from "../../../../types"; +import { + LovelaceDashboard, + LovelaceDashboardMutableParams, + LovelaceDashboardCreateParams, +} from "../../../../data/lovelace"; +import { LovelaceDashboardDetailsDialogParams } from "./show-dialog-lovelace-dashboard-detail"; +import { PolymerChangedEvent } from "../../../../polymer-types"; +import { HaSwitch } from "../../../../components/ha-switch"; +import { createCloseHeading } from "../../../../components/ha-dialog"; +import { haStyleDialog } from "../../../../resources/styles"; + +@customElement("dialog-lovelace-dashboard-detail") +export class DialogLovelaceDashboardDetail extends LitElement { + @property() public hass!: HomeAssistant; + @property() private _params?: LovelaceDashboardDetailsDialogParams; + @property() private _urlPath!: LovelaceDashboard["url_path"]; + @property() private _showSidebar!: boolean; + @property() private _sidebarIcon!: string; + @property() private _sidebarTitle!: string; + @property() private _requireAdmin!: LovelaceDashboard["require_admin"]; + + @property() private _error?: string; + @property() private _submitting = false; + + public async showDialog( + params: LovelaceDashboardDetailsDialogParams + ): Promise { + this._params = params; + this._error = undefined; + if (this._params.dashboard) { + this._urlPath = this._params.dashboard.url_path || ""; + this._showSidebar = !!this._params.dashboard.sidebar; + this._sidebarIcon = this._params.dashboard.sidebar?.icon || ""; + this._sidebarTitle = this._params.dashboard.sidebar?.title || ""; + this._requireAdmin = this._params.dashboard.require_admin || false; + } else { + this._urlPath = ""; + this._showSidebar = true; + this._sidebarIcon = ""; + this._sidebarTitle = ""; + this._requireAdmin = false; + } + await this.updateComplete; + } + + protected render(): TemplateResult { + if (!this._params) { + return html``; + } + const urlInvalid = !/^[a-zA-Z0-9_-]+$/.test(this._urlPath); + return html` + +
+ ${this._error + ? html` +
${this._error}
+ ` + : ""} +
+ ${this.hass!.localize( + "ui.panel.config.lovelace.dashboards.detail.show_sidebar" + )} + ${this._showSidebar + ? html` + + + ` + : ""} + ${!this._params.dashboard + ? html` + + ` + : ""} + ${this.hass!.localize( + "ui.panel.config.lovelace.dashboards.detail.require_admin" + )} +
+
+ ${this._params.dashboard + ? html` + + ${this.hass!.localize( + "ui.panel.config.lovelace.dashboards.detail.delete" + )} + + ` + : html``} + + ${this._params.dashboard + ? this.hass!.localize( + "ui.panel.config.lovelace.dashboards.detail.update" + ) + : this.hass!.localize( + "ui.panel.config.lovelace.dashboards.detail.create" + )} + +
+ `; + } + + private _urlChanged(ev: PolymerChangedEvent) { + this._error = undefined; + this._urlPath = ev.detail.value; + } + + private _sidebarIconChanged(ev: PolymerChangedEvent) { + this._error = undefined; + this._sidebarIcon = ev.detail.value; + } + + private _sidebarTitleChanged(ev: PolymerChangedEvent) { + this._error = undefined; + this._sidebarTitle = ev.detail.value; + } + + private _fillUrlPath() { + if (this._urlPath) { + return; + } + const parts = this._sidebarTitle.split(" "); + + if (parts.length) { + this._urlPath = parts[0].toLowerCase(); + } + } + + private _showSidebarChanged(ev: Event) { + this._showSidebar = (ev.target as HaSwitch).checked; + } + + private _requireAdminChanged(ev: Event) { + this._requireAdmin = (ev.target as HaSwitch).checked; + } + + private async _updateDashboard() { + this._submitting = true; + try { + const values: Partial = { + require_admin: this._requireAdmin, + sidebar: this._showSidebar + ? { icon: this._sidebarIcon, title: this._sidebarTitle } + : null, + }; + if (this._params!.dashboard) { + await this._params!.updateDashboard(values); + } else { + (values as LovelaceDashboardCreateParams).url_path = this._urlPath.trim(); + (values as LovelaceDashboardCreateParams).mode = "storage"; + await this._params!.createDashboard( + values as LovelaceDashboardCreateParams + ); + } + this._params = undefined; + } catch (err) { + this._error = err?.message || "Unknown error"; + } finally { + this._submitting = false; + } + } + + private async _deleteDashboard() { + this._submitting = true; + try { + if (await this._params!.removeDashboard()) { + this._close(); + } + } finally { + this._submitting = false; + } + } + + private _close(): void { + this._params = undefined; + } + + static get styles(): CSSResult[] { + return [ + haStyleDialog, + css` + .form { + padding-bottom: 24px; + } + ha-switch { + padding: 16px 0; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "dialog-lovelace-dashboard-detail": DialogLovelaceDashboardDetail; + } +} diff --git a/src/panels/config/lovelace/dashboards/ha-config-lovelace-dashboards.ts b/src/panels/config/lovelace/dashboards/ha-config-lovelace-dashboards.ts new file mode 100644 index 0000000000..e791036abc --- /dev/null +++ b/src/panels/config/lovelace/dashboards/ha-config-lovelace-dashboards.ts @@ -0,0 +1,276 @@ +import { + customElement, + html, + LitElement, + property, + PropertyValues, + TemplateResult, + CSSResult, + css, +} from "lit-element"; +import memoize from "memoize-one"; +import { + DataTableColumnContainer, + RowClickedEvent, +} from "../../../../components/data-table/ha-data-table"; +import "../../../../components/ha-icon"; +import "../../../../layouts/hass-loading-screen"; +import "../../../../layouts/hass-tabs-subpage-data-table"; +import { HomeAssistant, Route } from "../../../../types"; +import { + LovelaceDashboard, + fetchDashboards, + createDashboard, + updateDashboard, + deleteDashboard, + LovelaceDashboardCreateParams, +} from "../../../../data/lovelace"; +import { showDashboardDetailDialog } from "./show-dialog-lovelace-dashboard-detail"; +import { compare } from "../../../../common/string/compare"; +import { + showConfirmationDialog, + showAlertDialog, +} from "../../../../dialogs/generic/show-dialog-box"; +import { lovelaceTabs } from "../ha-config-lovelace"; +import { navigate } from "../../../../common/navigate"; + +@customElement("ha-config-lovelace-dashboards") +export class HaConfigLovelaceDashboards extends LitElement { + @property() public hass!: HomeAssistant; + @property() public isWide!: boolean; + @property() public narrow!: boolean; + @property() public route!: Route; + @property() private _dashboards: LovelaceDashboard[] = []; + + private _columns = memoize( + (_language, dashboards): DataTableColumnContainer => { + const columns: DataTableColumnContainer = { + icon: { + title: "", + type: "icon", + template: (icon) => + icon + ? html` + + ` + : html``, + }, + title: { + title: this.hass.localize( + "ui.panel.config.lovelace.dashboards.picker.headers.title" + ), + sortable: true, + filterable: true, + direction: "asc", + }, + mode: { + title: this.hass.localize( + "ui.panel.config.lovelace.dashboards.picker.headers.conf_mode" + ), + sortable: true, + filterable: true, + template: (mode) => + html` + ${this.hass.localize( + `ui.panel.config.lovelace.dashboards.conf_mode.${mode}` + ) || mode} + `, + }, + }; + + if (dashboards.some((dashboard) => dashboard.mode === "yaml")) { + columns.filename = { + title: this.hass.localize( + "ui.panel.config.lovelace.dashboards.picker.headers.filename" + ), + sortable: true, + filterable: true, + }; + } + + const columns2: DataTableColumnContainer = { + require_admin: { + title: this.hass.localize( + "ui.panel.config.lovelace.dashboards.picker.headers.require_admin" + ), + sortable: true, + type: "icon", + template: (requireAdmin: boolean) => + requireAdmin + ? html` + + ` + : html` + - + `, + }, + sidebar: { + title: this.hass.localize( + "ui.panel.config.lovelace.dashboards.picker.headers.sidebar" + ), + type: "icon", + template: (sidebar) => + sidebar + ? html` + + ` + : html` + - + `, + }, + url_path: { + title: "", + type: "icon", + filterable: true, + template: (urlPath) => + html` + ${this.hass.localize( + "ui.panel.config.lovelace.dashboards.picker.open" + )} + `, + }, + }; + return { ...columns, ...columns2 }; + } + ); + + private _getItems = memoize((dashboards: LovelaceDashboard[]) => { + return dashboards.map((dashboard) => { + return { + filename: "", + ...dashboard, + icon: dashboard.sidebar?.icon, + title: dashboard.sidebar?.title || dashboard.url_path, + }; + }); + }); + + protected render(): TemplateResult { + if (!this.hass || this._dashboards === undefined) { + return html` + + `; + } + + return html` + + + + `; + } + + protected firstUpdated(changedProps: PropertyValues) { + super.firstUpdated(changedProps); + this._getDashboards(); + } + + private async _getDashboards() { + this._dashboards = await fetchDashboards(this.hass); + } + + private _navigate(ev: Event) { + ev.stopPropagation(); + const url = `/${(ev.target as any).urlPath}`; + navigate(this, url); + } + + private _editDashboard(ev: CustomEvent) { + const id = (ev.detail as RowClickedEvent).id; + const dashboard = id + ? this._dashboards.find((res) => res.id === id) + : undefined; + if (!dashboard) { + showAlertDialog(this, { + text: this.hass!.localize( + "ui.panel.config.lovelace.dashboards.cant_edit_yaml" + ), + }); + return; + } + this._openDialog(dashboard); + } + + private _addDashboard() { + this._openDialog(); + } + + private async _openDialog(dashboard?: LovelaceDashboard): Promise { + showDashboardDetailDialog(this, { + dashboard, + createDashboard: async (values: LovelaceDashboardCreateParams) => { + const created = await createDashboard(this.hass!, values); + this._dashboards = this._dashboards!.concat( + created + ).sort((res1, res2) => compare(res1.url_path, res2.url_path)); + }, + updateDashboard: async (values) => { + const updated = await updateDashboard( + this.hass!, + dashboard!.id, + values + ); + this._dashboards = this._dashboards!.map((res) => + res === dashboard ? updated : res + ); + }, + removeDashboard: async () => { + if ( + !(await showConfirmationDialog(this, { + text: this.hass!.localize( + "ui.panel.config.lovelace.dashboards.confirm_delete" + ), + })) + ) { + return false; + } + + try { + await deleteDashboard(this.hass!, dashboard!.id); + this._dashboards = this._dashboards!.filter( + (res) => res !== dashboard + ); + return true; + } catch (err) { + return false; + } + }, + }); + } + + static get styles(): CSSResult { + return css` + ha-fab { + position: fixed; + bottom: 16px; + right: 16px; + z-index: 1; + } + ha-fab[is-wide] { + bottom: 24px; + right: 24px; + } + ha-fab[narrow] { + bottom: 84px; + } + `; + } +} diff --git a/src/panels/config/lovelace/dashboards/show-dialog-lovelace-dashboard-detail.ts b/src/panels/config/lovelace/dashboards/show-dialog-lovelace-dashboard-detail.ts new file mode 100644 index 0000000000..84c72d7176 --- /dev/null +++ b/src/panels/config/lovelace/dashboards/show-dialog-lovelace-dashboard-detail.ts @@ -0,0 +1,31 @@ +import { fireEvent } from "../../../../common/dom/fire_event"; +import { + LovelaceDashboard, + LovelaceDashboardMutableParams, + LovelaceDashboardCreateParams, +} from "../../../../data/lovelace"; + +export interface LovelaceDashboardDetailsDialogParams { + dashboard?: LovelaceDashboard; + createDashboard: (values: LovelaceDashboardCreateParams) => Promise; + updateDashboard: ( + updates: Partial + ) => Promise; + removeDashboard: () => Promise; +} + +export const loadDashboardDetailDialog = () => + import( + /* webpackChunkName: "lovelace-dashboard-detail-dialog" */ "./dialog-lovelace-dashboard-detail" + ); + +export const showDashboardDetailDialog = ( + element: HTMLElement, + dialogParams: LovelaceDashboardDetailsDialogParams +) => { + fireEvent(element, "show-dialog", { + dialogTag: "dialog-lovelace-dashboard-detail", + dialogImport: loadDashboardDetailDialog, + dialogParams, + }); +}; diff --git a/src/panels/config/lovelace/ha-config-lovelace.ts b/src/panels/config/lovelace/ha-config-lovelace.ts new file mode 100644 index 0000000000..d509d9161b --- /dev/null +++ b/src/panels/config/lovelace/ha-config-lovelace.ts @@ -0,0 +1,63 @@ +import { + HassRouterPage, + RouterOptions, +} from "../../../layouts/hass-router-page"; +import { property, customElement } from "lit-element"; +import { HomeAssistant } from "../../../types"; + +export const lovelaceTabs = [ + { + component: "lovelace", + path: "/config/lovelace/dashboards", + translationKey: "ui.panel.config.lovelace.dashboards.caption", + icon: "hass:view-dashboard", + }, + { + component: "lovelace", + path: "/config/lovelace/resources", + translationKey: "ui.panel.config.lovelace.resources.caption", + icon: "hass:file-multiple", + advancedOnly: true, + }, +]; + +@customElement("ha-config-lovelace") +class HaConfigLovelace extends HassRouterPage { + @property() public hass!: HomeAssistant; + @property() public narrow!: boolean; + @property() public isWide!: boolean; + + protected routerOptions: RouterOptions = { + defaultPage: "dashboards", + routes: { + dashboards: { + tag: "ha-config-lovelace-dashboards", + load: () => + import( + /* webpackChunkName: "panel-config-lovelace-dashboards" */ "./dashboards/ha-config-lovelace-dashboards" + ), + cache: true, + }, + resources: { + tag: "ha-config-lovelace-resources", + load: () => + import( + /* webpackChunkName: "panel-config-lovelace-resources" */ "./resources/ha-config-lovelace-resources" + ), + }, + }, + }; + + protected updatePageEl(pageEl) { + pageEl.hass = this.hass; + pageEl.narrow = this.narrow; + pageEl.isWide = this.isWide; + pageEl.route = this.routeTail; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-config-lovelace": HaConfigLovelace; + } +} diff --git a/src/panels/config/lovelace/resources/dialog-lovelace-resource-detail.ts b/src/panels/config/lovelace/resources/dialog-lovelace-resource-detail.ts new file mode 100644 index 0000000000..f2571805d3 --- /dev/null +++ b/src/panels/config/lovelace/resources/dialog-lovelace-resource-detail.ts @@ -0,0 +1,228 @@ +import { + css, + CSSResult, + customElement, + html, + LitElement, + property, + TemplateResult, +} from "lit-element"; +import { HomeAssistant } from "../../../../types"; +import { + LovelaceResource, + LovelaceResourcesMutableParams, +} from "../../../../data/lovelace"; +import { LovelaceResourceDetailsDialogParams } from "./show-dialog-lovelace-resource-detail"; +import { PolymerChangedEvent } from "../../../../polymer-types"; +import { createCloseHeading } from "../../../../components/ha-dialog"; +import { haStyleDialog } from "../../../../resources/styles"; + +@customElement("dialog-lovelace-resource-detail") +export class DialogLovelaceResourceDetail extends LitElement { + @property() public hass!: HomeAssistant; + @property() private _params?: LovelaceResourceDetailsDialogParams; + @property() private _url!: LovelaceResource["url"]; + @property() private _type!: LovelaceResource["type"]; + @property() private _error?: string; + @property() private _submitting = false; + + public async showDialog( + params: LovelaceResourceDetailsDialogParams + ): Promise { + this._params = params; + this._error = undefined; + if (this._params.resource) { + this._url = this._params.resource.url || ""; + this._type = this._params.resource.type || "module"; + } else { + this._url = ""; + this._type = "module"; + } + await this.updateComplete; + } + + protected render(): TemplateResult { + if (!this._params) { + return html``; + } + const urlInvalid = this._url.trim() === ""; + return html` + +
+ ${this._error + ? html` +
${this._error}
+ ` + : ""} +
+

+ ${this.hass!.localize( + "ui.panel.config.lovelace.resources.detail.warning_header" + )} +

+ ${this.hass!.localize( + "ui.panel.config.lovelace.resources.detail.warning_text" + )} + +
+ + + + ${this.hass!.localize( + "ui.panel.config.lovelace.resources.types.module" + )} + + ${this._type === "js" + ? html` + + ${this.hass!.localize( + "ui.panel.config.lovelace.resources.types.js" + )} + + ` + : ""} + + ${this.hass!.localize( + "ui.panel.config.lovelace.resources.types.css" + )} + + ${this._type === "html" + ? html` + + ${this.hass!.localize( + "ui.panel.config.lovelace.resources.types.html" + )} + + ` + : ""} + + +
+
+ ${this._params.resource + ? html` + + ${this.hass!.localize( + "ui.panel.config.lovelace.resources.detail.delete" + )} + + ` + : html``} + + ${this._params.resource + ? this.hass!.localize( + "ui.panel.config.lovelace.resources.detail.update" + ) + : this.hass!.localize( + "ui.panel.config.lovelace.resources.detail.create" + )} + +
+ `; + } + + private _urlChanged(ev: PolymerChangedEvent) { + this._error = undefined; + this._url = ev.detail.value; + } + + private _typeChanged(ev: CustomEvent) { + this._type = ev.detail.item.getAttribute("type"); + } + + private async _updateResource() { + this._submitting = true; + try { + const values: LovelaceResourcesMutableParams = { + url: this._url.trim(), + res_type: this._type, + }; + if (this._params!.resource) { + await this._params!.updateResource(values); + } else { + await this._params!.createResource(values); + } + this._params = undefined; + } catch (err) { + this._error = err?.message || "Unknown error"; + } finally { + this._submitting = false; + } + } + + private async _deleteResource() { + this._submitting = true; + try { + if (await this._params!.removeResource()) { + this._close(); + } + } finally { + this._submitting = false; + } + } + + private _close(): void { + this._params = undefined; + } + + static get styles(): CSSResult[] { + return [ + haStyleDialog, + css` + .form { + padding-bottom: 24px; + } + .warning { + color: var(--error-color); + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "dialog-lovelace-resource-detail": DialogLovelaceResourceDetail; + } +} diff --git a/src/panels/config/lovelace/resources/ha-config-lovelace-resources.ts b/src/panels/config/lovelace/resources/ha-config-lovelace-resources.ts new file mode 100644 index 0000000000..bda6b20e9b --- /dev/null +++ b/src/panels/config/lovelace/resources/ha-config-lovelace-resources.ts @@ -0,0 +1,209 @@ +import "@polymer/paper-checkbox/paper-checkbox"; +import "@polymer/paper-dropdown-menu/paper-dropdown-menu"; +import "@polymer/paper-item/paper-icon-item"; +import "@polymer/paper-listbox/paper-listbox"; +import "@polymer/paper-tooltip/paper-tooltip"; +import { + customElement, + html, + LitElement, + property, + PropertyValues, + TemplateResult, + CSSResult, + css, +} from "lit-element"; +import memoize from "memoize-one"; +import "../../../../common/search/search-input"; +import { + DataTableColumnContainer, + RowClickedEvent, +} from "../../../../components/data-table/ha-data-table"; +import "../../../../components/ha-icon"; +import "../../../../layouts/hass-loading-screen"; +import "../../../../layouts/hass-tabs-subpage-data-table"; +import { HomeAssistant, Route } from "../../../../types"; +import { + LovelaceResource, + fetchResources, + createResource, + updateResource, + deleteResource, +} from "../../../../data/lovelace"; +import { showResourceDetailDialog } from "./show-dialog-lovelace-resource-detail"; +import { compare } from "../../../../common/string/compare"; +import { + showConfirmationDialog, + showAlertDialog, +} from "../../../../dialogs/generic/show-dialog-box"; +import { lovelaceTabs } from "../ha-config-lovelace"; +import { loadLovelaceResources } from "../../../lovelace/common/load-resources"; + +@customElement("ha-config-lovelace-resources") +export class HaConfigLovelaceRescources extends LitElement { + @property() public hass!: HomeAssistant; + @property() public isWide!: boolean; + @property() public narrow!: boolean; + @property() public route!: Route; + @property() private _resources: LovelaceResource[] = []; + + private _columns = memoize( + (_language): DataTableColumnContainer => { + return { + url: { + title: this.hass.localize( + "ui.panel.config.lovelace.resources.picker.headers.url" + ), + sortable: true, + filterable: true, + direction: "asc", + }, + type: { + title: this.hass.localize( + "ui.panel.config.lovelace.resources.picker.headers.type" + ), + sortable: true, + filterable: true, + template: (type) => + html` + ${this.hass.localize( + `ui.panel.config.lovelace.resources.types.${type}` + ) || type} + `, + }, + }; + } + ); + + protected render(): TemplateResult { + if (!this.hass || this._resources === undefined) { + return html` + + `; + } + + return html` + + + + `; + } + + protected firstUpdated(changedProps: PropertyValues) { + super.firstUpdated(changedProps); + this._getResources(); + } + + private async _getResources() { + this._resources = await fetchResources(this.hass.connection); + } + + private _editResource(ev: CustomEvent) { + if ((this.hass.panels.lovelace?.config as any)?.mode !== "storage") { + showAlertDialog(this, { + text: this.hass!.localize( + "ui.panel.config.lovelace.resources.cant_edit_yaml" + ), + }); + return; + } + const id = (ev.detail as RowClickedEvent).id; + const resource = this._resources.find((res) => res.id === id); + this._openDialog(resource); + } + + private _addResource() { + if ((this.hass.panels.lovelace?.config as any)?.mode !== "storage") { + showAlertDialog(this, { + text: this.hass!.localize( + "ui.panel.config.lovelace.resources.cant_edit_yaml" + ), + }); + return; + } + this._openDialog(); + } + + private async _openDialog(resource?: LovelaceResource): Promise { + showResourceDetailDialog(this, { + resource, + createResource: async (values) => { + const created = await createResource(this.hass!, values); + this._resources = this._resources!.concat(created).sort((res1, res2) => + compare(res1.url, res2.url) + ); + loadLovelaceResources(this._resources, this.hass!.auth.data.hassUrl); + }, + updateResource: async (values) => { + const updated = await updateResource(this.hass!, resource!.id, values); + this._resources = this._resources!.map((res) => + res === resource ? updated : res + ); + loadLovelaceResources(this._resources, this.hass!.auth.data.hassUrl); + }, + removeResource: async () => { + if ( + !(await showConfirmationDialog(this, { + text: this.hass!.localize( + "ui.panel.config.lovelace.resources.confirm_delete" + ), + })) + ) { + return false; + } + + try { + await deleteResource(this.hass!, resource!.id); + this._resources = this._resources!.filter((res) => res !== resource); + showConfirmationDialog(this, { + title: this.hass!.localize( + "ui.panel.config.lovelace.resources.refresh_header" + ), + text: this.hass!.localize( + "ui.panel.config.lovelace.resources.refresh_body" + ), + confirm: () => location.reload(), + }); + return true; + } catch (err) { + return false; + } + }, + }); + } + + static get styles(): CSSResult { + return css` + ha-fab { + position: fixed; + bottom: 16px; + right: 16px; + z-index: 1; + } + ha-fab[is-wide] { + bottom: 24px; + right: 24px; + } + ha-fab[narrow] { + bottom: 84px; + } + `; + } +} diff --git a/src/panels/config/lovelace/resources/show-dialog-lovelace-resource-detail.ts b/src/panels/config/lovelace/resources/show-dialog-lovelace-resource-detail.ts new file mode 100644 index 0000000000..815f32f642 --- /dev/null +++ b/src/panels/config/lovelace/resources/show-dialog-lovelace-resource-detail.ts @@ -0,0 +1,30 @@ +import { fireEvent } from "../../../../common/dom/fire_event"; +import { + LovelaceResource, + LovelaceResourcesMutableParams, +} from "../../../../data/lovelace"; + +export interface LovelaceResourceDetailsDialogParams { + resource?: LovelaceResource; + createResource: (values: LovelaceResourcesMutableParams) => Promise; + updateResource: ( + updates: Partial + ) => Promise; + removeResource: () => Promise; +} + +export const loadResourceDetailDialog = () => + import( + /* webpackChunkName: "lovelace-resource-detail-dialog" */ "./dialog-lovelace-resource-detail" + ); + +export const showResourceDetailDialog = ( + element: HTMLElement, + dialogParams: LovelaceResourceDetailsDialogParams +) => { + fireEvent(element, "show-dialog", { + dialogTag: "dialog-lovelace-resource-detail", + dialogImport: loadResourceDetailDialog, + dialogParams, + }); +}; diff --git a/src/panels/config/person/dialog-person-detail.ts b/src/panels/config/person/dialog-person-detail.ts index e22cec2b71..95d16c9284 100644 --- a/src/panels/config/person/dialog-person-detail.ts +++ b/src/panels/config/person/dialog-person-detail.ts @@ -13,11 +13,12 @@ import "@material/mwc-button"; import "../../../components/entity/ha-entities-picker"; import "../../../components/user/ha-user-picker"; -import "../../../components/ha-dialog"; import { PersonDetailDialogParams } from "./show-dialog-person-detail"; import { PolymerChangedEvent } from "../../../polymer-types"; import { HomeAssistant } from "../../../types"; import { PersonMutableParams } from "../../../data/person"; +import { createCloseHeading } from "../../../components/ha-dialog"; +import { haStyleDialog } from "../../../resources/styles"; class DialogPersonDetail extends LitElement { @property() public hass!: HomeAssistant; @@ -55,26 +56,18 @@ class DialogPersonDetail extends LitElement { return html``; } const nameInvalid = this._name.trim() === ""; - const title = html` - ${this._params.entry - ? this._params.entry.name - : this.hass!.localize("ui.panel.config.person.detail.new_person")} - - `; return html`
${this._error @@ -236,34 +229,14 @@ class DialogPersonDetail extends LitElement { static get styles(): CSSResult[] { return [ + haStyleDialog, css` - ha-dialog { - --mdc-dialog-min-width: 400px; - --mdc-dialog-max-width: 600px; - --mdc-dialog-title-ink-color: var(--primary-text-color); - --justify-action-buttons: space-between; - } - /* make dialog fullscreen on small screens */ - @media all and (max-width: 450px), all and (max-height: 500px) { - ha-dialog { - --mdc-dialog-min-width: 100vw; - --mdc-dialog-max-height: 100vh; - --mdc-dialog-shape-radius: 0px; - --vertial-align-dialog: flex-end; - } - } .form { padding-bottom: 24px; } ha-user-picker { margin-top: 16px; } - mwc-button.warning { - --mdc-theme-primary: var(--google-red-500); - } - .error { - color: var(--google-red-500); - } a { color: var(--primary-color); } diff --git a/src/panels/config/zone/dialog-zone-detail.ts b/src/panels/config/zone/dialog-zone-detail.ts index 24242c6822..580cd5f87c 100644 --- a/src/panels/config/zone/dialog-zone-detail.ts +++ b/src/panels/config/zone/dialog-zone-detail.ts @@ -12,7 +12,6 @@ import "@material/mwc-button"; import "../../../components/map/ha-location-editor"; import "../../../components/ha-switch"; -import "../../../components/ha-dialog"; import { ZoneDetailDialogParams } from "./show-dialog-zone-detail"; import { HomeAssistant } from "../../../types"; @@ -23,6 +22,8 @@ import { getZoneEditorInitData, } from "../../../data/zone"; import { addDistanceToCoord } from "../../../common/location/add_distance_to_coord"; +import { createCloseHeading } from "../../../components/ha-dialog"; +import { haStyleDialog } from "../../../resources/styles"; class DialogZoneDetail extends LitElement { @property() public hass!: HomeAssistant; @@ -72,19 +73,6 @@ class DialogZoneDetail extends LitElement { if (!this._params) { return html``; } - const title = html` - ${this._params.entry - ? this._params.entry.name - : this.hass!.localize("ui.panel.config.zone.detail.new_zone")} - - `; const nameValid = this._name.trim() === ""; const iconValid = !this._icon.trim().includes(":"); const latValid = String(this._latitude) === ""; @@ -100,7 +88,12 @@ class DialogZoneDetail extends LitElement { @closing="${this._close}" scrimClickAction="" escapeKeyAction="" - .heading=${title} + .heading=${createCloseHeading( + this.hass, + this._params.entry + ? this._params.entry.name + : this.hass!.localize("ui.panel.config.zone.detail.new_zone") + )} >
${this._error @@ -277,26 +270,8 @@ class DialogZoneDetail extends LitElement { static get styles(): CSSResult[] { return [ + haStyleDialog, css` - ha-dialog { - --mdc-dialog-title-ink-color: var(--primary-text-color); - --justify-action-buttons: space-between; - } - @media only screen and (min-width: 600px) { - ha-dialog { - --mdc-dialog-min-width: 600px; - } - } - - /* make dialog fullscreen on small screens */ - @media all and (max-width: 450px), all and (max-height: 500px) { - ha-dialog { - --mdc-dialog-min-width: 100vw; - --mdc-dialog-max-height: 100vh; - --mdc-dialog-shape-radius: 0px; - --vertial-align-dialog: flex-end; - } - } .form { padding-bottom: 24px; color: var(--primary-text-color); @@ -320,12 +295,6 @@ class DialogZoneDetail extends LitElement { ha-user-picker { margin-top: 16px; } - mwc-button.warning { - --mdc-theme-primary: var(--google-red-500); - } - .error { - color: var(--google-red-500); - } a { color: var(--primary-color); } diff --git a/src/panels/lovelace/common/load-resources.ts b/src/panels/lovelace/common/load-resources.ts index b08736bbee..1b58eeb509 100644 --- a/src/panels/lovelace/common/load-resources.ts +++ b/src/panels/lovelace/common/load-resources.ts @@ -1,13 +1,13 @@ import { loadModule, loadCSS, loadJS } from "../../../common/dom/load_resource"; -import { LovelaceResources } from "../../../data/lovelace"; +import { LovelaceResource } from "../../../data/lovelace"; // CSS and JS should only be imported once. Modules and HTML are safe. const CSS_CACHE = {}; const JS_CACHE = {}; export const loadLovelaceResources = ( - resources: NonNullable, + resources: NonNullable, hassUrl: string ) => resources.forEach((resource) => { diff --git a/src/resources/styles.ts b/src/resources/styles.ts index 95838b464e..972e734538 100644 --- a/src/resources/styles.ts +++ b/src/resources/styles.ts @@ -180,4 +180,27 @@ export const haStyleDialog = css` border-bottom-right-radius: 0px; } } + + /* mwc-dialog (ha-dialog) styles */ + ha-dialog { + --mdc-dialog-min-width: 400px; + --mdc-dialog-max-width: 600px; + --mdc-dialog-title-ink-color: var(--primary-text-color); + --justify-action-buttons: space-between; + } + /* make dialog fullscreen on small screens */ + @media all and (max-width: 450px), all and (max-height: 500px) { + ha-dialog { + --mdc-dialog-min-width: 100vw; + --mdc-dialog-max-height: 100vh; + --mdc-dialog-shape-radius: 0px; + --vertial-align-dialog: flex-end; + } + } + mwc-button.warning { + --mdc-theme-primary: var(--google-red-500); + } + .error { + color: var(--google-red-500); + } `; diff --git a/src/translations/en.json b/src/translations/en.json index 870d45e079..19985e2b29 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -595,7 +595,8 @@ "generic": { "cancel": "Cancel", "ok": "OK", - "default_confirmation_title": "Are you sure?" + "default_confirmation_title": "Are you sure?", + "close": "close" }, "more_info_control": { "dismiss": "Dismiss dialog", @@ -847,6 +848,76 @@ } } }, + "lovelace": { + "caption": "Lovelace Dashboards", + "description": "Configure your Lovelace Dashboards", + "dashboards": { + "caption": "Dashboards", + "conf_mode": { + "yaml": "YAML file", + "storage": "UI controlled" + }, + "picker": { + "headers": { + "title": "Title", + "conf_mode": "Configuration method", + "require_admin": "Admin only", + "sidebar": "Show in sidebar", + "filename": "Filename" + }, + "open": "Open dashboard", + "add_dashboard": "Add dashboard" + }, + "confirm_delete": "Are you sure you want to delete this dashboard?", + "cant_edit_yaml": "Dashboards defined in YAML can not be edited from the UI. Change them in configuration.yaml.", + "detail": { + "edit_dashboard": "Edit dashboard", + "new_dashboard": "Add new dashboard", + "dismiss": "Close", + "show_sidebar": "Show in sidebar", + "icon": "Sidebar icon", + "title": "Sidebar title", + "url": "Url", + "url_error_msg": "The url can not contain spaces or special characters, except for _ and -", + "require_admin": "Admin only", + "delete": "Delete", + "update": "Update", + "create": "Create" + } + }, + "resources": { + "caption": "Resources", + "types": { + "css": "Stylesheet", + "html": "HTML (deprecated)", + "js": "JavaScript File (deprecated)", + "module": "JavaScript Module" + }, + "picker": { + "headers": { + "url": "Url", + "type": "Type" + }, + "add_resource": "Add resource" + }, + "confirm_delete": "Are you sure you want to delete this resource?", + "refresh_header": "Do you want to refresh?", + "refresh_body": "You have to refresh the page to complete the removal, do you want to refresh now?", + "cant_edit_yaml": "You are using Lovelace in YAML mode, therefore you can not manage your resources through the UI. Manage them in configuration.yaml.", + "detail": { + "new_resource": "Add new resource", + "dismiss": "Close", + "warning_header": "Be cautious!", + "warning_text": "Adding resources can be dangerous, make sure you know the source of the resource and trust them. Bad resources could seriously harm your system.", + "url": "Url", + "url_error_msg": "Url is a required field", + "type": "Resource type", + "delete": "Delete", + "update": "Update", + "create": "Create" + } + } + }, "server_control": { "caption": "Server Controls", "description": "Restart and stop the Home Assistant server", From 0d6de9fe7351cce2d063be8cb732e38037f110ce Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 28 Feb 2020 21:59:14 +0100 Subject: [PATCH 30/33] Fix for unavailable input-select (#4991) * Fix for unavailable select * Update hui-thermostat-card.ts --- .../lovelace/cards/hui-entities-card.ts | 4 ++ src/panels/lovelace/cards/hui-light-card.ts | 10 ++++- .../lovelace/cards/hui-thermostat-card.ts | 8 +++- .../hui-input-select-entity-row.ts | 37 +++++++++++++++---- 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/panels/lovelace/cards/hui-entities-card.ts b/src/panels/lovelace/cards/hui-entities-card.ts index f4fc025b7a..645b94452c 100644 --- a/src/panels/lovelace/cards/hui-entities-card.ts +++ b/src/panels/lovelace/cards/hui-entities-card.ts @@ -190,6 +190,10 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard { overflow: hidden; } + #states > div { + position: relative; + } + .icon { padding: 0px 18px 0px 8px; } diff --git a/src/panels/lovelace/cards/hui-light-card.ts b/src/panels/lovelace/cards/hui-light-card.ts index 8ee03fbd10..0f3eb52e7f 100644 --- a/src/panels/lovelace/cards/hui-light-card.ts +++ b/src/panels/lovelace/cards/hui-light-card.ts @@ -29,6 +29,7 @@ import { toggleEntity } from "../common/entity/toggle-entity"; import { LightCardConfig } from "./types"; import { supportsFeature } from "../../../common/entity/supports-feature"; import { SUPPORT_BRIGHTNESS } from "../../../data/light"; +import { UNAVAILABLE } from "../../../data/entity"; @customElement("hui-light-card") export class HuiLightCard extends LitElement implements LovelaceCard { @@ -84,10 +85,11 @@ export class HuiLightCard extends LitElement implements LovelaceCard { return html` - ${stateObj.state === "unavailable" + ${stateObj.state === UNAVAILABLE ? html` ` : ""} @@ -233,6 +235,10 @@ export class HuiLightCard extends LitElement implements LovelaceCard { display: block; } + hui-unavailable { + cursor: pointer; + } + ha-card { position: relative; overflow: hidden; diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index fa099fefdc..6b51051906 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -34,6 +34,7 @@ import { } from "../../../data/climate"; import { HassEntity } from "home-assistant-js-websocket"; import { actionHandler } from "../common/directives/action-handler-directive"; +import { UNAVAILABLE } from "../../../data/entity"; const modeIcons: { [mode in HvacMode]: string } = { auto: "hass:calendar-repeat", @@ -208,10 +209,11 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { [mode]: true, })} > - ${stateObj.state === "unavailable" + ${stateObj.state === UNAVAILABLE ? html` ` : ""} @@ -396,6 +398,10 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { display: block; } + hui-unavailable { + cursor: pointer; + } + ha-card { position: relative; overflow: hidden; diff --git a/src/panels/lovelace/entity-rows/hui-input-select-entity-row.ts b/src/panels/lovelace/entity-rows/hui-input-select-entity-row.ts index e7f5a945bb..4307be3130 100644 --- a/src/panels/lovelace/entity-rows/hui-input-select-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-input-select-entity-row.ts @@ -32,6 +32,8 @@ import { actionHandler } from "../common/directives/action-handler-directive"; import { hasAction } from "../common/has-action"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { handleAction } from "../common/handle-action"; +import { UNAVAILABLE } from "../../../data/entity"; +import { fireEvent } from "../../../common/dom/fire_event"; @customElement("hui-input-select-entity-row") class HuiInputSelectEntityRow extends LitElement implements LovelaceRow { @@ -78,6 +80,14 @@ class HuiInputSelectEntityRow extends LitElement implements LovelaceRow { !DOMAINS_HIDE_MORE_INFO.includes(computeDomain(this._config.entity))); return html` + ${stateObj.state === UNAVAILABLE + ? html` + + ` + : ""} - ${stateObj.attributes.options.map( - (option) => html` - ${option} - ` - )} + ${stateObj.attributes.options + ? stateObj.attributes.options.map( + (option) => html` + ${option} + ` + ) + : ""} `; @@ -126,15 +138,21 @@ class HuiInputSelectEntityRow extends LitElement implements LovelaceRow { } // Update selected after rendering the items or else it won't work in Firefox - this.shadowRoot!.querySelector( - "paper-listbox" - )!.selected = stateObj.attributes.options.indexOf(stateObj.state); + if (stateObj.attributes.options) { + this.shadowRoot!.querySelector( + "paper-listbox" + )!.selected = stateObj.attributes.options.indexOf(stateObj.state); + } } private _handleAction(ev: ActionHandlerEvent) { handleAction(this, this.hass!, this._config!, ev.detail.action!); } + private _showMoreInfo() { + fireEvent(this, "hass-more-info", { entityId: this._config!.entity }); + } + static get styles(): CSSResult { return css` :host { @@ -157,6 +175,9 @@ class HuiInputSelectEntityRow extends LitElement implements LovelaceRow { background: var(--divider-color); border-radius: 100%; } + hui-unavailable { + cursor: pointer; + } `; } From 724357683c5e42eb23ba9e7a9d86aa0f2ec100cc Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 28 Feb 2020 22:00:01 +0100 Subject: [PATCH 31/33] Add take control for yaml mode (#4992) --- src/components/ha-yaml-editor.ts | 8 ++ .../lovelace/editor/hui-dialog-save-config.ts | 107 +++++++++++++----- .../editor/show-save-config-dialog.ts | 1 + src/panels/lovelace/ha-panel-lovelace.ts | 1 + src/translations/en.json | 4 + 5 files changed, 95 insertions(+), 26 deletions(-) diff --git a/src/components/ha-yaml-editor.ts b/src/components/ha-yaml-editor.ts index a637a28cc3..046fcd36ca 100644 --- a/src/components/ha-yaml-editor.ts +++ b/src/components/ha-yaml-editor.ts @@ -6,6 +6,13 @@ import { afterNextRender } from "../common/util/render-status"; // tslint:disable-next-line import { HaCodeEditor } from "./ha-code-editor"; +declare global { + // for fire event + interface HASSDomEvents { + "editor-refreshed": undefined; + } +} + const isEmpty = (obj: object) => { if (typeof obj !== "object") { return false; @@ -37,6 +44,7 @@ export class HaYamlEditor extends LitElement { if (this._editor?.codemirror) { this._editor.codemirror.refresh(); } + afterNextRender(() => fireEvent(this, "editor-refreshed")); }); } diff --git a/src/panels/lovelace/editor/hui-dialog-save-config.ts b/src/panels/lovelace/editor/hui-dialog-save-config.ts index 2b44e165b1..b51641dc22 100644 --- a/src/panels/lovelace/editor/hui-dialog-save-config.ts +++ b/src/panels/lovelace/editor/hui-dialog-save-config.ts @@ -6,9 +6,11 @@ import { CSSResult, customElement, property, + query, } from "lit-element"; import "@polymer/paper-spinner/paper-spinner"; import "../../../components/dialog/ha-paper-dialog"; +import "../../../components/ha-yaml-editor"; // tslint:disable-next-line:no-duplicate-imports import { HaPaperDialog } from "../../../components/dialog/ha-paper-dialog"; import "@material/mwc-button"; @@ -16,6 +18,8 @@ import "@material/mwc-button"; import { haStyleDialog } from "../../../resources/styles"; import { HomeAssistant } from "../../../types"; import { SaveDialogParams } from "./show-save-config-dialog"; +import { PolymerChangedEvent } from "../../../polymer-types"; +import { fireEvent } from "../../../common/dom/fire_event"; @customElement("hui-dialog-save-config") export class HuiSaveConfig extends LitElement { @@ -24,6 +28,7 @@ export class HuiSaveConfig extends LitElement { @property() private _params?: SaveDialogParams; @property() private _saving: boolean; + @query("ha-paper-dialog") private _dialog?: HaPaperDialog; public constructor() { super(); @@ -33,16 +38,19 @@ export class HuiSaveConfig extends LitElement { public async showDialog(params: SaveDialogParams): Promise { this._params = params; await this.updateComplete; - this._dialog.open(); - } - - private get _dialog(): HaPaperDialog { - return this.shadowRoot!.querySelector("ha-paper-dialog")!; + this._dialog!.open(); } protected render(): TemplateResult { + if (!this._params) { + return html``; + } return html` - +

${this.hass!.localize("ui.panel.lovelace.editor.save_config.header")}

@@ -50,34 +58,81 @@ export class HuiSaveConfig extends LitElement {

${this.hass!.localize("ui.panel.lovelace.editor.save_config.para")}

-

- ${this.hass!.localize( - "ui.panel.lovelace.editor.save_config.para_sure" - )} -

+ ${this._params.mode === "storage" + ? html` +

+ ${this.hass!.localize( + "ui.panel.lovelace.editor.save_config.para_sure" + )} +

+ ` + : html` +

+ ${this.hass!.localize( + "ui.panel.lovelace.editor.save_config.yaml_mode" + )} +

+

+ ${this.hass!.localize( + "ui.panel.lovelace.editor.save_config.yaml_control" + )} +

+

+ ${this.hass!.localize( + "ui.panel.lovelace.editor.save_config.yaml_config" + )} +

+ + `}
- ${this.hass!.localize( - "ui.panel.lovelace.editor.save_config.cancel" - )} - - - ${this.hass!.localize( - "ui.panel.lovelace.editor.save_config.save" - )} + ${this._params.mode === "storage" + ? html` + ${this.hass!.localize( + "ui.panel.lovelace.editor.save_config.cancel" + )} + + + + ${this.hass!.localize( + "ui.panel.lovelace.editor.save_config.save" + )} + + ` + : html` + ${this.hass!.localize( + "ui.panel.lovelace.editor.save_config.close" + )} + + `}
`; } private _closeDialog(): void { - this._dialog.close(); + this._dialog!.close(); + } + + private _openedChanged(ev: PolymerChangedEvent): void { + if (!ev.detail.value) { + this._params = undefined; + } + } + + private _editorRefreshed() { + fireEvent(this._dialog! as HTMLElement, "iron-resize"); } private async _saveConfig(): Promise { diff --git a/src/panels/lovelace/editor/show-save-config-dialog.ts b/src/panels/lovelace/editor/show-save-config-dialog.ts index 62615d6db6..96c7cb9ed6 100644 --- a/src/panels/lovelace/editor/show-save-config-dialog.ts +++ b/src/panels/lovelace/editor/show-save-config-dialog.ts @@ -13,6 +13,7 @@ const dialogTag = "hui-dialog-save-config"; export interface SaveDialogParams { lovelace: Lovelace; + mode: "yaml" | "storage"; } let registeredDialog = false; diff --git a/src/panels/lovelace/ha-panel-lovelace.ts b/src/panels/lovelace/ha-panel-lovelace.ts index 3a44999272..9cf9f46cd7 100644 --- a/src/panels/lovelace/ha-panel-lovelace.ts +++ b/src/panels/lovelace/ha-panel-lovelace.ts @@ -339,6 +339,7 @@ class LovelacePanel extends LitElement { } showSaveDialog(this, { lovelace: this.lovelace!, + mode: this.panel!.config.mode, }); }, saveConfig: async (newConfig: LovelaceConfig): Promise => { diff --git a/src/translations/en.json b/src/translations/en.json index 19985e2b29..cedffd2311 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1935,7 +1935,11 @@ "header": "Take control of your Lovelace UI", "para": "By default Home Assistant will maintain your user interface, updating it when new entities or Lovelace UI components become available. If you take control we will no longer make changes automatically for you.", "para_sure": "Are you sure you want to take control of your user interface?", + "yaml_mode": "You are using YAML mode, that means you can not change your Lovelace config from the UI. If you want to change Lovelace from the UI, remove the 'mode: yaml' from your Lovelace configuration in 'configuration.yaml.'", + "yaml_control": "To take control in YAML mode, create a YAML file with the name you specified in your config for this dashboard, or the default 'ui-lovelace.yaml'.", + "yaml_config": "To help you start here is the current config of this dashboard:", "cancel": "Never mind", + "close": "Close", "save": "Take control" }, "migrate": { From a1a176389738385152e022475e5b02d5a2439e81 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 28 Feb 2020 22:20:44 +0100 Subject: [PATCH 32/33] Bumped version to 20200228.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 76e88054d6..b37397edb7 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20200220.1", + version="20200228.0", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors", From d7aaed05b7bbcb878ece722784952ffe77c3c325 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 28 Feb 2020 13:35:42 -0800 Subject: [PATCH 33/33] Clean up generic row (#5022) --- src/data/sensor.ts | 1 + .../more-info/controls/more-info-camera.ts | 2 +- .../notifications/notification-item.ts | 4 +- .../persistent-notification-item.ts | 2 +- .../ha-automation-condition-numeric_state.ts | 2 +- .../ha-automation-trigger-numeric_state.ts | 2 +- .../config/cloud/account/cloud-google-pref.ts | 2 +- src/panels/config/zha/zha-add-devices-page.ts | 2 +- .../config/zha/zha-cluster-attributes.ts | 4 +- src/panels/config/zha/zha-cluster-commands.ts | 4 +- src/panels/config/zha/zha-device-card.ts | 4 +- src/panels/config/zha/zha-device-page.ts | 12 +- .../lovelace/components/hui-action-editor.ts | 2 +- .../lovelace/components/hui-entity-editor.ts | 4 +- .../components/hui-generic-entity-row.ts | 119 +++++++++--------- src/panels/lovelace/components/hui-image.ts | 2 +- .../card-editor/hui-dialog-edit-card.ts | 6 +- .../card-editor/hui-dialog-suggest-card.ts | 2 +- .../hui-alarm-panel-card-editor.ts | 4 +- .../config-elements/hui-button-card-editor.ts | 8 +- .../hui-entities-card-editor.ts | 4 +- .../config-elements/hui-gauge-card-editor.ts | 4 +- .../config-elements/hui-glance-card-editor.ts | 4 +- .../hui-history-graph-card-editor.ts | 2 +- .../config-elements/hui-light-card-editor.ts | 4 +- .../config-elements/hui-map-card-editor.ts | 4 +- .../hui-markdown-card-editor.ts | 2 +- .../hui-media-control-card-editor.ts | 2 +- .../hui-picture-card-editor.ts | 6 +- .../hui-picture-entity-card-editor.ts | 10 +- .../hui-picture-glance-card-editor.ts | 12 +- .../hui-plant-status-card-editor.ts | 4 +- .../config-elements/hui-sensor-card-editor.ts | 4 +- .../hui-shopping-list-editor.ts | 2 +- .../config-elements/hui-stack-card-editor.ts | 2 +- .../hui-thermostat-card-editor.ts | 4 +- .../hui-weather-forecast-card-editor.ts | 4 +- .../hui-dialog-edit-lovelace.ts | 2 +- .../view-editor/hui-dialog-edit-view.ts | 2 +- .../editor/view-editor/hui-edit-view.ts | 4 +- .../lovelace/elements/hui-image-element.ts | 2 +- .../elements/hui-service-button-element.ts | 2 +- .../elements/hui-state-badge-element.ts | 2 +- .../elements/hui-state-icon-element.ts | 2 +- .../entity-rows/hui-climate-entity-row.ts | 6 +- .../entity-rows/hui-cover-entity-row.ts | 10 +- .../entity-rows/hui-group-entity-row.ts | 8 +- .../hui-input-datetime-entity-row.ts | 2 +- .../hui-input-number-entity-row.ts | 60 +++++---- .../entity-rows/hui-input-text-entity-row.ts | 2 +- .../entity-rows/hui-lock-entity-row.ts | 4 +- .../hui-media-player-entity-row.ts | 9 +- .../entity-rows/hui-scene-entity-row.ts | 19 +-- .../entity-rows/hui-script-entity-row.ts | 8 +- .../entity-rows/hui-sensor-entity-row.ts | 14 ++- .../entity-rows/hui-text-entity-row.ts | 4 +- .../entity-rows/hui-timer-entity-row.ts | 4 +- .../entity-rows/hui-toggle-entity-row.ts | 8 +- src/panels/lovelace/ha-panel-lovelace.ts | 2 +- src/panels/lovelace/hui-editor.ts | 2 +- 60 files changed, 213 insertions(+), 227 deletions(-) diff --git a/src/data/sensor.ts b/src/data/sensor.ts index e4da2f9825..7c05a30c08 100644 --- a/src/data/sensor.ts +++ b/src/data/sensor.ts @@ -1 +1,2 @@ export const SENSOR_DEVICE_CLASS_BATTERY = "battery"; +export const SENSOR_DEVICE_CLASS_TIMESTAMP = "timestamp"; diff --git a/src/dialogs/more-info/controls/more-info-camera.ts b/src/dialogs/more-info/controls/more-info-camera.ts index 2d2b3eece7..3dda7275b0 100644 --- a/src/dialogs/more-info/controls/more-info-camera.ts +++ b/src/dialogs/more-info/controls/more-info-camera.ts @@ -45,7 +45,7 @@ class MoreInfoCamera extends LitElement { return html` diff --git a/src/dialogs/notifications/notification-item.ts b/src/dialogs/notifications/notification-item.ts index d953a8b510..12c96da45e 100644 --- a/src/dialogs/notifications/notification-item.ts +++ b/src/dialogs/notifications/notification-item.ts @@ -36,13 +36,13 @@ export class HuiNotificationItem extends LitElement { return "entity_id" in this.notification ? html` ` : html` `; diff --git a/src/dialogs/notifications/persistent-notification-item.ts b/src/dialogs/notifications/persistent-notification-item.ts index bd87f7d885..3ef90bba41 100644 --- a/src/dialogs/notifications/persistent-notification-item.ts +++ b/src/dialogs/notifications/persistent-notification-item.ts @@ -39,7 +39,7 @@ export class HuiPersistentNotificationItem extends LitElement {
${this.device && this.device.device_type !== "Coordinator" ? html` @@ -92,7 +92,7 @@ export class ZHADevicePage extends LitElement { ? html` @@ -103,7 +103,7 @@ export class ZHADevicePage extends LitElement { diff --git a/src/panels/lovelace/components/hui-action-editor.ts b/src/panels/lovelace/components/hui-action-editor.ts index 0969574766..1fdd456131 100644 --- a/src/panels/lovelace/components/hui-action-editor.ts +++ b/src/panels/lovelace/components/hui-action-editor.ts @@ -106,7 +106,7 @@ export class HuiActionEditor extends LitElement { ${this.config && this.config.action === "call-service" ? html`
diff --git a/src/panels/lovelace/components/hui-generic-entity-row.ts b/src/panels/lovelace/components/hui-generic-entity-row.ts index 50fa3cb1ed..2a0336bb09 100644 --- a/src/panels/lovelace/components/hui-generic-entity-row.ts +++ b/src/panels/lovelace/components/hui-generic-entity-row.ts @@ -32,7 +32,7 @@ class HuiGenericEntityRow extends LitElement { @property() public config?: EntitiesCardEntityConfig; - @property() public showSecondary: boolean = true; + @property() public secondaryText?: string; protected render(): TemplateResult { if (!this.hass || !this.config) { @@ -59,6 +59,8 @@ class HuiGenericEntityRow extends LitElement { (this.config.entity && !DOMAINS_HIDE_MORE_INFO.includes(computeDomain(this.config.entity))); + const hasSecondary = this.secondaryText || this.config.secondary_info; + return html` -
-
- ${this.config.name || computeStateName(stateObj)} -
- ${!this.showSecondary - ? html` - - ` - : this.config.secondary_info === "entity-id" - ? stateObj.entity_id - : this.config.secondary_info === "last-changed" - ? html` - - ` - : this.config.secondary_info === "last-triggered" - ? stateObj.attributes.last_triggered - ? html` - - ` - : this.hass.localize( - "ui.panel.lovelace.cards.entities.never_triggered" - ) - : ""} -
-
- - +
+ ${this.config.name || computeStateName(stateObj)} + ${hasSecondary + ? html` +
+ ${this.secondaryText || + this.config.secondary_info === "entity-id" + ? stateObj.entity_id + : this.config.secondary_info === "last-changed" + ? html` + + ` + : this.config.secondary_info === "last-triggered" + ? stateObj.attributes.last_triggered + ? html` + + ` + : this.hass.localize( + "ui.panel.lovelace.cards.entities.never_triggered" + ) + : ""} + } +
+ ` + : ""}
+ `; } protected updated(changedProps: PropertyValues): void { super.updated(changedProps); + toggleAttribute( + this, + "no-secondary", + !this.secondaryText && !this.config?.secondary_info + ); if (changedProps.has("hass")) { toggleAttribute(this, "rtl", computeRTL(this.hass!)); } @@ -143,16 +145,10 @@ class HuiGenericEntityRow extends LitElement { :host { display: flex; align-items: center; - } - .flex { - flex: 1; - margin-left: 16px; - display: flex; - justify-content: space-between; - align-items: center; - min-width: 0; + flex-direction: row; } .info { + margin-left: 16px; flex: 1 0 60px; } .info, @@ -161,6 +157,11 @@ class HuiGenericEntityRow extends LitElement { overflow: hidden; text-overflow: ellipsis; } + :host([no-secondary]) .text-content, + :host([no-secondary]) ::slotted(.text-content) { + position: relative; + top: 2px; + } .flex ::slotted(*) { margin-left: 8px; min-width: 0; @@ -192,12 +193,6 @@ class HuiGenericEntityRow extends LitElement { .pointer { cursor: pointer; } - .padName { - padding: 12px 0px; - } - .padSecondary { - padding: 4px 0px; - } `; } } diff --git a/src/panels/lovelace/components/hui-image.ts b/src/panels/lovelace/components/hui-image.ts index a4457a8533..ff48cc9910 100644 --- a/src/panels/lovelace/components/hui-image.ts +++ b/src/panels/lovelace/components/hui-image.ts @@ -133,7 +133,7 @@ export class HuiImage extends LitElement { ${this.cameraImage && this.cameraView === "live" ? html` ` diff --git a/src/panels/lovelace/editor/card-editor/hui-dialog-edit-card.ts b/src/panels/lovelace/editor/card-editor/hui-dialog-edit-card.ts index 66e3ed2429..08f60fd5d8 100755 --- a/src/panels/lovelace/editor/card-editor/hui-dialog-edit-card.ts +++ b/src/panels/lovelace/editor/card-editor/hui-dialog-edit-card.ts @@ -99,7 +99,7 @@ export class HuiDialogEditCard extends LitElement { ${this._cardConfig === undefined ? html` ` @@ -107,14 +107,14 @@ export class HuiDialogEditCard extends LitElement {
diff --git a/src/panels/lovelace/editor/card-editor/hui-dialog-suggest-card.ts b/src/panels/lovelace/editor/card-editor/hui-dialog-suggest-card.ts index b76bf47ed9..b478663aab 100755 --- a/src/panels/lovelace/editor/card-editor/hui-dialog-suggest-card.ts +++ b/src/panels/lovelace/editor/card-editor/hui-dialog-suggest-card.ts @@ -78,7 +78,7 @@ export class HuiDialogSuggestCard extends LitElement { ${this._cardConfig.map( (cardConfig) => html` ` diff --git a/src/panels/lovelace/editor/config-elements/hui-alarm-panel-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-alarm-panel-card-editor.ts index 014ba22b90..e6bbf53ab6 100644 --- a/src/panels/lovelace/editor/config-elements/hui-alarm-panel-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-alarm-panel-card-editor.ts @@ -75,7 +75,7 @@ export class HuiAlarmPanelCardEditor extends LitElement )} (${this.hass.localize( "ui.panel.lovelace.editor.card.config.required" )})" - .hass="${this.hass}" + .hass=${this.hass} .value="${this._entity}" .configValue=${"entity"} include-domains='["alarm_control_panel"]' @@ -120,7 +120,7 @@ export class HuiAlarmPanelCardEditor extends LitElement
px
diff --git a/src/panels/lovelace/editor/config-elements/hui-gauge-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-gauge-card-editor.ts index e28d6c52cb..7924783cdc 100644 --- a/src/panels/lovelace/editor/config-elements/hui-gauge-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-gauge-card-editor.ts @@ -86,7 +86,7 @@ export class HuiGaugeCardEditor extends LitElement )} (${this.hass.localize( "ui.panel.lovelace.editor.card.config.required" )})" - .hass="${this.hass}" + .hass=${this.hass} .value="${this._entity}" .configValue=${"entity"} include-domains='["sensor"]' @@ -114,7 +114,7 @@ export class HuiGaugeCardEditor extends LitElement @value-changed="${this._valueChanged}" >
diff --git a/src/panels/lovelace/editor/config-elements/hui-history-graph-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-history-graph-card-editor.ts index ffa079ca3d..d8e1dfd134 100644 --- a/src/panels/lovelace/editor/config-elements/hui-history-graph-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-history-graph-card-editor.ts @@ -109,7 +109,7 @@ export class HuiHistoryGraphCardEditor extends LitElement >
diff --git a/src/panels/lovelace/editor/config-elements/hui-light-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-light-card-editor.ts index fccd34317b..2e8bf72542 100644 --- a/src/panels/lovelace/editor/config-elements/hui-light-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-light-card-editor.ts @@ -70,7 +70,7 @@ export class HuiLightCardEditor extends LitElement )} (${this.hass.localize( "ui.panel.lovelace.editor.card.config.required" )})" - .hass="${this.hass}" + .hass=${this.hass} .value="${this._entity}" .configValue=${"entity"} include-domains='["light"]' @@ -103,7 +103,7 @@ export class HuiLightCardEditor extends LitElement
@@ -135,7 +135,7 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor { inputLabel=${this.hass.localize( "ui.panel.lovelace.editor.card.map.source" )} - .hass="${this.hass}" + .hass=${this.hass} .value="${this._geo_location_sources}" .configValue="${"geo_location_sources"}" @value-changed="${this._valueChanged}" diff --git a/src/panels/lovelace/editor/config-elements/hui-markdown-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-markdown-card-editor.ts index 7830aa3c4b..6bfd0c2f0a 100644 --- a/src/panels/lovelace/editor/config-elements/hui-markdown-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-markdown-card-editor.ts @@ -81,7 +81,7 @@ export class HuiMarkdownCardEditor extends LitElement spellcheck="false" >
` diff --git a/src/panels/lovelace/editor/config-elements/hui-thermostat-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-thermostat-card-editor.ts index 78b91ff9b4..575d8d6b2e 100644 --- a/src/panels/lovelace/editor/config-elements/hui-thermostat-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-thermostat-card-editor.ts @@ -63,7 +63,7 @@ export class HuiThermostatCardEditor extends LitElement )} (${this.hass.localize( "ui.panel.lovelace.editor.card.config.required" )})" - .hass="${this.hass}" + .hass=${this.hass} .value="${this._entity}" .configValue=${"entity"} include-domains='["climate"]' @@ -81,7 +81,7 @@ export class HuiThermostatCardEditor extends LitElement @value-changed="${this._valueChanged}" > diff --git a/src/panels/lovelace/editor/view-editor/hui-edit-view.ts b/src/panels/lovelace/editor/view-editor/hui-edit-view.ts index 1c44cc168a..ad7db50707 100644 --- a/src/panels/lovelace/editor/view-editor/hui-edit-view.ts +++ b/src/panels/lovelace/editor/view-editor/hui-edit-view.ts @@ -110,7 +110,7 @@ export class HuiEditView extends LitElement { content = html` @@ -119,7 +119,7 @@ export class HuiEditView extends LitElement { case "tab-badges": content = html` diff --git a/src/panels/lovelace/elements/hui-image-element.ts b/src/panels/lovelace/elements/hui-image-element.ts index b86c6f3ad2..07279d200c 100644 --- a/src/panels/lovelace/elements/hui-image-element.ts +++ b/src/panels/lovelace/elements/hui-image-element.ts @@ -43,7 +43,7 @@ export class HuiImageElement extends LitElement implements LovelaceElement { return html` + `; diff --git a/src/panels/lovelace/entity-rows/hui-cover-entity-row.ts b/src/panels/lovelace/entity-rows/hui-cover-entity-row.ts index 3b675768df..dbd67cb5b2 100644 --- a/src/panels/lovelace/entity-rows/hui-cover-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-cover-entity-row.ts @@ -56,18 +56,18 @@ class HuiCoverEntityRow extends LitElement implements LovelaceRow { } return html` - + ${isTiltOnly(stateObj) ? html` ` : html` `} diff --git a/src/panels/lovelace/entity-rows/hui-group-entity-row.ts b/src/panels/lovelace/entity-rows/hui-group-entity-row.ts index 530608ff70..f60e6a966d 100644 --- a/src/panels/lovelace/entity-rows/hui-group-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-group-entity-row.ts @@ -54,16 +54,16 @@ class HuiGroupEntityRow extends LitElement implements LovelaceRow { } return html` - + ${this._computeCanToggle(stateObj.attributes.entity_id) ? html` ` : html` -
+
${computeStateDisplay( this.hass!.localize, stateObj, diff --git a/src/panels/lovelace/entity-rows/hui-input-datetime-entity-row.ts b/src/panels/lovelace/entity-rows/hui-input-datetime-entity-row.ts index f236d09b3e..7afbc34dd6 100644 --- a/src/panels/lovelace/entity-rows/hui-input-datetime-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-input-datetime-entity-row.ts @@ -56,7 +56,7 @@ class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow { } return html` - + ${stateObj.attributes.has_date ? html` -
- ${stateObj.attributes.mode === "slider" - ? html` -
- - - ${Number(stateObj.state)} - ${stateObj.attributes.unit_of_measurement} - -
- ` - : html` - + ${stateObj.attributes.mode === "slider" + ? html` +
+ - `} -
+ > + + ${Number(stateObj.state)} + ${stateObj.attributes.unit_of_measurement} + +
+ ` + : html` + + `}
`; } diff --git a/src/panels/lovelace/entity-rows/hui-input-text-entity-row.ts b/src/panels/lovelace/entity-rows/hui-input-text-entity-row.ts index 7396249f28..e8fa7eb863 100644 --- a/src/panels/lovelace/entity-rows/hui-input-text-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-input-text-entity-row.ts @@ -53,7 +53,7 @@ class HuiInputTextEntityRow extends LitElement implements LovelaceRow { } return html` - + - + + ${stateObj.state === "locked" ? this.hass!.localize("ui.card.lock.unlock") : this.hass!.localize("ui.card.lock.lock")} 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 55a3f0b66a..67c112e085 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 @@ -64,13 +64,13 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { return html` ${OFF_STATES.includes(stateObj.state) ? html` -
+
${this.hass!.localize(`state.media_player.${stateObj.state}`) || this.hass!.localize(`state.default.${stateObj.state}`) || stateObj.state} @@ -96,7 +96,6 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { ` : ""}
-
${this._computeMediaTitle(stateObj)}
`} `; diff --git a/src/panels/lovelace/entity-rows/hui-scene-entity-row.ts b/src/panels/lovelace/entity-rows/hui-scene-entity-row.ts index 0cdbacfc44..7e096fbc88 100644 --- a/src/panels/lovelace/entity-rows/hui-scene-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-scene-entity-row.ts @@ -55,20 +55,11 @@ class HuiSceneEntityRow extends LitElement implements LovelaceRow { } return html` - - ${stateObj.attributes.can_cancel - ? html` - - ` - : html` - - ${this._config.action_name || - this.hass!.localize("ui.card.scene.activate")} - - `} + + + ${this._config.action_name || + this.hass!.localize("ui.card.scene.activate")} + `; } diff --git a/src/panels/lovelace/entity-rows/hui-script-entity-row.ts b/src/panels/lovelace/entity-rows/hui-script-entity-row.ts index 3300b0fc6e..bc0dd5b468 100644 --- a/src/panels/lovelace/entity-rows/hui-script-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-script-entity-row.ts @@ -54,16 +54,16 @@ class HuiScriptEntityRow extends LitElement implements LovelaceRow { } return html` - + ${stateObj.attributes.can_cancel ? html` ` : html` - + ${this._config.action_name || this.hass!.localize("ui.card.script.execute")} diff --git a/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts b/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts index 5907011139..f3f4e6da7e 100644 --- a/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts @@ -17,6 +17,7 @@ import { HomeAssistant } from "../../../types"; import { LovelaceRow, EntityConfig } from "./types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import { computeStateDisplay } from "../../../common/entity/compute_state_display"; +import { SENSOR_DEVICE_CLASS_TIMESTAMP } from "../../../data/sensor"; interface SensorEntityConfig extends EntityConfig { format?: "relative" | "date" | "time" | "datetime"; @@ -59,16 +60,17 @@ class HuiSensorEntityRow extends LitElement implements LovelaceRow { } return html` - -
- ${stateObj.attributes.device_class === "timestamp" && + +
+ ${stateObj.attributes.device_class === + SENSOR_DEVICE_CLASS_TIMESTAMP && stateObj.state !== "unavailable" && stateObj.state !== "unknown" ? html` ` : computeStateDisplay( diff --git a/src/panels/lovelace/entity-rows/hui-text-entity-row.ts b/src/panels/lovelace/entity-rows/hui-text-entity-row.ts index 9dcc0e6a28..45ccce5afb 100644 --- a/src/panels/lovelace/entity-rows/hui-text-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-text-entity-row.ts @@ -54,8 +54,8 @@ class HuiTextEntityRow extends LitElement implements LovelaceRow { } return html` - -
+ +
${computeStateDisplay( this.hass!.localize, stateObj, diff --git a/src/panels/lovelace/entity-rows/hui-timer-entity-row.ts b/src/panels/lovelace/entity-rows/hui-timer-entity-row.ts index 9ba7896235..4e5bcb71bb 100644 --- a/src/panels/lovelace/entity-rows/hui-timer-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-timer-entity-row.ts @@ -70,8 +70,8 @@ class HuiTimerEntityRow extends LitElement { } return html` - -
${this._computeDisplay(stateObj)}
+ +
${this._computeDisplay(stateObj)}
`; } diff --git a/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts b/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts index 00568506b2..b166ba9d2b 100644 --- a/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts @@ -53,16 +53,16 @@ class HuiToggleEntityRow extends LitElement implements LovelaceRow { } return html` - + ${stateObj.state === "on" || stateObj.state === "off" ? html` ` : html` -
+
${computeStateDisplay( this.hass!.localize, stateObj, diff --git a/src/panels/lovelace/ha-panel-lovelace.ts b/src/panels/lovelace/ha-panel-lovelace.ts index 9cf9f46cd7..1b30c6938d 100644 --- a/src/panels/lovelace/ha-panel-lovelace.ts +++ b/src/panels/lovelace/ha-panel-lovelace.ts @@ -125,7 +125,7 @@ class LovelacePanel extends LitElement { if (state === "yaml-editor") { return html` diff --git a/src/panels/lovelace/hui-editor.ts b/src/panels/lovelace/hui-editor.ts index 502aae0af3..a66dd52e7f 100644 --- a/src/panels/lovelace/hui-editor.ts +++ b/src/panels/lovelace/hui-editor.ts @@ -92,7 +92,7 @@ class LovelaceFullConfigEditor extends LitElement { mode="yaml" autofocus .rtl=${computeRTL(this.hass)} - .hass="${this.hass}" + .hass=${this.hass} @value-changed="${this._yamlChanged}" @editor-save="${this._handleSave}" >