diff --git a/gallery/src/demos/demo-integration-card.ts b/gallery/src/demos/demo-integration-card.ts index 1e23303bc4..97e581f2cc 100644 --- a/gallery/src/demos/demo-integration-card.ts +++ b/gallery/src/demos/demo-integration-card.ts @@ -28,10 +28,13 @@ const createConfigEntry = ( title, source: "zeroconf", state: "loaded", - connection_class: "local_push", supports_options: false, supports_unload: true, disabled_by: null, + system_options: { + disable_new_entities: false, + disable_polling: false, + }, reason: null, ...override, }); @@ -64,6 +67,12 @@ const configPanelEntry = createConfigEntry("Config Panel", { const optionsFlowEntry = createConfigEntry("Options Flow", { supports_options: true, }); +const disabledPollingEntry = createConfigEntry("Disabled Polling", { + system_options: { + disable_new_entities: false, + disable_polling: true, + }, +}); const setupErrorEntry = createConfigEntry("Setup Error", { state: "setup_error", }); @@ -136,6 +145,7 @@ const configEntries: Array<{ { items: [loadedEntry] }, { items: [configPanelEntry] }, { items: [optionsFlowEntry] }, + { items: [disabledPollingEntry] }, { items: [nameAsDomainEntry] }, { items: [longNameEntry] }, { items: [longNonBreakingNameEntry] }, diff --git a/setup.py b/setup.py index acc46ddd38..e5030abd42 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20210531.0", + version="20210531.1", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors", diff --git a/src/components/ha-network.ts b/src/components/ha-network.ts index a4163ae720..451e709176 100644 --- a/src/components/ha-network.ts +++ b/src/components/ha-network.ts @@ -1,5 +1,12 @@ import "@polymer/paper-tooltip/paper-tooltip"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { + css, + CSSResultGroup, + html, + nothing, + LitElement, + TemplateResult, +} from "lit"; import { customElement, state, property } from "lit/decorators"; import { Adapter, @@ -17,18 +24,19 @@ import "./ha-icon"; const format_addresses = ( addresses: IPv6ConfiguredAddress[] | IPv4ConfiguredAddress[] -): TemplateResult[] => - addresses.map( - (address) => html`${address.address}/${address.network_prefix}` - ); +): TemplateResult => + html`${addresses.map((address, i) => [ + html`${address.address}/${address.network_prefix}`, + i < addresses.length - 1 ? ", " : nothing, + ])}`; const format_auto_detected_interfaces = ( adapters: Adapter[] ): Array => adapters.map((adapter) => adapter.auto - ? html`${adapter.name} (${format_addresses(adapter.ipv4)} - ${format_addresses(adapter.ipv6)} )` + ? html`${adapter.name} + (${format_addresses([...adapter.ipv4, ...adapter.ipv6])})` : "" ); @@ -88,8 +96,7 @@ export class HaNetwork extends LitElement { : ""} - ${format_addresses(adapter.ipv4)} - ${format_addresses(adapter.ipv6)} + ${format_addresses([...adapter.ipv4, ...adapter.ipv6])} ` ) diff --git a/src/data/config_entries.ts b/src/data/config_entries.ts index 9bb203c942..8e4de41a9e 100644 --- a/src/data/config_entries.ts +++ b/src/data/config_entries.ts @@ -12,9 +12,9 @@ export interface ConfigEntry { | "setup_retry" | "not_loaded" | "failed_unload"; - connection_class: string; supports_options: boolean; supports_unload: boolean; + system_options: ConfigEntrySystemOptions; disabled_by: "user" | null; reason: string | null; } @@ -25,6 +25,7 @@ export interface ConfigEntryMutableParams { export interface ConfigEntrySystemOptions { disable_new_entities: boolean; + disable_polling: boolean; } export const getConfigEntries = (hass: HomeAssistant) => @@ -72,21 +73,15 @@ export const enableConfigEntry = (hass: HomeAssistant, configEntryId: string) => disabled_by: null, }); -export const getConfigEntrySystemOptions = ( - hass: HomeAssistant, - configEntryId: string -) => - hass.callWS({ - type: "config_entries/system_options/list", - entry_id: configEntryId, - }); - export const updateConfigEntrySystemOptions = ( hass: HomeAssistant, configEntryId: string, params: Partial ) => - hass.callWS({ + hass.callWS<{ + require_restart: boolean; + system_options: ConfigEntrySystemOptions; + }>({ type: "config_entries/system_options/update", entry_id: configEntryId, ...params, diff --git a/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts b/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts index bd1f6bbcd1..92cac06fef 100644 --- a/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts +++ b/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts @@ -3,17 +3,14 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; import { computeRTLDirection } from "../../common/util/compute_rtl"; -import "../../components/ha-circular-progress"; import "../../components/ha-dialog"; import "../../components/ha-formfield"; import "../../components/ha-switch"; import type { HaSwitch } from "../../components/ha-switch"; -import { - getConfigEntrySystemOptions, - updateConfigEntrySystemOptions, -} from "../../data/config_entries"; +import { updateConfigEntrySystemOptions } from "../../data/config_entries"; import { haStyleDialog } from "../../resources/styles"; import type { HomeAssistant } from "../../types"; +import { showAlertDialog } from "../generic/show-dialog-box"; import { ConfigEntrySystemOptionsDialogParams } from "./show-dialog-config-entry-system-options"; @customElement("dialog-config-entry-system-options") @@ -22,12 +19,12 @@ class DialogConfigEntrySystemOptions extends LitElement { @state() private _disableNewEntities!: boolean; + @state() private _disablePolling!: boolean; + @state() private _error?: string; @state() private _params?: ConfigEntrySystemOptionsDialogParams; - @state() private _loading = false; - @state() private _submitting = false; public async showDialog( @@ -35,13 +32,8 @@ class DialogConfigEntrySystemOptions extends LitElement { ): Promise { this._params = params; this._error = undefined; - this._loading = true; - const systemOptions = await getConfigEntrySystemOptions( - this.hass, - params.entry.entry_id - ); - this._loading = false; - this._disableNewEntities = systemOptions.disable_new_entities; + this._disableNewEntities = params.entry.system_options.disable_new_entities; + this._disablePolling = params.entry.system_options.disable_polling; } public closeDialog(): void { @@ -66,45 +58,57 @@ class DialogConfigEntrySystemOptions extends LitElement { this._params.entry.domain )} > -
- ${this._loading - ? html` -
- -
- ` - : html` - ${this._error - ? html`
${this._error}
` - : ""} -
- - ${this.hass.localize( - "ui.dialogs.config_entry_system_options.enable_new_entities_label" - )} -

-

- ${this.hass.localize( - "ui.dialogs.config_entry_system_options.enable_new_entities_description", - "integration", - this.hass.localize( - `component.${this._params.entry.domain}.title` - ) || this._params.entry.domain - )} -

`} - .dir=${computeRTLDirection(this.hass)} - > - - -
-
- `} -
+ ${this._error ? html`
${this._error}
` : ""} + + ${this.hass.localize( + "ui.dialogs.config_entry_system_options.enable_new_entities_label" + )} +

+

+ ${this.hass.localize( + "ui.dialogs.config_entry_system_options.enable_new_entities_description", + "integration", + this.hass.localize( + `component.${this._params.entry.domain}.title` + ) || this._params.entry.domain + )} +

`} + .dir=${computeRTLDirection(this.hass)} + > + +
+ ${this._allowUpdatePolling() + ? html` + + ${this.hass.localize( + "ui.dialogs.config_entry_system_options.enable_polling_label" + )} +

+

+ ${this.hass.localize( + "ui.dialogs.config_entry_system_options.enable_polling_description", + "integration", + this.hass.localize( + `component.${this._params.entry.domain}.title` + ) || this._params.entry.domain + )} +

`} + .dir=${computeRTLDirection(this.hass)} + > + +
+ ` + : ""} ${this.hass.localize("ui.dialogs.config_entry_system_options.update")} @@ -123,21 +127,53 @@ class DialogConfigEntrySystemOptions extends LitElement { `; } + private _allowUpdatePolling() { + return ( + this._params!.manifest && + (this._params!.manifest.iot_class === "local_polling" || + this._params!.manifest.iot_class === "cloud_polling") + ); + } + private _disableNewEntitiesChanged(ev: Event): void { this._error = undefined; this._disableNewEntities = !(ev.target as HaSwitch).checked; } + private _disablePollingChanged(ev: Event): void { + this._error = undefined; + this._disablePolling = !(ev.target as HaSwitch).checked; + } + private async _updateEntry(): Promise { this._submitting = true; + const data: Parameters[2] = { + disable_new_entities: this._disableNewEntities, + }; + if (this._allowUpdatePolling()) { + data.disable_polling = this._disablePolling; + } try { - await updateConfigEntrySystemOptions( + const result = await updateConfigEntrySystemOptions( this.hass, this._params!.entry.entry_id, - { - disable_new_entities: this._disableNewEntities, - } + data ); + if (result.require_restart) { + await showAlertDialog(this, { + text: this.hass.localize( + "ui.dialogs.config_entry_system_options.restart_home_assistant" + ), + }); + } + const curEntry = this._params!.entry; + this._params!.entryUpdated({ + ...curEntry, + system_options: { + ...curEntry.system_options, + ...data, + }, + }); this._params = undefined; } catch (err) { this._error = err.message || "Unknown error"; @@ -150,20 +186,6 @@ class DialogConfigEntrySystemOptions extends LitElement { return [ haStyleDialog, css` - .init-spinner { - padding: 50px 100px; - text-align: center; - } - - .form { - padding-top: 6px; - padding-bottom: 24px; - color: var(--primary-text-color); - } - .secondary { - color: var(--secondary-text-color); - } - .error { color: var(--error-color); } diff --git a/src/dialogs/config-entry-system-options/show-dialog-config-entry-system-options.ts b/src/dialogs/config-entry-system-options/show-dialog-config-entry-system-options.ts index 6b8a6c0329..77415e02cd 100644 --- a/src/dialogs/config-entry-system-options/show-dialog-config-entry-system-options.ts +++ b/src/dialogs/config-entry-system-options/show-dialog-config-entry-system-options.ts @@ -1,12 +1,11 @@ import { fireEvent } from "../../common/dom/fire_event"; import { ConfigEntry } from "../../data/config_entries"; +import { IntegrationManifest } from "../../data/integration"; export interface ConfigEntrySystemOptionsDialogParams { entry: ConfigEntry; - // updateEntry: ( - // updates: Partial - // ) => Promise; - // removeEntry: () => Promise; + manifest?: IntegrationManifest; + entryUpdated(entry: ConfigEntry): void; } export const loadConfigEntrySystemOptionsDialog = () => diff --git a/src/dialogs/ha-store-auth-card.ts b/src/dialogs/ha-store-auth-card.ts index b3229bfa73..6d7e5d3e8f 100644 --- a/src/dialogs/ha-store-auth-card.ts +++ b/src/dialogs/ha-store-auth-card.ts @@ -50,6 +50,9 @@ class HaStoreAuth extends LitElement { bottom: 16px; right: 16px; transition: bottom 0.25s; + --ha-card-box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2), + 0px 6px 10px 0px rgba(0, 0, 0, 0.14), + 0px 1px 18px 0px rgba(0, 0, 0, 0.12); } .card-actions { diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index cbd7de5aab..4e2a103c48 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -110,6 +110,7 @@ export class HaIntegrationCard extends LitElement { : undefined} .localizedDomainName=${item ? item.localized_domain_name : undefined} .manifest=${this.manifest} + .configEntry=${item} > ${this.items.length > 1 ? html` @@ -466,6 +467,11 @@ export class HaIntegrationCard extends LitElement { private _showSystemOptions(configEntry: ConfigEntry) { showConfigEntrySystemOptionsDialog(this, { entry: configEntry, + manifest: this.manifest, + entryUpdated: (entry) => + fireEvent(this, "entry-updated", { + entry, + }), }); } diff --git a/src/panels/config/integrations/ha-integration-header.ts b/src/panels/config/integrations/ha-integration-header.ts index cd189da48b..d18ba01670 100644 --- a/src/panels/config/integrations/ha-integration-header.ts +++ b/src/panels/config/integrations/ha-integration-header.ts @@ -1,8 +1,9 @@ -import { mdiCloud, mdiPackageVariant } from "@mdi/js"; +import { mdiCloud, mdiPackageVariant, mdiSyncOff } from "@mdi/js"; import "@polymer/paper-tooltip/paper-tooltip"; import { css, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; import "../../../components/ha-svg-icon"; +import { ConfigEntry } from "../../../data/config_entries"; import { domainToName, IntegrationManifest } from "../../../data/integration"; import { HomeAssistant } from "../../../types"; import { brandsUrl } from "../../../util/brands-url"; @@ -21,6 +22,8 @@ export class HaIntegrationHeader extends LitElement { @property({ attribute: false }) public manifest?: IntegrationManifest; + @property({ attribute: false }) public configEntry?: ConfigEntry; + protected render(): TemplateResult { let primary: string; let secondary: string | undefined; @@ -59,6 +62,15 @@ export class HaIntegrationHeader extends LitElement { ), ]); } + + if (this.configEntry?.system_options.disable_polling) { + icons.push([ + mdiSyncOff, + this.hass.localize( + "ui.panel.config.integrations.config_entry.disabled_polling" + ), + ]); + } } return html` diff --git a/src/state/auth-mixin.ts b/src/state/auth-mixin.ts index 7800ce8433..21575adc33 100644 --- a/src/state/auth-mixin.ts +++ b/src/state/auth-mixin.ts @@ -33,7 +33,7 @@ export default >(superClass: T) => .then(() => { const el = document.createElement("ha-store-auth-card"); this.provideHass(el); - this.shadowRoot!.appendChild(el); + document.body.appendChild(el); }); } } diff --git a/src/translations/en.json b/src/translations/en.json index 584e25f33e..dae343b3c2 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -759,7 +759,10 @@ "config_entry_system_options": { "title": "System Options for {integration}", "enable_new_entities_label": "Enable newly added entities.", - "enable_new_entities_description": "If disabled, newly discovered entities for {integration} will not be automatically added to Home Assistant.", + "enable_new_entities_description": "If newly discovered devices for {integration} should be automatically added.", + "enable_polling_label": "Enable polling for updates.", + "enable_polling_description": "If Home Assistant should automatically poll {integration} entities for updates.", + "restart_home_assistant": "You need to restart Home Assistant for your changes to take effect.", "update": "Update" }, "zha_reconfigure_device": { @@ -2182,6 +2185,7 @@ }, "provided_by_custom_integration": "Provided by a custom integration", "depends_on_cloud": "Depends on the cloud", + "disabled_polling": "Automatic polling for updated data disabled", "state": { "loaded": "Loaded", "setup_error": "Failed to set up", diff --git a/src/util/register-service-worker.ts b/src/util/register-service-worker.ts index 709c8f2a6c..1a029f97d0 100644 --- a/src/util/register-service-worker.ts +++ b/src/util/register-service-worker.ts @@ -39,13 +39,12 @@ export const registerServiceWorker = async ( } // Notify users a new frontend is available. - // When showToast(rootEl, { message: "A new version of the frontend is available.", action: { // We tell the service worker to call skipWaiting, which activates // the new service worker. Above we listen for `controllerchange` - // so we reload the page once a new servic worker activates. + // so we reload the page once a new service worker activates. action: () => installingWorker.postMessage({ type: "skipWaiting" }), text: "reload", }, diff --git a/translations/frontend/cs.json b/translations/frontend/cs.json index f093bf9861..e65cdf03ff 100644 --- a/translations/frontend/cs.json +++ b/translations/frontend/cs.json @@ -385,8 +385,13 @@ "create_blocked_not_running": "Vytvoření zálohy není momentálně možné, protože systém je ve \"{state}\".", "create_snapshot": "Vytvořit zálohu", "created": "Vytvořeno", + "delete_selected": "Smazat vybrané zálohy", + "delete_snapshot_confirm": "smazat", + "delete_snapshot_text": "Chcete smazat {number} {number, plural,\n one {zálohu}\n few {zálohy}\n other {záloh}\n}?", + "delete_snapshot_title": "Smazat zálohu", "description": "Zálohy umožňují snadno zálohovat a obnovovat všechna data vaší instance Home Assistant.", "enter_password": "Prosím zadejte heslo.", + "failed_to_delete": "Smazání se nezdařilo", "folder": { "addons/local": "Místní doplňky", "homeassistant": "Nastavení Home Asistent", @@ -404,6 +409,7 @@ "password_protection": "Ochrana heslem", "security": "Zabezpečení", "select_type": "Vyberte, co chcete obnovit", + "selected": "{number} vybraných", "type": "Typ zálohy", "upload_snapshot": "Nahrát zálohu" }, diff --git a/translations/frontend/da.json b/translations/frontend/da.json index 2498e9f36e..ccd8b05d22 100644 --- a/translations/frontend/da.json +++ b/translations/frontend/da.json @@ -385,8 +385,13 @@ "create_blocked_not_running": "Det er ikke muligt at oprette et snapshot lige nu, fordi systemet er i tilstanden {state}.", "create_snapshot": "Opret snapshot", "created": "Oprettet", + "delete_selected": "Slet valgte snapshots", + "delete_snapshot_confirm": "Slet", + "delete_snapshot_text": "Vil du slette {number} \n{number, plural,\n one {snapshot}\n other {snapshots}\n}?", + "delete_snapshot_title": "Slet snapshot", "description": "Snapshots giver dig mulighed for nemt at sikkerhedskopiere og gendanne alle data fra dit instans af Home Assistant.", "enter_password": "Venligst indtast et kodeord.", + "failed_to_delete": "Kunne ikke slette", "folder": { "addons/local": "Lokale tilføjelsesprogrammer", "homeassistant": "Home Assistant konfiguration", @@ -403,6 +408,8 @@ "password_protected": "beskyttet med kodeord", "password_protection": "Kodeordsbeskyttelse", "security": "Sikkerhed", + "select_type": "Vælg, hvad der skal gendannes", + "selected": "{number} valgt", "type": "Type", "upload_snapshot": "Upload snapshot" }, @@ -720,6 +727,9 @@ "no_match": "Ingen matchende områder fundet", "show_areas": "Vis områder" }, + "attributes": { + "expansion_header": "Attributter" + }, "blueprint-picker": { "add_user": "Tilføj bruger", "remove_user": "Fjern bruger", @@ -1719,6 +1729,7 @@ "title": "Alexa" }, "connected": "Forbundet", + "connecting": "Forbinder...", "connection_status": "Cloud-forbindelsesstatus", "fetching_subscription": "Henter abonnement...", "google": { @@ -2588,6 +2599,8 @@ "add_scene": "Tilføj scene", "delete_confirm": "Er du sikker på, at du vil slette denne scene?", "delete_scene": "Slet scene", + "duplicate": "Kopier", + "duplicate_scene": "Kopier scene", "edit_scene": "Rediger scene", "header": "Sceneredigering", "headers": { @@ -2916,6 +2929,8 @@ "follow_device_instructions": "Følg instruktionerne, der fulgte med din enhed for at starte parring af enheden.", "inclusion_failed": "Noden kunne ikke tilføjes. Se i logfilerne for at få flere oplysninger.", "inclusion_finished": "Noden er blevet tilføjet. Det kan tage et par minutter før alle enheder dukker op, mens konfiguration af noden fuldføres.", + "interview_failed": "Forespørgsel af enheden er mislykkedes. Der kan være yderligere oplysninger i logfilerne.", + "interview_started": "Enheden forespørges. Dette kan tage noget tid.", "introduction": "Denne guide hjælper dig med at føje en node til dit Z-Wave-netværk.", "secure_inclusion_warning": "Sikre enheder kræver ekstra båndbredde. For mange sikre enheder kan gøre dit Z-Wave-netværk langsomt. Det anbefaler kun at bruge sikker inklusion til de enheder, hvor det er nødvendigt. For eksempel til låse eller garageportåbnere.", "start_inclusion": "Start inklusionstilstand", @@ -2955,6 +2970,7 @@ }, "logs": { "log_level": "Log niveau", + "log_level_changed": "Logniveauet er ændret til: {level}", "subscribed_to_logs": "Abboner på Z-Wave JS Log beskeder", "title": "Z-Wave JS-logfiler" }, @@ -4004,6 +4020,17 @@ "primary_color": "Primær farve", "reset": "Nulstil" }, + "time_format": { + "description": "Vælg, hvordan klokkeslæt skal formateres.", + "dropdown_label": "Tidsformat", + "formats": { + "12": "12 timer (AM / PM)", + "24": "24 timer", + "language": "Automatisk (brug sprogindstilling)", + "system": "Brug systemets landestandard" + }, + "header": "Tidsformat" + }, "vibrate": { "description": "Aktivér eller deaktiver vibrationer på denne enhed, når du styrer enheder.", "header": "Vibrer" diff --git a/translations/frontend/en.json b/translations/frontend/en.json index a2cade9a79..f076e43678 100644 --- a/translations/frontend/en.json +++ b/translations/frontend/en.json @@ -929,8 +929,11 @@ }, "dialogs": { "config_entry_system_options": { - "enable_new_entities_description": "If disabled, newly discovered entities for {integration} will not be automatically added to Home Assistant.", + "enable_new_entities_description": "If newly discovered devices for {integration} should be automatically added.", "enable_new_entities_label": "Enable newly added entities.", + "enable_polling_description": "If Home Assistant should automatically poll {integration} entities for updates.", + "enable_polling_label": "Enable polling for updates.", + "restart_home_assistant": "You need to restart Home Assistant for your changes to take effect.", "title": "System Options for {integration}", "update": "Update" }, @@ -2217,6 +2220,7 @@ }, "disabled_cause": "Disabled by {cause}" }, + "disabled_polling": "Automatic polling for updated data disabled", "documentation": "Documentation", "enable_restart_confirm": "Restart Home Assistant to finish enabling this integration", "entities": "{count} {count, plural,\n one {entity}\n other {entities}\n}", diff --git a/translations/frontend/ko.json b/translations/frontend/ko.json index 066fd0a1ea..16898e6ed1 100644 --- a/translations/frontend/ko.json +++ b/translations/frontend/ko.json @@ -385,8 +385,13 @@ "create_blocked_not_running": "시스템이 {state} 상태이기 때문에 지금은 스냅숏을 생성할 수 없습니다.", "create_snapshot": "스냅숏 생성하기", "created": "생성됨", + "delete_selected": "선택한 스냅샷 삭제", + "delete_snapshot_confirm": "삭제", + "delete_snapshot_text": "{number} {number, plural,\n one{개의 스냅샷}\n other{개의 스냅샷}\n}를 삭제하시겠습니까?", + "delete_snapshot_title": "스냅샷 삭제", "description": "스냅숏을 사용하면 Home Assistant 인스턴스의 모든 데이터를 쉽게 백업하고 복원할 수 있습니다.", "enter_password": "비밀번호를 입력해주세요.", + "failed_to_delete": "삭제하지 못했습니다.", "folder": { "addons/local": "로컬 애드온", "homeassistant": "Home Assistant 구성 내용", @@ -404,6 +409,7 @@ "password_protection": "비밀번호 보호", "security": "보안", "select_type": "복원 할 항목 선택", + "selected": "{number}개 선택됨", "type": "유형", "upload_snapshot": "스냅숏 올리기" }, diff --git a/translations/frontend/nb.json b/translations/frontend/nb.json index 375698e2b9..f5d487d89e 100644 --- a/translations/frontend/nb.json +++ b/translations/frontend/nb.json @@ -385,8 +385,13 @@ "create_blocked_not_running": "Å lage en sikkerhetskopi er ikke mulig akkurat nå fordi systemet er i {state} status", "create_snapshot": "Opprett sikkerhetskopi", "created": "Opprettet", + "delete_selected": "Slett valgte sikkerhetskopier", + "delete_snapshot_confirm": "slett", + "delete_snapshot_text": "Vl du slette {number} {number, plural,\n one {sikkerhetskopi}\n other {sikkerhetskopier}\n}?", + "delete_snapshot_title": "Slett sikkerhetskopi", "description": "Sikkerhetskopier lar deg enkelt sikkerhetskopiere og gjenopprette alle dataene fra din Home Assistant forekomst", "enter_password": "Vennligst skriv inn et passord", + "failed_to_delete": "Kunne ikke slette", "folder": { "addons/local": "Lokale tillegg", "homeassistant": "Home Assistant-konfigurasjon", @@ -404,6 +409,7 @@ "password_protection": "Passordbeskyttelse", "security": "Sikkerhet", "select_type": "Velg hva du vil gjenopprette", + "selected": "{number} valgt", "type": "Type øyeblikksbilde", "upload_snapshot": "Last opp sikkerhetskopi" }, diff --git a/translations/frontend/pt-BR.json b/translations/frontend/pt-BR.json index 90742292f6..67fa944000 100644 --- a/translations/frontend/pt-BR.json +++ b/translations/frontend/pt-BR.json @@ -713,9 +713,20 @@ }, "zha_reconfigure_device": { "attribute": "Atributo", + "battery_device_warning": "Você precisará despertar os dispositivos alimentados por bateria antes de iniciar o processo de reconfiguração. Consulte o manual do seu dispositivo para obter instruções sobre como despertar o dispositivo.", "bind_header": "Vinculação", + "button_hide": "Ocultar detalhes", + "button_show": "Mostrar detalhes", + "cluster_header": "Cluster", + "configuration_complete": "Reconfiguração do dispositivo concluída.", + "configuration_failed": "A reconfiguração do dispositivo falhou. Informações adicionais podem estar disponíveis nos logs.", + "configuring_alt": "Configurando", + "in_progress": "O dispositivo está sendo reconfigurado. Isto pode levar algum tempo.", + "introduction": "Reconfigure um dispositivo em sua rede Zigbee. Use este recurso se o seu dispositivo não estiver funcionando corretamente.", "min_max_change": "min/máx/mudança", - "reporting_header": "Relatório" + "reporting_header": "Relatório", + "run_in_background": "Você pode fechar esta caixa de diálogo e a reconfiguração continuará em segundo plano.", + "start_reconfiguration": "Iniciar reconfiguração" } }, "duration": { @@ -770,6 +781,7 @@ "linked_entities_caption": "Entidades", "name": "Nome", "name_required": "Nome é obrigatório", + "no_linked_entities": "Não há entidades vinculadas a esta área.", "unknown_error": "Erro desconhecido", "update": "Atualizar" }, @@ -2120,6 +2132,7 @@ "zwave_js": { "logs": { "log_level": "Nível de Log", + "log_level_changed": "Nível de Log mudou para: {level}", "subscribed_to_logs": "Inscrito em mensagens de log JS do Z-Wave ...", "title": "Logs Z-Wave JS" }, diff --git a/translations/frontend/ru.json b/translations/frontend/ru.json index fd7dcbf674..62a5597b76 100644 --- a/translations/frontend/ru.json +++ b/translations/frontend/ru.json @@ -219,7 +219,7 @@ }, "boot": { "description": "Запускать дополнение во время загрузки системы", - "title": "Запускать при загрузке" + "title": "Автозагрузка" }, "ingress_panel": { "description": "Добавить это дополнение на боковую панель", diff --git a/translations/frontend/zh-Hans.json b/translations/frontend/zh-Hans.json index eac6f6b64e..2e84844e56 100644 --- a/translations/frontend/zh-Hans.json +++ b/translations/frontend/zh-Hans.json @@ -387,7 +387,7 @@ "created": "创建于", "delete_selected": "删除选定的快照", "delete_snapshot_confirm": "删除", - "delete_snapshot_text": "您是否要删除{number}个快照?", + "delete_snapshot_text": "是否要删除这 {number} 个快照?", "delete_snapshot_title": "删除快照", "description": "“快照”使您可以轻松地备份和还原 Home Assistant 实例的所有数据。", "enter_password": "请输入密码。", @@ -408,8 +408,8 @@ "password_protected": "密码保护", "password_protection": "密码保护", "security": "安全性", - "select_type": "选择要还原的内容", - "selected": "选择了 {number} 项", + "select_type": "请选择要还原的内容", + "selected": "已选择 {number} 项", "type": "类型", "upload_snapshot": "上传快照" }, @@ -580,8 +580,8 @@ }, "lock": { "code": "密码", - "lock": "上锁", - "unlock": "开锁" + "lock": "锁定", + "unlock": "解锁" }, "media_player": { "browse_media": "浏览媒体", @@ -798,13 +798,13 @@ "was_closed": "已关闭", "was_connected": "已连接", "was_disconnected": "已断开", - "was_locked": "已上锁", + "was_locked": "已锁定", "was_low": "较低", "was_normal": "正常", "was_opened": "已打开", "was_plugged_in": "已插入", "was_safe": "[%key_id:6884522%]", - "was_unlocked": "已打开", + "was_unlocked": "已解锁", "was_unplugged": "已拔出", "was_unsafe": "[%key_id:6884523%]" }, @@ -1129,7 +1129,7 @@ "command_line": "命令行实体", "core": "位置和自定义", "filesize": "文件大小实体", - "filter": "筛选实体", + "filter": "Filter 实体", "generic": "通用 IP 摄像机实体", "generic_thermostat": "通用恒温器实体", "group": "分组、分组实体及其通知服务", @@ -1803,7 +1803,7 @@ } }, "alexa": { - "banner": "您在configuration.yaml中配置了实体过滤器,因此无法用此UI修改被公开的实体名单。", + "banner": "由于您在 configuration.yaml 中配置了实体过滤器,无法通过此 UI 修改要开放的实体。", "dont_expose_entity": "使实体不可发现", "expose": "向Alexa发送你的位置", "expose_entity": "使实体可发现", @@ -2672,7 +2672,7 @@ "command_line": "命令行实体", "core": "位置和自定义", "filesize": "文件大小实体", - "filter": "筛选实体", + "filter": "Filter 实体", "generic": "通用 IP 摄像机实体", "generic_thermostat": "通用恒温器实体", "group": "分组、分组实体及其通知服务", @@ -2970,7 +2970,7 @@ }, "logs": { "log_level": "日志级别", - "log_level_changed": "日志级别更改为: {level}", + "log_level_changed": "日志级别更改为: {level}", "subscribed_to_logs": "已订阅 Z-Wave JS 日志消息...", "title": "Z-Wave JS 日志" },