diff --git a/hassio/src/addon-view/info/hassio-addon-info.ts b/hassio/src/addon-view/info/hassio-addon-info.ts index 89a2426199..0be5862955 100644 --- a/hassio/src/addon-view/info/hassio-addon-info.ts +++ b/hassio/src/addon-view/info/hassio-addon-info.ts @@ -242,19 +242,23 @@ class HassioAddonInfo extends LitElement { ` : ""}
- - - + ${this.addon.stage !== "stable" + ? html` + + ` + : ""} + @@ -46,10 +50,6 @@ class HassioMarkdownDialog extends LitElement { `; } - private _closeDialog(): void { - this._opened = false; - } - static get styles(): CSSResult[] { return [ haStyleDialog, diff --git a/hassio/src/hassio-main.ts b/hassio/src/hassio-main.ts index 074c40baaa..d20c690e30 100644 --- a/hassio/src/hassio-main.ts +++ b/hassio/src/hassio-main.ts @@ -1,92 +1,29 @@ -import { PolymerElement } from "@polymer/polymer"; import { - customElement, - property, - internalProperty, + html, PropertyValues, + customElement, + LitElement, + property, } from "lit-element"; +import "./hassio-router"; +import { urlSyncMixin } from "../../src/state/url-sync-mixin"; +import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin"; +import { HomeAssistant, Route } from "../../src/types"; +import { HassioPanelInfo } from "../../src/data/hassio/supervisor"; import { applyThemesOnElement } from "../../src/common/dom/apply_themes_on_element"; import { fireEvent } from "../../src/common/dom/fire_event"; -import { navigate } from "../../src/common/navigate"; -import { fetchHassioAddonInfo } from "../../src/data/hassio/addon"; -import { - fetchHassioHassOsInfo, - fetchHassioHostInfo, - HassioHassOSInfo, - HassioHostInfo, -} from "../../src/data/hassio/host"; -import { - createHassioSession, - fetchHassioHomeAssistantInfo, - fetchHassioSupervisorInfo, - fetchHassioInfo, - HassioHomeAssistantInfo, - HassioInfo, - HassioPanelInfo, - HassioSupervisorInfo, -} from "../../src/data/hassio/supervisor"; -import { - AlertDialogParams, - showAlertDialog, -} from "../../src/dialogs/generic/show-dialog-box"; import { makeDialogManager } from "../../src/dialogs/make-dialog-manager"; -import { - HassRouterPage, - RouterOptions, -} from "../../src/layouts/hass-router-page"; -import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin"; -import "../../src/resources/ha-style"; -import { HomeAssistant } from "../../src/types"; -// Don't codesplit it, that way the dashboard always loads fast. -import "./hassio-panel"; +import { atLeastVersion } from "../../src/common/config/version"; @customElement("hassio-main") -class HassioMain extends ProvideHassLitMixin(HassRouterPage) { +export class HassioMain extends urlSyncMixin(ProvideHassLitMixin(LitElement)) { @property({ attribute: false }) public hass!: HomeAssistant; @property() public panel!: HassioPanelInfo; @property() public narrow!: boolean; - protected routerOptions: RouterOptions = { - // Hass.io has a page with tabs, so we route all non-matching routes to it. - defaultPage: "dashboard", - initialLoad: () => this._fetchData(), - showLoading: true, - routes: { - dashboard: { - tag: "hassio-panel", - cache: true, - }, - snapshots: "dashboard", - store: "dashboard", - system: "dashboard", - addon: { - tag: "hassio-addon-dashboard", - load: () => - import( - /* webpackChunkName: "hassio-addon-dashboard" */ "./addon-view/hassio-addon-dashboard" - ), - }, - ingress: { - tag: "hassio-ingress-view", - load: () => - import( - /* webpackChunkName: "hassio-ingress-view" */ "./ingress-view/hassio-ingress-view" - ), - }, - }, - }; - - @internalProperty() private _supervisorInfo: HassioSupervisorInfo; - - @internalProperty() private _hostInfo: HassioHostInfo; - - @internalProperty() private _hassioInfo?: HassioInfo; - - @internalProperty() private _hassOsInfo?: HassioHassOSInfo; - - @internalProperty() private _hassInfo: HassioHomeAssistantInfo; + @property() public route?: Route; protected firstUpdated(changedProps: PropertyValues) { super.firstUpdated(changedProps); @@ -94,24 +31,13 @@ class HassioMain extends ProvideHassLitMixin(HassRouterPage) { applyThemesOnElement( this.parentElement, this.hass.themes, - this.hass.selectedTheme?.theme || this.hass.themes.default_theme, + (atLeastVersion(this.hass.config.version, 0, 114) + ? this.hass.selectedTheme?.theme + : ((this.hass.selectedTheme as unknown) as string)) || + this.hass.themes.default_theme, this.hass.selectedTheme ); - this.style.setProperty( - "--app-header-background-color", - "var(--sidebar-background-color)" - ); - this.style.setProperty( - "--app-header-text-color", - "var(--sidebar-text-color)" - ); - this.style.setProperty( - "--app-header-border-bottom", - "1px solid var(--divider-color)" - ); - - this.addEventListener("hass-api-called", (ev) => this._apiCalled(ev)); // Paulus - March 17, 2019 // We went to a single hass-toggle-menu event in HA 0.90. However, the // supervisor UI can also run under older versions of Home Assistant. @@ -144,152 +70,18 @@ class HassioMain extends ProvideHassLitMixin(HassRouterPage) { }); }); - makeDialogManager(this, document.body); + makeDialogManager(this, this.shadowRoot!); } - protected updatePageEl(el) { - // the tabs page does its own routing so needs full route. - const route = el.nodeName === "HASSIO-PANEL" ? this.route : this.routeTail; - - if ("setProperties" in el) { - // As long as we have Polymer pages - (el as PolymerElement).setProperties({ - hass: this.hass, - narrow: this.narrow, - supervisorInfo: this._supervisorInfo, - hassioInfo: this._hassioInfo, - hostInfo: this._hostInfo, - hassInfo: this._hassInfo, - hassOsInfo: this._hassOsInfo, - route, - }); - } else { - el.hass = this.hass; - el.narrow = this.narrow; - el.supervisorInfo = this._supervisorInfo; - el.hassioInfo = this._hassioInfo; - el.hostInfo = this._hostInfo; - el.hassInfo = this._hassInfo; - el.hassOsInfo = this._hassOsInfo; - el.route = route; - } - } - - private async _fetchData() { - if (this.panel.config && this.panel.config.ingress) { - await this._redirectIngress(this.panel.config.ingress); - return; - } - - const [supervisorInfo, hostInfo, hassInfo, hassioInfo] = await Promise.all([ - fetchHassioSupervisorInfo(this.hass), - fetchHassioHostInfo(this.hass), - fetchHassioHomeAssistantInfo(this.hass), - fetchHassioInfo(this.hass), - ]); - this._supervisorInfo = supervisorInfo; - this._hassioInfo = hassioInfo; - this._hostInfo = hostInfo; - this._hassInfo = hassInfo; - - if (this._hostInfo.features && this._hostInfo.features.includes("hassos")) { - this._hassOsInfo = await fetchHassioHassOsInfo(this.hass); - } - } - - private async _redirectIngress(addonSlug: string) { - // When we trigger a navigation, we sleep to make sure we don't - // show the hassio dashboard before navigating away. - const awaitAlert = async ( - alertParams: AlertDialogParams, - action: () => void - ) => { - await new Promise((resolve) => { - alertParams.confirm = resolve; - showAlertDialog(this, alertParams); - }); - action(); - await new Promise((resolve) => setTimeout(resolve, 1000)); - }; - - const createSessionPromise = createHassioSession(this.hass).then( - () => true, - () => false - ); - - let addon; - - try { - addon = await fetchHassioAddonInfo(this.hass, addonSlug); - } catch (err) { - await awaitAlert( - { - text: "Unable to fetch add-on info to start Ingress", - title: "Supervisor", - }, - () => history.back() - ); - - return; - } - - if (!addon.ingress_url) { - await awaitAlert( - { - text: "Add-on does not support Ingress", - title: addon.name, - }, - () => history.back() - ); - - return; - } - - if (addon.state !== "started") { - await awaitAlert( - { - text: "Add-on is not running. Please start it first", - title: addon.name, - }, - () => navigate(this, `/hassio/addon/${addon.slug}/info`, true) - ); - - return; - } - - if (!(await createSessionPromise)) { - await awaitAlert( - { - text: "Unable to create an Ingress session", - title: addon.name, - }, - () => history.back() - ); - - return; - } - - location.assign(addon.ingress_url); - // await a promise that doesn't resolve, so we show the loading screen - // while we load the next page. - await new Promise(() => undefined); - } - - private _apiCalled(ev) { - if (!ev.detail.success) { - return; - } - - let tries = 1; - - const tryUpdate = () => { - this._fetchData().catch(() => { - tries += 1; - setTimeout(tryUpdate, Math.min(tries, 5) * 1000); - }); - }; - - tryUpdate(); + protected render() { + return html` + + `; } } diff --git a/hassio/src/hassio-panel.ts b/hassio/src/hassio-panel.ts index 471c717970..245f8ba1ee 100644 --- a/hassio/src/hassio-panel.ts +++ b/hassio/src/hassio-panel.ts @@ -4,6 +4,8 @@ import { LitElement, property, TemplateResult, + css, + CSSResult, } from "lit-element"; import { HassioHassOSInfo, HassioHostInfo } from "../../src/data/hassio/host"; import { @@ -33,6 +35,9 @@ class HassioPanel extends LitElement { @property({ attribute: false }) public hassOsInfo!: HassioHassOSInfo; protected render(): TemplateResult { + if (!this.supervisorInfo) { + return html``; + } return html` `; } + + static get styles(): CSSResult { + return css` + :host { + --app-header-background-color: var(--sidebar-background-color); + --app-header-text-color: var(--sidebar-text-color); + --app-header-border-bottom: 1px solid var(--divider-color); + } + `; + } } declare global { diff --git a/hassio/src/hassio-router.ts b/hassio/src/hassio-router.ts new file mode 100644 index 0000000000..a3ecdaf784 --- /dev/null +++ b/hassio/src/hassio-router.ts @@ -0,0 +1,150 @@ +import { + customElement, + property, + internalProperty, + PropertyValues, +} from "lit-element"; +import { + fetchHassioHassOsInfo, + fetchHassioHostInfo, + HassioHassOSInfo, + HassioHostInfo, +} from "../../src/data/hassio/host"; +import { + fetchHassioHomeAssistantInfo, + fetchHassioSupervisorInfo, + fetchHassioInfo, + HassioHomeAssistantInfo, + HassioInfo, + HassioPanelInfo, + HassioSupervisorInfo, +} from "../../src/data/hassio/supervisor"; +import { + HassRouterPage, + RouterOptions, +} from "../../src/layouts/hass-router-page"; +import "../../src/resources/ha-style"; +import { HomeAssistant } from "../../src/types"; +// Don't codesplit it, that way the dashboard always loads fast. +import "./hassio-panel"; + +@customElement("hassio-router") +class HassioRouter extends HassRouterPage { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public panel!: HassioPanelInfo; + + @property() public narrow!: boolean; + + protected routerOptions: RouterOptions = { + // Hass.io has a page with tabs, so we route all non-matching routes to it. + defaultPage: "dashboard", + initialLoad: () => this._fetchData(), + showLoading: true, + routes: { + dashboard: { + tag: "hassio-panel", + cache: true, + }, + snapshots: "dashboard", + store: "dashboard", + system: "dashboard", + addon: { + tag: "hassio-addon-dashboard", + load: () => + import( + /* webpackChunkName: "hassio-addon-dashboard" */ "./addon-view/hassio-addon-dashboard" + ), + }, + ingress: { + tag: "hassio-ingress-view", + load: () => + import( + /* webpackChunkName: "hassio-ingress-view" */ "./ingress-view/hassio-ingress-view" + ), + }, + }, + }; + + @internalProperty() private _supervisorInfo: HassioSupervisorInfo; + + @internalProperty() private _hostInfo: HassioHostInfo; + + @internalProperty() private _hassioInfo?: HassioInfo; + + @internalProperty() private _hassOsInfo?: HassioHassOSInfo; + + @internalProperty() private _hassInfo: HassioHomeAssistantInfo; + + protected firstUpdated(changedProps: PropertyValues) { + super.firstUpdated(changedProps); + this.addEventListener("hass-api-called", (ev) => this._apiCalled(ev)); + } + + protected updatePageEl(el) { + // the tabs page does its own routing so needs full route. + const route = el.nodeName === "HASSIO-PANEL" ? this.route : this.routeTail; + + el.hass = this.hass; + el.narrow = this.narrow; + el.supervisorInfo = this._supervisorInfo; + el.hassioInfo = this._hassioInfo; + el.hostInfo = this._hostInfo; + el.hassInfo = this._hassInfo; + el.hassOsInfo = this._hassOsInfo; + el.route = route; + + if (el.localName === "hassio-ingress-view") { + el.ingressPanel = this.panel.config && this.panel.config.ingress; + } + } + + private async _fetchData() { + if (this.panel.config && this.panel.config.ingress) { + this._redirectIngress(this.panel.config.ingress); + return; + } + + const [supervisorInfo, hostInfo, hassInfo, hassioInfo] = await Promise.all([ + fetchHassioSupervisorInfo(this.hass), + fetchHassioHostInfo(this.hass), + fetchHassioHomeAssistantInfo(this.hass), + fetchHassioInfo(this.hass), + ]); + this._supervisorInfo = supervisorInfo; + this._hassioInfo = hassioInfo; + this._hostInfo = hostInfo; + this._hassInfo = hassInfo; + + if (this._hostInfo.features && this._hostInfo.features.includes("hassos")) { + this._hassOsInfo = await fetchHassioHassOsInfo(this.hass); + } + } + + private _redirectIngress(addonSlug: string) { + this.route = { prefix: "/hassio", path: `/ingress/${addonSlug}` }; + } + + private _apiCalled(ev) { + if (!ev.detail.success) { + return; + } + + let tries = 1; + + const tryUpdate = () => { + this._fetchData().catch(() => { + tries += 1; + setTimeout(tryUpdate, Math.min(tries, 5) * 1000); + }); + }; + + tryUpdate(); + } +} + +declare global { + interface HTMLElementTagNameMap { + "hassio-router": HassioRouter; + } +} diff --git a/hassio/src/ingress-view/hassio-ingress-view.ts b/hassio/src/ingress-view/hassio-ingress-view.ts index 42cf1b373a..8780d9617d 100644 --- a/hassio/src/ingress-view/hassio-ingress-view.ts +++ b/hassio/src/ingress-view/hassio-ingress-view.ts @@ -17,6 +17,10 @@ import { createHassioSession } from "../../../src/data/hassio/supervisor"; import "../../../src/layouts/hass-loading-screen"; import "../../../src/layouts/hass-subpage"; import { HomeAssistant, Route } from "../../../src/types"; +import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box"; +import { navigate } from "../../../src/common/navigate"; +import { mdiMenu } from "@mdi/js"; +import { fireEvent } from "../../../src/common/dom/fire_event"; @customElement("hassio-ingress-view") class HassioIngressView extends LitElement { @@ -24,22 +28,45 @@ class HassioIngressView extends LitElement { @property() public route!: Route; + @property() public ingressPanel = false; + @internalProperty() private _addon?: HassioAddonDetails; + @property({ type: Boolean }) + public narrow = false; + protected render(): TemplateResult { if (!this._addon) { return html` `; } - return html` - - - - `; + const iframe = html``; + + if (!this.ingressPanel) { + return html` + ${iframe} + `; + } + + return html`${this.narrow || this.hass.dockedSidebar === "always_hidden" + ? html`
+ + + +
${this._addon.name}
+
+ ${iframe}` + : iframe}`; } protected updated(changedProps: PropertyValues) { - super.firstUpdated(changedProps); + super.updated(changedProps); if (!changedProps.has("route")) { return; @@ -56,27 +83,56 @@ class HassioIngressView extends LitElement { } private async _fetchData(addonSlug: string) { + const createSessionPromise = createHassioSession(this.hass).then( + () => true, + () => false + ); + + let addon; + try { - const [addon] = await Promise.all([ - fetchHassioAddonInfo(this.hass, addonSlug).catch(() => { - throw new Error("Failed to fetch add-on info"); - }), - createHassioSession(this.hass).catch(() => { - throw new Error("Failed to create an ingress session"); - }), - ]); - - if (!addon.ingress) { - throw new Error("This add-on does not support ingress"); - } - - this._addon = addon; + addon = await fetchHassioAddonInfo(this.hass, addonSlug); } catch (err) { - // eslint-disable-next-line - console.error(err); - alert(err.message || "Unknown error starting ingress."); + await showAlertDialog(this, { + text: "Unable to fetch add-on info to start Ingress", + title: "Supervisor", + }); history.back(); + return; } + + if (!addon.ingress_url) { + await showAlertDialog(this, { + text: "Add-on does not support Ingress", + title: addon.name, + }); + history.back(); + return; + } + + if (addon.state !== "started") { + await showAlertDialog(this, { + text: "Add-on is not running. Please start it first", + title: addon.name, + }); + navigate(this, `/hassio/addon/${addon.slug}/info`, true); + return; + } + + if (!(await createSessionPromise)) { + await showAlertDialog(this, { + text: "Unable to create an Ingress session", + title: addon.name, + }); + history.back(); + return; + } + + this._addon = addon; + } + + private _toggleMenu(): void { + fireEvent(this, "hass-toggle-menu"); } static get styles(): CSSResult { @@ -87,6 +143,41 @@ class HassioIngressView extends LitElement { height: 100%; border: 0; } + + .header + iframe { + height: calc(100% - 40px); + } + + .header { + display: flex; + align-items: center; + font-size: 16px; + height: 40px; + padding: 0 16px; + pointer-events: none; + background-color: var(--app-header-background-color); + font-weight: 400; + color: var(--app-header-text-color, white); + border-bottom: var(--app-header-border-bottom, none); + box-sizing: border-box; + --mdc-icon-size: 20px; + } + + .main-title { + margin: 0 0 0 24px; + line-height: 20px; + flex-grow: 1; + } + + mwc-icon-button { + pointer-events: auto; + } + + hass-subpage { + --app-header-background-color: var(--sidebar-background-color); + --app-header-text-color: var(--sidebar-text-color); + --app-header-border-bottom: 1px solid var(--divider-color); + } `; } } diff --git a/setup.py b/setup.py index e9d1a60254..f4c217e8bd 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20200805.0", + version="20200807.0", 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-date-range-picker.ts b/src/components/ha-date-range-picker.ts index 965c3c0cd6..884c893d56 100644 --- a/src/components/ha-date-range-picker.ts +++ b/src/components/ha-date-range-picker.ts @@ -163,13 +163,6 @@ export class HaDateRangePicker extends LitElement { border-right: 1px solid var(--divider-color); } - @media only screen and (max-width: 800px) { - .date-range-ranges { - border-right: none; - border-bottom: 1px solid var(--divider-color); - } - } - .date-range-footer { display: flex; justify-content: flex-end; @@ -179,12 +172,30 @@ export class HaDateRangePicker extends LitElement { paper-input { display: inline-block; - max-width: 200px; + max-width: 250px; + min-width: 200px; } paper-input:last-child { margin-left: 8px; } + + @media only screen and (max-width: 800px) { + .date-range-ranges { + border-right: none; + border-bottom: 1px solid var(--divider-color); + } + } + + @media only screen and (max-width: 500px) { + paper-input { + min-width: inherit; + } + + ha-svg-icon { + display: none; + } + } `; } } diff --git a/src/components/ha-markdown.ts b/src/components/ha-markdown.ts index 397a216cab..978a979776 100644 --- a/src/components/ha-markdown.ts +++ b/src/components/ha-markdown.ts @@ -57,6 +57,10 @@ class HaMarkdown extends LitElement { background-color: var(--markdown-code-background-color, none); border-radius: 3px; } + ha-markdown-element svg { + background-color: var(--markdown-svg-background-color, none); + color: var(--markdown-svg-color, none); + } ha-markdown-element code { font-size: 85%; padding: 0.2em 0.4em; @@ -70,8 +74,8 @@ class HaMarkdown extends LitElement { line-height: 1.45; } ha-markdown-element h2 { - font-size: 1.5em !important; - font-weight: bold !important; + font-size: 1.5em; + font-weight: bold; } `; } diff --git a/src/html/index.html.template b/src/html/index.html.template index 8f20524cd0..0225c9b3ab 100644 --- a/src/html/index.html.template +++ b/src/html/index.html.template @@ -46,6 +46,14 @@ html { background-color: var(--primary-background-color); } + @media (prefers-color-scheme: dark) { + #ha-init-skeleton::before { + background-color: #1c1c1c; + } + html { + background-color: #111111; + } + } diff --git a/src/layouts/ha-init-page.ts b/src/layouts/ha-init-page.ts index 3e98b1bea0..0da8b57a45 100644 --- a/src/layouts/ha-init-page.ts +++ b/src/layouts/ha-init-page.ts @@ -60,6 +60,7 @@ class HaInitPage extends LitElement { } p { max-width: 350px; + color: var(--text-primary-color); } `; } diff --git a/src/panels/config/entities/dialog-entity-editor.ts b/src/panels/config/entities/dialog-entity-editor.ts index 72fda1301a..5a1cac4066 100644 --- a/src/panels/config/entities/dialog-entity-editor.ts +++ b/src/panels/config/entities/dialog-entity-editor.ts @@ -247,6 +247,7 @@ export class DialogEntityEditor extends LitElement { ha-dialog { --dialog-content-position: static; --dialog-content-padding: 0; + --dialog-z-index: 6; } @media all and (min-width: 451px) and (min-height: 501px) { diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index 63a3cfe573..d88b075a10 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -453,6 +453,9 @@ export class HaIntegrationCard extends LitElement { cursor: pointer; min-height: 35px; } + mwc-list-item ha-svg-icon { + color: var(--secondary-text-color); + } .back-btn { position: absolute; background: rgba(var(--rgb-card-background-color), 0.6); diff --git a/src/panels/lovelace/cards/hui-light-card.ts b/src/panels/lovelace/cards/hui-light-card.ts index 51fb22a991..bb65f89e1c 100644 --- a/src/panels/lovelace/cards/hui-light-card.ts +++ b/src/panels/lovelace/cards/hui-light-card.ts @@ -32,6 +32,7 @@ import { hasConfigOrEntityChanged } from "../common/has-changed"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import { LovelaceCard, LovelaceCardEditor } from "../types"; import { LightCardConfig } from "./types"; +import { mdiDotsVertical } from "@mdi/js"; @customElement("hui-light-card") export class HuiLightCard extends LitElement implements LovelaceCard { @@ -101,12 +102,14 @@ export class HuiLightCard extends LitElement implements LovelaceCard { return html` - + > + +
@@ -284,7 +287,7 @@ export class HuiLightCard extends LitElement implements LovelaceCard { right: 0; border-radius: 100%; color: var(--secondary-text-color); - z-index: 25; + z-index: 1; } .content { diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index 04a7a8a1ac..e8a7f71b48 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -35,6 +35,7 @@ import { createEntityNotFoundWarning } from "../components/hui-warning"; import { LovelaceCard, LovelaceCardEditor } from "../types"; import { ThermostatCardConfig } from "./types"; import type { HaCard } from "../../../components/ha-card"; +import { mdiDotsVertical } from "@mdi/js"; const modeIcons: { [mode in HvacMode]: string } = { auto: "hass:calendar-sync", @@ -216,12 +217,14 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { [mode]: true, })} > - + > + +
@@ -465,7 +468,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { right: 0; border-radius: 100%; color: var(--secondary-text-color); - z-index: 25; + z-index: 1; } .content { 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 0186f24508..effc794665 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 @@ -80,6 +80,9 @@ export class HuiDialogEditCard extends LitElement implements HassDialog { if (this._cardConfig && !Object.isFrozen(this._cardConfig)) { this._cardConfig = deepFreeze(this._cardConfig); } + if (params.cardConfig) { + this._dirty = true; + } } public closeDialog(): boolean { diff --git a/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts b/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts index dadddcd25f..9720fad71f 100644 --- a/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts +++ b/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts @@ -4,13 +4,14 @@ import { LitElement, internalProperty, TemplateResult, - CSSResult, css, + CSSResultArray, } from "lit-element"; import "../../../../components/dialog/ha-paper-dialog"; import "../../components/hui-views-list"; import type { SelectViewDialogParams } from "./show-select-view-dialog"; import { HomeAssistant } from "../../../../types"; +import { haStyleDialog } from "../../../../resources/styles"; import { createCloseHeading } from "../../../../components/ha-dialog"; import "../../../../components/ha-paper-dropdown-menu"; import "@polymer/paper-item/paper-item"; @@ -135,12 +136,15 @@ export class HuiDialogSelectView extends LitElement { this.closeDialog(); } - static get styles(): CSSResult { - return css` - ha-paper-dropdown-menu { - width: 100%; - } - `; + static get styles(): CSSResultArray { + return [ + haStyleDialog, + css` + ha-paper-dropdown-menu { + width: 100%; + } + `, + ]; } } diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index ca41fe1899..a720fde6bb 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -138,6 +138,7 @@ class HUIRoot extends LitElement { >( +export const urlSyncMixin = < + T extends Constructor +>( superClass: T ) => // Disable this functionality in the demo. @@ -35,11 +38,17 @@ export const urlSyncMixin = >( private _dialogClosedListener = ( ev: HASSDomEvent ) => { + if (DEBUG) { + console.log("dialog closed", ev.detail.dialog); + } // If not closed by navigating back, and not a new dialog is open, remove the open state from history if ( history.state?.open && history.state?.dialog === ev.detail.dialog ) { + if (DEBUG) { + console.log("remove state", ev.detail.dialog); + } this._ignoreNextPopState = true; history.back(); } @@ -65,6 +74,9 @@ export const urlSyncMixin = >( if (!state.open) { const closed = await closeDialog(state.dialog); if (!closed) { + if (DEBUG) { + console.log("dialog could not be closed"); + } // dialog could not be closed, push state again history.pushState( { @@ -78,6 +90,9 @@ export const urlSyncMixin = >( return; } if (state.oldState) { + if (DEBUG) { + console.log("handle old state"); + } this._handleDialogStateChange(state.oldState); } return; diff --git a/translations/frontend/ca.json b/translations/frontend/ca.json index 4765777501..5ceba7af7b 100644 --- a/translations/frontend/ca.json +++ b/translations/frontend/ca.json @@ -833,6 +833,15 @@ "name": "Acció", "type_select": "Tipus d'acció", "type": { + "choose": { + "add_option": "Afegeix opció", + "conditions": "Condicions", + "default": "Accions per defecte", + "label": "Triar", + "option": "Opció {number}", + "remove_option": "Eliminar opció", + "sequence": "Accions" + }, "condition": { "label": "Condició" }, @@ -852,6 +861,24 @@ "label": "Disparar esdeveniment", "service_data": "Dades de servei" }, + "repeat": { + "label": "Repetir", + "sequence": "Accions", + "type_select": "Tipus de repetició", + "type": { + "count": { + "label": "Comptar" + }, + "until": { + "conditions": "Fins a les condicions", + "label": "Fins que" + }, + "while": { + "conditions": "Mentre que les condicions", + "label": "Mentre" + } + } + }, "scene": { "label": "Activa escena" }, @@ -1619,6 +1646,18 @@ "title": "MQTT", "topic": "tòpic" }, + "ozw": { + "common": { + "node_id": "Node ID", + "ozw_instance": "Instància OpenZWave", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Ha fallat el node", + "stage": "Etapa", + "zwave_info": "Informació Z-Wave" + } + }, "person": { "add_person": "Afegeix persona", "caption": "Persones", @@ -2387,6 +2426,9 @@ "para_migrate": "Home Assistant pot afegir ID's a totes les targetes i visualitzacions automàticament fent clic al botó 'Migrar la configuració'.", "para_no_id": "Aquest element no té ID. Afegeix un ID per aquest element a 'ui-lovelace.yaml'." }, + "move_card": { + "header": "Trieu una vista per desplaçar la tarjeta a" + }, "raw_editor": { "confirm_remove_config_text": "Si elimines la configuració de la interfície d'usuari Lovelace es generaran automàticament les visualitzacions de Lovelace amb les teves àrees i dispositius.", "confirm_remove_config_title": "Estàs segur que vols eliminar la configuració de la interfície d'usuari Lovelace? Es generaran automàticament les visualitzacions de Lovelace amb les teves àrees i dispositius.", @@ -2414,6 +2456,10 @@ "yaml_control": "Per configurar el panell en mode YAML, crea un fitxer YAML amb el nom que hagis establert a la configuració del panell, o bé el nom per defecte 'ui-lovelace.yaml'.", "yaml_mode": "Estàs utilitzant el mode YAML per aquest panell, per tant no pots editar-lo des de la interfície d'usuari. Si vols poder editar-lo des de la UI, elimina 'mode: yaml' del fitxer 'configuration.yaml' en l'apartat de configuració de Lovelace." }, + "select_view": { + "dashboard_label": "Panell", + "header": "Trieu una vista" + }, "suggest_card": { "add": "Afegeix a la UI Lovelace", "create_own": "Escull una targeta diferent", @@ -2731,10 +2777,18 @@ "header": "Tanca la connexió automàticament" }, "themes": { + "accent_color": "Color accent", + "dark_mode": { + "auto": "Auto", + "dark": "Fosc", + "light": "Clar" + }, "dropdown_label": "Tema", "error_no_theme": "No hi ha temes disponibles.", "header": "Tema", - "link_promo": "Crea temes personalitzats" + "link_promo": "Crea temes personalitzats", + "primary_color": "Color primari", + "reset": "Restablir" }, "vibrate": { "description": "Activa o desactiva la vibració en d'aquest dispositiu.", diff --git a/translations/frontend/cs.json b/translations/frontend/cs.json index f3f38d7533..6ec56b85ff 100644 --- a/translations/frontend/cs.json +++ b/translations/frontend/cs.json @@ -1638,6 +1638,11 @@ "title": "MQTT", "topic": "téma" }, + "ozw": { + "common": { + "zwave": "Z-Wave" + } + }, "person": { "add_person": "Přidat osobu", "caption": "Osoby", @@ -2406,6 +2411,9 @@ "para_migrate": "Home Assistant může automaticky přidávat ID ke všem kartám a pohledům stisknutím tlačítka \"Migrovat konfiguraci\".", "para_no_id": "Tento prvek nemá ID. Přidejte k tomuto prvku ID v 'ui-lovelace.yaml'." }, + "move_card": { + "header": "Vyberte pohled, do kterého chcete kartu přesunout" + }, "raw_editor": { "confirm_remove_config_text": "Pokud odeberete nastavení Lovelace, automaticky vygenerujeme vaše zobrazení Lovelace s vašimi oblastmi a zařízeními.", "confirm_remove_config_title": "Opravdu chcete odstranit nastavení Lovelace? Automaticky vygenerujeme vaše zobrazení Lovelace s vašimi oblastmi a zařízeními.", @@ -2433,6 +2441,10 @@ "yaml_control": "Chcete-li převzít kontrolu v režimu YAML, vytvořte soubor YAML s názvem, který jste uvedli ve své konfiguraci pro tento dashboard nebo výchozí 'ui-lovelace.yaml'.", "yaml_mode": "Používáte režim YAML, což znamená, že nemůžete změnit konfiguraci Lovelace z uživatelského rozhraní. Pokud chcete měnit Lovelace z uživatelského rozhraní, odstraňte 'mode: yaml' z vaší konfigurace Lovelace v 'configuration.yaml.'" }, + "select_view": { + "dashboard_label": "Dashboard", + "header": "Vyberte pohled" + }, "suggest_card": { "add": "Přidat do Lovelance", "create_own": "Vytvořit vlastní", diff --git a/translations/frontend/da.json b/translations/frontend/da.json index 0595cfed51..14550a224a 100644 --- a/translations/frontend/da.json +++ b/translations/frontend/da.json @@ -1646,6 +1646,18 @@ "title": "MQTT", "topic": "emne" }, + "ozw": { + "common": { + "node_id": "knudepunkts-id", + "ozw_instance": "OpenZWave-instans", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Problematisk knudepunkt", + "stage": "Fase", + "zwave_info": "Z-Wave-info" + } + }, "person": { "add_person": "Tilføj person", "caption": "Personer", @@ -2414,6 +2426,9 @@ "para_migrate": "Home Assistant kan tilføje id'er til alle dine kort og visninger automatisk for dig ved at trykke på knappen 'Migrer opsætning'.", "para_no_id": "Dette element har ikke et id. Tilføj venligst et id til dette element i 'ui-lovelace.yaml'." }, + "move_card": { + "header": "Vælg en visning, som kortet skal flyttes til" + }, "raw_editor": { "confirm_remove_config_text": "Vi genererer automatisk dine Lovelace-brugerfladevisninger med dine områder og enheder, hvis du fjerner din Lovelace-brugerfladekonfiguration.", "confirm_remove_config_title": "Er du sikker på, at du vil fjerne din Lovelace-brugerfladekonfiguration? Vi vil automatisk generere dine Lovelace-brugerfladevisninger med dine områder og enheder.", @@ -2441,6 +2456,10 @@ "yaml_control": "For at tage kontrol i YAML-tilstand skal du oprette en YAML-fil med det navn, du har angivet i din konfiguration for dette betjeningspanel, eller standard-'ui-lovelace.yaml'-filen.", "yaml_mode": "Du bruger YAML-tilstand for dette betjeningspanel. Det betyder, at du ikke kan ændre din Lovelace-konfiguration fra brugerfladen. Hvis du vil ændre dette betjeningspanel fra brugerfladen, skal du fjerne 'mode: yaml' fra din Lovelace-konfiguration i 'configuration.yaml.'" }, + "select_view": { + "dashboard_label": "Betjeningspanel", + "header": "Vælg en visning" + }, "suggest_card": { "add": "Tilføj til Lovelace-brugerflade", "create_own": "Lav dit eget", diff --git a/translations/frontend/es.json b/translations/frontend/es.json index 2abd30946d..6241c73978 100644 --- a/translations/frontend/es.json +++ b/translations/frontend/es.json @@ -1646,6 +1646,18 @@ "title": "MQTT", "topic": "tema" }, + "ozw": { + "common": { + "node_id": "ID del Nodo", + "ozw_instance": "Instancia OpenZWave", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Error en el Nodo", + "stage": "Etapa", + "zwave_info": "Información Z-Wave" + } + }, "person": { "add_person": "Añadir persona", "caption": "Personas", @@ -2414,6 +2426,9 @@ "para_migrate": "Home Assistant puede añadir IDs a todas tus tarjetas y vistas automáticamente pulsando el botón 'Migrar configuración'.", "para_no_id": "Este elemento no tiene un ID. Por favor añade uno a este elemento en 'ui-lovelace.yaml'." }, + "move_card": { + "header": "Elige una vista hacia la que mover la tarjeta" + }, "raw_editor": { "confirm_remove_config_text": "Generaremos automáticamente tus vistas de la IU Lovelace con tus áreas y dispositivos si eliminas tu configuración de Lovelace.", "confirm_remove_config_title": "¿Estás seguro de que deseas eliminar tu configuración de la IU Lovelace? Generaremos automáticamente tus vistas de la IU Lovelace con tus áreas y dispositivos.", @@ -2441,6 +2456,10 @@ "yaml_control": "Para tomar el control en modo YAML, crea un archivo YAML con el nombre que especificaste en la configuración para este panel de control, o el valor predeterminado 'ui-lovelace.yaml'.", "yaml_mode": "Estás utilizando el modo YAML para este panel de control, lo que significa que no puedes cambiar la configuración de Lovelace desde la IU. Si quieres gestionar este panel de control desde la IU, elimina 'mode: yaml' de la configuración de Lovelace en 'configuration.yaml.'" }, + "select_view": { + "dashboard_label": "Panel de control", + "header": "Elige una vista" + }, "suggest_card": { "add": "Añadir a la IU Lovelace", "create_own": "Elige una tarjeta diferente", diff --git a/translations/frontend/fr.json b/translations/frontend/fr.json index e979ab1497..dd5e569a1d 100644 --- a/translations/frontend/fr.json +++ b/translations/frontend/fr.json @@ -1646,6 +1646,18 @@ "title": "MQTT", "topic": "sujet" }, + "ozw": { + "common": { + "node_id": "ID du nœud", + "ozw_instance": "Instance Z-Wave", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Nœud Défaillant", + "stage": "Étape", + "zwave_info": "Informations Z-Wave" + } + }, "person": { "add_person": "Ajouter une personne", "caption": "Personnes", @@ -2414,6 +2426,9 @@ "para_migrate": "Home Assistant peut ajouter automatiquement des identifiants à toutes vos cartes et vues en appuyant sur le bouton «Migrer la configuration».", "para_no_id": "Cet élément n'a pas d'identifiant. Veuillez ajouter un identifiant à cet élément dans 'ui-lovelace.yaml'." }, + "move_card": { + "header": "Choisissez une vue vers laquelle déplacer la carte" + }, "raw_editor": { "confirm_remove_config_text": "Nous générerons automatiquement vos vues Lovelace UI avec vos zones et appareils si vous supprimez votre configuration Lovelace UI.", "confirm_remove_config_title": "Êtes-vous sûr de vouloir supprimer votre configuration Lovelace UI? Nous générerons automatiquement vos vues Lovelace UI avec vos zones et vos appareils.", @@ -2441,6 +2456,10 @@ "yaml_control": "Pour prendre le contrôle en mode YAML, créez un fichier YAML avec le nom que vous avez spécifié dans votre configuration pour ce tableau de bord, ou le 'ui-lovelace.yaml' par défaut.", "yaml_mode": "Vous utilisez le mode YAML pour ce tableau de bord, ce qui signifie que vous ne pouvez pas modifier votre configuration Lovelace depuis l'interface utilisateur. Si vous souhaitez gérer votre tableau de bord via l'interface utilisateur, supprimez «mode: yaml» de votre configuration Lovelace dans «configuration.yaml»." }, + "select_view": { + "dashboard_label": "Tableau de bord", + "header": "Choisissez une vue" + }, "suggest_card": { "add": "Ajouter à Lovelace UI", "create_own": "Choisissez une autre carte", diff --git a/translations/frontend/nb.json b/translations/frontend/nb.json index 606fa95014..b22415f52b 100644 --- a/translations/frontend/nb.json +++ b/translations/frontend/nb.json @@ -1646,6 +1646,18 @@ "title": "MQTT", "topic": "emne" }, + "ozw": { + "common": { + "node_id": "Node-ID", + "ozw_instance": "OpenZWave Instance", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Noden mislyktes", + "stage": "Scene", + "zwave_info": "Z-Wave Info" + } + }, "person": { "add_person": "Legg til person", "caption": "Personer", @@ -2414,6 +2426,9 @@ "para_migrate": "Home Assistant kan legge til ID-er på alle kortene og visningene automatisk for deg ved å trykke på 'Migrer konfigurasjon' knappen.", "para_no_id": "Dette elementet har ingen ID. Vennligst legg til en ID på dette elementet i 'ui-lovelace.yaml'." }, + "move_card": { + "header": "Velg en visning du vil flytte kortet til" + }, "raw_editor": { "confirm_remove_config_text": "Vi vil automatisk opprette Lovelace-visningene dine med områdene og enhetene dine hvis du fjerner Lovelace-konfigurasjonen.", "confirm_remove_config_title": "Er du sikker på at du vil fjerne Lovelace-konfigurasjonen? Vi vil automatisk opprette Lovelace-visningene dine med områdene og enhetene dine.", @@ -2441,6 +2456,10 @@ "yaml_control": "Hvis du vil ta kontroll i YAML-modus, oppretter du en YAML-fil med navnet du angav i konfigurasjonen for dette instrumentbordet, eller standard 'ui-lovelace.yaml'.", "yaml_mode": "Du bruker YAML-modus for dette instrumentbordet, noe som betyr at du ikke kan endre Lovelace-konfigurasjonen fra brukergrensesnittet. Hvis du vil administrere dette instrumentbordet fra brukergrensesnittet, må du fjerne 'modus: yaml' fra Lovelace-konfigurasjonen i 'configuration.yaml'." }, + "select_view": { + "dashboard_label": "Dashboard", + "header": "Velg en visning" + }, "suggest_card": { "add": "Legg til i Lovelace brukergrensesnitt", "create_own": "Velg et annet kort", diff --git a/translations/frontend/pl.json b/translations/frontend/pl.json index 0bfe1d26fa..3f772729ec 100644 --- a/translations/frontend/pl.json +++ b/translations/frontend/pl.json @@ -1646,6 +1646,18 @@ "title": "MQTT", "topic": "temat" }, + "ozw": { + "common": { + "node_id": "Identyfikator węzła", + "ozw_instance": "Instancja OpenZWave", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Węzeł uszkodzony", + "stage": "Etap", + "zwave_info": "Informacje Z-Wave" + } + }, "person": { "add_person": "Dodaj osobę", "caption": "Osoby", @@ -2414,6 +2426,9 @@ "para_migrate": "Home Assistant może automatycznie dodać ID do wszystkich twoich kart i widoków, po kliknięciu przycisku \"Migracja konfiguracji\".", "para_no_id": "Ten element nie ma ID. Dodaj ID do tego elementu w \"ui-lovelace.yaml\"." }, + "move_card": { + "header": "Wybierz widok, do którego chcesz przenieść kartę" + }, "raw_editor": { "confirm_remove_config_text": "Jeśli usuniesz konfigurację interfejsu użytkownika Lovelace, widoki automatycznie będą generowane z obszarów i urządzeń.", "confirm_remove_config_title": "Na pewno chcesz usunąć konfigurację interfejsu użytkownika Lovelace? Widoki będą automatycznie generowane z obszarów i urządzeń.", @@ -2441,6 +2456,10 @@ "yaml_control": "Aby zarządzać w trybie YAML, utwórz plik o nazwie podanej w konfiguracji dla tego dashboardu lub domyślny 'ui-lovelace.yaml'.", "yaml_mode": "Używasz trybu YAML, co oznacza, że nie możesz zmienić konfiguracji Lovelace z poziomu interfejsu użytkownika. Jeśli chcesz zarządzać Lovelace z poziomu interfejsu użytkownika, usuń 'mode: yaml' z konfiguracji Lovelace w pliku 'configuration.yaml'." }, + "select_view": { + "dashboard_label": "Dashboard", + "header": "Wybierz widok" + }, "suggest_card": { "add": "Dodaj do interfejsu użytkownika Lovelace", "create_own": "Wybierz inną kartę", diff --git a/translations/frontend/pt.json b/translations/frontend/pt.json index 062a1d3098..911e0e5131 100644 --- a/translations/frontend/pt.json +++ b/translations/frontend/pt.json @@ -833,6 +833,15 @@ "name": "Ação", "type_select": "Tipo de ação", "type": { + "choose": { + "add_option": "Adicionar opção", + "conditions": "Condições", + "default": "Ações por defeito", + "label": "Escolha", + "option": "Opção {number}", + "remove_option": "Remover opção", + "sequence": "Ações" + }, "condition": { "label": "Condição" }, @@ -852,6 +861,24 @@ "label": "Disparar evento", "service_data": "Informação de Serviço" }, + "repeat": { + "label": "Repetir", + "sequence": "Ações", + "type_select": "Tipo de repetição", + "type": { + "count": { + "label": "Contagem" + }, + "until": { + "conditions": "Até que as condições", + "label": "Até" + }, + "while": { + "conditions": "Enquanto as condições", + "label": "Enquanto" + } + } + }, "scene": { "label": "Ativar cena" }, @@ -1619,6 +1646,16 @@ "title": "MQTT", "topic": "tópico" }, + "ozw": { + "common": { + "ozw_instance": "Instância OpenZWave", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Falha no nó", + "zwave_info": "Informações sobre Z-Wave" + } + }, "person": { "add_person": "Adicionar Pessoa", "caption": "Pessoas", @@ -2387,6 +2424,9 @@ "para_migrate": "Ao clicar no botão 'Migrar configuração', o Home Assistant pode adicionar IDs a todos os seus cartões e vistas automaticamente.", "para_no_id": "Este elemento não possui um ID. Por favor adicione um ID a este elemento em 'ui-lovelace.yaml'." }, + "move_card": { + "header": "Escolha uma vista para mover o cartão para" + }, "raw_editor": { "confirm_remove_config_text": "Iremos gerar automaticamente as suas vistas do Lovelace UI com as suas áreas e dispositivos se você remover a sua configuração do Lovelace UI.", "confirm_remove_config_title": "Tem a certeza que deseja remover a configuração do interface de utilizador do Lovelace? Iremos gerar automaticamente as suas vistas do IU Lovelace com as suas áreas e dispositivos.", @@ -2414,6 +2454,10 @@ "yaml_control": "Para assumir o controle no modo YAML, crie um ficheiro YAML com o nome que especificou na sua configuração para este painel de controle, ou o padrão 'ui-lovelace.yaml'.", "yaml_mode": "Está a usar o modo YAML para este painel, o que significa que não pode alterar a sua configuração Lovelace a partir da UI. Se quiser alterar este painel a partir da UI, remova 'mode: yaml' da configuração Lovelace em 'configuration.yaml'." }, + "select_view": { + "dashboard_label": "Painel de instrumentos", + "header": "Escolha uma vista" + }, "suggest_card": { "add": "Adicionar à Lovelace UI", "create_own": "Escolha um cartão diferente", @@ -2731,10 +2775,17 @@ "header": "Fechar automaticamente a conexão" }, "themes": { + "dark_mode": { + "auto": "Automático", + "dark": "Escuro", + "light": "Luz" + }, "dropdown_label": "Tema", "error_no_theme": "Não há temas disponíveis.", "header": "Tema", - "link_promo": "Saiba mais sobre temas" + "link_promo": "Saiba mais sobre temas", + "primary_color": "Cor primária", + "reset": "Redefinir" }, "vibrate": { "description": "Ative ou desative a vibração neste dispositivo ao controlar dispositivos.", diff --git a/translations/frontend/ru.json b/translations/frontend/ru.json index d24d9239d2..15337b2b0b 100644 --- a/translations/frontend/ru.json +++ b/translations/frontend/ru.json @@ -1627,6 +1627,18 @@ "title": "MQTT", "topic": "Топик" }, + "ozw": { + "common": { + "node_id": "ID узла", + "ozw_instance": "Экземпляр OpenZWave", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Ошибка узла", + "stage": "Этап", + "zwave_info": "Информация о Z-Wave" + } + }, "person": { "add_person": "Добавить персону", "caption": "Люди", @@ -2395,6 +2407,9 @@ "para_migrate": "Home Assistant может автоматически добавить ID для всех карточек и вкладок, если нажать кнопку 'Перенести настройки'.", "para_no_id": "Этот элемент не имеет ID. Добавьте ID для этого элемента в 'ui-lovelace.yaml'." }, + "move_card": { + "header": "На какую вкладку нужно переместить карточку?" + }, "raw_editor": { "confirm_remove_config_text": "Если Вы очистите конфигурацию этой панели Lovelace, карточки с Вашими устройствами и помещениями будут создаваться автоматически.", "confirm_remove_config_title": "Очистить конфигурацию?", @@ -2422,6 +2437,10 @@ "yaml_control": "Чтобы получить контроль в режиме YAML, создайте файл с именем, указанным в настройках этой панели (по умолчанию 'ui-lovelace.yaml').", "yaml_mode": "Эта панель Lovelace используется в режиме YAML. В этом режиме невозможно использовать визуальный редактор интерфейса. Если Вы всё же хотите редактировать конфигурацию этой панели из пользовательского интерфейса, удалите строку 'mode: yaml' из раздела Lovelace в файле configuration.yaml." }, + "select_view": { + "dashboard_label": "Панель", + "header": "Выберите вкладку" + }, "suggest_card": { "add": "Подтвердить", "create_own": "Изменить", diff --git a/translations/frontend/sv.json b/translations/frontend/sv.json index f7212100d2..b69e34e610 100644 --- a/translations/frontend/sv.json +++ b/translations/frontend/sv.json @@ -1646,6 +1646,18 @@ "title": "MQTT", "topic": "ämne" }, + "ozw": { + "common": { + "node_id": "Nod-ID", + "ozw_instance": "OpenZWave-instans", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Noden misslyckades", + "stage": "Steg", + "zwave_info": "Z-Wave info" + } + }, "person": { "add_person": "Lägg till person", "caption": "Personer", @@ -2414,6 +2426,9 @@ "para_migrate": "Home Assistant kan automatiskt lägga till ID:n till alla dina kort och vyer genom att du klickar på \"Migrera konfiguration\".", "para_no_id": "Det här elementet har inget ID. Lägg till ett ID till det här elementet i \"ui-lovelace.yaml\"." }, + "move_card": { + "header": "Välj en vy att flytta kortet till" + }, "raw_editor": { "confirm_remove_config_text": "Vi kommer automatiskt att generera dina Lovelace UI-vyer med dina områden och enheter om du tar bort din Lovelace UI-konfiguration.", "confirm_remove_config_title": "Är du säker på att du vill ta bort din Lovelace UI konfiguration? Vi kommer automatiskt att generera dina Lovelace UI-vyer med dina områden och enheter.", @@ -2441,6 +2456,10 @@ "yaml_control": "Om du vill ta kontroll i YAML-läge skapar du en YAML-fil med det namn du angav i konfigurationen för den här instrumentpanelen eller standard \"ui-lovelace.yaml\".", "yaml_mode": "Du använder YAML-läge, vilket betyder att du inte kan ändra dina Lovelace-inställning från användargränssnittet. Om du vill hantera Lovelace från användargränssnittet, ta bort 'mode: yaml' från din Lovelace-inställning i 'configuration.yaml'" }, + "select_view": { + "dashboard_label": "Instrumentpanel", + "header": "Välj en vy" + }, "suggest_card": { "add": "Lägg till i Lovelace-gränsnitt", "create_own": "Välj annat kort", diff --git a/translations/frontend/zh-Hans.json b/translations/frontend/zh-Hans.json index bc6c0aa2ef..6101afd109 100644 --- a/translations/frontend/zh-Hans.json +++ b/translations/frontend/zh-Hans.json @@ -1646,6 +1646,18 @@ "title": "MQTT", "topic": "主题(Topic)" }, + "ozw": { + "common": { + "node_id": "节点 ID", + "ozw_instance": "OpenZWave 实例", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "节点故障", + "stage": "阶段", + "zwave_info": "Z-Wave 信息" + } + }, "person": { "add_person": "添加人员", "caption": "人员", @@ -2414,6 +2426,9 @@ "para_migrate": "通过点击“迁移配置”按钮,Home Assistant 可以自动为您的所有卡片和视图添加 ID。", "para_no_id": "此元素没有 ID。请在 'ui-lovelace.yaml' 中为此元素添加 ID。" }, + "move_card": { + "header": "选择要将卡片移动到哪个视图" + }, "raw_editor": { "confirm_remove_config_text": "如果您删除了 Lovelace 配置,我们将通过您的区域和设备自动生成 Lovelace 视图。", "confirm_remove_config_title": "您确定要删除 Lovelace 配置吗?我们将通过您的区域和设备自动生成 Lovelace 视图。", @@ -2441,6 +2456,10 @@ "yaml_control": "要以 YAML 模式下自行编辑,请创建 YAML 文件并命名为在配置中为此仪表盘指定的名称,或使用默认的 'ui-lovelace.yaml'。", "yaml_mode": "此仪表盘正在使用 YAML 模式,因此无法从 UI 更改 Lovelace 配置。若要从 UI 管理此仪表盘,请从 'configuration.yaml' 中的 Lovelace 配置中删除 'mode: yaml'。" }, + "select_view": { + "dashboard_label": "仪表盘", + "header": "选择视图" + }, "suggest_card": { "add": "添加至 Lovelace UI", "create_own": "选择其他卡片", diff --git a/translations/frontend/zh-Hant.json b/translations/frontend/zh-Hant.json index 27e391707f..d0be0db91b 100644 --- a/translations/frontend/zh-Hant.json +++ b/translations/frontend/zh-Hant.json @@ -833,6 +833,15 @@ "name": "動作", "type_select": "觸發後動作類別", "type": { + "choose": { + "add_option": "新增選項", + "conditions": "觸發條件", + "default": "預設觸發動作", + "label": "選擇", + "option": "選項 {number}", + "remove_option": "移除選項", + "sequence": "觸發後動作" + }, "condition": { "label": "判斷式" }, @@ -852,6 +861,24 @@ "label": "執行事件", "service_data": "資料" }, + "repeat": { + "label": "重複", + "sequence": "觸發後動作", + "type_select": "重複類型", + "type": { + "count": { + "label": "計次" + }, + "until": { + "conditions": "直到條件發生", + "label": "直到" + }, + "while": { + "conditions": "當條件發生", + "label": "當" + } + } + }, "scene": { "label": "啟用場景" }, @@ -1619,6 +1646,18 @@ "title": "MQTT", "topic": "主題" }, + "ozw": { + "common": { + "node_id": "節點 ID", + "ozw_instance": "OpenZWave 設備", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "節點失敗", + "stage": "階段", + "zwave_info": "Z-Wave 資訊" + } + }, "person": { "add_person": "新增人員", "caption": "人員", @@ -2387,6 +2426,9 @@ "para_migrate": "Home Assistant 能於您點選「遷移設定」按鈕後,自動新增 ID 與視圖至所有面板。", "para_no_id": "該元件未含 ID,請於「ui-lovelace.yaml」中為該元件新增 ID。" }, + "move_card": { + "header": "移動至哪個面板" + }, "raw_editor": { "confirm_remove_config_text": "假如移除 Lovelace UI 設定的話,將自動以區域與設備產生 Lovelace UI 視圖。", "confirm_remove_config_title": "確定要移除 Lovelace UI 設定?將依據區域與設備自動產生 Lovelace UI 視圖。", @@ -2414,6 +2456,10 @@ "yaml_control": "欲使用 YAML 進行控制、新增一個與此主面板相同名稱的 YAML 檔案、或者預設為「ui-lovelace.yaml」。", "yaml_mode": "正使用 YAML 模式、表示您無法藉由 UI 變更 Lovelace 設定。假如您想由 UI 中進行變更、請於「configuration.yaml」檔案中移除 'mode: yaml' 參數。" }, + "select_view": { + "dashboard_label": "主面板", + "header": "選擇面板" + }, "suggest_card": { "add": "新增至 Lovelace UI", "create_own": "選擇其他面板", @@ -2731,10 +2777,18 @@ "header": "自動關閉連線" }, "themes": { + "accent_color": "加重顏色", + "dark_mode": { + "auto": "自動", + "dark": "深色", + "light": "淡色" + }, "dropdown_label": "主題", "error_no_theme": "無主題可使用。", "header": "主題", - "link_promo": "關於此主題" + "link_promo": "關於此主題", + "primary_color": "主色彩", + "reset": "重置" }, "vibrate": { "description": "當控制裝置時、開啟或關閉此裝置震動。",