mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-01 13:37:47 +00:00
commit
8dd44bca32
2
setup.py
2
setup.py
@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name="home-assistant-frontend",
|
||||
version="20190719.0",
|
||||
version="20190720.0",
|
||||
description="The Home Assistant frontend",
|
||||
url="https://github.com/home-assistant/home-assistant-polymer",
|
||||
author="The Home Assistant Authors",
|
||||
|
@ -39,7 +39,7 @@ class HaClimateState extends LocalizeMixin(PolymerElement) {
|
||||
<div class="target">
|
||||
<template is="dom-if" if="[[_hasKnownState(stateObj.state)]]">
|
||||
<span class="state-label">
|
||||
[[_localizeState(localize, stateObj.state)]]
|
||||
[[_localizeState(localize, stateObj)]]
|
||||
<template is="dom-if" if="[[stateObj.attributes.preset_mode]]">
|
||||
- [[_localizePreset(localize, stateObj.attributes.preset_mode)]]
|
||||
</template>
|
||||
@ -116,8 +116,15 @@ class HaClimateState extends LocalizeMixin(PolymerElement) {
|
||||
return state !== "unknown";
|
||||
}
|
||||
|
||||
_localizeState(localize, state) {
|
||||
return localize(`state.climate.${state}`) || state;
|
||||
_localizeState(localize, stateObj) {
|
||||
const stateString = localize(`state.climate.${stateObj.state}`);
|
||||
return stateObj.attributes.hvac_action
|
||||
? `${localize(
|
||||
`state_attributes.climate.hvac_action.${
|
||||
stateObj.attributes.hvac_action
|
||||
}`
|
||||
)} (${stateString})`
|
||||
: stateString;
|
||||
}
|
||||
|
||||
_localizePreset(localize, preset) {
|
||||
|
@ -78,14 +78,25 @@ class HaMenuButton extends LitElement {
|
||||
protected updated(changedProps) {
|
||||
super.updated(changedProps);
|
||||
|
||||
if (!changedProps.has("narrow")) {
|
||||
if (!changedProps.has("narrow") && !changedProps.has("hass")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
const oldNarrow =
|
||||
changedProps.get("narrow") ||
|
||||
(oldHass && oldHass.dockedSidebar === "always_hidden");
|
||||
const newNarrow =
|
||||
this.narrow || this.hass.dockedSidebar === "always_hidden";
|
||||
|
||||
if (oldNarrow === newNarrow) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.style.visibility =
|
||||
this.narrow || this._alwaysVisible ? "initial" : "hidden";
|
||||
newNarrow || this._alwaysVisible ? "initial" : "hidden";
|
||||
|
||||
if (!this.narrow) {
|
||||
if (!newNarrow) {
|
||||
this._hasNotifications = false;
|
||||
if (this._unsubNotifications) {
|
||||
this._unsubNotifications();
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
css,
|
||||
PropertyValues,
|
||||
property,
|
||||
eventOptions,
|
||||
} from "lit-element";
|
||||
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
@ -28,11 +29,11 @@ import {
|
||||
} from "../data/persistent_notification";
|
||||
import computeDomain from "../common/entity/compute_domain";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
// tslint:disable-next-line: no-duplicate-imports
|
||||
import { PaperIconItemElement } from "@polymer/paper-item/paper-icon-item";
|
||||
|
||||
const SHOW_AFTER_SPACER = ["config", "developer-tools"];
|
||||
|
||||
const computeUrl = (urlPath) => `/${urlPath}`;
|
||||
|
||||
const SUPPORT_SCROLL_IF_NEEDED = "scrollIntoViewIfNeeded" in document.body;
|
||||
|
||||
const SORT_VALUE = {
|
||||
@ -91,22 +92,6 @@ const computePanels = (hass: HomeAssistant): [PanelInfo[], PanelInfo[]] => {
|
||||
return [beforeSpacer, afterSpacer];
|
||||
};
|
||||
|
||||
const renderPanel = (hass, panel) => html`
|
||||
<a
|
||||
aria-role="option"
|
||||
href="${computeUrl(panel.url_path)}"
|
||||
data-panel="${panel.url_path}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<paper-icon-item>
|
||||
<ha-icon slot="item-icon" .icon="${panel.icon}"></ha-icon>
|
||||
<span class="item-text">
|
||||
${hass.localize(`panel.${panel.title}`) || panel.title}
|
||||
</span>
|
||||
</paper-icon-item>
|
||||
</a>
|
||||
`;
|
||||
|
||||
/*
|
||||
* @appliesMixin LocalizeMixin
|
||||
*/
|
||||
@ -116,13 +101,14 @@ class HaSidebar extends LitElement {
|
||||
|
||||
@property({ type: Boolean }) public alwaysExpand = false;
|
||||
@property({ type: Boolean, reflect: true }) public expanded = false;
|
||||
@property({ type: Boolean, reflect: true }) public expandedWidth = false;
|
||||
@property() public _defaultPage?: string =
|
||||
localStorage.defaultPage || DEFAULT_PANEL;
|
||||
@property() private _externalConfig?: ExternalConfig;
|
||||
@property() private _notifications?: PersistentNotification[];
|
||||
private _expandTimeout?: number;
|
||||
private _contractTimeout?: number;
|
||||
|
||||
private _mouseLeaveTimeout?: number;
|
||||
private _tooltipHideTimeout?: number;
|
||||
private _recentKeydownActiveUntil = 0;
|
||||
|
||||
protected render() {
|
||||
const hass = this.hass;
|
||||
@ -148,30 +134,44 @@ class HaSidebar extends LitElement {
|
||||
? html`
|
||||
<paper-icon-button
|
||||
aria-label="Sidebar Toggle"
|
||||
.icon=${hass.dockedSidebar ? "hass:menu-open" : "hass:menu"}
|
||||
.icon=${hass.dockedSidebar === "docked"
|
||||
? "hass:menu-open"
|
||||
: "hass:menu"}
|
||||
@click=${this._toggleSidebar}
|
||||
></paper-icon-button>
|
||||
`
|
||||
: ""}
|
||||
<span class="title">Home Assistant</span>
|
||||
</div>
|
||||
<paper-listbox attr-for-selected="data-panel" .selected=${hass.panelUrl}>
|
||||
<a
|
||||
aria-role="option"
|
||||
href="${computeUrl(this._defaultPage)}"
|
||||
data-panel=${this._defaultPage}
|
||||
tabindex="-1"
|
||||
>
|
||||
<paper-icon-item>
|
||||
<ha-icon slot="item-icon" icon="hass:apps"></ha-icon>
|
||||
<span class="item-text">${hass.localize("panel.states")}</span>
|
||||
</paper-icon-item>
|
||||
</a>
|
||||
|
||||
${beforeSpacer.map((panel) => renderPanel(hass, panel))}
|
||||
<paper-listbox
|
||||
attr-for-selected="data-panel"
|
||||
.selected=${hass.panelUrl}
|
||||
@focusin=${this._listboxFocusIn}
|
||||
@focusout=${this._listboxFocusOut}
|
||||
@scroll=${this._listboxScroll}
|
||||
@keydown=${this._listboxKeydown}
|
||||
>
|
||||
${this._renderPanel(
|
||||
this._defaultPage,
|
||||
"hass:apps",
|
||||
hass.localize("panel.states")
|
||||
)}
|
||||
${beforeSpacer.map((panel) =>
|
||||
this._renderPanel(
|
||||
panel.url_path,
|
||||
panel.icon,
|
||||
hass.localize(`panel.${panel.title}`) || panel.title
|
||||
)
|
||||
)}
|
||||
<div class="spacer" disabled></div>
|
||||
|
||||
${afterSpacer.map((panel) => renderPanel(hass, panel))}
|
||||
${afterSpacer.map((panel) =>
|
||||
this._renderPanel(
|
||||
panel.url_path,
|
||||
panel.icon,
|
||||
hass.localize(`panel.${panel.title}`) || panel.title
|
||||
)
|
||||
)}
|
||||
${this._externalConfig && this._externalConfig.hasSettingsScreen
|
||||
? html`
|
||||
<a
|
||||
@ -181,7 +181,10 @@ class HaSidebar extends LitElement {
|
||||
tabindex="-1"
|
||||
@click=${this._handleExternalAppConfiguration}
|
||||
>
|
||||
<paper-icon-item>
|
||||
<paper-icon-item
|
||||
@mouseenter=${this._itemMouseEnter}
|
||||
@mouseleave=${this._itemMouseLeave}
|
||||
>
|
||||
<ha-icon
|
||||
slot="item-icon"
|
||||
icon="hass:cellphone-settings-variant"
|
||||
@ -201,9 +204,11 @@ class HaSidebar extends LitElement {
|
||||
class="notifications"
|
||||
aria-role="option"
|
||||
@click=${this._handleShowNotificationDrawer}
|
||||
@mouseenter=${this._itemMouseEnter}
|
||||
@mouseleave=${this._itemMouseLeave}
|
||||
>
|
||||
<ha-icon slot="item-icon" icon="hass:bell"></ha-icon>
|
||||
${notificationCount > 0
|
||||
${!this.expanded && notificationCount > 0
|
||||
? html`
|
||||
<span class="notification-badge" slot="item-icon">
|
||||
${notificationCount}
|
||||
@ -213,6 +218,11 @@ class HaSidebar extends LitElement {
|
||||
<span class="item-text">
|
||||
${hass.localize("ui.notification_drawer.title")}
|
||||
</span>
|
||||
${this.expanded && notificationCount > 0
|
||||
? html`
|
||||
<span class="notification-badge">${notificationCount}</span>
|
||||
`
|
||||
: ""}
|
||||
</paper-icon-item>
|
||||
|
||||
<a
|
||||
@ -227,7 +237,10 @@ class HaSidebar extends LitElement {
|
||||
aria-role="option"
|
||||
aria-label=${hass.localize("panel.profile")}
|
||||
>
|
||||
<paper-icon-item>
|
||||
<paper-icon-item
|
||||
@mouseenter=${this._itemMouseEnter}
|
||||
@mouseleave=${this._itemMouseLeave}
|
||||
>
|
||||
<ha-user-badge slot="item-icon" .user=${hass.user}></ha-user-badge>
|
||||
|
||||
<span class="item-text">
|
||||
@ -236,13 +249,13 @@ class HaSidebar extends LitElement {
|
||||
</paper-icon-item>
|
||||
</a>
|
||||
<div disabled class="bottom-spacer"></div>
|
||||
<div class="tooltip"></div>
|
||||
`;
|
||||
}
|
||||
|
||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||
if (
|
||||
changedProps.has("expanded") ||
|
||||
changedProps.has("expandedWidth") ||
|
||||
changedProps.has("narrow") ||
|
||||
changedProps.has("alwaysExpand") ||
|
||||
changedProps.has("_externalConfig") ||
|
||||
@ -275,21 +288,6 @@ class HaSidebar extends LitElement {
|
||||
this._externalConfig = conf;
|
||||
});
|
||||
}
|
||||
// On tablets, there is no hover. So we receive click and mouseenter at the
|
||||
// same time. In that case, we're going to cancel expanding, because it is
|
||||
// going to require another tap outside the sidebar to trigger mouseleave
|
||||
this.addEventListener("click", () => {
|
||||
if (this._expandTimeout) {
|
||||
clearTimeout(this._expandTimeout);
|
||||
this._expandTimeout = undefined;
|
||||
}
|
||||
});
|
||||
this.addEventListener("mouseenter", () => {
|
||||
this._expand();
|
||||
});
|
||||
this.addEventListener("mouseleave", () => {
|
||||
this._contract();
|
||||
});
|
||||
subscribeNotifications(this.hass.connection, (notifications) => {
|
||||
this._notifications = notifications;
|
||||
});
|
||||
@ -297,9 +295,8 @@ class HaSidebar extends LitElement {
|
||||
|
||||
protected updated(changedProps) {
|
||||
super.updated(changedProps);
|
||||
if (changedProps.has("alwaysExpand") && this.alwaysExpand) {
|
||||
this.expanded = true;
|
||||
this.expandedWidth = true;
|
||||
if (changedProps.has("alwaysExpand")) {
|
||||
this.expanded = this.alwaysExpand;
|
||||
}
|
||||
if (!SUPPORT_SCROLL_IF_NEEDED || !changedProps.has("hass")) {
|
||||
return;
|
||||
@ -314,31 +311,89 @@ class HaSidebar extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _expand() {
|
||||
// We debounce it one frame, because on tablets, the mouse-enter and
|
||||
// click event fire at the same time.
|
||||
this._expandTimeout = window.setTimeout(() => {
|
||||
this.expanded = true;
|
||||
this.expandedWidth = true;
|
||||
}, 0);
|
||||
if (this._contractTimeout) {
|
||||
clearTimeout(this._contractTimeout);
|
||||
this._contractTimeout = undefined;
|
||||
}
|
||||
private get _tooltip() {
|
||||
return this.shadowRoot!.querySelector(".tooltip")! as HTMLDivElement;
|
||||
}
|
||||
|
||||
private _contract() {
|
||||
if (this._expandTimeout) {
|
||||
clearTimeout(this._expandTimeout);
|
||||
this._expandTimeout = undefined;
|
||||
}
|
||||
if (this.alwaysExpand) {
|
||||
private _itemMouseEnter(ev: MouseEvent) {
|
||||
// On keypresses on the listbox, we're going to ignore mouse enter events
|
||||
// for 100ms so that we ignore it when pressing down arrow scrolls the
|
||||
// sidebar causing the mouse to hover a new icon
|
||||
if (
|
||||
this.expanded ||
|
||||
new Date().getTime() < this._recentKeydownActiveUntil
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.expandedWidth = false;
|
||||
this._contractTimeout = window.setTimeout(() => {
|
||||
this.expanded = this.alwaysExpand || false;
|
||||
}, 400);
|
||||
if (this._mouseLeaveTimeout) {
|
||||
clearTimeout(this._mouseLeaveTimeout);
|
||||
this._mouseLeaveTimeout = undefined;
|
||||
}
|
||||
this._showTooltip(ev.currentTarget as PaperIconItemElement);
|
||||
}
|
||||
|
||||
private _itemMouseLeave() {
|
||||
if (this._mouseLeaveTimeout) {
|
||||
clearTimeout(this._mouseLeaveTimeout);
|
||||
}
|
||||
this._mouseLeaveTimeout = window.setTimeout(() => {
|
||||
this._hideTooltip();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
private _listboxFocusIn(ev) {
|
||||
if (this.expanded || ev.target.nodeName !== "A") {
|
||||
return;
|
||||
}
|
||||
this._showTooltip(ev.target.querySelector("paper-icon-item"));
|
||||
}
|
||||
|
||||
private _listboxFocusOut() {
|
||||
this._hideTooltip();
|
||||
}
|
||||
|
||||
@eventOptions({
|
||||
passive: true,
|
||||
})
|
||||
private _listboxScroll() {
|
||||
// On keypresses on the listbox, we're going to ignore scroll events
|
||||
// for 100ms so that if pressing down arrow scrolls the sidebar, the tooltip
|
||||
// will not be hidden.
|
||||
if (new Date().getTime() < this._recentKeydownActiveUntil) {
|
||||
return;
|
||||
}
|
||||
this._hideTooltip();
|
||||
}
|
||||
|
||||
private _listboxKeydown() {
|
||||
this._recentKeydownActiveUntil = new Date().getTime() + 100;
|
||||
}
|
||||
|
||||
private _showTooltip(item: PaperIconItemElement) {
|
||||
if (this._tooltipHideTimeout) {
|
||||
clearTimeout(this._tooltipHideTimeout);
|
||||
this._tooltipHideTimeout = undefined;
|
||||
}
|
||||
const tooltip = this._tooltip;
|
||||
const listbox = this.shadowRoot!.querySelector("paper-listbox")!;
|
||||
let top = item.offsetTop + 7;
|
||||
if (listbox.contains(item)) {
|
||||
top -= listbox.scrollTop;
|
||||
}
|
||||
tooltip.innerHTML = item.querySelector(".item-text")!.innerHTML;
|
||||
tooltip.style.display = "block";
|
||||
tooltip.style.top = `${top}px`;
|
||||
tooltip.style.left = `${item.offsetLeft + item.clientWidth + 12}px`;
|
||||
}
|
||||
|
||||
private _hideTooltip() {
|
||||
// Delay it a little in case other events are pending processing.
|
||||
if (!this._tooltipHideTimeout) {
|
||||
this._tooltipHideTimeout = window.setTimeout(() => {
|
||||
this._tooltipHideTimeout = undefined;
|
||||
this._tooltip.style.display = "none";
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
|
||||
private _handleShowNotificationDrawer() {
|
||||
@ -356,6 +411,25 @@ class HaSidebar extends LitElement {
|
||||
fireEvent(this, "hass-toggle-menu");
|
||||
}
|
||||
|
||||
private _renderPanel(urlPath, icon, title) {
|
||||
return html`
|
||||
<a
|
||||
aria-role="option"
|
||||
href="${`/${urlPath}`}"
|
||||
data-panel="${urlPath}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<paper-icon-item
|
||||
@mouseenter=${this._itemMouseEnter}
|
||||
@mouseleave=${this._itemMouseLeave}
|
||||
>
|
||||
<ha-icon slot="item-icon" .icon="${icon}"></ha-icon>
|
||||
<span class="item-text">${title}</span>
|
||||
</paper-icon-item>
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
:host {
|
||||
@ -366,17 +440,10 @@ class HaSidebar extends LitElement {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
border-right: 1px solid var(--divider-color);
|
||||
background-color: var(
|
||||
--sidebar-background-color,
|
||||
var(--primary-background-color)
|
||||
);
|
||||
background-color: var(--sidebar-background-color);
|
||||
width: 64px;
|
||||
transition: width 0.2s ease-in;
|
||||
will-change: width;
|
||||
contain: strict;
|
||||
transition-delay: 0.2s;
|
||||
}
|
||||
:host([expandedwidth]) {
|
||||
:host([expanded]) {
|
||||
width: 256px;
|
||||
}
|
||||
|
||||
@ -512,6 +579,9 @@ class HaSidebar extends LitElement {
|
||||
.notifications {
|
||||
cursor: pointer;
|
||||
}
|
||||
.notifications .item-text {
|
||||
flex: 1;
|
||||
}
|
||||
.profile {
|
||||
}
|
||||
.profile paper-icon-item {
|
||||
@ -522,19 +592,22 @@ class HaSidebar extends LitElement {
|
||||
}
|
||||
|
||||
.notification-badge {
|
||||
position: absolute;
|
||||
font-weight: 400;
|
||||
bottom: 14px;
|
||||
left: 26px;
|
||||
min-width: 20px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 50%;
|
||||
font-weight: 400;
|
||||
background-color: var(--primary-color);
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
padding: 0px 6px;
|
||||
font-size: 0.65em;
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
ha-icon + .notification-badge {
|
||||
position: absolute;
|
||||
bottom: 14px;
|
||||
left: 26px;
|
||||
font-size: 0.65em;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex: 1;
|
||||
@ -561,6 +634,18 @@ class HaSidebar extends LitElement {
|
||||
.dev-tools a {
|
||||
color: var(--sidebar-icon-color);
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
display: none;
|
||||
position: absolute;
|
||||
opacity: 0.9;
|
||||
border-radius: 2px;
|
||||
white-space: nowrap;
|
||||
color: var(--sidebar-background-color);
|
||||
background-color: var(--sidebar-text-color);
|
||||
padding: 4px;
|
||||
font-weight: 500;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@ -49,3 +49,16 @@ export const CLIMATE_SUPPORT_FAN_MODE = 8;
|
||||
export const CLIMATE_SUPPORT_PRESET_MODE = 16;
|
||||
export const CLIMATE_SUPPORT_SWING_MODE = 32;
|
||||
export const CLIMATE_SUPPORT_AUX_HEAT = 64;
|
||||
|
||||
const hvacModeOrdering: { [key in HvacMode]: number } = {
|
||||
auto: 1,
|
||||
heat_cool: 2,
|
||||
heat: 3,
|
||||
cool: 4,
|
||||
dry: 5,
|
||||
fan_only: 6,
|
||||
off: 7,
|
||||
};
|
||||
|
||||
export const compareClimateHvacModes = (mode1: HvacMode, mode2: HvacMode) =>
|
||||
hvacModeOrdering[mode1] - hvacModeOrdering[mode2];
|
||||
|
@ -29,6 +29,7 @@ import {
|
||||
CLIMATE_SUPPORT_SWING_MODE,
|
||||
CLIMATE_SUPPORT_AUX_HEAT,
|
||||
CLIMATE_SUPPORT_PRESET_MODE,
|
||||
compareClimateHvacModes,
|
||||
} from "../../../data/climate";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
@ -176,13 +177,16 @@ class MoreInfoClimate extends LitElement {
|
||||
.selected=${stateObj.state}
|
||||
@selected-changed=${this._handleOperationmodeChanged}
|
||||
>
|
||||
${stateObj.attributes.hvac_modes.map(
|
||||
(mode) => html`
|
||||
<paper-item item-name=${mode}>
|
||||
${hass.localize(`state.climate.${mode}`)}
|
||||
</paper-item>
|
||||
`
|
||||
)}
|
||||
${stateObj.attributes.hvac_modes
|
||||
.concat()
|
||||
.sort(compareClimateHvacModes)
|
||||
.map(
|
||||
(mode) => html`
|
||||
<paper-item item-name=${mode}>
|
||||
${hass.localize(`state.climate.${mode}`)}
|
||||
</paper-item>
|
||||
`
|
||||
)}
|
||||
</paper-listbox>
|
||||
</ha-paper-dropdown-menu>
|
||||
</div>
|
||||
@ -202,11 +206,6 @@ class MoreInfoClimate extends LitElement {
|
||||
.selected=${stateObj.attributes.preset_mode}
|
||||
@selected-changed=${this._handlePresetmodeChanged}
|
||||
>
|
||||
<paper-item item-name="">
|
||||
${hass.localize(
|
||||
`state_attributes.climate.preset_mode.none`
|
||||
)}
|
||||
</paper-item>
|
||||
${stateObj.attributes.preset_modes!.map(
|
||||
(mode) => html`
|
||||
<paper-item item-name=${mode}>
|
||||
|
@ -159,7 +159,7 @@ export const provideHass = (
|
||||
localize: () => "",
|
||||
|
||||
translationMetadata: translationMetadata as any,
|
||||
dockedSidebar: false,
|
||||
dockedSidebar: "auto",
|
||||
moreInfoEntityId: null as any,
|
||||
async callService(domain, service, data) {
|
||||
if (data && "entity_id" in data) {
|
||||
|
@ -44,8 +44,11 @@ class HomeAssistantMain extends LitElement {
|
||||
return;
|
||||
}
|
||||
|
||||
const sidebarNarrow =
|
||||
this.narrow || this.hass.dockedSidebar === "always_hidden";
|
||||
|
||||
const disableSwipe =
|
||||
!this.narrow || NON_SWIPABLE_PANELS.indexOf(hass.panelUrl) !== -1;
|
||||
!sidebarNarrow || NON_SWIPABLE_PANELS.indexOf(hass.panelUrl) !== -1;
|
||||
|
||||
return html`
|
||||
<iron-media-query
|
||||
@ -55,7 +58,7 @@ class HomeAssistantMain extends LitElement {
|
||||
|
||||
<app-drawer-layout
|
||||
fullbleed
|
||||
.forceNarrow=${this.narrow}
|
||||
.forceNarrow=${sidebarNarrow}
|
||||
responsive-width="0"
|
||||
>
|
||||
<app-drawer
|
||||
@ -64,12 +67,14 @@ class HomeAssistantMain extends LitElement {
|
||||
slot="drawer"
|
||||
.disableSwipe=${disableSwipe}
|
||||
.swipeOpen=${!disableSwipe}
|
||||
.persistent=${!this.narrow}
|
||||
.persistent=${!this.narrow &&
|
||||
this.hass.dockedSidebar !== "always_hidden"}
|
||||
>
|
||||
<ha-sidebar
|
||||
.hass=${hass}
|
||||
.narrow=${this.narrow}
|
||||
.alwaysExpand=${this.narrow || hass.dockedSidebar}
|
||||
.narrow=${sidebarNarrow}
|
||||
.alwaysExpand=${sidebarNarrow ||
|
||||
this.hass.dockedSidebar === "docked"}
|
||||
></ha-sidebar>
|
||||
</app-drawer>
|
||||
|
||||
@ -86,7 +91,7 @@ class HomeAssistantMain extends LitElement {
|
||||
import(/* webpackChunkName: "ha-sidebar" */ "../components/ha-sidebar");
|
||||
|
||||
this.addEventListener("hass-toggle-menu", () => {
|
||||
if (this.narrow) {
|
||||
if (this.narrow || this.hass.dockedSidebar === "always_hidden") {
|
||||
if (this.drawer.opened) {
|
||||
this.drawer.close();
|
||||
} else {
|
||||
@ -94,7 +99,7 @@ class HomeAssistantMain extends LitElement {
|
||||
}
|
||||
} else {
|
||||
fireEvent(this, "hass-dock-sidebar", {
|
||||
dock: !this.hass.dockedSidebar,
|
||||
dock: this.hass.dockedSidebar === "auto" ? "docked" : "auto",
|
||||
});
|
||||
setTimeout(() => this.appLayout.resetLayout());
|
||||
}
|
||||
@ -110,7 +115,10 @@ class HomeAssistantMain extends LitElement {
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
super.updated(changedProps);
|
||||
|
||||
this.toggleAttribute("expanded", this.narrow || this.hass.dockedSidebar);
|
||||
this.toggleAttribute(
|
||||
"expanded",
|
||||
this.narrow || this.hass.dockedSidebar !== "auto"
|
||||
);
|
||||
|
||||
if (changedProps.has("route") && this.narrow) {
|
||||
this.drawer.close();
|
||||
|
@ -146,7 +146,8 @@ class HaPanelConfig extends HassRouterPage {
|
||||
const showAdvanced = !!(
|
||||
this._coreUserData && this._coreUserData.showAdvanced
|
||||
);
|
||||
const isWide = this.hass.dockedSidebar ? this._wideSidebar : this._wide;
|
||||
const isWide =
|
||||
this.hass.dockedSidebar === "docked" ? this._wideSidebar : this._wide;
|
||||
|
||||
if ("setProperties" in el) {
|
||||
// As long as we have Polymer panels
|
||||
|
@ -2,7 +2,6 @@ import "../../../layouts/hass-loading-screen";
|
||||
|
||||
import { customElement, property } from "lit-element";
|
||||
|
||||
import { listenMediaQuery } from "../../../common/dom/media_query";
|
||||
import {
|
||||
HassRouterPage,
|
||||
RouterOptions,
|
||||
@ -12,8 +11,7 @@ import { HomeAssistant } from "../../../types";
|
||||
@customElement("zha-config-panel")
|
||||
class ZHAConfigPanel extends HassRouterPage {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public _wideSidebar: boolean = false;
|
||||
@property() public _wide: boolean = false;
|
||||
@property() public isWide!: boolean;
|
||||
|
||||
protected routerOptions: RouterOptions = {
|
||||
defaultPage: "configuration",
|
||||
@ -33,33 +31,10 @@ class ZHAConfigPanel extends HassRouterPage {
|
||||
},
|
||||
};
|
||||
|
||||
private _listeners: Array<() => void> = [];
|
||||
|
||||
public connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
this._listeners.push(
|
||||
listenMediaQuery("(min-width: 1040px)", (matches) => {
|
||||
this._wide = matches;
|
||||
})
|
||||
);
|
||||
this._listeners.push(
|
||||
listenMediaQuery("(min-width: 1296px)", (matches) => {
|
||||
this._wideSidebar = matches;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public disconnectedCallback(): void {
|
||||
super.disconnectedCallback();
|
||||
while (this._listeners.length) {
|
||||
this._listeners.pop()!();
|
||||
}
|
||||
}
|
||||
|
||||
protected updatePageEl(el): void {
|
||||
el.route = this.routeTail;
|
||||
el.hass = this.hass;
|
||||
el.isWide = this.hass.dockedSidebar ? this._wideSidebar : this._wide;
|
||||
el.isWide = this.isWide;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,11 @@ import { loadRoundslider } from "../../../resources/jquery.roundslider.ondemand"
|
||||
import { UNIT_F } from "../../../common/const";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { ThermostatCardConfig } from "./types";
|
||||
import { ClimateEntity, HvacMode } from "../../../data/climate";
|
||||
import {
|
||||
ClimateEntity,
|
||||
HvacMode,
|
||||
compareClimateHvacModes,
|
||||
} from "../../../data/climate";
|
||||
|
||||
const thermostatConfig = {
|
||||
radius: 150,
|
||||
@ -144,7 +148,13 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
|
||||
<div class="climate-info">
|
||||
<div id="set-temperature"></div>
|
||||
<div class="current-mode">
|
||||
${this.hass!.localize(`state.climate.${stateObj.state}`)}
|
||||
${stateObj.attributes.hvac_action
|
||||
? this.hass!.localize(
|
||||
`state_attributes.climate.hvac_action.${
|
||||
stateObj.attributes.hvac_action
|
||||
}`
|
||||
)
|
||||
: this.hass!.localize(`state.climate.${stateObj.state}`)}
|
||||
${stateObj.attributes.preset_mode
|
||||
? html`
|
||||
-
|
||||
@ -157,9 +167,10 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
|
||||
: ""}
|
||||
</div>
|
||||
<div class="modes">
|
||||
${stateObj.attributes.hvac_modes.map((modeItem) =>
|
||||
this._renderIcon(modeItem, mode)
|
||||
)}
|
||||
${stateObj.attributes.hvac_modes
|
||||
.concat()
|
||||
.sort(compareClimateHvacModes)
|
||||
.map((modeItem) => this._renderIcon(modeItem, mode))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -178,7 +178,8 @@ class LovelacePanel extends LitElement {
|
||||
// Do -1 column if the menu is docked and open
|
||||
this._columns = Math.max(
|
||||
1,
|
||||
matchColumns - Number(!this.narrow && this.hass!.dockedSidebar)
|
||||
matchColumns -
|
||||
Number(!this.narrow && this.hass!.dockedSidebar === "docked")
|
||||
);
|
||||
}
|
||||
|
||||
|
52
src/panels/profile/ha-force-narrow-row.ts
Normal file
52
src/panels/profile/ha-force-narrow-row.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import {
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
html,
|
||||
property,
|
||||
customElement,
|
||||
} from "lit-element";
|
||||
import "@polymer/paper-toggle-button/paper-toggle-button";
|
||||
|
||||
import "./ha-settings-row";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { PolymerChangedEvent } from "../../polymer-types";
|
||||
|
||||
@customElement("ha-force-narrow-row")
|
||||
class HaPushNotificationsRow extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public narrow!: boolean;
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
return html`
|
||||
<ha-settings-row .narrow=${this.narrow}>
|
||||
<span slot="heading">
|
||||
${this.hass.localize("ui.panel.profile.force_narrow.header")}
|
||||
</span>
|
||||
<span slot="description">
|
||||
${this.hass.localize("ui.panel.profile.force_narrow.description")}
|
||||
</span>
|
||||
<paper-toggle-button
|
||||
.checked=${this.hass.dockedSidebar === "always_hidden"}
|
||||
@checked-changed=${this._checkedChanged}
|
||||
></paper-toggle-button>
|
||||
</ha-settings-row>
|
||||
`;
|
||||
}
|
||||
|
||||
private async _checkedChanged(ev: PolymerChangedEvent<boolean>) {
|
||||
const newValue = ev.detail.value;
|
||||
if (newValue === (this.hass.dockedSidebar === "always_hidden")) {
|
||||
return;
|
||||
}
|
||||
fireEvent(this, "hass-dock-sidebar", {
|
||||
dock: newValue ? "always_hidden" : "auto",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-force-narrow-row": HaPushNotificationsRow;
|
||||
}
|
||||
}
|
@ -25,6 +25,7 @@ import "./ha-long-lived-access-tokens-card";
|
||||
import "./ha-pick-language-row";
|
||||
import "./ha-pick-theme-row";
|
||||
import "./ha-push-notifications-row";
|
||||
import "./ha-force-narrow-row";
|
||||
|
||||
/*
|
||||
* @appliesMixin EventsMixin
|
||||
@ -83,6 +84,15 @@ class HaPanelProfile extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
||||
narrow="[[narrow]]"
|
||||
hass="[[hass]]"
|
||||
></ha-pick-theme-row>
|
||||
<template
|
||||
is="dom-if"
|
||||
if="[[_showNarrowRow(hass.dockedSidebar, narrow)]]"
|
||||
>
|
||||
<ha-force-narrow-row
|
||||
narrow="[[narrow]]"
|
||||
hass="[[hass]]"
|
||||
></ha-force-narrow-row>
|
||||
</template>
|
||||
<ha-push-notifications-row
|
||||
narrow="[[narrow]]"
|
||||
hass="[[hass]]"
|
||||
@ -174,6 +184,10 @@ class HaPanelProfile extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
||||
_isAdmin(user) {
|
||||
return user.is_admin;
|
||||
}
|
||||
|
||||
_showNarrowRow(dockedSidebar, narrow) {
|
||||
return dockedSidebar === "auto" ? !narrow : true;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ha-panel-profile", HaPanelProfile);
|
||||
|
@ -237,7 +237,7 @@ class PartialCards extends EventsMixin(NavigateMixin(PolymerElement)) {
|
||||
// Do -1 column if the menu is docked and open
|
||||
this._columns = Math.max(
|
||||
1,
|
||||
matchColumns - (!this.narrow && this.hass.dockedSidebar)
|
||||
matchColumns - (!this.narrow && this.hass.dockedSidebar === "docked")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ export const connectionMixin = (
|
||||
localize: () => "",
|
||||
|
||||
translationMetadata,
|
||||
dockedSidebar: true,
|
||||
dockedSidebar: "docked",
|
||||
moreInfoEntityId: null,
|
||||
callService: async (domain, service, serviceData = {}) => {
|
||||
if (__DEV__) {
|
||||
|
@ -2,9 +2,10 @@ import { storeState } from "../util/ha-pref-storage";
|
||||
import { Constructor, LitElement } from "lit-element";
|
||||
import { HassBaseEl } from "./hass-base-mixin";
|
||||
import { HASSDomEvent } from "../common/dom/fire_event";
|
||||
import { HomeAssistant } from "../types";
|
||||
|
||||
interface DockSidebarParams {
|
||||
dock: boolean;
|
||||
dock: HomeAssistant["dockedSidebar"];
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -323,6 +323,14 @@
|
||||
"home": "Home",
|
||||
"sleep": "Sleep",
|
||||
"activity": "Activity"
|
||||
},
|
||||
"hvac_action": {
|
||||
"off": "Off",
|
||||
"heating": "Heating",
|
||||
"cooling": "Cooling",
|
||||
"drying": "Drying",
|
||||
"idle": "Idle",
|
||||
"fan": "Fan"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1044,6 +1052,10 @@
|
||||
"current_user": "You are currently logged in as {fullName}.",
|
||||
"is_owner": "You are an owner.",
|
||||
"logout": "Log out",
|
||||
"force_narrow": {
|
||||
"header": "Always hide the sidebar",
|
||||
"description": "This will hide the sidebar by default, similar to the mobile experience."
|
||||
},
|
||||
"push_notifications": {
|
||||
"header": "Push Notifications",
|
||||
"description": "Send notifications to this device.",
|
||||
|
@ -139,7 +139,7 @@ export interface HomeAssistant {
|
||||
localize: LocalizeFunc;
|
||||
translationMetadata: TranslationMetadata;
|
||||
|
||||
dockedSidebar: boolean;
|
||||
dockedSidebar: "docked" | "always_hidden" | "auto";
|
||||
moreInfoEntityId: string | null;
|
||||
user?: CurrentUser;
|
||||
callService: (
|
||||
|
@ -19,7 +19,12 @@ export function getState() {
|
||||
|
||||
for (const key of STORED_STATE) {
|
||||
if (key in STORAGE) {
|
||||
state[key] = JSON.parse(STORAGE[key]);
|
||||
let value = JSON.parse(STORAGE[key]);
|
||||
// dockedSidebar went from boolean to enum on 20190720
|
||||
if (key === "dockedSidebar" && typeof value === "boolean") {
|
||||
value = value ? "docked" : "auto";
|
||||
}
|
||||
state[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,8 @@
|
||||
"high_demand": "Høj efterspørgsel",
|
||||
"heat_pump": "Varmepumpe",
|
||||
"gas": "Gas",
|
||||
"manual": "Manual"
|
||||
"manual": "Manual",
|
||||
"heat_cool": "Varme\/køl"
|
||||
},
|
||||
"configurator": {
|
||||
"configure": "Konfigurer",
|
||||
@ -613,6 +614,14 @@
|
||||
"add_node": "Tilføj node",
|
||||
"remove_node": "Fjern node",
|
||||
"cancel_command": "Annuller kommando"
|
||||
},
|
||||
"common": {
|
||||
"value": "Værdi",
|
||||
"instance": "Instans",
|
||||
"index": "Indeks"
|
||||
},
|
||||
"values": {
|
||||
"header": "Node værdier"
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
|
@ -816,7 +816,11 @@
|
||||
"close": "Close",
|
||||
"submit": "Submit"
|
||||
},
|
||||
"logout": "Log out"
|
||||
"logout": "Log out",
|
||||
"force_narrow": {
|
||||
"header": "Always hide the sidebar",
|
||||
"description": "This will hide the sidebar by default, similar to the mobile experience."
|
||||
}
|
||||
},
|
||||
"page-authorize": {
|
||||
"initializing": "Initializing",
|
||||
@ -1328,6 +1332,14 @@
|
||||
"home": "Home",
|
||||
"sleep": "Sleep",
|
||||
"activity": "Activity"
|
||||
},
|
||||
"hvac_action": {
|
||||
"off": "Off",
|
||||
"heating": "Heating",
|
||||
"cooling": "Cooling",
|
||||
"drying": "Drying",
|
||||
"idle": "Idle",
|
||||
"fan": "Fan"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -20,7 +20,7 @@
|
||||
"unavailable": "Indisponible"
|
||||
},
|
||||
"alarm_control_panel": {
|
||||
"armed": "Enclenchée",
|
||||
"armed": "Activé",
|
||||
"disarmed": "Désactivée",
|
||||
"armed_home": "Enclenchée (présent)",
|
||||
"armed_away": "Enclenchée (absent)",
|
||||
@ -591,8 +591,20 @@
|
||||
"zwave": {
|
||||
"caption": "Z-Wave",
|
||||
"description": "Gérez votre réseau Z-Wave",
|
||||
"network_status": {
|
||||
"network_stopped": "Réseau Z-Wave arrêté",
|
||||
"network_starting": "Démarrage du réseau Z-Wave...",
|
||||
"network_starting_note": "Ceci peut prendre un certain temps en fonction du débit de votre réseau.",
|
||||
"network_started": "Le réseau Z-Wave a été démarré"
|
||||
},
|
||||
"services": {
|
||||
"save_config": "Enregistrer la configuration"
|
||||
"start_network": "Démarrer le réseau",
|
||||
"stop_network": "Arrêter le réseau",
|
||||
"test_network": "Tester le réseau",
|
||||
"save_config": "Enregistrer la configuration",
|
||||
"add_node_secure": "Ajouter un nœud sécurisé",
|
||||
"add_node": "Ajouter un nœud",
|
||||
"remove_node": "Supprimer un nœud"
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
|
@ -8,7 +8,7 @@
|
||||
"mailbox": "메일함",
|
||||
"shopping_list": "장보기목록",
|
||||
"dev-info": "정보",
|
||||
"developer_tools": "개발자도구",
|
||||
"developer_tools": "개발자 도구",
|
||||
"calendar": "캘린더",
|
||||
"profile": "프로필"
|
||||
},
|
||||
@ -614,6 +614,14 @@
|
||||
"add_node": "노드 추가",
|
||||
"remove_node": "노드 제거",
|
||||
"cancel_command": "명령 취소"
|
||||
},
|
||||
"common": {
|
||||
"value": "값",
|
||||
"instance": "인스턴스",
|
||||
"index": "색인"
|
||||
},
|
||||
"values": {
|
||||
"header": "노드 값"
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
@ -642,7 +650,7 @@
|
||||
"caption": "Home Assistant Cloud",
|
||||
"description_login": "{email} 로 로그인 되어있습니다",
|
||||
"description_not_login": "로그인이 되어있지 않습니다",
|
||||
"description_features": "Alexa 및 Google Assistant 를 통해 집 밖에서도 집을 관리합니다."
|
||||
"description_features": "Alexa 및 Google Assistant 를 통해 집 밖에서도 집을 관리하세요."
|
||||
},
|
||||
"integrations": {
|
||||
"caption": "통합 구성요소",
|
||||
@ -1316,7 +1324,7 @@
|
||||
"eco": "절전",
|
||||
"away": "외출",
|
||||
"boost": "부스트",
|
||||
"comfort": "안락",
|
||||
"comfort": "쾌적",
|
||||
"home": "재실",
|
||||
"sleep": "수면",
|
||||
"activity": "활동"
|
||||
|
@ -354,6 +354,19 @@
|
||||
"introduction": "Pārvaldiet Home Assistant serveri no Home Assistant saskarnes.",
|
||||
"restart": "Restartēt",
|
||||
"stop": "Apturēt"
|
||||
},
|
||||
"core_config": {
|
||||
"edit_requires_storage": "Redaktors ir atspējots, jo konfigurācija ir definēta configuration.yaml.",
|
||||
"location_name": "Jūsu Home Assistant instalācijas nosaukums",
|
||||
"elevation": "Augstums",
|
||||
"elevation_meters": "metri",
|
||||
"time_zone": "Laika josla",
|
||||
"unit_system": "Mērvienību sistēma",
|
||||
"unit_system_imperial": "Imperiālā",
|
||||
"unit_system_metric": "Metriskā",
|
||||
"imperial_example": "Fārenheita, mārciņas",
|
||||
"metric_example": "Celsija, kilogrami",
|
||||
"save_button": "Saglabāt"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -367,20 +380,21 @@
|
||||
"description": "Veidojiet un rediģējiet automatizācijas",
|
||||
"picker": {
|
||||
"header": "Automatizāciju redaktors",
|
||||
"introduction": "Automatizācijas redaktors ļauj jums izveidot un rediģēt automatizācijas. Lūdzu, sekojiet [norādījumiem] (https:\/\/home-assistant.io\/docs\/automation\/editor\/), lai pārliecinātos, ka esat pareizi konfigurējis Home Assistant.",
|
||||
"introduction": "Automatizācijas redaktors ļauj jums izveidot un rediģēt automatizācijas. Lūdzu, sekojiet saitei zemāk, lai pārliecinātos, ka esat pareizi konfigurējis Home Assistant.",
|
||||
"pick_automation": "Izvēlieties automatizāciju rediģēšanai",
|
||||
"no_automations": "Mēs nevarējām atrast rediģējamas automatizācijas",
|
||||
"add_automation": "Pievienot automatizāciju"
|
||||
"add_automation": "Pievienot automatizāciju",
|
||||
"learn_more": "Uzziniet vairāk par automatizācijām"
|
||||
},
|
||||
"editor": {
|
||||
"introduction": "Lietojiet automatizācijas, lai ienestu dzīvību Jūsu mājās",
|
||||
"default_name": "Jauna Automatizācija",
|
||||
"introduction": "Lietojiet automatizācijas, lai iedzīvinātu Jūsu mājās",
|
||||
"default_name": "Jauna automatizācija",
|
||||
"save": "Saglabāt",
|
||||
"unsaved_confirm": "Jums ir nesaglabātas izmaiņas. Vai tiešām vēlaties pamest?",
|
||||
"alias": "Nosaukums",
|
||||
"triggers": {
|
||||
"header": "Trigeri",
|
||||
"introduction": "Trigeri ir tas, kas sāk automatizācijas noteikuma apstrādi. Vienam noteikumam ir iespējams norādīt vairākus trigerus. Kad trigeris sāk, Home Assistant apstiprina nosacījumus, ja tādi ir, un izsauc darbību. \n\n [Uzziniet vairāk par trigeriem.] (https:\/\/home-assistant.io\/docs\/automation\/trigger\/)",
|
||||
"introduction": "Trigeri ir tas, kas sāk automatizācijas noteikuma apstrādi. Vienam noteikumam ir iespējams norādīt vairākus trigerus. Kad trigeris sāk, Home Assistant apstiprina nosacījumus, ja tādi ir, un izsauc darbību.",
|
||||
"add": "Pievienot trigeri",
|
||||
"duplicate": "Dublicēt",
|
||||
"delete": "Dzēst",
|
||||
@ -452,11 +466,12 @@
|
||||
"geo_location": {
|
||||
"label": "Ģeogrāfiskā atrašanās vieta"
|
||||
}
|
||||
}
|
||||
},
|
||||
"learn_more": "Uzziniet vairāk par trigeriem"
|
||||
},
|
||||
"conditions": {
|
||||
"header": "Nosacījumi",
|
||||
"introduction": "Nosacījumi ir automatizācijas noteikuma izvēles daļa, un to var izmantot, lai novērstu darbību rašanos. Nosacījumi izskatās ļoti līdzīgi trigeriem, taču tie ir ļoti atšķirīgi. Trigeri izskatīs notikumus, kas notiek sistēmā, bet nosacījums tikai aplūko, kā sistēma šobrīd izskatās. Trigeri var novērot, ka slēdzis tiek ieslēgts. Nosacījums var redzēt tikai to, vai slēdzis pašlaik ir ieslēgts vai izslēgts. \n\n [Uzziniet vairāk par nosacījumiem.] (https:\/\/home-assistant.io\/docs\/scripts\/conditions\/)",
|
||||
"introduction": "Nosacījumi ir automatizācijas noteikuma izvēles daļa, un to var izmantot, lai novērstu darbību rašanos. Nosacījumi izskatās ļoti līdzīgi trigeriem, taču tie ir ļoti atšķirīgi. Trigeri izskatīs notikumus, kas notiek sistēmā, bet nosacījums tikai aplūko, kā sistēma šobrīd izskatās. Trigeri var novērot, ka slēdzis tiek ieslēgts. Nosacījums var redzēt tikai to, vai slēdzis pašlaik ir ieslēgts vai izslēgts.",
|
||||
"add": "Pievienot nosacījumu",
|
||||
"duplicate": "Duplicēt",
|
||||
"delete": "Dzēst",
|
||||
@ -497,11 +512,12 @@
|
||||
"entity": "Vienība ar atrašanos vietu",
|
||||
"zone": "Zona"
|
||||
}
|
||||
}
|
||||
},
|
||||
"learn_more": "Uzziniet vairāk par nosacījumiem"
|
||||
},
|
||||
"actions": {
|
||||
"header": "Darbības",
|
||||
"introduction": "Darbības ir tādas, kādas Home Assistant veiks, kad tiks aktivizēta automatizācija. \n\n [Uzziniet vairāk par darbībām.] (https:\/\/home-assistant.io\/docs\/automation\/action\/)",
|
||||
"introduction": "Darbības nosaka, ko Home Assistant darīs, kad tiks aktivizēta automatizācija.",
|
||||
"add": "Pievienot darbību",
|
||||
"duplicate": "Dublicēt",
|
||||
"delete": "Dzēst",
|
||||
@ -530,7 +546,8 @@
|
||||
"event": "Notikums:",
|
||||
"service_data": "Pakalpojuma dati"
|
||||
}
|
||||
}
|
||||
},
|
||||
"learn_more": "Uzziniet vairāk par darbībām"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -540,7 +557,10 @@
|
||||
},
|
||||
"zwave": {
|
||||
"caption": "Z-Wave",
|
||||
"description": "Pārvaldiet Z-Wave tīklu"
|
||||
"description": "Pārvaldiet Z-Wave tīklu",
|
||||
"services": {
|
||||
"save_config": "Saglabāt konfigurāciju"
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
"caption": "Lietotāji",
|
||||
@ -630,7 +650,7 @@
|
||||
},
|
||||
"long_lived_access_tokens": {
|
||||
"header": "Ilgtermiņas piekļuves pilnvaras",
|
||||
"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īvi šādas 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 radīšanas. Pašlaik ir aktīvas sekojošas ilgstošas piekļuves pilvaras.",
|
||||
"learn_auth_requests": "Uzziniet, kā veikt autentificētus pieprasījumus.",
|
||||
"created_at": "Izveidots {date}",
|
||||
"confirm_delete": "Vai tiešām vēlaties dzēst piekļuves pilnvaru {name}?",
|
||||
@ -665,7 +685,8 @@
|
||||
"step_done": "Iestatīšana ir pabeigta {step}",
|
||||
"close": "Aizvērt",
|
||||
"submit": "Iesniegt"
|
||||
}
|
||||
},
|
||||
"logout": "Iziet"
|
||||
},
|
||||
"page-authorize": {
|
||||
"initializing": "Inicializēšana",
|
||||
@ -836,6 +857,13 @@
|
||||
"help": "Palīdzība",
|
||||
"refresh": "Atsvaidzināt"
|
||||
}
|
||||
},
|
||||
"page-demo": {
|
||||
"cards": {
|
||||
"demo": {
|
||||
"learn_more": "Uzziniet vairāk par Home Assistant"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sidebar": {
|
||||
|
@ -614,6 +614,14 @@
|
||||
"add_node": "Dodaj węzeł",
|
||||
"remove_node": "Usuń węzeł",
|
||||
"cancel_command": "Anuluj polecenie"
|
||||
},
|
||||
"common": {
|
||||
"value": "Wartość",
|
||||
"instance": "Instancja",
|
||||
"index": "Indeks"
|
||||
},
|
||||
"values": {
|
||||
"header": "Wartości węzła"
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
|
@ -614,6 +614,14 @@
|
||||
"add_node": "Добавить узел",
|
||||
"remove_node": "Удалить узел",
|
||||
"cancel_command": "Отменить команду"
|
||||
},
|
||||
"common": {
|
||||
"value": "Значение",
|
||||
"instance": "Экземпляр",
|
||||
"index": "Индекс"
|
||||
},
|
||||
"values": {
|
||||
"header": "Значения узлов"
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user