Compare commits

..

62 Commits

Author SHA1 Message Date
Bram Kragten
685d28229e Fix for displaying time left for values > 24 hour 2020-07-27 19:04:25 +02:00
HomeAssistant Azure
8634ee536d [ci skip] Translation update 2020-07-27 00:32:48 +00:00
HomeAssistant Azure
632d3cda24 [ci skip] Translation update 2020-07-26 00:32:40 +00:00
HomeAssistant Azure
29b6a907d4 [ci skip] Translation update 2020-07-25 00:32:25 +00:00
HomeAssistant Azure
7474d09e5d [ci skip] Translation update 2020-07-24 00:32:32 +00:00
HomeAssistant Azure
fc7bcd7e00 [ci skip] Translation update 2020-07-23 00:32:33 +00:00
Bram Kragten
f6fb2e4b1d Missed the entities in the editors (#6443) 2020-07-22 14:16:25 +02:00
HomeAssistant Azure
8c8673a272 [ci skip] Translation update 2020-07-22 00:32:23 +00:00
Bram Kragten
4404a1173b Fix mwc-list/menu actions (#6442)
* Fix mwc-list/menu actions

Fix double actions when using request-selected

* Update ha-button-menu.ts

* Automation menu styling

* Update src/panels/lovelace/hui-root.ts

Co-authored-by: Zack Arnett <arnett.zackary@gmail.com>

* Move

Co-authored-by: Zack Arnett <arnett.zackary@gmail.com>
2020-07-21 23:22:19 +02:00
Bram Kragten
e08c10315e Fix removing/moving device actions (#6441)
Fixes https://github.com/home-assistant/frontend/issues/6438
2020-07-21 09:05:21 -07:00
Bram Kragten
16473c9177 Bump superstruct, add struct to automation action (#6436)
Co-authored-by: Zack Arnett <arnett.zackary@gmail.com>
2020-07-21 12:42:07 +02:00
HomeAssistant Azure
235fd5603f [ci skip] Translation update 2020-07-21 00:32:32 +00:00
Quinn Casey
d07d5832f5 Increase z-index of save button on editor (#6435) 2020-07-20 18:46:10 +02:00
Yosi Levy
ef8be5d559 Merge pull request #6433 from yosilevy/edit-card-RTL-fix
Edit card rtl fix
2020-07-20 14:44:05 +03:00
Yosi Levy
ccafdc6e1f Merge pull request #6431 from yosilevy/Unused-entities-search
ha-data-table search label + no data text label
2020-07-20 14:31:41 +03:00
Yosi Levy
11827aa4c0 Merge pull request #6426 from yosilevy/Logbook-link-fix
Logbook link fix
2020-07-20 14:31:21 +03:00
Yosi Levy
6b0589d343 Update lint 2020-07-20 14:30:32 +03:00
Yosi Levy
cec1eed99e Merge branch 'dev' into edit-card-RTL-fix 2020-07-20 14:01:20 +03:00
Yosi Levy
d7e1e9e284 Merge pull request #6417 from yosilevy/RTL-date-selector
RTL fix for range list
2020-07-20 13:57:27 +03:00
Yosi Levy
cae46453a7 New parameterized label 2020-07-20 13:56:39 +03:00
Yosi Levy
a6e948c808 Typeo 2020-07-20 13:41:20 +03:00
Yosi Levy
7638020bfc Changed default wording 2020-07-20 13:37:18 +03:00
Yosi Levy
10a62ca17c Fix bad merge 2020-07-20 13:29:51 +03:00
Yosi Levy
0afc7c184f Fixed comments 2020-07-20 13:25:34 +03:00
Yosi Levy
168e26aeb4 Merge branch 'dev' into RTL-date-selector 2020-07-20 13:12:53 +03:00
Yosi Levy
e6b9389b33 Fixed heading (concat) to support RTL (name comes last) 2020-07-20 07:49:09 +03:00
Yosi Levy
377c37425e Refactor ha-dialog RTL to include dialogs not using createCloseHeader 2020-07-20 07:32:09 +03:00
HomeAssistant Azure
4af26602bb [ci skip] Translation update 2020-07-20 00:32:37 +00:00
Yosi Levy
c6624e5cb6 Optimized RTL check 2020-07-19 15:09:34 +03:00
Yosi Levy
f7ae5b91bf Remove rtl update check 2020-07-19 14:17:09 +03:00
Yosi Levy
07e68496c0 Removed directive 2020-07-19 06:14:09 +03:00
Yosi Levy
d5a947e2cc Removed style 2020-07-19 06:09:57 +03:00
Yosi Levy
3f920767f1 Added noDataText 2020-07-19 06:04:42 +03:00
Yosi Levy
3e14d27a1e Usage of search label 2020-07-19 05:58:01 +03:00
Yosi Levy
cfa4c14108 Added search label support to ha-data-table 2020-07-19 05:56:39 +03:00
HomeAssistant Azure
209056dbe1 [ci skip] Translation update 2020-07-19 00:32:25 +00:00
Aidan Timson
10356a7496 Fix typo in ZHA (#6429) 2020-07-18 19:27:46 +02:00
Yosi Levy
d4ae74de44 Removed style 2020-07-18 11:06:43 +03:00
Yosi Levy
88d5e7dd5e Line breaks 2020-07-18 11:02:13 +03:00
Yosi Levy
06c7b0b82e Optimized 2020-07-18 10:59:48 +03:00
Yosi Levy
689febda60 Fixed comments 2020-07-18 06:48:36 +03:00
Yosi Levy
80bc6fda8b Improved 2020-07-18 06:31:33 +03:00
Yosi Levy
346eb78c4e Fixed extra space issue + RTL support when no entries 2020-07-18 06:29:21 +03:00
HomeAssistant Azure
2df02f1b09 [ci skip] Translation update 2020-07-18 00:32:26 +00:00
Bram Kragten
92915eddc2 Make menu's work with keyboard (#6421) 2020-07-17 20:31:44 +02:00
Bram Kragten
cddbf460f8 Add close function to edit card dialog (#6423) 2020-07-17 11:29:08 -07:00
Bram Kragten
3c63c23e5a Fix spacing more info (#6419) 2020-07-17 12:04:20 +02:00
Yosi Levy
ba67b1291f Merge pull request #6404 from yosilevy/RTL-dev-changes
Removed LTR force - looks much better
2020-07-17 07:00:07 +03:00
Yosi Levy
7bced28327 RTL fix for range list 2020-07-17 06:57:42 +03:00
HomeAssistant Azure
db2b60700c [ci skip] Translation update 2020-07-17 00:32:26 +00:00
Bram Kragten
9034822c44 Bump lit-analyzer and add back cast types (#6409) 2020-07-16 12:01:24 -07:00
Bram Kragten
a14179b81a Bumped version to 20200716.0 2020-07-16 17:51:47 +02:00
Bram Kragten
427c5db7f4 default 0 2020-07-16 17:51:01 +02:00
Bram Kragten
fcb5865468 Make gauge bit smaller 2020-07-16 17:49:35 +02:00
Bram Kragten
41370be2b8 Rewrite gauge (#6407) 2020-07-16 08:42:14 -07:00
Bram Kragten
d7d8dd8986 Debug was still true (#6410) 2020-07-16 17:18:55 +02:00
Bram Kragten
a0f596e419 Missing icon change (#6406) 2020-07-16 09:47:41 +02:00
Paulus Schoutsen
0a8894feb7 Random cleanups (#6402) 2020-07-16 08:24:16 +02:00
Bram Kragten
1db9eea0f8 Add visual-studio-code to icon conversion (#6401)
Fixes https://github.com/home-assistant/frontend/issues/6400
2020-07-16 08:22:22 +02:00
Sean Mooney
489783c398 Fix typo in icon rename mapping (#6405)
After updating all my MDI icons I noticed that one wasn't displaying anymore. Then realized there was a minor typo.
2020-07-16 08:21:32 +02:00
Yosi Levy
be62f327ee Removed LTR force - looks much better 2020-07-16 05:32:49 +03:00
HomeAssistant Azure
32359adb6d [ci skip] Translation update 2020-07-16 00:32:14 +00:00
114 changed files with 3375 additions and 1034 deletions

View File

@@ -52,7 +52,6 @@ class CastDemoRow extends LitElement implements LovelaceRow {
});
mgr.castContext.addEventListener(
// eslint-disable-next-line no-undef
// @ts-ignore
cast.framework.CastContextEventType.SESSION_STATE_CHANGED,
(ev) => {
// On Android, opening a new session always results in SESSION_RESUMED.

View File

@@ -25,6 +25,7 @@ import { HomeAssistant, Route } from "../../../src/types";
import { showRepositoriesDialog } from "../dialogs/repositories/show-dialog-repositories";
import { supervisorTabs } from "../hassio-tabs";
import "./hassio-addon-repository";
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
const sortRepos = (a: HassioAddonRepository, b: HassioAddonRepository) => {
if (a.slug === "local") {
@@ -97,14 +98,18 @@ class HassioAddonStore extends LitElement {
.tabs=${supervisorTabs}
>
<span slot="header">Add-on store</span>
<ha-button-menu corner="BOTTOM_START" slot="toolbar-icon">
<ha-button-menu
corner="BOTTOM_START"
slot="toolbar-icon"
@action=${this._handleAction}
>
<mwc-icon-button slot="trigger" alt="menu">
<ha-svg-icon path=${mdiDotsVertical}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item @tap=${this._manageRepositories}>
<mwc-list-item>
Repositories
</mwc-list-item>
<mwc-list-item @tap=${this.refreshData}>
<mwc-list-item>
Reload
</mwc-list-item>
</ha-button-menu>
@@ -143,6 +148,17 @@ class HassioAddonStore extends LitElement {
this._loadData();
}
private _handleAction(ev: CustomEvent<ActionDetail>) {
switch (ev.detail.index) {
case 0:
this._manageRepositories();
break;
case 1:
this.refreshData();
break;
}
}
private apiCalled(ev) {
if (ev.detail.success) {
this._loadData();

View File

@@ -13,7 +13,7 @@
"lint:prettier": "prettier '**/src/**/*.{js,ts,json,css,md}' --check",
"format:prettier": "prettier '**/src/**/*.{js,ts,json,css,md}' --write",
"lint:types": "tsc",
"lint:lit": "lit-analyzer '**/src/**/*.ts'",
"lint:lit": "lit-analyzer '**/src/**/*.ts' --format markdown --outFile result.md",
"lint": "npm run lint:eslint && npm run lint:prettier && npm run lint:types",
"format": "npm run format:eslint && npm run format:prettier",
"mocha": "node_modules/.bin/ts-mocha -p test-mocha/tsconfig.test.json --opts test-mocha/mocha.opts",
@@ -74,6 +74,7 @@
"@polymer/paper-tooltip": "^3.0.1",
"@polymer/polymer": "3.1.0",
"@thomasloven/round-slider": "0.5.0",
"@types/chromecast-caf-sender": "^1.0.3",
"@vaadin/vaadin-combo-box": "^5.0.10",
"@vaadin/vaadin-date-picker": "^4.0.7",
"@vue/web-component-wrapper": "^1.2.0",
@@ -107,8 +108,7 @@
"regenerator-runtime": "^0.13.2",
"resize-observer-polyfill": "^1.5.1",
"roboto-fontface": "^0.10.0",
"superstruct": "^0.6.1",
"svg-gauge": "^1.0.6",
"superstruct": "^0.10.12",
"unfetch": "^4.1.0",
"vue": "^2.6.11",
"vue2-daterange-picker": "^0.5.1",
@@ -171,7 +171,7 @@
"html-minifier": "^4.0.0",
"husky": "^1.3.1",
"lint-staged": "^8.1.5",
"lit-analyzer": "^1.1.10",
"lit-analyzer": "^1.2.0",
"lodash.template": "^4.5.0",
"magic-string": "^0.25.7",
"map-stream": "^0.0.7",
@@ -192,7 +192,7 @@
"source-map-url": "^0.4.0",
"systemjs": "^6.3.2",
"terser-webpack-plugin": "^3.0.6",
"ts-lit-plugin": "^1.1.10",
"ts-lit-plugin": "^1.2.0",
"ts-mocha": "^6.0.0",
"typescript": "^3.8.3",
"vinyl-buffer": "^1.0.1",

View File

@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup(
name="home-assistant-frontend",
version="20200715.1",
version="20200716.0",
description="The Home Assistant frontend",
url="https://github.com/home-assistant/home-assistant-polymer",
author="The Home Assistant Authors",

View File

@@ -1,4 +1,8 @@
/* eslint-disable no-undef, no-console */
import {
CastStateEventData,
SessionStateEventData,
} from "chromecast-caf-receiver/cast.framework";
import { Auth } from "home-assistant-js-websocket";
import { castApiAvailable } from "./cast_framework";
import { CAST_APP_ID, CAST_DEV, CAST_NS } from "./const";
@@ -40,16 +44,13 @@ export class CastManager {
const context = this.castContext;
context.setOptions({
receiverApplicationId: CAST_APP_ID,
// @ts-ignore
autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED,
});
context.addEventListener(
// @ts-ignore
cast.framework.CastContextEventType.SESSION_STATE_CHANGED,
(ev) => this._sessionStateChanged(ev)
);
context.addEventListener(
// @ts-ignore
cast.framework.CastContextEventType.CAST_STATE_CHANGED,
(ev) => this._castStateChanged(ev)
);
@@ -118,7 +119,7 @@ export class CastManager {
}
}
private _sessionStateChanged(ev) {
private _sessionStateChanged(ev: SessionStateEventData) {
if (__DEV__) {
console.log("Cast session state changed", ev.sessionState);
}
@@ -141,7 +142,7 @@ export class CastManager {
}
}
private _castStateChanged(ev) {
private _castStateChanged(ev: CastStateEventData) {
if (__DEV__) {
console.log("Cast state changed", ev.castState);
}

View File

@@ -1,4 +1,10 @@
export default function durationToSeconds(duration: string): number {
let days = 0;
if (duration.includes("day")) {
const position = duration.indexOf("day");
days = Number(duration.substr(0, position));
duration = duration.split(",")[1];
}
const parts = duration.split(":").map(Number);
return parts[0] * 3600 + parts[1] * 60 + parts[2];
return (days * 24 + parts[0]) * 3600 + parts[1] * 60 + parts[2];
}

View File

@@ -0,0 +1,14 @@
import {
RequestSelectedDetail,
ListItem,
} from "@material/mwc-list/mwc-list-item";
export const shouldHandleRequestSelectedEvent = (
ev: CustomEvent<RequestSelectedDetail>
): boolean => {
if (!ev.detail.selected && ev.detail.source !== "property") {
return false;
}
(ev.target as ListItem).selected = false;
return true;
};

View File

@@ -9,5 +9,9 @@ export function computeRTL(hass: HomeAssistant) {
}
export function computeRTLDirection(hass: HomeAssistant) {
return computeRTL(hass) ? "rtl" : "ltr";
return emitRTLDirection(computeRTL(hass));
}
export function emitRTLDirection(rtl: boolean) {
return rtl ? "rtl" : "ltr";
}

View File

@@ -98,6 +98,8 @@ export class HaDataTable extends LitElement {
@property({ type: String }) public noDataText?: string;
@property({ type: String }) public searchLabel?: string;
@property({ type: String }) public filter = "";
@internalProperty() private _filterable = false;
@@ -202,6 +204,7 @@ export class HaDataTable extends LitElement {
<div class="table-header">
<search-input
@value-changed=${this._handleSearchChange}
.label=${this.searchLabel}
></search-input>
</div>
`

View File

@@ -117,11 +117,7 @@ export abstract class HaDeviceAutomationPicker<
>
${this.NO_AUTOMATION_TEXT}
</paper-item>
<paper-item
key=${UNKNOWN_AUTOMATION_KEY}
.automation=${this.value}
hidden
>
<paper-item key=${UNKNOWN_AUTOMATION_KEY} hidden>
${this.UNKNOWN_AUTOMATION_TEXT}
</paper-item>
${this._automations.map(
@@ -175,18 +171,17 @@ export abstract class HaDeviceAutomationPicker<
}
private _automationChanged(ev) {
this._setValue(ev.detail.item.automation);
if (ev.detail.item.automation) {
this._setValue(ev.detail.item.automation);
}
}
private _setValue(automation: T) {
if (this.value && deviceAutomationsEqual(automation, this.value)) {
return;
}
this.value = automation;
setTimeout(() => {
fireEvent(this, "change");
fireEvent(this, "value-changed", { value: automation });
}, 0);
fireEvent(this, "change");
fireEvent(this, "value-changed", { value: automation });
}
static get styles(): CSSResult {

View File

@@ -10,7 +10,6 @@ import {
} from "lit-element";
import "@material/mwc-button";
import "@material/mwc-menu";
import "@material/mwc-list/mwc-list-item";
import type { Menu, Corner } from "@material/mwc-menu";
import "./ha-icon-button";
@@ -19,14 +18,30 @@ import "./ha-icon-button";
export class HaButtonMenu extends LitElement {
@property() public corner: Corner = "TOP_START";
@property({ type: Boolean }) public multi = false;
@property({ type: Boolean }) public activatable = false;
@query("mwc-menu") private _menu?: Menu;
public get items() {
return this._menu?.items;
}
public get selected() {
return this._menu?.selected;
}
protected render(): TemplateResult {
return html`
<div @click=${this._handleClick}>
<slot name="trigger"></slot>
</div>
<mwc-menu .corner=${this.corner}>
<mwc-menu
.corner=${this.corner}
.multi=${this.multi}
.activatable=${this.activatable}
>
<slot></slot>
</mwc-menu>
`;

View File

@@ -9,7 +9,7 @@ import {
} from "lit-element";
@customElement("ha-card")
class HaCard extends LitElement {
export class HaCard extends LitElement {
@property() public header?: string;
@property({ type: Boolean, reflect: true }) public outlined = false;

View File

@@ -17,6 +17,8 @@ import "./ha-svg-icon";
import "@polymer/paper-input/paper-input";
import "@material/mwc-list/mwc-list";
import "./date-range-picker";
import { computeRTLDirection } from "../common/util/compute_rtl";
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
export interface DateRangePickerRanges {
[key: string]: [Date, Date];
@@ -36,11 +38,14 @@ export class HaDateRangePicker extends LitElement {
@property({ type: Boolean }) private _hour24format = false;
@property({ type: String }) private _rtlDirection = "ltr";
protected updated(changedProps: PropertyValues) {
if (changedProps.has("hass")) {
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
if (!oldHass || oldHass.language !== this.hass.language) {
this._hour24format = this._compute24hourFormat();
this._rtlDirection = computeRTLDirection(this.hass);
}
}
}
@@ -76,16 +81,14 @@ export class HaDateRangePicker extends LitElement {
></paper-input>
</div>
${this.ranges
? html`<div slot="ranges" class="date-range-ranges">
<mwc-list @click=${this._setDateRange}>
${Object.entries(this.ranges).map(
([name, dates]) => html`<mwc-list-item
.activated=${this.startDate.getTime() ===
dates[0].getTime() &&
this.endDate.getTime() === dates[1].getTime()}
.startDate=${dates[0]}
.endDate=${dates[1]}
>
? html`<div
slot="ranges"
class="date-range-ranges"
.dir=${this._rtlDirection}
>
<mwc-list @action=${this._setDateRange} activatable>
${Object.keys(this.ranges).map(
(name) => html`<mwc-list-item>
${name}
</mwc-list-item>`
)}
@@ -116,12 +119,10 @@ export class HaDateRangePicker extends LitElement {
);
}
private _setDateRange(ev: Event) {
const target = ev.target as any;
const startDate = target.startDate;
const endDate = target.endDate;
private _setDateRange(ev: CustomEvent<ActionDetail>) {
const dateRange = Object.values(this.ranges!)[ev.detail.index];
const dateRangePicker = this._dateRangePicker;
dateRangePicker.clickRange([startDate, endDate]);
dateRangePicker.clickRange(dateRange);
dateRangePicker.clickedApply();
}

View File

@@ -5,7 +5,7 @@ import "./ha-icon-button";
import { css, CSSResult, customElement, html } from "lit-element";
import type { Constructor, HomeAssistant } from "../types";
import { mdiClose } from "@mdi/js";
import { computeRTL } from "../common/util/compute_rtl";
import { computeRTLDirection } from "../common/util/compute_rtl";
const MwcDialog = customElements.get("mwc-dialog") as Constructor<Dialog>;
@@ -14,8 +14,8 @@ export const createCloseHeading = (hass: HomeAssistant, title: string) => html`
<mwc-icon-button
aria-label=${hass.localize("ui.dialogs.generic.close")}
dialogAction="close"
?rtl=${computeRTL(hass)}
class="header_button"
dir=${computeRTLDirection(hass)}
>
<ha-svg-icon path=${mdiClose}></ha-svg-icon>
</mwc-icon-button>
@@ -61,7 +61,7 @@ export class HaDialog extends MwcDialog {
text-decoration: none;
color: inherit;
}
mwc-icon-button[rtl].header_button {
[dir="rtl"].header_button {
right: auto;
left: 16px;
}

130
src/components/ha-gauge.ts Normal file
View File

@@ -0,0 +1,130 @@
import {
LitElement,
svg,
customElement,
css,
property,
internalProperty,
PropertyValues,
} from "lit-element";
import { styleMap } from "lit-html/directives/style-map";
import { afterNextRender } from "../common/util/render-status";
const getAngle = (value: number, min: number, max: number) => {
const percentage = getValueInPercentage(normalize(value, min, max), min, max);
return (percentage * 180) / 100;
};
const normalize = (value: number, min: number, max: number) => {
if (value > max) return max;
if (value < min) return min;
return value;
};
const getValueInPercentage = (value: number, min: number, max: number) => {
const newMax = max - min;
const newVal = value - min;
return (100 * newVal) / newMax;
};
@customElement("ha-gauge")
export class Gauge extends LitElement {
@property({ type: Number }) public min = 0;
@property({ type: Number }) public max = 100;
@property({ type: Number }) public value = 0;
@property() public label = "";
@internalProperty() private _angle = 0;
@internalProperty() private _updated = false;
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
// Wait for the first render for the initial animation to work
afterNextRender(() => {
this._updated = true;
this._angle = getAngle(this.value, this.min, this.max);
this._rescale_svg();
});
}
protected updated(changedProperties: PropertyValues) {
super.updated(changedProperties);
if (!this._updated || !changedProperties.has("value")) {
return;
}
this._angle = getAngle(this.value, this.min, this.max);
this._rescale_svg();
}
protected render() {
return svg`
<svg viewBox="0 0 100 50" class="gauge">
<path
class="dial"
d="M 10 50 A 40 40 0 0 1 90 50"
></path>
<path
class="value"
style=${styleMap({ transform: `rotate(${this._angle}deg)` })}
d="M 90 50.001 A 40 40 0 0 1 10 50"
></path>
</svg>
<svg class="text">
<text class="value-text">
${this.value} ${this.label}
</text>
</svg>`;
}
private _rescale_svg() {
// Set the viewbox of the SVG containing the value to perfectly
// fit the text
// That way it will auto-scale correctly
const svgRoot = this.shadowRoot!.querySelector(".text")!;
const box = svgRoot.querySelector("text")!.getBBox()!;
svgRoot.setAttribute(
"viewBox",
`${box.x} ${box!.y} ${box.width} ${box.height}`
);
}
static get styles() {
return css`
:host {
position: relative;
}
.dial {
fill: none;
stroke: var(--primary-background-color);
stroke-width: 15;
}
.value {
fill: none;
stroke-width: 15;
stroke: var(--gauge-color);
transition: all 1000ms ease 0s;
transform-origin: 50% 100%;
}
.gauge {
display: block;
}
.text {
position: absolute;
max-height: 40%;
max-width: 55%;
left: 50%;
bottom: -6%;
transform: translate(-50%, 0%);
}
.value-text {
font-size: 50px;
fill: var(--primary-text-color);
text-anchor: middle;
}
`;
}
}

View File

@@ -89,7 +89,7 @@ const mdiRenameMapping = {
"library-movie": "filmstrip-box-multiple",
"library-music": "music-box-multiple",
"library-music-outline": "music-box-multiple-outline",
"library-video": "play-box-mutiple",
"library-video": "play-box-multiple",
markdown: "language-markdown",
"markdown-outline": "language-markdown-outline",
"message-settings-variant": "message-cog",
@@ -151,6 +151,8 @@ const mdiRenameMapping = {
"textbox-lock": "form-textbox-lock",
"textbox-password": "form-textbox-password",
"syllabary-katakana-half-width": "syllabary-katakana-halfwidth",
"visual-studio-code": "microsoft-visual-studio-code",
"visual-studio": "microsoft-visual-studio",
};
const mdiRemovedIcons = new Set([

View File

@@ -46,8 +46,8 @@ export interface MqttTrigger {
export interface GeoLocationTrigger {
platform: "geo_location";
source: "string";
zone: "string";
source: string;
zone: string;
event: "enter" | "leave";
}

View File

@@ -15,7 +15,8 @@ declare global {
}
}
interface HassDialog<T = HASSDomEvents[ValidHassDomEvent]> extends HTMLElement {
export interface HassDialog<T = HASSDomEvents[ValidHassDomEvent]>
extends HTMLElement {
showDialog(params: T);
closeDialog?: () => boolean | void;
}

View File

@@ -302,13 +302,15 @@ export class MoreInfoDialog extends LitElement {
}
}
state-history-charts {
margin-top: 16px 0;
}
ha-dialog[data-domain="camera"] {
--dialog-content-padding: 0;
}
state-card-content,
state-history-charts {
display: block;
margin-bottom: 16px;
}
`,
];
}

View File

@@ -29,6 +29,9 @@ import "./types/ha-automation-action-event";
import "./types/ha-automation-action-scene";
import "./types/ha-automation-action-service";
import "./types/ha-automation-action-wait_template";
import { handleStructError } from "../../../lovelace/common/structs/handle-errors";
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
import { haStyle } from "../../../../resources/styles";
const OPTIONS = [
"condition",
@@ -87,12 +90,16 @@ export default class HaAutomationActionRow extends LitElement {
@property() public totalActions!: number;
@internalProperty() private _warnings?: string[];
@internalProperty() private _uiModeAvailable = true;
@internalProperty() private _yamlMode = false;
protected render() {
const type = getType(this.action);
const selected = type ? OPTIONS.indexOf(type) : -1;
const yamlMode = this._yamlMode || selected === -1;
const yamlMode = this._yamlMode;
return html`
<ha-card>
@@ -128,17 +135,14 @@ export default class HaAutomationActionRow extends LitElement {
</mwc-icon-button>
`
: ""}
<ha-button-menu corner="BOTTOM_START">
<ha-button-menu corner="BOTTOM_START" @action=${this._handleAction}>
<mwc-icon-button
slot="trigger"
.title=${this.hass.localize("ui.common.menu")}
.label=${this.hass.localize("ui.common.overflow_menu")}
><ha-svg-icon path=${mdiDotsVertical}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item
@tap=${this._switchYamlMode}
.disabled=${selected === -1}
>
<mwc-list-item .disabled=${!this._uiModeAvailable}>
${yamlMode
? this.hass.localize(
"ui.panel.config.automation.editor.edit_ui"
@@ -152,30 +156,39 @@ export default class HaAutomationActionRow extends LitElement {
"ui.panel.config.automation.editor.actions.duplicate"
)}
</mwc-list-item>
<mwc-list-item @tap=${this._onDelete}>
<mwc-list-item>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
)}
</mwc-list-item>
</ha-button-menu>
</div>
${this._warnings
? html`<div class="warning">
UI editor is not supported for this config:
<br />
<ul>
${this._warnings.map((warning) => html`<li>${warning}</li>`)}
</ul>
You can still edit your config in yaml.
</div>`
: ""}
${yamlMode
? html`
<div style="margin-right: 24px;">
${selected === -1
? html`
${this.hass.localize(
"ui.panel.config.automation.editor.actions.unsupported_action",
"action",
type
)}
`
: ""}
<ha-yaml-editor
.defaultValue=${this.action}
@value-changed=${this._onYamlChange}
></ha-yaml-editor>
</div>
${selected === -1
? html`
${this.hass.localize(
"ui.panel.config.automation.editor.actions.unsupported_action",
"action",
type
)}
`
: ""}
<h2>Edit in YAML</h2>
<ha-yaml-editor
.defaultValue=${this.action}
@value-changed=${this._onYamlChange}
></ha-yaml-editor>
`
: html`
<paper-dropdown-menu-light
@@ -200,7 +213,7 @@ export default class HaAutomationActionRow extends LitElement {
)}
</paper-listbox>
</paper-dropdown-menu-light>
<div>
<div @ui-mode-not-available=${this._handleUiModeNotAvailable}>
${dynamicElement(`ha-automation-action-${type}`, {
hass: this.hass,
action: this.action,
@@ -212,6 +225,13 @@ export default class HaAutomationActionRow extends LitElement {
`;
}
private _handleUiModeNotAvailable(ev: CustomEvent) {
this._warnings = handleStructError(ev.detail);
if (!this._yamlMode) {
this._yamlMode = true;
}
}
private _moveUp() {
fireEvent(this, "move-action", { direction: "up" });
}
@@ -220,6 +240,19 @@ export default class HaAutomationActionRow extends LitElement {
fireEvent(this, "move-action", { direction: "down" });
}
private _handleAction(ev: CustomEvent<ActionDetail>) {
switch (ev.detail.index) {
case 0:
this._switchYamlMode();
break;
case 1:
break;
case 2:
this._onDelete();
break;
}
}
private _onDelete() {
showConfirmationDialog(this, {
text: this.hass.localize(
@@ -241,6 +274,11 @@ export default class HaAutomationActionRow extends LitElement {
return;
}
this._uiModeAvailable = OPTIONS.includes(type);
if (!this._uiModeAvailable && !this._yamlMode) {
this._yamlMode = false;
}
if (type !== getType(this.action)) {
const elClass = customElements.get(`ha-automation-action-${type}`);
@@ -264,26 +302,30 @@ export default class HaAutomationActionRow extends LitElement {
this._yamlMode = !this._yamlMode;
}
static get styles(): CSSResult {
return css`
.card-menu {
position: absolute;
top: 0;
right: 0;
z-index: 3;
--mdc-theme-text-primary-on-background: var(--primary-text-color);
}
.rtl .card-menu {
right: auto;
left: 0;
}
ha-button-menu {
margin: 8px;
}
mwc-list-item[disabled] {
--mdc-theme-text-primary-on-background: var(--disabled-text-color);
}
`;
static get styles(): CSSResult[] {
return [
haStyle,
css`
.card-menu {
float: right;
z-index: 3;
--mdc-theme-text-primary-on-background: var(--primary-text-color);
}
.rtl .card-menu {
float: left;
}
mwc-list-item[disabled] {
--mdc-theme-text-primary-on-background: var(--disabled-text-color);
}
.warning {
color: var(--warning-color);
margin-bottom: 8px;
}
.warning ul {
margin: 4px 0;
}
`,
];
}
}

View File

@@ -97,6 +97,7 @@ export class HaDeviceAction extends LitElement {
protected updated(changedPros) {
const prevAction = changedPros.get("action");
if (prevAction && !deviceAutomationsEqual(prevAction, this.action)) {
this._deviceId = undefined;
this._getCapabilities();
}
}

View File

@@ -19,12 +19,20 @@ import { ServiceAction } from "../../../../../data/script";
import type { PolymerChangedEvent } from "../../../../../polymer-types";
import type { HomeAssistant } from "../../../../../types";
import { ActionElement, handleChangeEvent } from "../ha-automation-action-row";
import { assert, optional, object, string } from "superstruct";
import { EntityId } from "../../../../lovelace/common/structs/is-entity-id";
const actionStruct = object({
service: optional(string()),
entity_id: optional(EntityId),
data: optional(object()),
});
@customElement("ha-automation-action-service")
export class HaServiceAction extends LitElement implements ActionElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property() public action!: ServiceAction;
@property({ attribute: false }) public action!: ServiceAction;
@query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor;
@@ -60,6 +68,11 @@ export class HaServiceAction extends LitElement implements ActionElement {
if (!changedProperties.has("action")) {
return;
}
try {
assert(this.action, actionStruct);
} catch (error) {
fireEvent(this, "ui-mode-not-available", error);
}
if (this._actionData && this._actionData !== this.action.data) {
if (this._yamlEditor) {
this._yamlEditor.setValue(this.action.data);

View File

@@ -2,7 +2,13 @@ import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-listbox/paper-listbox";
import type { PaperListboxElement } from "@polymer/paper-listbox/paper-listbox";
import { customElement, html, LitElement, property } from "lit-element";
import {
customElement,
html,
LitElement,
property,
CSSResult,
} from "lit-element";
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-card";
@@ -19,6 +25,7 @@ import "./types/ha-automation-condition-sun";
import "./types/ha-automation-condition-template";
import "./types/ha-automation-condition-time";
import "./types/ha-automation-condition-zone";
import { haStyle } from "../../../../resources/styles";
const OPTIONS = [
"device",
@@ -47,21 +54,20 @@ export default class HaAutomationConditionEditor extends LitElement {
return html`
${yamlMode
? html`
<div style="margin-right: 24px;">
${selected === -1
? html`
${this.hass.localize(
"ui.panel.config.automation.editor.conditions.unsupported_condition",
"condition",
this.condition.condition
)}
`
: ""}
<ha-yaml-editor
.defaultValue=${this.condition}
@value-changed=${this._onYamlChange}
></ha-yaml-editor>
</div>
${selected === -1
? html`
${this.hass.localize(
"ui.panel.config.automation.editor.conditions.unsupported_condition",
"condition",
this.condition.condition
)}
`
: ""}
<h2>Edit in YAML</h2>
<ha-yaml-editor
.defaultValue=${this.condition}
@value-changed=${this._onYamlChange}
></ha-yaml-editor>
`
: html`
<paper-dropdown-menu-light
@@ -123,6 +129,10 @@ export default class HaAutomationConditionEditor extends LitElement {
}
fireEvent(this, "value-changed", { value: ev.detail.value });
}
static get styles(): CSSResult {
return haStyle;
}
}
declare global {

View File

@@ -18,6 +18,7 @@ import { Condition } from "../../../../data/automation";
import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box";
import { HomeAssistant } from "../../../../types";
import "./ha-automation-condition-editor";
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
export interface ConditionElement extends LitElement {
condition: Condition;
@@ -64,14 +65,14 @@ export default class HaAutomationConditionRow extends LitElement {
<ha-card>
<div class="card-content">
<div class="card-menu">
<ha-button-menu corner="BOTTOM_START">
<ha-button-menu corner="BOTTOM_START" @action=${this._handleAction}>
<mwc-icon-button
.title=${this.hass.localize("ui.common.menu")}
.label=${this.hass.localize("ui.common.overflow_menu")}
slot="trigger"
><ha-svg-icon path=${mdiDotsVertical}></ha-svg-icon
></mwc-icon-button>
<mwc-list-item @tap=${this._switchYamlMode}>
<mwc-list-item>
${this._yamlMode
? this.hass.localize(
"ui.panel.config.automation.editor.edit_ui"
@@ -85,7 +86,7 @@ export default class HaAutomationConditionRow extends LitElement {
"ui.panel.config.automation.editor.actions.duplicate"
)}
</mwc-list-item>
<mwc-list-item @tap=${this._onDelete}>
<mwc-list-item>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
)}
@@ -102,6 +103,19 @@ export default class HaAutomationConditionRow extends LitElement {
`;
}
private _handleAction(ev: CustomEvent<ActionDetail>) {
switch (ev.detail.index) {
case 0:
this._switchYamlMode();
break;
case 1:
break;
case 2:
this._onDelete();
break;
}
}
private _onDelete() {
showConfirmationDialog(this, {
text: this.hass.localize(
@@ -122,18 +136,12 @@ export default class HaAutomationConditionRow extends LitElement {
static get styles(): CSSResult {
return css`
.card-menu {
position: absolute;
top: 0;
right: 0;
float: right;
z-index: 3;
--mdc-theme-text-primary-on-background: var(--primary-text-color);
}
.rtl .card-menu {
right: auto;
left: 0;
}
ha-button-menu {
margin: 8px;
float: left;
}
mwc-list-item[disabled] {
--mdc-theme-text-primary-on-background: var(--disabled-text-color);

View File

@@ -50,6 +50,13 @@ import { PaperListboxElement } from "@polymer/paper-listbox";
const MODES = ["single", "restart", "queued", "parallel"];
const MODES_MAX = ["queued", "parallel"];
declare global {
// for fire event
interface HASSDomEvents {
"ui-mode-not-available": Error;
}
}
export class HaAutomationEditor extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@@ -534,7 +541,7 @@ export class HaAutomationEditor extends LitElement {
position: fixed;
bottom: 16px;
right: 16px;
z-index: 1;
z-index: 3;
margin-bottom: -80px;
transition: margin-bottom 0.3s;
}

View File

@@ -34,6 +34,8 @@ import "./types/ha-automation-trigger-time";
import "./types/ha-automation-trigger-time_pattern";
import "./types/ha-automation-trigger-webhook";
import "./types/ha-automation-trigger-zone";
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
import { haStyle } from "../../../../resources/styles";
const OPTIONS = [
"device",
@@ -93,17 +95,14 @@ export default class HaAutomationTriggerRow extends LitElement {
<ha-card>
<div class="card-content">
<div class="card-menu">
<ha-button-menu corner="BOTTOM_START">
<ha-button-menu corner="BOTTOM_START" @action=${this._handleAction}>
<mwc-icon-button
slot="trigger"
.title=${this.hass.localize("ui.common.menu")}
.label=${this.hass.localize("ui.common.overflow_menu")}
><ha-svg-icon path=${mdiDotsVertical}></ha-svg-icon
></mwc-icon-button>
<mwc-list-item
@tap=${this._switchYamlMode}
.disabled=${selected === -1}
>
<mwc-list-item .disabled=${selected === -1}>
${yamlMode
? this.hass.localize(
"ui.panel.config.automation.editor.edit_ui"
@@ -117,7 +116,7 @@ export default class HaAutomationTriggerRow extends LitElement {
"ui.panel.config.automation.editor.actions.duplicate"
)}
</mwc-list-item>
<mwc-list-item @tap=${this._onDelete}>
<mwc-list-item>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
)}
@@ -126,21 +125,20 @@ export default class HaAutomationTriggerRow extends LitElement {
</div>
${yamlMode
? html`
<div style="margin-right: 24px;">
${selected === -1
? html`
${this.hass.localize(
"ui.panel.config.automation.editor.triggers.unsupported_platform",
"platform",
this.trigger.platform
)}
`
: ""}
<ha-yaml-editor
.defaultValue=${this.trigger}
@value-changed=${this._onYamlChange}
></ha-yaml-editor>
</div>
${selected === -1
? html`
${this.hass.localize(
"ui.panel.config.automation.editor.triggers.unsupported_platform",
"platform",
this.trigger.platform
)}
`
: ""}
<h2>Edit in YAML</h2>
<ha-yaml-editor
.defaultValue=${this.trigger}
@value-changed=${this._onYamlChange}
></ha-yaml-editor>
`
: html`
<paper-dropdown-menu-light
@@ -177,6 +175,19 @@ export default class HaAutomationTriggerRow extends LitElement {
`;
}
private _handleAction(ev: CustomEvent<ActionDetail>) {
switch (ev.detail.index) {
case 0:
this._switchYamlMode();
break;
case 1:
break;
case 2:
this._onDelete();
break;
}
}
private _onDelete() {
showConfirmationDialog(this, {
text: this.hass.localize(
@@ -222,26 +233,23 @@ export default class HaAutomationTriggerRow extends LitElement {
this._yamlMode = !this._yamlMode;
}
static get styles(): CSSResult {
return css`
.card-menu {
position: absolute;
top: 0;
right: 0;
z-index: 3;
--mdc-theme-text-primary-on-background: var(--primary-text-color);
}
.rtl .card-menu {
right: auto;
left: 0;
}
ha-button-menu {
margin: 8px;
}
mwc-list-item[disabled] {
--mdc-theme-text-primary-on-background: var(--disabled-text-color);
}
`;
static get styles(): CSSResult[] {
return [
haStyle,
css`
.card-menu {
float: right;
z-index: 3;
--mdc-theme-text-primary-on-background: var(--primary-text-color);
}
.rtl .card-menu {
float: left;
}
mwc-list-item[disabled] {
--mdc-theme-text-primary-on-background: var(--disabled-text-color);
}
`,
];
}
}

View File

@@ -57,6 +57,7 @@ import {
showEntityEditorDialog,
} from "./show-dialog-entity-editor";
import { mdiFilterVariant } from "@mdi/js";
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
export interface StateEntity extends EntityRegistryEntry {
readonly?: boolean;
@@ -449,7 +450,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
>
</div>`
: ""}
<ha-button-menu corner="BOTTOM_START">
<ha-button-menu corner="BOTTOM_START" multi>
<mwc-icon-button
slot="trigger"
.label=${this.hass!.localize(
@@ -462,8 +463,9 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
<ha-svg-icon path=${mdiFilterVariant}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item
@click="${this._showDisabledChanged}"
@request-selected="${this._showDisabledChanged}"
graphic="control"
.selected=${this._showDisabled}
>
<ha-checkbox
slot="graphic"
@@ -474,8 +476,9 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
)}
</mwc-list-item>
<mwc-list-item
@click="${this._showRestoredChanged}"
@request-selected="${this._showRestoredChanged}"
graphic="control"
.selected=${this._showUnavailable}
>
<ha-checkbox
slot="graphic"
@@ -486,8 +489,9 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
)}
</mwc-list-item>
<mwc-list-item
@click="${this._showReadOnlyChanged}"
@request-selected="${this._showReadOnlyChanged}"
graphic="control"
.selected=${this._showReadOnly}
>
<ha-checkbox
slot="graphic"
@@ -579,16 +583,25 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
}
}
private _showDisabledChanged() {
this._showDisabled = !this._showDisabled;
private _showDisabledChanged(ev: CustomEvent<RequestSelectedDetail>) {
if (ev.detail.source !== "property") {
return;
}
this._showDisabled = ev.detail.selected;
}
private _showRestoredChanged() {
this._showUnavailable = !this._showUnavailable;
private _showRestoredChanged(ev: CustomEvent<RequestSelectedDetail>) {
if (ev.detail.source !== "property") {
return;
}
this._showUnavailable = ev.detail.selected;
}
private _showReadOnlyChanged() {
this._showReadOnly = !this._showReadOnly;
private _showReadOnlyChanged(ev: CustomEvent<RequestSelectedDetail>) {
if (ev.detail.source !== "property") {
return;
}
this._showReadOnly = ev.detail.selected;
}
private _handleSearchChange(ev: CustomEvent) {

View File

@@ -276,7 +276,11 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
</div>
`
: ""}
<ha-button-menu corner="BOTTOM_START" slot="toolbar-icon">
<ha-button-menu
corner="BOTTOM_START"
slot="toolbar-icon"
@action=${this._toggleShowIgnored}
>
<mwc-icon-button
.title=${this.hass.localize("ui.common.menu")}
.label=${this.hass.localize("ui.common.overflow_menu")}
@@ -284,7 +288,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
>
<ha-svg-icon path=${mdiDotsVertical}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item @click=${this._toggleShowIgnored}>
<mwc-list-item>
${this.hass.localize(
this._showIgnored
? "ui.panel.config.integrations.ignore.hide_ignored"

View File

@@ -28,6 +28,7 @@ import { haStyle } from "../../../resources/styles";
import "../../../components/ha-icon-next";
import { fireEvent } from "../../../common/dom/fire_event";
import { mdiDotsVertical, mdiOpenInNew } from "@mdi/js";
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
export interface ConfigEntryUpdatedEvent {
entry: ConfigEntry;
@@ -223,7 +224,7 @@ export class HaIntegrationCard extends LitElement {
`
: ""}
</div>
<ha-button-menu corner="BOTTOM_START">
<ha-button-menu corner="BOTTOM_START" @action=${this._handleAction}>
<mwc-icon-button
.title=${this.hass.localize("ui.common.menu")}
.label=${this.hass.localize("ui.common.overflow_menu")}
@@ -231,7 +232,7 @@ export class HaIntegrationCard extends LitElement {
>
<ha-svg-icon path=${mdiDotsVertical}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item @click=${this._showSystemOptions}>
<mwc-list-item>
${this.hass.localize(
"ui.panel.config.integrations.config_entry.system_options"
)}
@@ -240,7 +241,6 @@ export class HaIntegrationCard extends LitElement {
? ""
: html`
<a
class="documentation"
href=${this.manifest.documentation}
rel="noreferrer"
target="_blank"
@@ -255,7 +255,7 @@ export class HaIntegrationCard extends LitElement {
</mwc-list-item>
</a>
`}
<mwc-list-item class="warning" @click=${this._removeIntegration}>
<mwc-list-item class="warning">
${this.hass.localize(
"ui.panel.config.integrations.config_entry.delete"
)}
@@ -305,32 +305,27 @@ export class HaIntegrationCard extends LitElement {
showOptionsFlowDialog(this, ev.target.closest("ha-card").configEntry);
}
private _showSystemOptions(ev) {
showConfigEntrySystemOptionsDialog(this, {
entry: ev.target.closest("ha-card").configEntry,
});
}
private async _editEntryName(ev) {
const configEntry = ev.target.closest("ha-card").configEntry;
const newName = await showPromptDialog(this, {
title: this.hass.localize("ui.panel.config.integrations.rename_dialog"),
defaultValue: configEntry.title,
inputLabel: this.hass.localize(
"ui.panel.config.integrations.rename_input_label"
),
});
if (newName === null) {
return;
private _handleAction(ev: CustomEvent<ActionDetail>) {
const configEntry = ((ev.target as HTMLElement).closest("ha-card") as any)
.configEntry;
switch (ev.detail.index) {
case 0:
this._showSystemOptions(configEntry);
break;
case 1:
this._removeIntegration(configEntry);
break;
}
const newEntry = await updateConfigEntry(this.hass, configEntry.entry_id, {
title: newName,
});
fireEvent(this, "entry-updated", { entry: newEntry });
}
private async _removeIntegration(ev) {
const entryId = ev.target.closest("ha-card").configEntry.entry_id;
private _showSystemOptions(configEntry: ConfigEntry) {
showConfigEntrySystemOptionsDialog(this, {
entry: configEntry,
});
}
private async _removeIntegration(configEntry: ConfigEntry) {
const entryId = configEntry.entry_id;
const confirmed = await showConfirmationDialog(this, {
text: this.hass.localize(
@@ -354,6 +349,24 @@ export class HaIntegrationCard extends LitElement {
});
}
private async _editEntryName(ev) {
const configEntry = ev.target.closest("ha-card").configEntry;
const newName = await showPromptDialog(this, {
title: this.hass.localize("ui.panel.config.integrations.rename_dialog"),
defaultValue: configEntry.title,
inputLabel: this.hass.localize(
"ui.panel.config.integrations.rename_input_label"
),
});
if (newName === null) {
return;
}
const newEntry = await updateConfigEntry(this.hass, configEntry.entry_id, {
title: newName,
});
fireEvent(this, "entry-updated", { entry: newEntry });
}
static get styles(): CSSResult[] {
return [
haStyle,
@@ -386,9 +399,6 @@ export class HaIntegrationCard extends LitElement {
align-items: center;
padding-right: 5px;
}
.card-actions .documentation {
color: var(--primary-text-color);
}
.group-header {
display: flex;
align-items: center;

View File

@@ -93,6 +93,8 @@ export class ZHAClustersDataTable extends LitElement {
selectable
auto-height
.dir=${computeRTLDirection(this.hass)}
.searchLabel=${this.hass.localize("ui.components.data-table.search")}
.noDataText=${this.hass.localize("ui.components.data-table.no-data")}
></ha-data-table>
`;
}

View File

@@ -149,6 +149,8 @@ export class ZHADeviceEndpointDataTable extends LitElement {
.selectable=${this.selectable}
auto-height
.dir=${computeRTLDirection(this.hass)}
.searchLabel=${this.hass.localize("ui.components.data-table.search")}
.noDataText=${this.hass.localize("ui.components.data-table.no-data")}
></ha-data-table>
`;
}

View File

@@ -440,7 +440,7 @@ export class HaScriptEditor extends LitElement {
position: fixed;
bottom: 16px;
right: 16px;
z-index: 1;
z-index: 3;
margin-bottom: -80px;
transition: margin-bottom 0.3s;
}

View File

@@ -29,7 +29,6 @@ class HaPanelDevEvent extends EventsMixin(LocalizeMixin(PolymerElement)) {
-moz-user-select: initial;
@apply --paper-font-body1;
padding: 16px;
direction: ltr;
display: block;
}

View File

@@ -11,6 +11,7 @@ import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
import LocalizeMixin from "../../../mixins/localize-mixin";
import "../../../styles/polymer-ha-style";
import "../../../util/app-localstorage-document";
import { computeRTL } from "../../../common/util/compute_rtl";
const ERROR_SENTINEL = {};
/*
@@ -26,7 +27,6 @@ class HaPanelDevService extends LocalizeMixin(PolymerElement) {
-moz-user-select: initial;
display: block;
padding: 16px;
direction: ltr;
}
.ha-form {
@@ -51,8 +51,13 @@ class HaPanelDevService extends LocalizeMixin(PolymerElement) {
text-align: left;
}
:host([rtl]) .attributes th {
text-align: right;
}
.attributes tr {
vertical-align: top;
direction: ltr;
}
.attributes tr:nth-child(odd) {
@@ -83,6 +88,14 @@ class HaPanelDevService extends LocalizeMixin(PolymerElement) {
.error {
color: var(--error-color);
}
:host([rtl]) .desc-container {
text-align: right;
}
:host([rtl]) .desc-container h3 {
direction: ltr;
}
</style>
<app-localstorage-document
@@ -141,7 +154,9 @@ class HaPanelDevService extends LocalizeMixin(PolymerElement) {
</h1>
</template>
<template is="dom-if" if="[[_description]]">
<h3>[[_description]]</h3>
<div class="desc-container">
<h3>[[_description]]</h3>
</div>
<table class="attributes">
<tr>
@@ -227,6 +242,10 @@ class HaPanelDevService extends LocalizeMixin(PolymerElement) {
type: String,
computed: "_computeDescription(hass, _domain, _service)",
},
rtl: {
reflectToAttribute: true,
computed: "_computeRTL(hass)",
},
};
}
@@ -329,6 +348,10 @@ class HaPanelDevService extends LocalizeMixin(PolymerElement) {
_yamlChanged(ev) {
this.serviceData = ev.detail.value;
}
_computeRTL(hass) {
return computeRTL(hass);
}
}
customElements.define("developer-tools-service", HaPanelDevService);

View File

@@ -13,6 +13,7 @@ import { EventsMixin } from "../../../mixins/events-mixin";
import LocalizeMixin from "../../../mixins/localize-mixin";
import "../../../styles/polymer-ha-style";
import { mdiInformationOutline } from "@mdi/js";
import { computeRTL } from "../../../common/util/compute_rtl";
const ERROR_SENTINEL = {};
/*
@@ -29,7 +30,6 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) {
-moz-user-select: initial;
display: block;
padding: 16px;
direction: ltr;
}
.inputs {
@@ -44,8 +44,13 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) {
text-align: left;
}
:host([rtl]) .entities th {
text-align: right;
}
.entities tr {
vertical-align: top;
direction: ltr;
}
.entities tr:nth-child(odd) {
@@ -232,6 +237,10 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) {
computed:
"computeEntities(hass, _entityFilter, _stateFilter, _attributeFilter)",
},
rtl: {
reflectToAttribute: true,
computed: "_computeRTL(hass)",
},
};
}
@@ -396,6 +405,10 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) {
_yamlChanged(ev) {
this._stateAttributes = ev.detail.value;
}
_computeRTL(hass) {
return computeRTL(hass);
}
}
customElements.define("developer-tools-state", HaPanelDevState);

View File

@@ -14,7 +14,7 @@ import { formatTimeWithSeconds } from "../../common/datetime/format_time";
import { fireEvent } from "../../common/dom/fire_event";
import { domainIcon } from "../../common/entity/domain_icon";
import { stateIcon } from "../../common/entity/state_icon";
import { computeRTL } from "../../common/util/compute_rtl";
import { computeRTL, emitRTLDirection } from "../../common/util/compute_rtl";
import "../../components/ha-icon";
import { LogbookEntry } from "../../data/logbook";
import { HomeAssistant } from "../../types";
@@ -28,7 +28,6 @@ class HaLogbook extends LitElement {
@property() public entries: LogbookEntry[] = [];
@property({ attribute: "rtl", type: Boolean, reflect: true })
// @ts-ignore
private _rtl = false;
// @ts-ignore
@@ -38,17 +37,22 @@ class HaLogbook extends LitElement {
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
const languageChanged =
oldHass === undefined || oldHass.language !== this.hass.language;
return changedProps.has("entries") || languageChanged;
}
protected updated(_changedProps: PropertyValues) {
this._rtl = computeRTL(this.hass);
const oldHass = _changedProps.get("hass") as HomeAssistant | undefined;
if (oldHass === undefined || oldHass.language !== this.hass.language) {
this._rtl = computeRTL(this.hass);
}
}
protected render(): TemplateResult {
if (!this.entries?.length) {
return html`
<div class="container">
<div class="container" .dir=${emitRTLDirection(this._rtl)}>
${this.hass.localize("ui.panel.logbook.entries_not_found")}
</div>
`;
@@ -106,9 +110,8 @@ class HaLogbook extends LitElement {
@click=${this._entityClicked}
.entityId=${item.entity_id}
class="name"
>${item.name}</a
>
${item.name}
</a>
`}
<span
>${item.message}${item_username

View File

@@ -1,5 +1,4 @@
import { HassEntity } from "home-assistant-js-websocket/dist/types";
import Gauge from "svg-gauge";
import {
css,
CSSResult,
@@ -10,7 +9,6 @@ import {
internalProperty,
PropertyValues,
TemplateResult,
query,
} from "lit-element";
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
@@ -24,6 +22,8 @@ import { hasConfigOrEntityChanged } from "../common/has-changed";
import { createEntityNotFoundWarning } from "../components/hui-warning";
import type { LovelaceCard, LovelaceCardEditor } from "../types";
import type { GaugeCardConfig } from "./types";
import "../../../components/ha-gauge";
import { styleMap } from "lit-html/directives/style-map";
export const severityMap = {
red: "var(--label-badge-red)",
@@ -68,10 +68,6 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
@internalProperty() private _config?: GaugeCardConfig;
@internalProperty() private _gauge?: any;
@query("#gauge") private _gaugeElement!: HTMLDivElement;
public getCardSize(): number {
return 2;
}
@@ -84,7 +80,6 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
throw new Error("Invalid Entity");
}
this._config = { min: 0, max: 100, ...config };
this._initGauge();
}
protected render(): TemplateResult {
@@ -118,7 +113,18 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
return html`
<ha-card @click=${this._handleClick} tabindex="0">
<div id="gauge"></div>
<ha-gauge
.min=${this._config.min!}
.max=${this._config.max!}
.value=${state}
.label=${this._config!.unit ||
this.hass?.states[this._config!.entity].attributes
.unit_of_measurement ||
""}
style=${styleMap({
"--gauge-color": this._computeSeverity(state),
})}
></ha-gauge>
<div class="name">
${this._config.name || computeStateName(stateObj)}
</div>
@@ -130,13 +136,6 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
return hasConfigOrEntityChanged(this, changedProps);
}
protected firstUpdated(changedProps: PropertyValues): void {
super.firstUpdated(changedProps);
if (!this._gauge) {
this._initGauge();
}
}
protected updated(changedProps: PropertyValues): void {
super.updated(changedProps);
if (!this._config || !this.hass) {
@@ -156,66 +155,38 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
) {
applyThemesOnElement(this, this.hass.themes, this._config.theme);
}
const oldState = oldHass?.states[this._config.entity];
const stateObj = this.hass.states[this._config.entity];
if (oldState?.state !== stateObj.state) {
this._gauge.setValueAnimated(stateObj.state, 1);
}
}
private _initGauge() {
if (!this._gaugeElement || !this._config || !this.hass) {
return;
private _computeSeverity(numberValue: number): string {
const sections = this._config!.severity;
if (!sections) {
return severityMap.normal;
}
if (this._gauge) {
this._gaugeElement.removeChild(this._gaugeElement.lastChild!);
this._gauge = undefined;
}
this._gauge = Gauge(this._gaugeElement, {
min: this._config.min,
max: this._config.max,
dialStartAngle: 180,
dialEndAngle: 0,
viewBox: "0 0 100 55",
label: (value) => `${Math.round(value)}
${
this._config!.unit ||
this.hass?.states[this._config!.entity].attributes
.unit_of_measurement ||
""
}`,
color: (value) => {
const sections = this._config!.severity;
if (!sections) {
return severityMap.normal;
}
const sectionsArray = Object.keys(sections);
const sortable = sectionsArray.map((severity) => [
severity,
sections[severity],
]);
const sectionsArray = Object.keys(sections);
const sortable = sectionsArray.map((severity) => [
severity,
sections[severity],
]);
for (const severity of sortable) {
if (severityMap[severity[0]] == null || isNaN(severity[1])) {
return severityMap.normal;
}
}
sortable.sort((a, b) => a[1] - b[1]);
if (value >= sortable[0][1] && value < sortable[1][1]) {
return severityMap[sortable[0][0]];
}
if (value >= sortable[1][1] && value < sortable[2][1]) {
return severityMap[sortable[1][0]];
}
if (value >= sortable[2][1]) {
return severityMap[sortable[2][0]];
}
for (const severity of sortable) {
if (severityMap[severity[0]] == null || isNaN(severity[1])) {
return severityMap.normal;
},
});
}
}
sortable.sort((a, b) => a[1] - b[1]);
if (numberValue >= sortable[0][1] && numberValue < sortable[1][1]) {
return severityMap[sortable[0][0]];
}
if (numberValue >= sortable[1][1] && numberValue < sortable[2][1]) {
return severityMap[sortable[1][0]];
}
if (numberValue >= sortable[2][1]) {
return severityMap[sortable[2][0]];
}
return severityMap.normal;
}
private _handleClick(): void {
@@ -244,31 +215,20 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
outline: none;
background: var(--divider-color);
}
#gauge {
ha-gauge {
--gauge-color: var(--label-badge-blue);
width: 100%;
max-width: 300px;
}
.dial {
stroke: #ccc;
stroke-width: 15;
}
.value {
stroke-width: 15;
}
.value-text {
fill: var(--primary-text-color);
font-size: var(--gauge-value-font-size, 1.1em);
transform: translate(0, -5px);
font-family: inherit;
max-width: 250px;
}
.name {
text-align: center;
line-height: initial;
color: var(--primary-text-color);
width: 100%;
font-size: 15px;
}
margin-top: 8px;
}
`;
}

View File

@@ -61,6 +61,8 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
private _interval?: number;
private _fetching = false;
public getCardSize(): number {
return 4;
}
@@ -138,6 +140,7 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
>
<state-history-charts
.hass=${this.hass}
.isLoadingData=${!this._stateHistory}
.historyData=${this._stateHistory}
.names=${this._names}
.upToNow=${true}
@@ -149,13 +152,21 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
}
private async _getStateHistory(): Promise<void> {
this._stateHistory = await getRecentWithCache(
this.hass!,
this._cacheConfig!.cacheKey,
this._cacheConfig!,
this.hass!.localize,
this.hass!.language
);
if (this._fetching) {
return;
}
this._fetching = true;
try {
this._stateHistory = await getRecentWithCache(
this.hass!,
this._cacheConfig!.cacheKey,
this._cacheConfig!,
this.hass!.localize,
this.hass!.language
);
} finally {
this._fetching = false;
}
}
private _clearInterval(): void {

View File

@@ -105,7 +105,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
.min=${stateObj.attributes.min_humidity}
.max=${stateObj.attributes.max_humidity}
.rtl=${rtlDirection === "rtl"}
.step="1"
step="1"
@value-changing=${this._dragEvent}
@value-changed=${this._setHumidity}
></round-slider>

View File

@@ -12,6 +12,7 @@ import {
PropertyValues,
svg,
TemplateResult,
query,
} from "lit-element";
import { classMap } from "lit-html/directives/class-map";
import { UNIT_F } from "../../../common/const";
@@ -33,6 +34,7 @@ import { hasConfigOrEntityChanged } from "../common/has-changed";
import { createEntityNotFoundWarning } from "../components/hui-warning";
import { LovelaceCard, LovelaceCardEditor } from "../types";
import { ThermostatCardConfig } from "./types";
import type { HaCard } from "../../../components/ha-card";
const modeIcons: { [mode in HvacMode]: string } = {
auto: "hass:calendar-sync",
@@ -77,6 +79,8 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
@internalProperty() private _setTemp?: number | number[];
@query("ha-card") private _card?: HaCard;
public getCardSize(): number {
return 5;
}
@@ -290,18 +294,17 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
// That way it will auto-scale correctly
// This is not done to the SVG containing the current temperature, because
// it should not be centered on the text, but only on the value
if (this.shadowRoot && this.shadowRoot.querySelector("ha-card")) {
(this.shadowRoot.querySelector(
"ha-card"
) as LitElement).updateComplete.then(() => {
const svgRoot = this.shadowRoot!.querySelector("#set-values");
const box = svgRoot!.querySelector("g")!.getBBox();
svgRoot!.setAttribute(
const card = this._card;
if (card) {
card.updateComplete.then(() => {
const svgRoot = this.shadowRoot!.querySelector("#set-values")!;
const box = svgRoot.querySelector("g")!.getBBox()!;
svgRoot.setAttribute(
"viewBox",
`${box!.x} ${box!.y} ${box!.width} ${box!.height}`
`${box.x} ${box!.y} ${box.width} ${box.height}`
);
svgRoot!.setAttribute("width", `${box!.width}`);
svgRoot!.setAttribute("height", `${box!.height}`);
svgRoot.setAttribute("width", `${box.width}`);
svgRoot.setAttribute("height", `${box.height}`);
});
}
}

View File

@@ -0,0 +1,24 @@
import { StructError } from "superstruct";
export const handleStructError = (err: Error): string[] => {
if (!(err instanceof StructError)) {
return [err.message];
}
const errors: string[] = [];
for (const failure of err.failures()) {
if (failure.type === "never") {
errors.push(
`Key "${failure.path[0]}" is not supported by the UI editor.`
);
} else {
errors.push(
`The value of "${failure.path.join(
"."
)}" is not supported by the UI editor, we support "${
failure.type
}" but received "${JSON.stringify(failure.value)}".`
);
}
}
return errors;
};

View File

@@ -1,9 +1,17 @@
export function isEntityId(value: any): string | boolean {
import { StructResult, StructContext, struct } from "superstruct";
const isEntityId = (value: unknown, context: StructContext): StructResult => {
if (typeof value !== "string") {
return "entity id should be a string";
return [context.fail({ type: "string" })];
}
if (!value.includes(".")) {
return "entity id should be in the format 'domain.entity'";
return [
context.fail({
type: "entity id should be in the format 'domain.entity'",
}),
];
}
return true;
}
};
export const EntityId = struct("entity-id", isEntityId);

View File

@@ -1,9 +1,17 @@
export function isIcon(value: any): string | boolean {
import { StructContext, StructResult, struct } from "superstruct";
const isIcon = (value: unknown, context: StructContext): StructResult => {
if (typeof value !== "string") {
return "icon should be a string";
return [context.fail({ type: "string" })];
}
if (!value.includes(":")) {
return "icon should be in the format 'mdi:icon'";
return [
context.fail({
type: "icon should be in the format 'mdi:icon'",
}),
];
}
return true;
}
};
export const Icon = struct("icon", isIcon);

View File

@@ -1,10 +0,0 @@
import { superstruct } from "superstruct";
import { isEntityId } from "./is-entity-id";
import { isIcon } from "./is-icon";
export const struct = superstruct({
types: {
"entity-id": isEntityId,
icon: isIcon,
},
});

View File

@@ -20,6 +20,7 @@ import { confDeleteCard } from "../editor/delete-card";
import { Lovelace, LovelaceCard } from "../types";
import { computeCardSize } from "../common/compute-card-size";
import { mdiDotsVertical, mdiArrowDown, mdiArrowUp } from "@mdi/js";
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
@customElement("hui-card-options")
export class HuiCardOptions extends LitElement {
@@ -65,7 +66,7 @@ export class HuiCardOptions extends LitElement {
?disabled=${this.path![1] === 0}
><ha-svg-icon path=${mdiArrowUp}></ha-svg-icon
></mwc-icon-button>
<ha-button-menu corner="BOTTOM_START">
<ha-button-menu corner="BOTTOM_START" @action=${this._handleAction}>
<mwc-icon-button
slot="trigger"
aria-label=${this.hass!.localize(
@@ -78,17 +79,17 @@ export class HuiCardOptions extends LitElement {
<ha-svg-icon path=${mdiDotsVertical}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item @tap=${this._moveCard}>
<mwc-list-item>
${this.hass!.localize(
"ui.panel.lovelace.editor.edit_card.move"
)}</mwc-list-item
>
<mwc-list-item @tap=${this._duplicateCard}
<mwc-list-item
>${this.hass!.localize(
"ui.panel.lovelace.editor.edit_card.duplicate"
)}</mwc-list-item
>
<mwc-list-item class="delete-item" @tap=${this._deleteCard}>
<mwc-list-item class="delete-item">
${this.hass!.localize(
"ui.panel.lovelace.editor.edit_card.delete"
)}</mwc-list-item
@@ -147,6 +148,20 @@ export class HuiCardOptions extends LitElement {
`;
}
private _handleAction(ev: CustomEvent<ActionDetail>) {
switch (ev.detail.index) {
case 0:
this._moveCard();
break;
case 1:
this._duplicateCard();
break;
case 2:
this._deleteCard();
break;
}
}
private _duplicateCard(): void {
const path = this.path!;
const cardConfig = this.lovelace!.config.views[path[0]].cards![path[1]];

View File

@@ -26,6 +26,8 @@ import type { LovelaceCardEditor } from "../../types";
import type { GUIModeChangedEvent } from "../types";
import "../../../../components/ha-circular-progress";
import { deepEqual } from "../../../../common/util/deep-equal";
import { handleStructError } from "../../common/structs/handle-errors";
import { GUISupportError } from "../gui-support-error";
export interface ConfigChangedEvent {
config: LovelaceCardConfig;
@@ -69,7 +71,7 @@ export class HuiCardEditor extends LitElement {
@internalProperty() private _error?: string;
// Warning: GUI editor can't handle configuration - ok to save
@internalProperty() private _warning?: string;
@internalProperty() private _warnings?: string[];
@internalProperty() private _loading = false;
@@ -121,7 +123,7 @@ export class HuiCardEditor extends LitElement {
}
public get hasWarning(): boolean {
return this._warning !== undefined;
return this._warnings !== undefined;
}
public get hasError(): boolean {
@@ -194,10 +196,15 @@ export class HuiCardEditor extends LitElement {
</div>
`
: ""}
${this._warning
${this._warnings
? html`
<div class="warning">
${this._warning}
UI editor is not supported for this config:
<br />
<ul>
${this._warnings.map((warning) => html`<li>${warning}</li>`)}
</ul>
You can still edit your config in yaml.
</div>
`
: ""}
@@ -238,7 +245,7 @@ export class HuiCardEditor extends LitElement {
let configElement = this._configElement;
try {
this._error = undefined;
this._warning = undefined;
this._warnings = undefined;
if (this._configElType !== cardType) {
// If the card type has changed, we need to load a new GUI editor
@@ -254,7 +261,9 @@ export class HuiCardEditor extends LitElement {
configElement = await elClass.getConfigElement();
} else {
configElement = undefined;
throw Error(`WARNING: No visual editor available for: ${cardType}`);
throw new GUISupportError(
`No visual editor available for: ${cardType}`
);
}
this._configElement = configElement;
@@ -272,11 +281,14 @@ export class HuiCardEditor extends LitElement {
try {
this._configElement!.setConfig(this.value);
} catch (err) {
throw Error(`WARNING: ${err.message}`);
throw new GUISupportError(
"Config is not supported",
handleStructError(err)
);
}
} catch (err) {
if (err.message.startsWith("WARNING:")) {
this._warning = err.message.substr(8);
if (err instanceof GUISupportError) {
this._warnings = err.warnings ?? [err.message];
} else {
this._error = err;
}
@@ -302,12 +314,19 @@ export class HuiCardEditor extends LitElement {
.yaml-editor {
padding: 8px 0px;
}
.error,
.warning {
word-break: break-word;
}
.error {
color: var(--error-color);
}
.warning {
color: var(--warning-color);
}
.warning ul {
margin: 4px 0;
}
ha-circular-progress {
display: block;
margin: auto;

View File

@@ -1,3 +1,4 @@
import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable";
import deepFreeze from "deep-freeze";
import {
css,

View File

@@ -11,7 +11,7 @@ import {
TemplateResult,
PropertyValues,
} from "lit-element";
import type { HASSDomEvent } from "../../../../common/dom/fire_event";
import { HASSDomEvent, fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-dialog";
import type {
LovelaceCardConfig,
@@ -30,6 +30,9 @@ import "./hui-card-preview";
import type { EditCardDialogParams } from "./show-edit-card-dialog";
import { getCardDocumentationURL } from "../get-card-documentation-url";
import { mdiHelpCircle } from "@mdi/js";
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
import { HassDialog } from "../../../../dialogs/make-dialog-manager";
import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box";
declare global {
// for fire event
@@ -43,7 +46,7 @@ declare global {
}
@customElement("hui-dialog-edit-card")
export class HuiDialogEditCard extends LitElement {
export class HuiDialogEditCard extends LitElement implements HassDialog {
@property() protected hass!: HomeAssistant;
@internalProperty() private _params?: EditCardDialogParams;
@@ -64,6 +67,8 @@ export class HuiDialogEditCard extends LitElement {
@internalProperty() private _documentationURL?: string;
@internalProperty() private _dirty = false;
public async showDialog(params: EditCardDialogParams): Promise<void> {
this._params = params;
this._GUImode = true;
@@ -77,6 +82,20 @@ export class HuiDialogEditCard extends LitElement {
}
}
public closeDialog(): boolean {
if (this._dirty) {
this._confirmCancel();
return false;
}
this._params = undefined;
this._cardConfig = undefined;
this._error = undefined;
this._documentationURL = undefined;
this._dirty = false;
fireEvent(this, "dialog-closed", { dialog: this.localName });
return true;
}
protected updated(changedProps: PropertyValues): void {
if (
!this._cardConfig ||
@@ -100,9 +119,13 @@ export class HuiDialogEditCard extends LitElement {
let heading: string;
if (this._cardConfig && this._cardConfig.type) {
heading = `${this.hass!.localize(
`ui.panel.lovelace.editor.card.${this._cardConfig.type}.name`
)} ${this.hass!.localize("ui.panel.lovelace.editor.edit_card.header")}`;
heading = this.hass!.localize(
"ui.panel.lovelace.editor.edit_card.typed_header",
"type",
this.hass!.localize(
`ui.panel.lovelace.editor.card.${this._cardConfig.type}.name`
)
);
} else if (!this._cardConfig) {
heading = this._viewConfig.title
? this.hass!.localize(
@@ -122,7 +145,7 @@ export class HuiDialogEditCard extends LitElement {
open
scrimClickAction
@keydown=${this._ignoreKeydown}
@closed=${this._close}
@closed=${this._cancel}
@opened=${this._opened}
.heading=${html`${heading}
${this._documentationURL !== undefined
@@ -133,6 +156,7 @@ export class HuiDialogEditCard extends LitElement {
title=${this.hass!.localize("ui.panel.lovelace.menu.help")}
target="_blank"
rel="noreferrer"
dir=${computeRTLDirection(this.hass)}
>
<mwc-icon-button>
<ha-svg-icon path=${mdiHelpCircle}></ha-svg-icon>
@@ -197,7 +221,7 @@ export class HuiDialogEditCard extends LitElement {
`
: ""}
<div slot="primaryAction" @click=${this._save}>
<mwc-button @click=${this._close}>
<mwc-button @click=${this._cancel}>
${this.hass!.localize("ui.common.cancel")}
</mwc-button>
${this._cardConfig !== undefined
@@ -214,7 +238,9 @@ export class HuiDialogEditCard extends LitElement {
size="small"
></ha-circular-progress>
`
: this.hass!.localize("ui.common.save")}
: this._dirty
? this.hass!.localize("ui.common.save")
: this.hass!.localize("ui.common.close")}
</mwc-button>
`
: ``}
@@ -344,12 +370,14 @@ export class HuiDialogEditCard extends LitElement {
}
this._cardConfig = deepFreeze(config);
this._error = ev.detail.error;
this._dirty = true;
}
private _handleConfigChanged(ev: HASSDomEvent<ConfigChangedEvent>) {
this._cardConfig = deepFreeze(ev.detail.config);
this._error = ev.detail.error;
this._guiModeAvailable = ev.detail.guiModeAvailable;
this._dirty = true;
}
private _handleGUIModeChanged(ev: HASSDomEvent<GUIModeChangedEvent>): void {
@@ -366,13 +394,6 @@ export class HuiDialogEditCard extends LitElement {
this._cardEditorEl?.refreshYamlEditor();
}
private _close(): void {
this._params = undefined;
this._cardConfig = undefined;
this._error = undefined;
this._documentationURL = undefined;
}
private get _canSave(): boolean {
if (this._saving) {
return false;
@@ -386,8 +407,38 @@ export class HuiDialogEditCard extends LitElement {
return true;
}
private async _confirmCancel() {
// Make sure the open state of this dialog is handled before the open state of confirm dialog
await new Promise((resolve) => setTimeout(resolve, 0));
const confirm = await showConfirmationDialog(this, {
title: this.hass!.localize(
"ui.panel.lovelace.editor.edit_card.unsaved_changes"
),
text: this.hass!.localize(
"ui.panel.lovelace.editor.edit_card.confirm_cancel"
),
dismissText: this.hass!.localize("ui.common.no"),
confirmText: this.hass!.localize("ui.common.yes"),
});
if (confirm) {
this._cancel();
}
}
private _cancel(ev?: Event) {
if (ev) {
ev.stopPropagation();
}
this._dirty = false;
this.closeDialog();
}
private async _save(): Promise<void> {
if (!this._canSave || this._saving) {
if (!this._canSave) {
return;
}
if (!this._dirty) {
this.closeDialog();
return;
}
this._saving = true;
@@ -405,8 +456,9 @@ export class HuiDialogEditCard extends LitElement {
)
);
this._saving = false;
this._dirty = false;
showSaveSuccessToast(this, this.hass);
this._close();
this.closeDialog();
}
}

View File

@@ -1,3 +1,4 @@
import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable";
import deepFreeze from "deep-freeze";
import {
css,

View File

@@ -16,18 +16,18 @@ import "../../../../components/entity/ha-entity-picker";
import "../../../../components/ha-icon";
import { HomeAssistant } from "../../../../types";
import { AlarmPanelCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import { assert, object, string, optional, array } from "superstruct";
const cardConfigStruct = struct({
type: "string",
entity: "string?",
name: "string?",
states: "array?",
theme: "string?",
const cardConfigStruct = object({
type: string(),
entity: optional(string()),
name: optional(string()),
states: optional(array()),
theme: optional(string()),
});
const includeDomains = ["alarm_control_panel"];
@@ -40,7 +40,7 @@ export class HuiAlarmPanelCardEditor extends LitElement
@internalProperty() private _config?: AlarmPanelCardConfig;
public setConfig(config: AlarmPanelCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -194,6 +194,7 @@ export class HuiAlarmPanelCardEditor extends LitElement
}
if (target.configValue) {
if (target.value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = {

View File

@@ -13,7 +13,6 @@ import "../../../../components/ha-icon-input";
import { ActionConfig } from "../../../../data/lovelace";
import { HomeAssistant } from "../../../../types";
import { ButtonCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-action-editor";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
@@ -27,19 +26,20 @@ import "../../../../components/ha-switch";
import "../../../../components/ha-formfield";
import { configElementStyle } from "./config-elements-style";
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
import { assert, object, string, optional, boolean } from "superstruct";
const cardConfigStruct = struct({
type: "string",
entity: "string?",
name: "string?",
show_name: "boolean?",
icon: "string?",
show_icon: "boolean?",
icon_height: "string?",
tap_action: struct.optional(actionConfigStruct),
hold_action: struct.optional(actionConfigStruct),
theme: "string?",
show_state: "boolean?",
const cardConfigStruct = object({
type: string(),
entity: optional(string()),
name: optional(string()),
show_name: optional(boolean()),
icon: optional(string()),
show_icon: optional(boolean()),
icon_height: optional(string()),
tap_action: optional(actionConfigStruct),
hold_action: optional(actionConfigStruct),
theme: optional(string()),
show_state: optional(boolean()),
});
@customElement("hui-button-card-editor")
@@ -50,7 +50,7 @@ export class HuiButtonCardEditor extends LitElement
@internalProperty() private _config?: ButtonCardConfig;
public setConfig(config: ButtonCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -258,6 +258,7 @@ export class HuiButtonCardEditor extends LitElement
}
if (target.configValue) {
if (target.value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
let newValue: string | undefined;

View File

@@ -16,7 +16,6 @@ import "../../../../components/entity/ha-entity-picker";
import { LovelaceConfig } from "../../../../data/lovelace";
import { HomeAssistant } from "../../../../types";
import { ConditionalCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import { LovelaceCardEditor } from "../../types";
import {
ConfigChangedEvent,
@@ -24,16 +23,17 @@ import {
} from "../card-editor/hui-card-editor";
import "../card-editor/hui-card-picker";
import { GUIModeChangedEvent } from "../types";
import { string, any, object, optional, array, assert } from "superstruct";
const conditionStruct = struct({
entity: "string",
state: "string?",
state_not: "string?",
const conditionStruct = object({
entity: string(),
state: optional(string()),
state_not: optional(string()),
});
const cardConfigStruct = struct({
type: "string",
card: "any",
conditions: struct.optional([conditionStruct]),
const cardConfigStruct = object({
type: string(),
card: any(),
conditions: optional(array(conditionStruct)),
});
@customElement("hui-conditional-card-editor")
@@ -54,7 +54,8 @@ export class HuiConditionalCardEditor extends LitElement
@query("hui-card-editor") private _cardEditorEl?: HuiCardEditor;
public setConfig(config: ConditionalCardConfig): void {
this._config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
public refreshYamlEditor(focus) {
@@ -217,7 +218,7 @@ export class HuiConditionalCardEditor extends LitElement
}
this._setMode(true);
this._guiModeAvailable = true;
this._config.card = ev.detail.config;
this._config = { ...this._config, card: ev.detail.config };
fireEvent(this, "config-changed", { config: this._config });
}
@@ -226,7 +227,7 @@ export class HuiConditionalCardEditor extends LitElement
if (!this._config) {
return;
}
this._config.card = ev.detail.config;
this._config = { ...this._config, card: ev.detail.config };
this._guiModeAvailable = ev.detail.guiModeAvailable;
fireEvent(this, "config-changed", { config: this._config });
}
@@ -236,7 +237,8 @@ export class HuiConditionalCardEditor extends LitElement
return;
}
// @ts-ignore
this._config.card = {};
this._config = { ...this._config, card: {} };
// @ts-ignore
fireEvent(this, "config-changed", { config: this._config });
}
@@ -245,10 +247,12 @@ export class HuiConditionalCardEditor extends LitElement
if (target.value === "" || !this._config) {
return;
}
this._config.conditions.push({
const conditions = [...this._config.conditions];
conditions.push({
entity: target.value,
state: "",
});
this._config = { ...this._config, conditions };
target.value = "";
fireEvent(this, "config-changed", { config: this._config });
}
@@ -258,10 +262,11 @@ export class HuiConditionalCardEditor extends LitElement
if (!this._config || !target) {
return;
}
const conditions = [...this._config.conditions];
if (target.configValue === "entity" && target.value === "") {
this._config.conditions.splice(target.index, 1);
conditions.splice(target.index, 1);
} else {
const condition = this._config.conditions[target.index];
const condition = { ...conditions[target.index] };
if (target.configValue === "entity") {
condition.entity = target.value;
} else if (target.configValue === "state") {
@@ -281,8 +286,9 @@ export class HuiConditionalCardEditor extends LitElement
delete condition.state_not;
}
}
this._config.conditions[target.index] = condition;
conditions[target.index] = condition;
}
this._config = { ...this._config, conditions };
fireEvent(this, "config-changed", { config: this._config });
}

View File

@@ -20,7 +20,6 @@ import {
EntitiesCardConfig,
EntitiesCardEntityConfig,
} from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
import { headerFooterConfigStructs } from "../../header-footer/types";
@@ -33,15 +32,24 @@ import {
} from "../types";
import { configElementStyle } from "./config-elements-style";
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
import {
string,
optional,
object,
boolean,
array,
union,
assert,
} from "superstruct";
const cardConfigStruct = struct({
type: "string",
title: "string|number?",
theme: "string?",
show_header_toggle: "boolean?",
entities: [entitiesConfigStruct],
header: struct.optional(headerFooterConfigStructs),
footer: struct.optional(headerFooterConfigStructs),
const cardConfigStruct = object({
type: string(),
title: optional(union([string(), boolean()])),
theme: optional(string()),
show_header_toggle: optional(boolean()),
entities: array(entitiesConfigStruct),
header: optional(headerFooterConfigStructs),
footer: optional(headerFooterConfigStructs),
});
@customElement("hui-entities-card-editor")
@@ -54,7 +62,7 @@ export class HuiEntitiesCardEditor extends LitElement
@internalProperty() private _configEntities?: EntitiesCardEntityConfig[];
public setConfig(config: EntitiesCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
this._configEntities = processEditorEntities(config.entities);
}
@@ -127,10 +135,12 @@ export class HuiEntitiesCardEditor extends LitElement
}
if (ev.detail && ev.detail.entities) {
this._config.entities = ev.detail.entities;
this._config = { ...this._config, entities: ev.detail.entities };
this._configEntities = processEditorEntities(this._config.entities);
} else if (target.configValue) {
if (target.value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = {

View File

@@ -12,7 +12,6 @@ import { stateIcon } from "../../../../common/entity/state_icon";
import "../../../../components/ha-icon-input";
import { HomeAssistant } from "../../../../types";
import { EntityCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-action-editor";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
@@ -20,16 +19,17 @@ import { headerFooterConfigStructs } from "../../header-footer/types";
import { LovelaceCardEditor } from "../../types";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import { string, object, optional, assert } from "superstruct";
const cardConfigStruct = struct({
type: "string",
entity: "string?",
name: "string?",
icon: "string?",
attribute: "string?",
unit: "string?",
theme: "string?",
footer: struct.optional(headerFooterConfigStructs),
const cardConfigStruct = object({
type: string(),
entity: optional(string()),
name: optional(string()),
icon: optional(string()),
attribute: optional(string()),
unit: optional(string()),
theme: optional(string()),
footer: optional(headerFooterConfigStructs),
});
@customElement("hui-entity-card-editor")
@@ -40,7 +40,7 @@ export class HuiEntityCardEditor extends LitElement
@internalProperty() private _config?: EntityCardConfig;
public setConfig(config: EntityCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -158,6 +158,7 @@ export class HuiEntityCardEditor extends LitElement
}
if (target.configValue) {
if (target.value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
let newValue: string | undefined;

View File

@@ -14,23 +14,23 @@ import "../../../../components/ha-switch";
import "../../../../components/ha-formfield";
import { HomeAssistant } from "../../../../types";
import { GaugeCardConfig, SeverityConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
import { assert, object, string, optional, number } from "superstruct";
const cardConfigStruct = struct({
type: "string",
name: "string?",
entity: "string?",
unit: "string?",
min: "number?",
max: "number?",
severity: "object?",
theme: "string?",
const cardConfigStruct = object({
type: string(),
name: optional(string()),
entity: optional(string()),
unit: optional(string()),
min: optional(number()),
max: optional(number()),
severity: optional(object()),
theme: optional(string()),
});
const includeDomains = ["sensor"];
@@ -43,7 +43,7 @@ export class HuiGaugeCardEditor extends LitElement
@internalProperty() private _config?: GaugeCardConfig;
public setConfig(config: GaugeCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -260,6 +260,7 @@ export class HuiGaugeCardEditor extends LitElement
target.value === "" ||
(target.type === "number" && isNaN(Number(target.value)))
) {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
let value: any = target.value;

View File

@@ -17,7 +17,6 @@ import "../../../../components/ha-switch";
import "../../../../components/ha-formfield";
import { HomeAssistant } from "../../../../types";
import { ConfigEntity, GlanceCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
@@ -29,16 +28,26 @@ import {
} from "../types";
import { configElementStyle } from "./config-elements-style";
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
import {
string,
union,
object,
optional,
number,
boolean,
assert,
array,
} from "superstruct";
const cardConfigStruct = struct({
type: "string",
title: "string|number?",
theme: "string?",
columns: "number?",
show_name: "boolean?",
show_state: "boolean?",
show_icon: "boolean?",
entities: [entitiesConfigStruct],
const cardConfigStruct = object({
type: string(),
title: optional(union([string(), number()])),
theme: optional(string()),
columns: optional(number()),
show_name: optional(boolean()),
show_state: optional(boolean()),
show_icon: optional(boolean()),
entities: array(entitiesConfigStruct),
});
@customElement("hui-glance-card-editor")
@@ -51,7 +60,7 @@ export class HuiGlanceCardEditor extends LitElement
@internalProperty() private _configEntities?: ConfigEntity[];
public setConfig(config: GlanceCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
this._configEntities = processEditorEntities(config.entities);
}
@@ -184,13 +193,15 @@ export class HuiGlanceCardEditor extends LitElement
return;
}
if (ev.detail && ev.detail.entities) {
this._config.entities = ev.detail.entities;
this._config = { ...this._config, entities: ev.detail.entities };
this._configEntities = processEditorEntities(this._config.entities);
} else if (target.configValue) {
if (
target.value === "" ||
(target.type === "number" && isNaN(Number(target.value)))
) {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
let value: any = target.value;

View File

@@ -10,28 +10,37 @@ import {
import { fireEvent } from "../../../../common/dom/fire_event";
import { HomeAssistant } from "../../../../types";
import { HistoryGraphCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-entity-editor";
import { EntityConfig } from "../../entity-rows/types";
import { LovelaceCardEditor } from "../../types";
import { processEditorEntities } from "../process-editor-entities";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import {
assert,
union,
optional,
string,
object,
array,
number,
} from "superstruct";
import { EntityId } from "../../common/structs/is-entity-id";
const entitiesConfigStruct = struct.union([
{
entity: "entity-id",
name: "string?",
},
"entity-id",
const entitiesConfigStruct = union([
object({
entity: EntityId,
name: optional(string()),
}),
EntityId,
]);
const cardConfigStruct = struct({
type: "string",
entities: [entitiesConfigStruct],
title: "string?",
hours_to_show: "number?",
refresh_interval: "number?",
const cardConfigStruct = object({
type: string(),
entities: array(entitiesConfigStruct),
title: optional(string()),
hours_to_show: optional(number()),
refresh_interval: optional(number()),
});
@customElement("hui-history-graph-card-editor")
@@ -44,7 +53,7 @@ export class HuiHistoryGraphCardEditor extends LitElement
@internalProperty() private _configEntities?: EntityConfig[];
public setConfig(config: HistoryGraphCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
this._configEntities = processEditorEntities(config.entities);
}
@@ -127,10 +136,11 @@ export class HuiHistoryGraphCardEditor extends LitElement
}
if (ev.detail && ev.detail.entities) {
this._config.entities = ev.detail.entities;
this._config = { ...this._config, entities: ev.detail.entities };
this._configEntities = processEditorEntities(this._config.entities);
} else if (target.configValue) {
if (target.value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
let value: any = target.value;

View File

@@ -11,17 +11,17 @@ import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/entity/ha-entity-picker";
import { HomeAssistant } from "../../../../types";
import { HumidifierCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import { string, object, optional, assert } from "superstruct";
const cardConfigStruct = struct({
type: "string",
entity: "string",
name: "string?",
theme: "string?",
const cardConfigStruct = object({
type: string(),
entity: string(),
name: optional(string()),
theme: optional(string()),
});
const includeDomains = ["humidifier"];
@@ -34,7 +34,7 @@ export class HuiHumidifierCardEditor extends LitElement
@internalProperty() private _config?: HumidifierCardConfig;
public setConfig(config: HumidifierCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -102,6 +102,7 @@ export class HuiHumidifierCardEditor extends LitElement
}
if (target.configValue) {
if (target.value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = { ...this._config, [target.configValue!]: target.value };

View File

@@ -10,16 +10,16 @@ import {
import { fireEvent } from "../../../../common/dom/fire_event";
import { HomeAssistant } from "../../../../types";
import { IframeCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import { LovelaceCardEditor } from "../../types";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import { string, assert, object, optional } from "superstruct";
const cardConfigStruct = struct({
type: "string",
title: "string?",
url: "string?",
aspect_ratio: "string?",
const cardConfigStruct = object({
type: string(),
title: optional(string()),
url: optional(string()),
aspect_ratio: optional(string()),
});
@customElement("hui-iframe-card-editor")
@@ -30,7 +30,7 @@ export class HuiIframeCardEditor extends LitElement
@internalProperty() private _config?: IframeCardConfig;
public setConfig(config: IframeCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -102,6 +102,7 @@ export class HuiIframeCardEditor extends LitElement
}
if (target.configValue) {
if (value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = { ...this._config, [target.configValue!]: value };

View File

@@ -13,7 +13,6 @@ import "../../../../components/ha-icon-input";
import { ActionConfig } from "../../../../data/lovelace";
import { HomeAssistant } from "../../../../types";
import { LightCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-action-editor";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
@@ -24,15 +23,16 @@ import {
EntitiesEditorEvent,
} from "../types";
import { configElementStyle } from "./config-elements-style";
import { string, object, optional, assert } from "superstruct";
const cardConfigStruct = struct({
type: "string",
name: "string?",
entity: "string?",
theme: "string?",
icon: "string?",
hold_action: struct.optional(actionConfigStruct),
double_tap_action: struct.optional(actionConfigStruct),
const cardConfigStruct = object({
type: string(),
name: optional(string()),
entity: optional(string()),
theme: optional(string()),
icon: optional(string()),
hold_action: optional(actionConfigStruct),
double_tap_action: optional(actionConfigStruct),
});
const includeDomains = ["light"];
@@ -45,7 +45,8 @@ export class HuiLightCardEditor extends LitElement
@internalProperty() private _config?: LightCardConfig;
public setConfig(config: LightCardConfig): void {
this._config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
get _name(): string {
@@ -177,6 +178,7 @@ export class HuiLightCardEditor extends LitElement
}
if (target.configValue) {
if (target.value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = {

View File

@@ -13,7 +13,6 @@ import { fireEvent } from "../../../../common/dom/fire_event";
import { PolymerChangedEvent } from "../../../../polymer-types";
import { HomeAssistant } from "../../../../types";
import { MapCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-entity-editor";
import "../../components/hui-input-list-editor";
import { EntityConfig } from "../../entity-rows/types";
@@ -28,16 +27,25 @@ import "../../../../components/ha-switch";
import "../../../../components/ha-formfield";
import { configElementStyle } from "./config-elements-style";
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
import {
string,
optional,
object,
number,
boolean,
array,
assert,
} from "superstruct";
const cardConfigStruct = struct({
type: "string",
title: "string?",
aspect_ratio: "string?",
default_zoom: "number?",
dark_mode: "boolean?",
entities: [entitiesConfigStruct],
hours_to_show: "number?",
geo_location_sources: "array?",
const cardConfigStruct = object({
type: string(),
title: optional(string()),
aspect_ratio: optional(string()),
default_zoom: optional(number()),
dark_mode: optional(boolean()),
entities: array(entitiesConfigStruct),
hours_to_show: optional(number()),
geo_location_sources: optional(array()),
});
@customElement("hui-map-card-editor")
@@ -49,7 +57,7 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
@internalProperty() private _configEntities?: EntityConfig[];
public setConfig(config: MapCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
this._configEntities = config.entities
? processEditorEntities(config.entities)
@@ -176,7 +184,8 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
return;
}
if (ev.detail && ev.detail.entities) {
this._config.entities = ev.detail.entities;
this._config = { ...this._config, entities: ev.detail.entities };
this._configEntities = processEditorEntities(this._config.entities);
fireEvent(this, "config-changed", { config: this._config });
}
@@ -195,6 +204,7 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
value = Number(value);
}
if (target.value === "" || (target.type === "number" && isNaN(value))) {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else if (target.configValue) {
this._config = {

View File

@@ -11,17 +11,17 @@ import {
import { fireEvent } from "../../../../common/dom/fire_event";
import { HomeAssistant } from "../../../../types";
import { MarkdownCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import { string, assert, object, optional } from "superstruct";
const cardConfigStruct = struct({
type: "string",
title: "string?",
content: "string",
theme: "string?",
const cardConfigStruct = object({
type: string(),
title: optional(string()),
content: string(),
theme: optional(string()),
});
@customElement("hui-markdown-card-editor")
@@ -32,7 +32,7 @@ export class HuiMarkdownCardEditor extends LitElement
@internalProperty() private _config?: MarkdownCardConfig;
public setConfig(config: MarkdownCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -100,6 +100,7 @@ export class HuiMarkdownCardEditor extends LitElement
}
if (target.configValue) {
if (target.value === "" && target.configValue !== "content") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = {

View File

@@ -10,13 +10,13 @@ import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/entity/ha-entity-picker";
import { HomeAssistant } from "../../../../types";
import { MediaControlCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import { LovelaceCardEditor } from "../../types";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { assert, object, string, optional } from "superstruct";
const cardConfigStruct = struct({
type: "string",
entity: "string?",
const cardConfigStruct = object({
type: string(),
entity: optional(string()),
});
const includeDomains = ["media_player"];
@@ -29,7 +29,7 @@ export class HuiMediaControlCardEditor extends LitElement
@internalProperty() private _config?: MediaControlCardConfig;
public setConfig(config: MediaControlCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -71,6 +71,7 @@ export class HuiMediaControlCardEditor extends LitElement
}
if (target.configValue) {
if (target.value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = {

View File

@@ -11,7 +11,6 @@ import { fireEvent } from "../../../../common/dom/fire_event";
import { ActionConfig } from "../../../../data/lovelace";
import { HomeAssistant } from "../../../../types";
import { PictureCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-action-editor";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
@@ -21,13 +20,14 @@ import {
EntitiesEditorEvent,
} from "../types";
import { configElementStyle } from "./config-elements-style";
import { string, object, optional, assert } from "superstruct";
const cardConfigStruct = struct({
type: "string",
image: "string?",
tap_action: struct.optional(actionConfigStruct),
hold_action: struct.optional(actionConfigStruct),
theme: "string?",
const cardConfigStruct = object({
type: string(),
image: optional(string()),
tap_action: optional(actionConfigStruct),
hold_action: optional(actionConfigStruct),
theme: optional(string()),
});
@customElement("hui-picture-card-editor")
@@ -38,7 +38,7 @@ export class HuiPictureCardEditor extends LitElement
@internalProperty() private _config?: PictureCardConfig;
public setConfig(config: PictureCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -128,6 +128,7 @@ export class HuiPictureCardEditor extends LitElement
}
if (target.configValue) {
if (target.value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = {

View File

@@ -16,7 +16,6 @@ import "../../../../components/ha-formfield";
import { ActionConfig } from "../../../../data/lovelace";
import { HomeAssistant } from "../../../../types";
import { PictureEntityCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-action-editor";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
@@ -28,20 +27,21 @@ import {
} from "../types";
import { configElementStyle } from "./config-elements-style";
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
import { assert, object, string, optional, boolean } from "superstruct";
const cardConfigStruct = struct({
type: "string",
entity: "string",
image: "string?",
name: "string?",
camera_image: "string?",
camera_view: "string?",
aspect_ratio: "string?",
tap_action: struct.optional(actionConfigStruct),
hold_action: struct.optional(actionConfigStruct),
show_name: "boolean?",
show_state: "boolean?",
theme: "string?",
const cardConfigStruct = object({
type: string(),
entity: string(),
image: optional(string()),
name: optional(string()),
camera_image: optional(string()),
camera_view: optional(string()),
aspect_ratio: optional(string()),
tap_action: optional(actionConfigStruct),
hold_action: optional(actionConfigStruct),
show_name: optional(boolean()),
show_state: optional(boolean()),
theme: optional(string()),
});
const includeDomains = ["camera"];
@@ -54,7 +54,7 @@ export class HuiPictureEntityCardEditor extends LitElement
@internalProperty() private _config?: PictureEntityCardConfig;
public setConfig(config: PictureEntityCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -275,6 +275,7 @@ export class HuiPictureEntityCardEditor extends LitElement
}
if (target.configValue) {
if (value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = {

View File

@@ -15,7 +15,6 @@ import "../../../../components/entity/ha-entity-picker";
import { ActionConfig } from "../../../../data/lovelace";
import { HomeAssistant } from "../../../../types";
import { PictureGlanceCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-action-editor";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
@@ -29,19 +28,20 @@ import {
EntitiesEditorEvent,
} from "../types";
import { configElementStyle } from "./config-elements-style";
import { assert, string, object, optional, array } from "superstruct";
const cardConfigStruct = struct({
type: "string",
title: "string?",
entity: "string?",
image: "string?",
camera_image: "string?",
camera_view: "string?",
aspect_ratio: "string?",
tap_action: struct.optional(actionConfigStruct),
hold_action: struct.optional(actionConfigStruct),
entities: [entitiesConfigStruct],
theme: "string?",
const cardConfigStruct = object({
type: string(),
title: optional(string()),
entity: optional(string()),
image: optional(string()),
camera_image: optional(string()),
camera_view: optional(string()),
aspect_ratio: optional(string()),
tap_action: optional(actionConfigStruct),
hold_action: optional(actionConfigStruct),
entities: array(entitiesConfigStruct),
theme: optional(string()),
});
const includeDomains = ["camera"];
@@ -56,7 +56,7 @@ export class HuiPictureGlanceCardEditor extends LitElement
@internalProperty() private _configEntities?: EntityConfig[];
public setConfig(config: PictureGlanceCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
this._configEntities = processEditorEntities(config.entities);
}
@@ -251,7 +251,8 @@ export class HuiPictureGlanceCardEditor extends LitElement
}
if (ev.detail && ev.detail.entities) {
this._config.entities = ev.detail.entities;
this._config = { ...this._config, entities: ev.detail.entities };
this._configEntities = processEditorEntities(this._config.entities);
} else if (target.configValue) {
if (
@@ -262,6 +263,7 @@ export class HuiPictureGlanceCardEditor extends LitElement
}
if (value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = {

View File

@@ -12,17 +12,17 @@ import "../../../../components/entity/ha-entity-picker";
import "../../../../components/ha-icon";
import { HomeAssistant } from "../../../../types";
import { PlantStatusCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import { assert, object, string, optional } from "superstruct";
const cardConfigStruct = struct({
type: "string",
entity: "string",
name: "string?",
theme: "string?",
const cardConfigStruct = object({
type: string(),
entity: string(),
name: optional(string()),
theme: optional(string()),
});
const includeDomains = ["plant"];
@@ -35,7 +35,7 @@ export class HuiPlantStatusCardEditor extends LitElement
@internalProperty() private _config?: PlantStatusCardConfig;
public setConfig(config: PlantStatusCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -102,6 +102,7 @@ export class HuiPlantStatusCardEditor extends LitElement
}
if (target.configValue) {
if (target.value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = {

View File

@@ -16,22 +16,22 @@ import "../../../../components/entity/ha-entity-picker";
import "../../../../components/ha-icon-input";
import { HomeAssistant } from "../../../../types";
import { SensorCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import { string, assert, object, optional, number } from "superstruct";
const cardConfigStruct = struct({
type: "string",
entity: "string?",
name: "string?",
icon: "string?",
graph: "string?",
unit: "string?",
detail: "number?",
theme: "string?",
hours_to_show: "number?",
const cardConfigStruct = object({
type: string(),
entity: optional(string()),
name: optional(string()),
icon: optional(string()),
graph: optional(string()),
unit: optional(string()),
detail: optional(number()),
theme: optional(string()),
hours_to_show: optional(number()),
});
const includeDomains = ["sensor"];
@@ -44,7 +44,7 @@ export class HuiSensorCardEditor extends LitElement
@internalProperty() private _config?: SensorCardConfig;
public setConfig(config: SensorCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -205,6 +205,7 @@ export class HuiSensorCardEditor extends LitElement
target.value === "" ||
(target.type === "number" && isNaN(Number(target.value)))
) {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
let value: any = target.value;

View File

@@ -13,15 +13,15 @@ import { isComponentLoaded } from "../../../../common/config/is_component_loaded
import { fireEvent } from "../../../../common/dom/fire_event";
import { HomeAssistant } from "../../../../types";
import { ShoppingListCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { string, assert, object, optional } from "superstruct";
const cardConfigStruct = struct({
type: "string",
title: "string?",
theme: "string?",
const cardConfigStruct = object({
type: string(),
title: optional(string()),
theme: optional(string()),
});
@customElement("hui-shopping-list-card-editor")
@@ -32,7 +32,7 @@ export class HuiShoppingListEditor extends LitElement
@internalProperty() private _config?: ShoppingListCardConfig;
public setConfig(config: ShoppingListCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -91,6 +91,7 @@ export class HuiShoppingListEditor extends LitElement
}
if (target.configValue) {
if (target.value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = {

View File

@@ -16,7 +16,6 @@ import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event";
import { LovelaceConfig } from "../../../../data/lovelace";
import { HomeAssistant } from "../../../../types";
import { StackCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import { LovelaceCardEditor } from "../../types";
import {
ConfigChangedEvent,
@@ -24,11 +23,12 @@ import {
} from "../card-editor/hui-card-editor";
import "../card-editor/hui-card-picker";
import { GUIModeChangedEvent } from "../types";
import { assert, object, string, array, any, optional } from "superstruct";
const cardConfigStruct = struct({
type: "string",
cards: ["any"],
title: "string?",
const cardConfigStruct = object({
type: string(),
cards: array(any()),
title: optional(string()),
});
@customElement("hui-stack-card-editor")
@@ -48,8 +48,9 @@ export class HuiStackCardEditor extends LitElement
@query("hui-card-editor") private _cardEditorEl?: HuiCardEditor;
public setConfig(config: StackCardConfig): void {
this._config = cardConfigStruct(config);
public setConfig(config: Readonly<StackCardConfig>): void {
assert(config, cardConfigStruct);
this._config = config;
}
public refreshYamlEditor(focus) {
@@ -162,7 +163,9 @@ export class HuiStackCardEditor extends LitElement
if (!this._config) {
return;
}
this._config.cards[this._selectedCard] = ev.detail.config;
const cards = [...this._config.cards];
cards[this._selectedCard] = ev.detail.config;
this._config = { ...this._config, cards };
this._guiModeAvailable = ev.detail.guiModeAvailable;
fireEvent(this, "config-changed", { config: this._config });
}
@@ -173,7 +176,8 @@ export class HuiStackCardEditor extends LitElement
return;
}
const config = ev.detail.config;
this._config.cards.push(config);
const cards = [...this._config.cards, config];
this._config = { ...this._config, cards };
fireEvent(this, "config-changed", { config: this._config });
}
@@ -181,7 +185,9 @@ export class HuiStackCardEditor extends LitElement
if (!this._config) {
return;
}
this._config.cards.splice(this._selectedCard, 1);
const cards = [...this._config.cards];
cards.splice(this._selectedCard, 1);
this._config = { ...this._config, cards };
this._selectedCard = Math.max(0, this._selectedCard - 1);
fireEvent(this, "config-changed", { config: this._config });
}
@@ -192,8 +198,13 @@ export class HuiStackCardEditor extends LitElement
}
const source = this._selectedCard;
const target = ev.target.id === "move-before" ? source - 1 : source + 1;
const card = this._config.cards.splice(this._selectedCard, 1)[0];
this._config.cards.splice(target, 0, card);
const cards = [...this._config.cards];
const card = cards.splice(this._selectedCard, 1)[0];
cards.splice(target, 0, card);
this._config = {
...this._config,
cards,
};
this._selectedCard = target;
fireEvent(this, "config-changed", { config: this._config });
}

View File

@@ -11,17 +11,17 @@ import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/entity/ha-entity-picker";
import { HomeAssistant } from "../../../../types";
import { ThermostatCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import { object, string, optional, assert } from "superstruct";
const cardConfigStruct = struct({
type: "string",
entity: "string",
name: "string?",
theme: "string?",
const cardConfigStruct = object({
type: string(),
entity: string(),
name: optional(string()),
theme: optional(string()),
});
const includeDomains = ["climate"];
@@ -34,7 +34,7 @@ export class HuiThermostatCardEditor extends LitElement
@internalProperty() private _config?: ThermostatCardConfig;
public setConfig(config: ThermostatCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -102,6 +102,7 @@ export class HuiThermostatCardEditor extends LitElement
}
if (target.configValue) {
if (target.value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = { ...this._config, [target.configValue!]: target.value };

View File

@@ -12,20 +12,20 @@ import "../../../../components/ha-switch";
import "../../../../components/ha-formfield";
import { HomeAssistant } from "../../../../types";
import { WeatherForecastCardConfig } from "../../cards/types";
import { struct } from "../../common/structs/struct";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
import { object, string, optional, boolean, assert } from "superstruct";
const cardConfigStruct = struct({
type: "string",
entity: "string?",
name: "string?",
theme: "string?",
show_forecast: "boolean?",
secondary_info_attribute: "string?",
const cardConfigStruct = object({
type: string(),
entity: optional(string()),
name: optional(string()),
theme: optional(string()),
show_forecast: optional(boolean()),
secondary_info_attribute: optional(string()),
});
const includeDomains = ["weather"];
@@ -38,7 +38,7 @@ export class HuiWeatherForecastCardEditor extends LitElement
@internalProperty() private _config?: WeatherForecastCardConfig;
public setConfig(config: WeatherForecastCardConfig): void {
config = cardConfigStruct(config);
assert(config, cardConfigStruct);
this._config = config;
}
@@ -139,6 +139,7 @@ export class HuiWeatherForecastCardEditor extends LitElement
}
if (target.configValue) {
if (target.value === "") {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
this._config = {

View File

@@ -0,0 +1,9 @@
export class GUISupportError extends Error {
public warnings?: string[] = [];
constructor(message: string, warnings?: string[]) {
super(message);
this.name = "GUISupportError";
this.warnings = warnings;
}
}

View File

@@ -4,8 +4,10 @@ import {
LovelaceViewConfig,
ShowViewConfig,
} from "../../../data/lovelace";
import { struct } from "../common/structs/struct";
import { EntityConfig } from "../entity-rows/types";
import { optional, string, object, union } from "superstruct";
import { EntityId } from "../common/structs/is-entity-id";
import { Icon } from "../common/structs/is-icon";
export interface YamlChangedEvent extends Event {
detail: {
@@ -66,19 +68,19 @@ export interface CardPickTarget extends EventTarget {
config: LovelaceCardConfig;
}
export const actionConfigStruct = struct({
action: "string",
navigation_path: "string?",
url_path: "string?",
service: "string?",
service_data: "object?",
export const actionConfigStruct = object({
action: string(),
navigation_path: optional(string()),
url_path: optional(string()),
service: optional(string()),
service_data: optional(object()),
});
export const entitiesConfigStruct = struct.union([
{
entity: "entity-id",
name: "string?",
icon: "icon?",
},
"entity-id",
export const entitiesConfigStruct = union([
object({
entity: EntityId,
name: optional(string()),
icon: optional(Icon),
}),
EntityId,
]);

View File

@@ -176,6 +176,12 @@ export class HuiUnusedEntities extends LitElement {
selectable
@selection-changed=${this._handleSelectionChanged}
.dir=${computeRTLDirection(this.hass)}
.searchLabel=${this.hass.localize(
"ui.panel.lovelace.unused_entities.search"
)}
.noDataText=${this.hass.localize(
"ui.panel.lovelace.unused_entities.no_data"
)}
></ha-data-table>
${this._selectedEntities.length

View File

@@ -98,7 +98,7 @@ class HuiInputNumberEntityRow extends LitElement implements LovelaceRow {
no-label-float
auto-validate
.disabled=${UNAVAILABLE_STATES.includes(stateObj.state)}
.pattern="[0-9]+([\\.][0-9]+)?"
pattern="[0-9]+([\\.][0-9]+)?"
.step="${Number(stateObj.attributes.step)}"
.min="${Number(stateObj.attributes.min)}"
.max="${Number(stateObj.attributes.max)}"

View File

@@ -1,5 +1,5 @@
import { ActionConfig } from "../../../data/lovelace";
import { struct } from "../common/structs/struct";
import { object, optional, union, string, number, array } from "superstruct";
import { actionConfigStruct, entitiesConfigStruct } from "../editor/types";
import { EntityConfig } from "../entity-rows/types";
@@ -24,27 +24,27 @@ export interface PictureHeaderFooterConfig extends LovelaceHeaderFooterConfig {
double_tap_action?: ActionConfig;
}
export const pictureHeaderFooterConfigStruct = struct({
type: "string",
image: "string",
tap_action: struct.optional(actionConfigStruct),
hold_action: struct.optional(actionConfigStruct),
double_tap_action: struct.optional(actionConfigStruct),
export const pictureHeaderFooterConfigStruct = object({
type: string(),
image: string(),
tap_action: optional(actionConfigStruct),
hold_action: optional(actionConfigStruct),
double_tap_action: optional(actionConfigStruct),
});
export const buttonsHeaderFooterConfigStruct = struct({
type: "string",
entities: [entitiesConfigStruct],
export const buttonsHeaderFooterConfigStruct = object({
type: string(),
entities: array(entitiesConfigStruct),
});
export const graphHeaderFooterConfigStruct = struct({
type: "string",
entity: "string",
detail: "number?",
hours_to_show: "number?",
export const graphHeaderFooterConfigStruct = object({
type: string(),
entity: string(),
detail: optional(string()),
hours_to_show: optional(number()),
});
export const headerFooterConfigStructs = struct.union([
export const headerFooterConfigStructs = union([
pictureHeaderFooterConfigStruct,
buttonsHeaderFooterConfigStruct,
graphHeaderFooterConfigStruct,

View File

@@ -27,12 +27,12 @@ import {
} from "../../dialogs/generic/show-dialog-box";
import { haStyle } from "../../resources/styles";
import type { HomeAssistant } from "../../types";
import { struct } from "./common/structs/struct";
import type { Lovelace } from "./types";
import { optional, array, string, object, type, assert } from "superstruct";
const lovelaceStruct = struct.interface({
title: "string?",
views: ["object"],
const lovelaceStruct = type({
title: optional(string()),
views: array(object()),
});
@customElement("hui-editor")
@@ -251,7 +251,7 @@ class LovelaceFullConfigEditor extends LitElement {
return;
}
try {
config = lovelaceStruct(config);
assert(config, lovelaceStruct);
} catch (err) {
showAlertDialog(this, {
text: this.hass.localize(

View File

@@ -58,6 +58,8 @@ import type { Lovelace } from "./types";
import "./views/hui-panel-view";
import type { HUIPanelView } from "./views/hui-panel-view";
import { HUIView } from "./views/hui-view";
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
import { shouldHandleRequestSelectedEvent } from "../../common/mwc/handle-request-selected-event";
class HUIRoot extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@@ -133,14 +135,19 @@ class HUIRoot extends LitElement {
<ha-svg-icon path=${mdiPencil}></ha-svg-icon>
</mwc-icon-button>
</div>
<mwc-icon-button
title="${this.hass!.localize(
"ui.panel.lovelace.menu.help"
)}"
@click="${this._handleHelp}"
<a
href="https://www.home-assistant.io/lovelace/"
rel="noreferrer"
target="_blank"
>
<ha-svg-icon path=${mdiHelpCircle}></ha-svg-icon>
</mwc-icon-button>
<mwc-icon-button
title="${this.hass!.localize(
"ui.panel.lovelace.menu.help"
)}"
>
<ha-svg-icon path=${mdiHelpCircle}></ha-svg-icon>
</mwc-icon-button>
</a>
<ha-button-menu corner="BOTTOM_START">
<mwc-icon-button
slot="trigger"
@@ -160,14 +167,14 @@ class HUIRoot extends LitElement {
aria-label=${this.hass!.localize(
"ui.panel.lovelace.unused_entities.title"
)}
@tap="${this._handleUnusedEntities}"
@request-selected="${this._handleUnusedEntities}"
>
${this.hass!.localize(
"ui.panel.lovelace.unused_entities.title"
)}
</mwc-list-item>
`}
<mwc-list-item @tap="${this.lovelace!.enableFullEditMode}">
<mwc-list-item @request-selected="${this._handleRawEditor}">
${this.hass!.localize(
"ui.panel.lovelace.editor.menu.raw_editor"
)}
@@ -210,7 +217,7 @@ class HUIRoot extends LitElement {
aria-label=${this.hass!.localize(
"ui.panel.lovelace.menu.refresh"
)}
@tap="${this._handleRefresh}"
@request-selected="${this._handleRefresh}"
>
${this.hass!.localize(
"ui.panel.lovelace.menu.refresh"
@@ -220,7 +227,7 @@ class HUIRoot extends LitElement {
aria-label=${this.hass!.localize(
"ui.panel.lovelace.unused_entities.title"
)}
@tap="${this._handleUnusedEntities}"
@request-selected="${this._handleUnusedEntities}"
>
${this.hass!.localize(
"ui.panel.lovelace.unused_entities.title"
@@ -235,7 +242,7 @@ class HUIRoot extends LitElement {
aria-label=${this.hass!.localize(
"ui.panel.lovelace.menu.reload_resources"
)}
@tap="${this._handleReloadResources}"
@request-selected=${this._handleReloadResources}
>
${this.hass!.localize(
"ui.panel.lovelace.menu.reload_resources"
@@ -249,7 +256,7 @@ class HUIRoot extends LitElement {
aria-label=${this.hass!.localize(
"ui.panel.lovelace.menu.configure_ui"
)}
@tap="${this._editModeEnable}"
@request-selected=${this._handleEnableEditMode}
>
${this.hass!.localize(
"ui.panel.lovelace.menu.configure_ui"
@@ -257,14 +264,19 @@ class HUIRoot extends LitElement {
</mwc-list-item>
`
: ""}
<mwc-list-item
aria-label=${this.hass!.localize(
"ui.panel.lovelace.menu.help"
)}
@tap="${this._handleHelp}"
<a
href="https://www.home-assistant.io/lovelace/"
rel="noreferrer"
target="_blank"
>
${this.hass!.localize("ui.panel.lovelace.menu.help")}
</mwc-list-item>
<mwc-list-item
aria-label=${this.hass!.localize(
"ui.panel.lovelace.menu.help"
)}
>
${this.hass!.localize("ui.panel.lovelace.menu.help")}
</mwc-list-item>
</a>
</ha-button-menu>
</app-toolbar>
`}
@@ -474,11 +486,17 @@ class HUIRoot extends LitElement {
return this.shadowRoot!.getElementById("view") as HTMLDivElement;
}
private _handleRefresh(): void {
private _handleRefresh(ev: CustomEvent<RequestSelectedDetail>): void {
if (!shouldHandleRequestSelectedEvent(ev)) {
return;
}
fireEvent(this, "config-refresh");
}
private _handleReloadResources(): void {
private _handleReloadResources(ev: CustomEvent<RequestSelectedDetail>): void {
if (!shouldHandleRequestSelectedEvent(ev)) {
return;
}
this.hass.callService("lovelace", "reload_resources");
showConfirmationDialog(this, {
title: this.hass!.localize(
@@ -491,7 +509,17 @@ class HUIRoot extends LitElement {
});
}
private _handleUnusedEntities(): void {
private _handleRawEditor(ev: CustomEvent<RequestSelectedDetail>): void {
if (!shouldHandleRequestSelectedEvent(ev)) {
return;
}
this.lovelace!.enableFullEditMode();
}
private _handleUnusedEntities(ev: CustomEvent<RequestSelectedDetail>): void {
if (!shouldHandleRequestSelectedEvent(ev)) {
return;
}
navigate(this, `${this.route?.prefix}/hass-unused-entities`);
}
@@ -499,17 +527,20 @@ class HUIRoot extends LitElement {
showVoiceCommandDialog(this);
}
private _handleHelp(): void {
window.open("https://www.home-assistant.io/lovelace/", "_blank");
}
private _editModeEnable(): void {
private _handleEnableEditMode(ev: CustomEvent<RequestSelectedDetail>): void {
if (!shouldHandleRequestSelectedEvent(ev)) {
return;
}
if (this._yamlMode) {
showAlertDialog(this, {
text: "The edit UI is not available when in YAML mode.",
});
return;
}
this._enableEditMode();
}
private _enableEditMode(): void {
this.lovelace!.setEditMode(true);
}
@@ -614,7 +645,7 @@ class HUIRoot extends LitElement {
const viewConfig = this.config.views[viewIndex];
if (!viewConfig) {
this._editModeEnable();
this._enableEditMode();
return;
}

View File

@@ -83,14 +83,14 @@ class HaPanelShoppingList extends LocalizeMixin(PolymerElement) {
icon="hass:microphone"
on-click="_showVoiceCommandDialog"
></ha-icon-button>
<ha-button-menu corner="BOTTOM_START">
<ha-button-menu corner="BOTTOM_START" on-action="_clearCompleted">
<ha-icon-button
icon="hass:dots-vertical"
label="Menu"
slot="trigger"
>
</ha-icon-button>
<mwc-list-item on-click="_clearCompleted">
<mwc-list-item>
[[localize('ui.panel.shopping-list.clear_completed')]]
</mwc-list-item>
</ha-button-menu>

View File

@@ -34,7 +34,7 @@ documentContainer.innerHTML = `<custom-style>
--scrollbar-thumb-color: rgb(194, 194, 194);
--error-color: #db4437;
--warning-color: #f4b400;
--warning-color: #FF9800;
--success-color: #0f9d58;
--info-color: #4285f4;

View File

@@ -9,7 +9,7 @@ import { Constructor } from "../types";
import { HassBaseEl } from "./hass-base-mixin";
import { HASSDomEvent } from "../common/dom/fire_event";
const DEBUG = true;
const DEBUG = false;
export const urlSyncMixin = <T extends Constructor<HassBaseEl>>(
superClass: T

View File

@@ -335,7 +335,8 @@
"automation": "Part of the following automations"
},
"data-table": {
"search": "Search"
"search": "Search",
"no-data": "No data"
}
},
"dialogs": {
@@ -1601,7 +1602,7 @@
"spinner": "Searching for ZHA Zigbee devices...",
"pairing_mode": "Make sure your devices are in pairing mode. Check the instructions of your device on how to do this.",
"discovered_text": "Devices will show up here once discovered.",
"no_devices_found": "No devices where found, make sure they are in paring mode and keep them awake while discovering is running.",
"no_devices_found": "No devices were found, make sure they are in paring mode and keep them awake while discovering is running.",
"search_again": "Search Again"
},
"network_management": {
@@ -1829,7 +1830,9 @@
"entity": "Entity",
"entity_id": "Entity ID",
"domain": "Domain",
"last_changed": "Last Changed"
"last_changed": "Last Changed",
"search": "Search entities",
"no_data": "No unused entities found"
},
"add_entities": {
"yaml_unsupported": "You cannot use this function when using Lovelace UI in YAML mode.",
@@ -1898,9 +1901,12 @@
},
"edit_card": {
"header": "Card Configuration",
"typed_header": "{type} Card Configuration",
"pick_card": "Which card would you like to add?",
"pick_card_view_title": "Which card would you like to add to your {name} view?",
"toggle_editor": "Toggle Editor",
"unsaved_changes": "You have unsaved changes",
"confirm_cancel": "Are you sure you want to cancel?",
"show_visual_editor": "Show Visual Editor",
"show_code_editor": "Show Code Editor",
"add": "Add Card",

View File

@@ -1,4 +1,9 @@
{
"config_entry": {
"disabled_by": {
"integration": "تكامل"
}
},
"groups": {
"system-admin": "مسؤولين",
"system-read-only": "مستخدمين للعرض فقط",
@@ -22,6 +27,19 @@
"auto": "تلقائي",
"off": "إيقاف",
"on": "تشغيل"
},
"hvac_action": {
"drying": "تجفيف"
}
},
"humidifier": {
"mode": {
"auto": "تلقائي",
"baby": "الطفل",
"comfort": "الراحة",
"eco": "اقتصادي",
"home": "في المنزل",
"normal": "عادي"
}
}
},
@@ -168,7 +186,7 @@
},
"configurator": {
"configure": "إعداد",
"configured": "تم الإعداد"
"configured": "تم التكوين"
},
"cover": {
"closed": "مغلق",
@@ -237,7 +255,7 @@
"on": "قيد التشغيل"
},
"scene": {
"scening": "قبد البحث"
"scening": "تشهيد"
},
"script": {
"off": "إيقاف",
@@ -299,7 +317,7 @@
"ui": {
"auth_store": {
"ask": "هل تريد حفظ هذا الدخول؟",
"confirm": "حفظ الدخول",
"confirm": "نعم",
"decline": "لا شكرا"
},
"card": {
@@ -330,10 +348,15 @@
"direction": "Richting",
"speed": "Snelheid"
},
"humidifier": {
"humidity": "الرطوبة المستهدفة",
"mode": "الوضع",
"target_humidity_entity": "{name} الرطوبة المستهدفة"
},
"light": {
"brightness": "Helderheid",
"color_temperature": "Kleurtemperatuur",
"white_value": "Witwaarde"
"white_value": "قيمة البياض"
},
"lock": {
"lock": "قفل",
@@ -351,6 +374,8 @@
"activate": "تفعيل"
},
"script": {
"cancel": "إلغاء",
"cancel_multiple": "إلغاء {number}",
"execute": "نفذ"
},
"service": {
@@ -414,6 +439,14 @@
"clear": "مسح",
"show_areas": "إظهار المناطق"
},
"data-table": {
"no-data": "لايوجد بيانات",
"search": "بحث"
},
"date-range-picker": {
"end_date": "تاريخ الإنتهاء",
"start_date": "تاريخ البدء"
},
"device-picker": {
"no_area": "لا مجال",
"toggle": "تبديل"
@@ -427,7 +460,14 @@
"loading_history": "جارٍ تحميل سجل الحالات ...",
"no_history_found": "لم يتم العثور على سجل الحالات."
},
"related-items": {
"integration": "تكامل"
},
"relative_time": {
"duration": {
"minute": "{count} {count, plural,\n one {دقيقة}\n other {دقائق}\n}"
},
"future": "قبل {time}",
"never": "Nooit"
},
"service-picker": {
@@ -436,14 +476,18 @@
},
"dialogs": {
"config_entry_system_options": {
"enable_new_entities_description": "إذا تم تعطيله ، فلن تتم إضافة الكيانات المكتشفة حديثًا لـ {integration} تلقائيًا إلى Home Assistant.",
"title": "خيارات النظام لـ {integration}",
"update": "تحديث"
},
"entity_registry": {
"editor": {
"confirm_delete": "هل أنت متأكد أنك تريد حذف هذا الإدخال؟",
"delete": "حذف",
"note": "ملاحظة: قد لا يعمل مع كافة التكاملات بعد.",
"update": "تحديث"
}
},
"related": "ذات صلة"
},
"generic": {
"cancel": "إلغاء الأمر",
@@ -465,8 +509,11 @@
"add": "إضافة"
},
"input_text": {
"max": "الحد الأقصى للطول",
"min": "الحد الأدنى للطول",
"password": "كلمة المرور"
}
},
"platform_not_loaded": "لم يتم تحميل تكامل {platform} . يرجى إضافته إلى التكوين الخاص بك إما عن طريق إضافة ':default_config' أو \"{platform}\"."
},
"more_info_control": {
"sun": {
@@ -493,13 +540,20 @@
"title": "{device} معلومات تصحيح الأخطاء",
"triggers": "محفزات"
},
"voice_command": {
"did_not_hear": "Home Assistant لم يسمع أي شيء"
},
"zha_device_info": {
"buttons": {
"add": "أضف أجهزة عبر هذا الجهاز",
"zigbee_information": "معلومات Zigbee"
},
"device_signature": "توقيع جهاز Zigbee",
"services": {
"zigbee_information": "عرض معلومات Zigbee للجهاز."
},
"zha_device_card": {
"device_name_placeholder": "تغيير اسم الجهاز"
}
}
},
@@ -510,7 +564,7 @@
},
"login-form": {
"log_in": "تسجيل الدخول",
"password": "كلمه السر",
"password": "كلمة السر",
"remember": "تذكر"
},
"notification_drawer": {
@@ -543,10 +597,15 @@
"name": "اسم",
"name_required": "الاسم مطلوب",
"unknown_error": "خطأ غير معروف"
},
"picker": {
"integrations_page": "صفحة التكاملات",
"introduction": "يتم استخدام المناطق لتنظيم أمكنة الأجهزة. سيتم استخدام هذه المعلومات في جميع أنحاء Home Assistant لمساعدتك في تنظيم الواجهة والأذونات و التكاملات مع الأنظمة الأخرى.",
"introduction2": "لوضع الأجهزة في منطقة ما، إستخدم الرابط أدناه للإنتقال إلى صفحة التكاملات ثم انقر فوق تكامل مكوّن للوصول إلى بطاقات الجهاز."
}
},
"automation": {
"caption": "التشغيل التلقائي",
"caption": "الأتمتة",
"description": "إنشاء وتحرير التشغيل الألي",
"editor": {
"actions": {
@@ -623,7 +682,7 @@
"sunset": "غروب الشمس"
},
"template": {
"label": "النموذج",
"label": "نموذج",
"value_template": "نموذج القيمة"
},
"time": {
@@ -632,7 +691,7 @@
"label": "وقت"
},
"zone": {
"entity": "الجهاز في المنطقة",
"entity": "كيان مع موقع",
"label": "المنطقة",
"zone": "المنطقة"
}
@@ -642,6 +701,17 @@
"default_name": "متحكم آلي جديد",
"enable_disable": "تمكين/تعطيل التنفيذ التلقائي",
"introduction": "استخدم المتحكمات الآلية لتجعل منزلك ينبض بالحياة",
"max": {
"queued": "طول قائمة الإنتظار"
},
"modes": {
"documentation": "وثائق الأتمتة",
"label": "وضع",
"parallel": "موازي",
"queued": "في قائمة الإنتظار",
"restart": "إعادة تشغيل",
"single": "فردي (افتراضي)"
},
"move_down": "تحرك لأسفل",
"move_up": "تحريك لأعلى",
"save": "حفظ",
@@ -653,6 +723,7 @@
"header": "المشغلات",
"introduction": "المشغلات هي ما يبدأ تشغيل قاعدة المتحكم الآلي. من الممكن تحديد مشغلات متعددة لنفس القاعدة. بمجرد بدء المشغل ، سيقوم Home Assistant بالتحقق من الشروط ، إن وجدت ، واستدعاء الإجراء. \n\n [مزيد من المعلومات حول المشغلات.] (https://home-assistant.io/docs/automation/trigger/)",
"learn_more": "معرفة المزيد عن المشغلات",
"name": "المشغل",
"type_select": "نوع المشغل",
"type": {
"device": {
@@ -732,13 +803,25 @@
}
},
"cloud": {
"caption": "كلاود هوم اسيستينت",
"account": {
"integrations": "تكاملات",
"integrations_introduction2": "تحقق من الموقع ل",
"integrations_link_all_features": " جميع الميزات المتوفرة"
},
"caption": "سحابة Home Assistant",
"description_login": "تم تسجيل الدخول كـ {email}",
"description_not_login": "لم يتم تسجيل الدخول"
"description_not_login": "لم يتم تسجيل الدخول",
"dialog_cloudhook": {
"info_disable_webhook": "إذا كنت لم تعد ترغب في استخدام هذا الwebhook ، يمكنك"
},
"register": {
"feature_amazon_alexa": "التكامل مع Amazon Alexa",
"feature_google_home": "التكامل مع Google Assistant"
}
},
"core": {
"caption": "عام",
"description": "التحقق من صحة ملف الإعدادات والتحكم بالخادم",
"description": "قم بتغيير التكوينات العامة لـ Home Assistant",
"section": {
"core": {
"core_config": {
@@ -754,18 +837,22 @@
"caption": "التخصيص",
"description": "تخصيص الكيانات الخاصة بك",
"picker": {
"entity": "الكيان"
"entity": "الكيان",
"introduction": "تعديل السمات لكل كيان. سيتم تفعيل التخصيصات المضافة / المعدلة على الفور. ستسري التخصيصات التي تمت إزالتها عندما يتم تحديث الكيان."
}
},
"devices": {
"cant_edit": "يمكنك فقط تحرير العناصر التي تم إنشاؤها في واجهة المستخدم.",
"confirm_delete": "هل أنت متأكد أنك تريد حذف هذا الجهاز؟",
"data_table": {
"integration": "تكامل",
"no_area": "لا مجال",
"no_devices": "لا توجد أجهزة"
},
"delete": "حذف",
"device_info": "معلومات الجهاز",
"entities": {
"add_entities_lovelace": "أضف إلى Lovelace",
"disabled_entities": "{count} {count, plural,\n one {كيان}\n other {كيانات}\n}",
"hide_disabled": "إخفاء معطل"
},
@@ -773,10 +860,14 @@
},
"entities": {
"picker": {
"headers": {
"integration": "تكامل"
},
"remove_selected": {
"confirm_partly_text": "يمكنك فقط إزالة {removable} من الكيانات {selected} . لا يمكن إزالة الكيانات إلا عندما يتوقف التكامل عن توفير الكيانات. في بعض الأحيان ، يتعين عليك إعادة تشغيل Home Assistant قبل أن تتمكن من إزالة كيانات التكامل الذي تمت إزالته. هل أنت متأكد من أنك تريد إزالة الكيانات القابلة للإزالة؟",
"confirm_partly_title": "يمكن فقط إزالة {number} الكيانات المحددة."
},
"search": "إبحث عن الكيانات",
"status": {
"restored": "مستعاد"
}
@@ -786,7 +877,7 @@
"clear": "محو",
"filtering_by": "التصفية حسب"
},
"header": "برمجة نظام مساعد البيت",
"header": "تكوين Home Assistant",
"helpers": {
"dialog": {
"create": "إضافة"
@@ -800,6 +891,7 @@
}
},
"types": {
"input_boolean": "تبديل",
"input_number": "رقم",
"input_select": "القائمه المنسدله",
"input_text": "النص"
@@ -809,54 +901,85 @@
"caption": "معلومات",
"description": "معلومات حول تثبيت Home Assistant",
"documentation": "الوثائق",
"home_assistant_logo": "شعار Home Assistant",
"integrations": "تكاملات",
"issues": "الاعطال"
},
"integration_panel_move": {
"link_integration_page": "صفحة التكاملات",
"missing_zha": "هل فقدت لوحة تكوين ZHA؟ تم نقله إلى إدخال ZHA على {integrations_page} ."
},
"integrations": {
"add_integration": "أضف integration",
"caption": "تكاملات",
"add_integration": "أضف تكامل",
"caption": "التكاملات",
"config_entry": {
"area": "في {area}",
"delete": "حذف",
"delete_button": "حذف {integration}",
"delete_confirm": "هل تريد حقا حذف هذا التكامل؟",
"device_unavailable": "الجهاز غير متوفر",
"devices": "{count} {count, plural,\n one {جهاز}\n other {أجهزة}\n}",
"documentation": "الوثائق",
"entities": "{count} {count, plural,\n one {كيان}\n other {كيانات}\n}",
"entity_unavailable": "العنصر غير متوفر",
"entity_unavailable": "الكيان غير متوفر",
"firmware": "نظام التشغيل {version}",
"hub": "متصل عبر",
"manuf": "بواسطة {manufacturer}",
"no_area": "لا توجد منطقة",
"no_device": "عناصر بدون أجهزة",
"no_device": "كيانات بدون أجهزة",
"no_devices": "هذا التكامل لا يوجد لديه الأجهزة.",
"options": "خيارات",
"rename": "إعادة تسمية",
"restart_confirm": "اعادة تشغيل هوم اسيستينت لإنهاء حذف هذه التكامل",
"restart_confirm": "أعد تشغيل Home Assistant لإنهاء حذف هذا التكامل",
"settings_button": "تحرير الإعدادات لـ {integration}",
"system_options": "خيارات النظام",
"system_options_button": "خيارات النظام لـ {integration}",
"unnamed_entry": "إدخال بدون اسم"
},
"config_flow": {
"loading_first_time": "يرجى الانتظار بينما يتم تثبيت الـintegration"
"aborted": "تم الإلغاء",
"close": "إغلاق",
"created_config": "تم إنشاء تكوين لـ {name}.",
"error_saving_area": "خطأ في حفظ المنطقة: {error}",
"external_step": {
"description": "تتطلب هذه الخطوة زيارة موقع خارجي للإكمال.",
"open_site": "افتح الموقع"
},
"finish": "إنهاء",
"loading_first_time": "يرجى الانتظار بينما يتم تثبيت الـintegration",
"not_all_required_fields": "لم يتم تعبئة جميع الحقول المطلوبة."
},
"configure": "إعداد",
"configured": "تم الإعداد",
"description": "إدارة الأجهزة والخدمات المتصلة",
"configured": "تم التكوين",
"description": عداد وإدارة التكاملات",
"details": "تفاصيل التكامل",
"discovered": "مكتشف",
"home_assistant_website": "موقع Home Assistant",
"ignore": {
"confirm_delete_ignore": "سيؤدي ذلك إلى ظهور التكامل في عمليات التكامل المكتشفة مرة أخرى عند اكتشافها. قد يتطلب هذا إعادة تشغيل أو يستغرق بعض الوقت.",
"confirm_delete_ignore_title": "توقف عن تجاهل {name} ؟",
"confirm_ignore": "هل أنت متأكد أنك لا تريد إعداد هذا التكامل؟ يمكنك التراجع بالنقر على \"إظهار عمليات التكامل التي تم تجاهلها\" في القائمة بأعلى اليسار.",
"confirm_ignore_title": "تجاهل اكتشاف {name} ؟",
"hide_ignored": "إخفاء التكاملات المتجاهلة",
"ignore": "تجاهل",
"ignored": "تجاهل",
"show_ignored": "أظهر الدمج المتجاهل",
"ignored": "متجاهل",
"show_ignored": "أظهر التكاملات المتجاهلة",
"stop_ignore": "توقف عن التجاهل"
},
"integration": "integration",
"integration": "تكامل",
"integration_not_found": "لم يتم العثور على التكامل.",
"new": "إعداد تكامل جديد",
"no_integrations": "يبدوأن ليس هناك أي integations بعد. انقر على الزر أدناه لإضافة واحدة!",
"none": "لم يتم الإعداد بعد",
"none_found": "لم يتم العثور على عمليات تكامل",
"none_found_detail": "اضبط معايير البحث.",
"rename_dialog": "تعديل الاسم",
"rename_input_label": "الاسم"
"no_integrations": "يبدو أنه لم يتم تكوين أي تكاملات بعد. انقر على الزر أدناه لإضافة تكاملك الأول!",
"none": "لم يتم تكوين أي شيء حتى الآن",
"none_found": "لم يتم العثور على تكاملات",
"none_found_detail": "إضبط معايير بحثك.",
"note_about_integrations": "لا يمكن تكوين جميع التكاملات عبر واجهة المستخدم حتى الآن.",
"note_about_website_reference": "يتوفر المزيد على ",
"rename_dialog": "تحرير إسم إدخال هذا التكوين",
"rename_input_label": "الاسم",
"search": "إبحث عن التكاملات"
},
"introduction": "يمكنك هنا برمجة المكونات الخاصة بك و إعداد نظام مساعد البيت. ليس كل شيء متاح للبرمجة من خلال واجهة المستخدم حتى الآن، ولكننا نعمل على ذلك.",
"introduction": "يمكنك هنا برمجة المكونات الخاصة بك و إعداد نظام Home Assistant. ليس كل شيء متاح للبرمجة من خلال واجهة المستخدم حتى الآن، ولكننا نعمل على ذلك.",
"logs": {
"caption": "السجلات",
"description": "عرض سجلات Home Assistant"
@@ -921,14 +1044,26 @@
}
},
"mqtt": {
"button": "كوِن",
"title": "MQTT"
},
"person": {
"caption": "الأشخاص",
"description": "إدارة الأشخاص الذين يتتبعهم Home Assistant.",
"detail": {
"device_tracker_pick": "اختر جهاز لتتبع"
}
"device_tracker_pick": "اختر جهاز لتتبع",
"link_integrations_page": "صفحة التكاملات",
"link_presence_detection_integrations": "تكاملات الكشف عن التواجد",
"name_error_msg": "الاسم مطلوب",
"no_device_tracker_available_intro": "عندما يكون لديك أجهزة تشير إلى تواجد شخص ، ستتمكن من تعيينها إلى شخص هنا. يمكنك إضافة جهازك الأول عن طريق إضافة تكامل كشف التواجد من صفحة التكاملات."
},
"no_persons_created_yet": "يبدو أنك لم تقم بإنشاء أي شخص حتى الآن.",
"note_about_persons_configured_in_yaml": "ملاحظة: لا يمكن تعديل الأشخاص الذين تم تكوينهم عبر config.yaml عبر واجهة المستخدم."
},
"scene": {
"editor": {
"icon": "أيقونة"
},
"picker": {
"headers": {
"name": "الاسم"
@@ -939,7 +1074,20 @@
"caption": "السكريبت",
"description": "إنشاء و تحرير السكريبت",
"editor": {
"alias": "الاسم"
"alias": "الاسم",
"icon": "أيقونة",
"id": "معرف الكيان",
"id_already_exists": "هذا المعرف موجود بالفعل",
"max": {
"queued": "طول قائمة الإنتظار"
},
"modes": {
"label": "وضع",
"parallel": "موازي",
"queued": "في قائمة الإنتظار",
"restart": "إعادة تشغيل",
"single": "فردي (إفتراضي)"
}
},
"picker": {
"headers": {
@@ -951,11 +1099,22 @@
"server_control": {
"section": {
"reloading": {
"automation": "إعادة تحميل الأتمتة",
"core": "إعادة تحميل الموقع والتخصيصات",
"input_boolean": "إعادة تحميل مدخلات منطقية",
"input_datetime": "إعادة تحميل أوقات تاريخ الإدخال",
"input_number": "إعادة تحميل أرقام الإدخال",
"input_select": "إعادة تحميل تحديدات الإدخال",
"input_text": "إعادة تحميل النصوص المدخلة"
"input_text": "إعادة تحميل النصوص المدخلة",
"person": "إعادة تحميل الأشخاص",
"zone": "إعادة تحميل المناطق"
},
"server_management": {
"confirm_restart": "هل تريد بالتأكيد اعادة تشغيل Home Assistant؟",
"confirm_stop": "هل تريد بالتأكيد إيقاف Home Assistant؟"
},
"validation": {
"introduction": "تحقق من صلاحية التكوين الخاص بك إذا قمت مؤخرًا بإجراء بعض التغييرات وتريد التأكد من صلاحية جميعها"
}
}
},
@@ -989,29 +1148,52 @@
},
"users_privileges_note": "مجموعة المستخدمين هي عمل قيد التقدم. لن يتمكن المستخدم من إدارة المثيل عبر واجهة المستخدم. ما زلنا نقوم بتدقيق جميع نقاط نهاية واجهة برمجة تطبيقات الإدارة للتأكد من أنها تحد من الوصول إلى المسؤولين بشكل صحيح."
},
"zha": {
"add_device_page": {
"discovered_text": "ستظهر الأجهزة هنا عند إكتشافها."
},
"button": "كوِن",
"groups": {
"zha_zigbee_groups": "مجموعات ZHA Zigbee"
},
"network": {
"caption": "الشبكة"
},
"node_management": {
"header": "إدارة الجهاز"
}
},
"zone": {
"add_zone": "إضافة المنطقة",
"caption": "المناطق",
"configured_in_yaml": "لا يمكن تحرير المناطق التي تم تكوينها بواسطة configuration.yaml عبر واجهة المستخدم.",
"description": "إدارة المناطق التي تريد تتبع الأشخاص فيها.",
"detail": {
"create": "إضافة",
"delete": "حذف",
"icon": "أيقونة",
"name": "الاسم",
"required_error_msg": "العنوان مطلوب.",
"new_zone": "منطقة جديدة",
"required_error_msg": "هذا الحقل مطلوب",
"update": "تحديث"
}
},
"introduction": "تسمح لك المناطق بتحديد مناطق معينة على وجه الأرض. عندما يكون الشخص داخل منطقة ما ، ستأخذ الحالة الاسم من المنطقة. يمكن أيضًا استخدام المناطق كمشغل أو حالة داخل إعدادات الأتمتة."
},
"zwave": {
"button": "كوِن",
"caption": "Z-Wave",
"description": "إدارة شبكة Z-Wave",
"node_config": {
"seconds": "ثواني",
"set_config_parameter": "تعيين معلمة التكوين"
},
"node_management": {
"add_to_group": "إضافة إلى المجموعة",
"entities": "كيانات هذه العقدة",
"entity_info": "معلومات الكيان",
"exclude_entity": "تحكم بسيرفر Home Assistant ... من Home Assistant.",
"exclude_entity": "استبعد هذا الكيان من Home Assistant",
"group": "مجموعة",
"header": "إدارة العقدة Z-Wave",
"header": "إدارة عقد Z-Wave",
"introduction": "قم بتشغيل أوامر Z-Wave التي تؤثر على عقدة واحدة. اختر عقدة لترى قائمة بالأوامر المتاحة.",
"max_associations": "اعلى رقم للجمعيات:",
"node_group_associations": "ارتباطات مجموعة العقدة",
@@ -1039,6 +1221,9 @@
"refresh_node": "تحديث العقدة",
"remove_failed_node": "إزالة العقدة الفاشلة",
"replace_failed_node": "استبدال العقدة الفاشلة",
"start_network": "بدء تشغيل الشبكة",
"stop_network": "إيقاف الشبكة",
"test_network": "اختبار الشبكة",
"test_node": "اختبار عقدة"
}
}
@@ -1052,6 +1237,7 @@
"title": "الخدمات"
},
"states": {
"description2": "لن يتواصل هذا مع الجهاز الفعلي.",
"title": "الحالات"
},
"templates": {
@@ -1061,16 +1247,35 @@
},
"history": {
"period": "المدة",
"ranges": {
"last_week": "الأسبوع الماضي",
"this_week": "هذا الأسبوع",
"today": "اليوم",
"yesterday": "أمس"
},
"showing_entries": "عرض الأحداث لـ"
},
"logbook": {
"ranges": {
"last_week": "الأسبوع الماضي",
"this_week": "هذا الأسبوع",
"today": "اليوم",
"yesterday": "أمس"
},
"showing_entries": "عرض الأحداث لـ"
},
"lovelace": {
"cards": {
"empty_state": {
"go_to_integrations_page": "انتقل إلى صفحة التكاملات.",
"no_devices": "تسمح لك هذه الصفحة بالتحكم في أجهزتك ، ولكن يبدو أنك لم تعد أي أجهزة حتى الآن. توجه إلى صفحة التكاملات للبدء."
},
"safe-mode": {
"description": "واجه Home Assistant مشكلة أثناء تحميل التكوينات الخاصة بك ويتم تشغيله الآن في الوضع الآمن. أنظر إلى سجل الأخطاء لمعرفة الخطأ."
},
"starting": {
"description": "Home Assistant يبدأ، يرجى الانتظار...",
"header": "يبدأ مساعد المنزل ..."
"header": "Home Assistant يبدأ..."
}
},
"editor": {
@@ -1107,11 +1312,14 @@
},
"generic": {
"attribute": "السمه",
"camera_view": "عرض الكاميرا",
"double_tap_action": "تأثير النقر المزدوج",
"manual": "يدويا",
"manual_description": "هل تريد إضافة بطاقة مخصصة أو ترغب فقط في كتابة yaml يدويًا؟",
"no_theme": "لا توجد تصاميم متاحة",
"search": "بحث",
"secondary_info_attribute": "سمة المعلومات الثانوية",
"show_name": "أظهر الاسم؟",
"state": "الحالة"
},
"glance": {
@@ -1123,6 +1331,10 @@
"horizontal-stack": {
"description": "تتيح لك بطاقة التكديس الأفقي تجميع عدة بطاقات معًا ، بحيث تكون دائمًا بجانب بعضها البعض في مساحة عمود واحد."
},
"humidifier": {
"description": "تتيح بطاقة المرطب التحكم في كيان المرطب. يسمح لك بتغيير الرطوبة ووضع الكيان.",
"name": "المرطب"
},
"iframe": {
"description": "تسمح لك بطاقة صفحة الويب بتضمين صفحة ويب مباشرةً في Home Assistant."
},
@@ -1176,12 +1388,20 @@
"no_description": "لا يوجد وصف متاح."
},
"edit_card": {
"confirm_cancel": "هل أنت متأكد من الإلغاء؟",
"delete": "حذف",
"duplicate": "بطاقة مكررة",
"edit": "تصحيح",
"move": "نقل"
"move": "نقل",
"options": "المزيد من الخيارات",
"typed_header": "{type} تكوين البطاقة",
"unsaved_changes": "لديك تغييرات غير محفوظة"
},
"edit_lovelace": {
"title": "عنوان"
},
"edit_view": {
"header_name": "{name} عرض التكوين",
"tab_visibility": "الرؤية",
"visibility": {
"select_users": "تحديد المستخدمين الذين يجب أن يروا طريقة العرض هذه في التنقل"
@@ -1197,6 +1417,7 @@
"cancel": "لا يهم",
"close": "إغلاق",
"empty_config": "ابدأ بلوحة معلومات فارغة",
"para_sure": "هل أنت متأكد أنك تريد التحكم في واجهة المستخدم الخاصة بك؟",
"yaml_mode": "أنت تستخدم وضع YAML للوحة البيانات هذه ، مما يعني أنه لا يمكنك تغيير تكوين Lovelace من واجهة المستخدم. إذا كنت تريد إدارة لوحة التحكم هذه من واجهة المستخدم ، فقم بإزالة \"الوضع: yaml\" من تكوين Lovelace في \"config.yaml.\"."
},
"view": {
@@ -1208,10 +1429,15 @@
"menu": {
"reload_resources": "إعادة تحميل الموارد"
},
"reload_lovelace": "إعادة تحميل واجهة المستخدم",
"reload_resources": {
"refresh_body": "يجب عليك تحديث الصفحة لإكمال إعادة التحميل ، هل تريد التحديث الآن؟",
"refresh_header": "هل تريد التحديث؟"
},
"unused_entities": {
"no_data": "لم يعثر على كيانات غير مستخدمة",
"search": "إبحث عن الكيانات"
},
"views": {
"confirm_delete_existing_cards": "سيؤدي حذف هذا العرض إلى إزالة البطاقات أيضًا",
"confirm_delete_existing_cards_text": "هل أنت متأكد من أنك تريد حذف طريقة عرض ''{name}''؟ تحتوي طريقة العرض على {number} بطاقات سيتم حذفها. لا يمكن التراجع عن هذا الإجراء.",
@@ -1221,7 +1447,7 @@
"attribute_not_found": "السمة {attribute} غير متاحة في: {entity}",
"entity_not_found": "الجهاز غير متوفر: {entity}",
"entity_unavailable": "العنصر غير متوفر",
"starting": "يبدأ مساعد المنزل ، قد لا يكون كل شيء متاح حتى الآن"
"starting": "Home Assistant يبدأ، قد لا يكون كل شيء متاح حتى الآن"
}
},
"mailbox": {
@@ -1245,6 +1471,16 @@
}
}
}
},
"trusted_networks": {
"abort": {
"not_allowed": "كمبيوترك غير مسموح به."
},
"step": {
"init": {
"description": "يرجى تحديد المستخدم الذي تريد تسجيل الدخول باسمه:"
}
}
}
},
"start_over": "البدء من جديد",
@@ -1252,7 +1488,22 @@
},
"initializing": "جار التهيئة"
},
"page-demo": {
"config": {
"arsaboo": {
"labels": {
"air": "هواء"
}
}
}
},
"page-onboarding": {
"integration": {
"finish": "إنهاء",
"intro": "يتم تمثيل الأجهزة والخدمات في Home Assistant كتكاملات. يمكنك إعدادها الآن ، أو القيام بذلك لاحقًا من شاشة التكوين.",
"more_integrations": "المزيد"
},
"intro": "هل أنت مستعد لإيقاظ منزلك واستعادة خصوصيتك والانضمام إلى مجتمع عالمي من اللاعبين؟",
"user": {
"data": {
"password": "كلمه السر",
@@ -1287,7 +1538,7 @@
"language": {
"dropdown_label": "اللغة",
"header": "اللغة",
"link_promo": "المساعدة في ترجمة"
"link_promo": "ساعد في الترجمة"
},
"long_lived_access_tokens": {
"last_used": "آخر استخدام بتاريخ {date} من {location}",
@@ -1317,6 +1568,10 @@
"last_used": "آخر استخدام بتاريخ {date} من {location}",
"not_used": "لم يتم استخدامها ابدأ"
},
"suspend": {
"description": "هل يغلق الاتصال بالخادم بعد إخفاؤه لمدة 5 دقائق؟",
"header": "إغلق الاتصال تلقائيًا"
},
"themes": {
"dropdown_label": "التصميم",
"error_no_theme": "لا توجد تصاميم متاحة.",

View File

@@ -1159,6 +1159,7 @@
},
"edit_card": {
"add": "Добавяне на карта",
"confirm_cancel": "Сигурни ли сте, че искате да отмените?",
"delete": "Изтриване на карта",
"edit": "Редактиране",
"header": "Конфигуриране на Карта",

View File

@@ -430,6 +430,8 @@
"activate": "Activar"
},
"script": {
"cancel": "Cancel·la",
"cancel_multiple": "Cancel·la {number}",
"execute": "Executar"
},
"service": {
@@ -526,6 +528,7 @@
"show_areas": "Mostra àrees"
},
"data-table": {
"no-data": "No hi ha dades",
"search": "Cerca"
},
"date-range-picker": {
@@ -949,10 +952,10 @@
"description": "El mode controla què passa quan es dispara l'automatització i encara hi ha accions executant-se d'un disparament anterior. Consulta {documentation_link} per a més informació.",
"documentation": "documentació d'automatització",
"label": "Mode",
"parallel": "Paral·lel (per defecte)",
"parallel": "Paral·lel",
"queued": "A la cua",
"restart": "Reinicia",
"single": "Individual"
"single": "Individual (per defecte)"
},
"move_down": "Mou avall",
"move_up": "Mou amunt",
@@ -1662,6 +1665,7 @@
"introduction": "Les entitats que no pertanyen a un dispositiu es poden configurar aquí.",
"without_device": "Entitats sense dispositiu"
},
"icon": "Icona",
"introduction": "Utilitza les escenes per donar més vida a la teva llar.",
"load_error_not_editable": "Només es poden editar les escenes de l'arxiu scenes.yaml.",
"load_error_unknown": "Error en carregar l'escena ({err_no}).",
@@ -1695,6 +1699,10 @@
"delete_confirm": "Estàs segur que vols eliminar aquest script?",
"delete_script": "Elimina l'script",
"header": "Script: {name}",
"icon": "Icona",
"id": "ID de l'entitat",
"id_already_exists": "Aquest ID ja existeix",
"id_already_exists_save_error": "No pots desar aquest script perquè l'ID no és únic, tria'n un altre o deixa-ho en blanc perquè se'n generi un automàticament.",
"introduction": "Utilitza els scripts per executar seqüències d'accions.",
"link_available_actions": "Més informació sobre les accions disponibles.",
"load_error_not_editable": "Només es poden editar els scripts dins de l'arxiu scripts.yaml.",
@@ -1808,7 +1816,7 @@
"discovered_text": "Els dispositius apareixeran aquí un cop descoberts.",
"discovery_text": "Els dispositius descoberts apareixeran aquí. Segueix les instruccions del/s teu/s dispositiu/s i posa el dispositiu/s en mode d'emparellament.",
"header": "Domòtica amb Zigbee - Afegir dispositius",
"no_devices_found": "No s'han trobat dispositius, assegura't que estiguin en mode vinculació i manten-los desperts mentre estiguin intentant ser descoberts.",
"no_devices_found": "No s'han trobat dispositius, assegura't que estiguin en mode vinculació i manten-los desperts mentre s'estiguin descoberint.",
"pairing_mode": "Assegura't que els dispositiu estiguin en mode vinculació. Consulta les instruccions del dispositiu per saber com fer-ho.",
"search_again": "Torna a cercar",
"spinner": "S'estan cercant dispositius ZHA Zigbee..."
@@ -2332,6 +2340,7 @@
},
"edit_card": {
"add": "Afegir targeta",
"confirm_cancel": "Segur que vols cancel·lar?",
"delete": "Elimina targeta",
"duplicate": "Duplica targeta",
"edit": "Editar",
@@ -2342,7 +2351,9 @@
"pick_card_view_title": "Quina targeta vols afegir a la visualització {name}?",
"show_code_editor": "Mostra l'editor de codi",
"show_visual_editor": "Mostra l'editor visual",
"toggle_editor": "Commutar l'editor"
"toggle_editor": "Commutar l'editor",
"typed_header": "Configuració de la targeta {type}",
"unsaved_changes": "Hi ha canvis no desats"
},
"edit_lovelace": {
"edit_title": "Edita el títol",
@@ -2435,6 +2446,8 @@
"entity": "Entitat",
"entity_id": "ID de l'entitat",
"last_changed": "Últim canvi",
"no_data": "No s'han trobat entitats sense utilitzar",
"search": "Cerca entitats",
"select_to_add": "Selecciona les entitats que vols afegir a una targeta i fés clic al botó d'afegir targeta.",
"title": "Entitats sense utilitzar"
},

View File

@@ -70,9 +70,9 @@
"armed_custom_bypass": "Zabezpečeno",
"armed_home": "Zabezpečeno",
"armed_night": "Zabezpečeno",
"arming": "Aktivace",
"arming": "Zabezpečování",
"disarmed": "Nezabezpečeno",
"disarming": "Deaktivace",
"disarming": "Odbezpečování",
"pending": "Čeká",
"triggered": "Spuštěn"
},
@@ -95,7 +95,7 @@
"alarm_control_panel": {
"armed": "Zabezpečeno",
"armed_away": "Režim nepřítomnost",
"armed_custom_bypass": "Aktivní uživatelským obejitím",
"armed_custom_bypass": "Zabezpečeno uživatelským obejitím",
"armed_home": "Režim domov",
"armed_night": "Noční režim",
"arming": "Zabezpečování",
@@ -430,6 +430,8 @@
"activate": "Aktivovat"
},
"script": {
"cancel": "Zrušit",
"cancel_multiple": "Zrušit {number}",
"execute": "Vykonat"
},
"service": {
@@ -525,6 +527,10 @@
"clear": "Vymazat",
"show_areas": "Zobrazit oblasti"
},
"data-table": {
"no-data": "Žádná data",
"search": "Hledat"
},
"date-range-picker": {
"end_date": "Koncové datum",
"select": "Vybrat",
@@ -938,6 +944,19 @@
"introduction": "Použijte automatizace k oživení svého domova",
"load_error_not_editable": "Lze upravovat pouze automatizace v automations.yaml.",
"load_error_unknown": "Chyba při načítání automatizace ({err_no}).",
"max": {
"parallel": "Maximální počet paralelních spuštění",
"queued": "Délka fronty"
},
"modes": {
"description": "Režim určuje, co se stane, když je automatizace spuštěna a zároveň stále ještě běží akce na základě předchozího spuštění. Další informace naleznete na {documentation_link}.",
"documentation": "Dokumentace automatizací",
"label": "Režim",
"parallel": "Paralelně",
"queued": "Fronta",
"restart": "Restart",
"single": "Jediný (výchozí)"
},
"move_down": "Posunout dolů",
"move_up": "Posunout nahoru",
"save": "Uložit",
@@ -1356,6 +1375,7 @@
"confirm_text": "Entity lze odebrat pouze v případě, že integrace již entity neposkytuje.",
"confirm_title": "Chcete odstranit {number} entit?"
},
"search": "Hledat entitu",
"selected": "{number} vybraných",
"status": {
"disabled": "Zakázáno",
@@ -1386,13 +1406,14 @@
"entity_id": "ID entity",
"name": "Název",
"type": "Typ"
}
},
"no_helpers": "Vypadá to, že ještě nemáte žádné pomocníky!"
},
"types": {
"input_boolean": "Přepnout",
"input_boolean": "Přepínač",
"input_datetime": "Datum a/nebo čas",
"input_number": "Číslo",
"input_select": "Rozbalovací nabídka",
"input_select": "Výběr",
"input_text": "Text"
}
},
@@ -1490,7 +1511,8 @@
"note_about_integrations": "Ne všechny integrace lze prozatím konfigurovat prostřednictvím uživatelského rozhraní.",
"note_about_website_reference": "Další jsou k dispozici na ",
"rename_dialog": "Upravit název této položky nastavení",
"rename_input_label": "Název položky"
"rename_input_label": "Název položky",
"search": "Hledat integraci"
},
"introduction": "Zde je možné konfigurovat vaše komponenty a Home Assistant.\nZ uživatelského rozhraní sice zatím není možné konfigurovat vše, ale pracujeme na tom.",
"logs": {
@@ -1643,6 +1665,7 @@
"introduction": "Zde lze nastavit entity, které nepatří k zařízení.",
"without_device": "Entity bez zařízení"
},
"icon": "Ikona",
"introduction": "Pomocí scén oživte svůj domov.",
"load_error_not_editable": "Lze upravovat pouze scény v souboru scenes.yaml.",
"load_error_unknown": "Chyba při načítání scény ({err_no}).",
@@ -1676,9 +1699,26 @@
"delete_confirm": "Opravdu chcete tento skript smazat?",
"delete_script": "Smazat skript",
"header": "Skript: {name}",
"icon": "Ikona",
"id": "ID entity",
"id_already_exists": "Toto ID již existuje",
"id_already_exists_save_error": "Tento skript nelze uložit, protože ID není jedinečné, vyberte jiné ID nebo jej nechte prázdné a bude automaticky vygenerováno.",
"introduction": "K provedení posloupnosti akcí použijte skripty.",
"link_available_actions": "Další informace o dostupných akcích.",
"load_error_not_editable": "Upravovat lze pouze skripty uvnitř scripts.yaml.",
"max": {
"parallel": "Maximální počet paralelních spuštění",
"queued": "Délka fronty"
},
"modes": {
"description": "Režim určuje, co se stane, když je skript spuštěn a zároveň stále ještě běží na základě předchozího spuštění. Další informace naleznete na {documentation_link}.",
"documentation": "Dokumentace skriptů",
"label": "Režim",
"parallel": "Paralelně",
"queued": "Fronta",
"restart": "Restart",
"single": "Jediný (výchozí)"
},
"sequence": "Sekvence",
"sequence_sentence": "Posloupnost akcí tohoto skriptu."
},
@@ -1691,7 +1731,7 @@
},
"introduction": "Editor skriptů umožňuje vytvářet a upravovat skripty. Postupujte podle níže uvedeného odkazu a přečtěte si pokyny, abyste se ujistili, že jste Home Assistant nakonfigurovali správně.",
"learn_more": "Další informace o skriptech",
"no_scripts": "Nemohli jsme najít žádné editovatelné skripty",
"no_scripts": "Nemohli jsme najít žádné upravitelné skripty",
"show_info": "Zobrazit informace o skriptu",
"trigger_script": "Spustit skript"
}
@@ -1705,11 +1745,11 @@
"core": "Znovu načíst umístění a přizpůsobení",
"group": "Znovu načíst skupiny",
"heading": "Konfigurace se načítá",
"input_boolean": "Znovu načíst logické hodnoty",
"input_datetime": "Znovu načíst časy",
"input_number": "Znovu načíst vstupní čísla",
"input_select": "Znovu načíst výběr",
"input_text": "Znovu načíst text",
"input_boolean": "Znovu načíst pomocníky - čísla",
"input_datetime": "Znovu načíst pomocníky - data/časy",
"input_number": "Znovu načíst pomocníky - přepínače",
"input_select": "Znovu načíst pomocníky - výběry",
"input_text": "Znovu načíst pomocníky - texty",
"introduction": "Některé části Home Assistant lze načíst bez nutnosti restartování. Volba načtení zahodí jejich aktuální konfiguraci a načte novou.",
"person": "Znovu načíst osoby",
"scene": "Znovu načíst scény",
@@ -1899,9 +1939,9 @@
"update": "Aktualizovat"
},
"edit_home_zone": "Poloměr domovské zóny zatím nelze upravit z frontendu. Z frontendu se dá změnit jen poloha domovské zóny.",
"edit_home_zone_narrow": "Poloměr domovské zóny zatím nelze upravit z frontendu. Umístění lze změnit z obecné konfigurace.",
"edit_home_zone_narrow": "Poloměr domovské zóny zatím nelze upravit z rozhraní. Umístění lze změnit z obecné konfigurace.",
"go_to_core_config": "Přejít na obecnou konfiguraci?",
"home_zone_core_config": "Umístění vaší domovské zóny lze upravit na stránce obecné konfigurace. Poloměr domovské zóny zatím nelze upravit z frontendu. Chcete přejít na obecnou konfiguraci?",
"home_zone_core_config": "Umístění vaší domovské zóny lze upravit na stránce obecné konfigurace. Poloměr domovské zóny zatím nelze upravit z rozhraní. Chcete přejít na obecnou konfiguraci?",
"introduction": "Zóny umožňují určit určité oblasti na zemi. Když je osoba v zóně, stav převezme název ze zóny. Zóny lze také použít jako aktivační událost nebo podmínku v nastavení automatizace.",
"no_zones_created_yet": "Vypadá to, že nejsou vytvořené žádné zóny."
},
@@ -2194,6 +2234,7 @@
"name": "Název",
"no_theme": "Žádný motiv",
"refresh_interval": "Interval obnovení",
"search": "Hledat",
"secondary_info_attribute": "Sekundární informační atribut",
"show_icon": "Zobrazit ikonu?",
"show_name": "Zobrazit název?",
@@ -2299,6 +2340,7 @@
},
"edit_card": {
"add": "Přidat kartu",
"confirm_cancel": "Opravdu chcete zahodit změny?",
"delete": "Odstranit",
"duplicate": "Duplikovat Kartu",
"edit": "Upravit",
@@ -2309,12 +2351,15 @@
"pick_card_view_title": "Kterou kartu byste chtěli přidat do svého {name} pohledu?",
"show_code_editor": "Zobrazit editor kódu",
"show_visual_editor": "Zobrazit vizuální editor",
"toggle_editor": "Přepnout Editor"
"toggle_editor": "Přepnout Editor",
"typed_header": "{type} Konfigurace karty",
"unsaved_changes": "Změny nejsou uloženy"
},
"edit_lovelace": {
"edit_title": "Upravit titulek",
"explanation": "Tento název je zobrazen nad všemi vašimi zobrazeními v Lovelace.",
"header": "Název vašeho uživatelského rozhraní Lovelace"
"header": "Název vašeho uživatelského rozhraní Lovelace",
"title": "Název"
},
"edit_view": {
"add": "Přidat pohled",
@@ -2363,7 +2408,7 @@
"empty_config": "Začít s prázdným dashboardem",
"header": "Převzít kontrolu nad vaší Lovelace UI",
"para": "Ve výchozím nastavení bude Home Assistant spravovat vaše uživatelské rozhraní aktualizovat jej při přidání nové entity nebo Lovelace komponenty. Pokud převezmete kontrolu, nebudeme již provádět změny automaticky za vás.",
"para_sure": "Opravdu chcete převzít kontrolu nad uživalským rohraním ?",
"para_sure": "Opravdu chcete převzít kontrolu nad uživalským rozhraním ?",
"save": "Převzít kontrolu",
"yaml_config": "Abyste mohli snadněji začít, zde aktuální konfigurace tohoto dashboardu:",
"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'.",
@@ -2401,6 +2446,8 @@
"entity": "Entita",
"entity_id": "ID entity",
"last_changed": "Naposledy změněno",
"no_data": "Nebyly nalezeny žádné nepoužívané entity",
"search": "Hledat entitu",
"select_to_add": "Vyberte entity, které chcete přidat do karty, a poté klikněte na tlačítko přidat kartu.",
"title": "Nepoužité entity"
},
@@ -2503,6 +2550,7 @@
},
"trusted_networks": {
"abort": {
"not_allowed": "Váš počítač není povolen.",
"not_whitelisted": "Váš počítač není na seznamu povolených."
},
"step": {
@@ -2678,6 +2726,10 @@
"not_used": "Nikdy nebylo použito",
"token_title": "Obnovovací token pro {clientId}"
},
"suspend": {
"description": "Měli bychom ukončit spojení se serverem, pokud není Home Assistant viditelný po dobu delší než 5 minut?",
"header": "Automaticky ukončovat spojení"
},
"themes": {
"dropdown_label": "Motiv",
"error_no_theme": "Žádné motivy nejsou k dispozici.",

View File

@@ -77,7 +77,7 @@
"triggered": "Ausgel."
},
"default": {
"entity_not_found": "Entität nicht gefunden!",
"entity_not_found": "Entität nicht gefunden",
"error": "Fehler",
"unavailable": "N.v.",
"unknown": "Unbek."
@@ -430,6 +430,8 @@
"activate": "Aktivieren"
},
"script": {
"cancel": "Abbrechen",
"cancel_multiple": "Abbrechen {number}",
"execute": "Ausführen"
},
"service": {
@@ -526,6 +528,7 @@
"show_areas": "Bereiche anzeigen"
},
"data-table": {
"no-data": "Keine Daten",
"search": "Suche"
},
"date-range-picker": {
@@ -737,7 +740,7 @@
"power_source": "Energiequelle",
"quirk": "Eigenart",
"services": {
"reconfigure": "Konfigurieren Sie das ZHA-Gerät neu (Gerät heilen). Verwenden Sie diese Option, wenn Sie Probleme mit dem Gerät haben. Wenn es sich bei dem fraglichen Gerät um ein batteriebetriebenes Gerät handelt, vergewissern Sie sich, dass es wach ist und Befehle akzeptiert, wenn Sie diesen Dienst nutzen.",
"reconfigure": "Konfiguriere das ZHA-Gerät neu (Gerät heilen). Verwende diese Option, wenn du Probleme mit dem Gerät hast. Wenn es sich bei dem fraglichen Gerät um ein batteriebetriebenes Gerät handelt, vergewissere dich, dass es wach ist und Befehle akzeptiert, wenn du diesen Dienst nutzt.",
"remove": "Ein Gerät aus dem ZigBee-Netzwerk entfernen.",
"updateDeviceName": "Lege einen benutzerdefinierten Namen für dieses Gerät in der Geräteregistrierung fest.",
"zigbee_information": "Zeige die ZigBee-Informationen für das Gerät an."
@@ -763,7 +766,7 @@
"remember": "Merken"
},
"notification_drawer": {
"click_to_configure": "Klicke auf die Schaltfläche, um {entity} zu konfigurieren.",
"click_to_configure": "Klicke auf die Schaltfläche, um {entity} zu konfigurieren",
"close": "Schließen",
"empty": "Keine Benachrichtigungen",
"title": "Benachrichtigungen"
@@ -772,7 +775,7 @@
"connection_lost": "Verbindung getrennt. Verbinde erneut...",
"service_call_failed": "Fehler beim Aufrufen des Service {service}.",
"started": "Home Assistant wurde vollständig gestartet!",
"starting": "Home Assistant startet, währenddessen kann es sein das nicht alles verfügbar ist.",
"starting": "Home Assistant startet, währenddessen kann es sein, dass nicht alles verfügbar ist.",
"triggered": "{name} ausgelöst"
},
"panel": {
@@ -811,7 +814,7 @@
"header": "Bereiche",
"integrations_page": "Integrationsseite",
"introduction": "In Bereichen wird festgelegt, wo sich Geräte befinden. Diese Informationen werden in Home Assistant verwendet, um Sie bei der Organisation Ihrer Benutzeroberfläche, Berechtigungen und Integrationen mit anderen Systemen zu unterstützen.",
"introduction2": "Um Geräte in einem Bereich zu platzieren, navigieren Sie mit dem Link unten zur Integrationsseite und klicken Sie dann auf eine konfigurierte Integration, um zu den Gerätekarten zu gelangen.",
"introduction2": "Um Geräte in einem Bereich zu platzieren, navigiere mit dem Link unten zur Integrationsseite und klicke dann auf eine konfigurierte Integration, um zu den Gerätekarten zu gelangen.",
"no_areas": "Sieht aus, als hätten Sie noch keine Bereiche!"
}
},
@@ -941,6 +944,19 @@
"introduction": "Benutze Automatisierungen, um deinem Zuhause Leben einzuhauchen",
"load_error_not_editable": "Nur Automatisierungen in automations.yaml sind editierbar.",
"load_error_unknown": "Fehler beim Laden der Automatisierung ({err_no}).",
"max": {
"parallel": "Maximale Anzahl paralleler Läufe",
"queued": "Länge der Warteschlange"
},
"modes": {
"description": "Der Modus steuert, was passiert, wenn ein Skript aufgerufen wird, während es noch von einem oder mehreren vorherigen Aufrufen ausgeführt wird. Überprüfen Sie den {documentation_link} für weitere Informationen.",
"documentation": "Automatisierungs-Dokumentation",
"label": "Modus",
"parallel": "Parallel",
"queued": "In Warteschlange",
"restart": "Neu starten",
"single": "Einzeln (Standard)"
},
"move_down": "Runterschieben",
"move_up": "Hochschieben",
"save": "Speichern",
@@ -1142,7 +1158,7 @@
"dialog_cloudhook": {
"available_at": "Der Webhook ist unter der folgenden URL verfügbar:",
"close": "Schließen",
"confirm_disable": "Möchten Sie diesen Webhook wirklich deaktivieren?",
"confirm_disable": "Möchtest du diesen Webhook wirklich deaktivieren?",
"copied_to_clipboard": "In die Zwischenablage kopiert",
"info_disable_webhook": "Wenn du diesen Webhook nicht mehr nutzen willst, kannst du",
"link_disable_webhook": "deaktiviere es",
@@ -1391,7 +1407,7 @@
"name": "Name",
"type": "Typ"
},
"no_helpers": "Sieht so aus, als hätten Sie noch keine Helfer!"
"no_helpers": "Sieht so aus, als hättest du noch keine Helfer!"
},
"types": {
"input_boolean": "Umschalten",
@@ -1423,8 +1439,8 @@
},
"integration_panel_move": {
"link_integration_page": "Integrationsseite",
"missing_zha": "Vermissen Sie das ZHA-Konfigurationspanel? Es wurde in den ZHA-Eintrag auf der {integrations_page} verschoben.",
"missing_zwave": "Vermissen Sie das Z-Wave-Konfigurationspanel? Es wurde in den Z-Wave-Eintrag auf der {integrations_page} verschoben."
"missing_zha": "Vermisst du das ZHA-Konfigurationspanel? Es wurde in den ZHA-Eintrag auf der {integrations_page} verschoben.",
"missing_zwave": "Vermisst du das Z-Wave-Konfigurationspanel? Es wurde in den Z-Wave-Eintrag auf der {integrations_page} verschoben."
},
"integrations": {
"add_integration": "Integration hinzufügen",
@@ -1606,7 +1622,7 @@
"person": {
"add_person": "Person hinzufügen",
"caption": "Personen",
"confirm_delete": "Möchten Sie diese Person wirklich löschen?",
"confirm_delete": "Möchtest du diese Person wirklich löschen?",
"confirm_delete2": "Alle Geräte, die zu dieser Person gehören, werden nicht mehr zugeordnet.",
"create_person": "Person erstellen",
"description": "Verwalte die Personen, die Home Assistant verfolgt.",
@@ -1622,7 +1638,7 @@
"name": "Name",
"name_error_msg": "Name erforderlich",
"new_person": "Neue Person",
"no_device_tracker_available_intro": "Wenn Sie Geräte haben, die die Anwesenheit einer Person anzeigen, können Sie diese hier einer Person zuordnen. Sie können Ihr erstes Gerät hinzufügen, indem Sie eine Integration zur Anwesenheitserkennung auf der Integrationsseite hinzufügen.",
"no_device_tracker_available_intro": "Wenn du Geräte hast, die die Anwesenheit einer Person anzeigen, kannst du diese hier einer Person zuordnen. Du kannst dein erstes Gerät hinzufügen, indem du eine Integration zur Anwesenheitserkennung auf der Integrationsseite hinzufügst.",
"update": "Aktualisieren"
},
"introduction": "Hier können Sie jede Person von Interesse in Home Assistant definieren.",
@@ -1649,6 +1665,7 @@
"introduction": "Entitäten, die nicht zu einem Gerät gehören, können hier festgelegt werden.",
"without_device": "Entitäten ohne Gerät"
},
"icon": "Symbol",
"introduction": "Benutze Szenen um deinem Zuhause Leben einzuhauchen.",
"load_error_not_editable": "Nur Szenen in der scenes.yaml sind editierbar.",
"load_error_unknown": "Fehler beim Laden der Szene ({err_no}).",
@@ -1682,9 +1699,26 @@
"delete_confirm": "Möchtest du dieses Skript wirklich löschen?",
"delete_script": "Skript löschen",
"header": "Skript: {name}",
"icon": "Symbol",
"id": "Entitäts-ID",
"id_already_exists": "Diese ID existiert bereits",
"id_already_exists_save_error": "Du kannst dieses Skript nicht speichern, da die ID nicht eindeutig ist. Wähle eine andere ID aus oder lasse sie leer, um automatisch eine zu generieren.",
"introduction": "Verwende Skripte, um eine Abfolge von Aktionen auszuführen.",
"link_available_actions": "Erfahre mehr über verfügbare Aktionen.",
"load_error_not_editable": "Nur Skripte in scripts.yaml können bearbeitet werden.",
"max": {
"parallel": "Maximale Anzahl paralleler Läufe",
"queued": "Länge der Warteschlange"
},
"modes": {
"description": "Der Modus steuert, was passiert, wenn ein Skript aufgerufen wird, während es noch von einem oder mehreren vorherigen Aufrufen ausgeführt wird. Überprüfen Sie den {documentation_link} für weitere Informationen.",
"documentation": "Skript-Dokumentation",
"label": "Modus",
"parallel": "Parallel",
"queued": "In Warteschlange",
"restart": "Neu starten",
"single": "Einzeln (Standard)"
},
"sequence": "Sequenz",
"sequence_sentence": "Die Abfolge der Aktionen dieses Skripts."
},
@@ -1695,7 +1729,7 @@
"headers": {
"name": "Name"
},
"introduction": "Mit dem Skript-Editor können Skripte erstellt und bearbeitet werden. Bitte folge Sie dem untenstehenden Link, um die Anleitung zu finden. Das stellt sicher, dass Home Assistant richtig konfiguriert ist.",
"introduction": "Mit dem Skript-Editor können Skripte erstellt und bearbeitet werden. Bitte folge dem untenstehenden Link, um die Anleitung zu finden. Das stellt sicher, dass Home Assistant richtig konfiguriert ist.",
"learn_more": "Weitere Informationen zu Skripten",
"no_scripts": "Wir konnten keine bearbeitbaren Skripte finden",
"show_info": "Informationen zum Skript anzeigen",
@@ -1723,8 +1757,8 @@
"zone": "Zonen neu laden"
},
"server_management": {
"confirm_restart": "Möchten Sie Home Assistant wirklich neu starten?",
"confirm_stop": "Möchten Sie Home Assistant wirklich beenden?",
"confirm_restart": "Möchtest du Home Assistant wirklich neu starten?",
"confirm_stop": "Möchtest du Home Assistant wirklich beenden?",
"heading": "Serververwaltung",
"introduction": "Verwalte Home Assistant… von Home Assistant aus.",
"restart": "Neu starten",
@@ -1755,7 +1789,7 @@
"admin": "Administrator",
"caption": "Benutzer anzeigen",
"change_password": "Passwort ändern",
"confirm_user_deletion": "Möchten Sie {name} wirklich löschen?",
"confirm_user_deletion": "Möchtest du {name} wirklich löschen?",
"deactivate_user": "Benutzer deaktivieren",
"delete_user": "Benutzer löschen",
"group": "Gruppe",
@@ -1782,7 +1816,7 @@
"discovered_text": "Geräte werden hier angezeigt sobald sie erkannt worden sind.",
"discovery_text": "Erkannte Geräte werden hier angezeigt. Befolgen Sie die Anweisungen für Ihr Gerät und versetzen Sie das Gerät in den Pairing-Modus.",
"header": "Zigbee Home Automation - Geräte hinzufügen",
"no_devices_found": "Es wurden keine Geräte erkannt. Stelle sicher, dass sie sich im Pairing-Modus befinden und halte sie aktiv, solange die Erkennung läuft,",
"no_devices_found": "Es wurden keine Geräte erkannt. Stelle sicher, dass sie sich im Pairing-Modus befinden und halte sie aktiv, solange die Erkennung läuft.",
"pairing_mode": "Stelle sicher, dass sich deine Geräte im Pairing-Modus befinden. Überprüfe dazu die Anweisungen deines Geräts.",
"search_again": "Erneut suchen",
"spinner": "Suche nach ZHA Zigbee Geräten..."
@@ -1949,10 +1983,10 @@
"add_to_group": "Zur Gruppe hinzufügen",
"entities": "Entitäten dieses Knotens",
"entity_info": "Entitätsinformationen",
"exclude_entity": "Schließen Sie diese Entität vom Home Assistant aus",
"exclude_entity": "Schließe diese Entität vom Home Assistant aus",
"group": "Gruppe",
"header": "Z-Wave-Knotenverwaltung",
"introduction": "Führen Sie Z-Wave-Befehle aus, die einen einzelnen Knoten betreffen. Wählen Sie einen Knoten aus, um eine Liste der verfügbaren Befehle anzuzeigen.",
"introduction": "Führe Z-Wave-Befehle aus, die einen einzelnen Knoten betreffen. Wähle einen Knoten aus, um eine Liste der verfügbaren Befehle anzuzeigen.",
"max_associations": "Max Assoziationen:",
"node_group_associations": "Knotengruppenzuordnungen",
"node_protection": "Knotenschutz",
@@ -2122,7 +2156,7 @@
"clear_items": "Markierte Elemente löschen"
},
"starting": {
"description": "Home Assistant startet, bitte warten Sie..",
"description": "Home Assistant startet, bitte warten",
"header": "Home Assistant startet ..."
}
},
@@ -2306,6 +2340,7 @@
},
"edit_card": {
"add": "Karte hinzufügen",
"confirm_cancel": "Bist du sicher, dass du Abbrechen willst?",
"delete": "Löschen",
"duplicate": "Karte duplizieren",
"edit": "Bearbeiten",
@@ -2316,7 +2351,9 @@
"pick_card_view_title": "Welche Karte möchten Sie Ihrer {name} -Ansicht hinzufügen?",
"show_code_editor": "Code-Editor anzeigen",
"show_visual_editor": "Visuellen Editor anzeigen",
"toggle_editor": "Editor umschalten"
"toggle_editor": "Editor umschalten",
"typed_header": "{type} Kartenkonfiguration",
"unsaved_changes": "Nicht gespeicherte Änderungen"
},
"edit_lovelace": {
"edit_title": "Titel bearbeiten",
@@ -2370,7 +2407,7 @@
"close": "Schließen",
"empty_config": "Beginne mit einem leeren Dashboard",
"header": "Lovelace Userinterface selbst verwalten",
"para": "Dieses Dashboard wird derzeit von Home Assistant verwaltet. Es wird automatisch aktualisiert, wenn neue Entitäten oder Lovelace-UI-Komponenten verfügbar werden. Wenn Sie die Kontrolle übernehmen, wird dieses Dashboard nicht mehr automatisch aktualisiert. Sie können jederzeit ein neues Dashboard in der Konfiguration erstellen, mit dem Sie herumspielen können.",
"para": "Dieses Dashboard wird derzeit von Home Assistant verwaltet. Es wird automatisch aktualisiert, wenn neue Entitäten oder Lovelace-UI-Komponenten verfügbar werden. Wenn du die Kontrolle übernimmst, wird dieses Dashboard nicht mehr automatisch aktualisiert. Du kannst jederzeit ein neues Dashboard in der Konfiguration erstellen, mit dem du herumspielen kannst.",
"para_sure": "Bist du dir sicher, dass du die Benutzeroberfläche selbst verwalten möchtest?",
"save": "Kontrolle übernehmen",
"yaml_config": "Um dir den Einstieg zu erleichtern, findest du hier die aktuelle Konfiguration dieses Dashboards:",
@@ -2409,6 +2446,8 @@
"entity": "Entität",
"entity_id": "Entitäts-ID",
"last_changed": "Zuletzt geändert",
"no_data": "Keine ungenutzten Entitäten gefunden",
"search": "Entitäten durchsuchen",
"select_to_add": "Wähle die Entitäten aus, die du zur Karte hinzufügen möchtest und klicke auf den Karte hinzufügen-Button.",
"title": "Nicht verwendete Entitäten"
},
@@ -2488,7 +2527,7 @@
"legacy_api_password": {
"abort": {
"login_expired": "Sitzung abgelaufen, bitte erneut anmelden.",
"no_api_password_set": "Sie haben kein API-Passwort konfiguriert."
"no_api_password_set": "Du hast kein API-Passwort konfiguriert."
},
"error": {
"invalid_auth": "Ungültiges API-Passwort",
@@ -2511,6 +2550,7 @@
},
"trusted_networks": {
"abort": {
"not_allowed": "Dein Computer ist nicht auf der Whitelist.",
"not_whitelisted": "Dein Computer ist nicht auf der Whitelist."
},
"step": {
@@ -2649,7 +2689,7 @@
"empty_state": "Sie haben noch keine langlebigen Zugangs-Token.",
"header": "Langlebige Zugangs-Token",
"last_used": "Zuletzt verwendet am {date} in {location}",
"learn_auth_requests": "Erfahren Sie, wie Sie authentifizierte Anfragen stellen können.",
"learn_auth_requests": "Erfahre, wie du authentifizierte Anfragen stellen kannst.",
"not_used": "Wurde noch nie benutzt",
"prompt_copy_token": "Kopiere deinen Zugangs-Token. Er wird nicht wieder angezeigt werden.",
"prompt_name": "Name?"
@@ -2697,7 +2737,7 @@
"link_promo": "Erfahre mehr über Themen"
},
"vibrate": {
"description": "Aktivieren oder deaktivieren Sie die Vibration an diesem Gerät, wenn Sie Geräte steuern.",
"description": "Aktiviere oder deaktiviere die Vibration an diesem Gerät, wenn du Geräte steuerst.",
"header": "Vibrieren"
}
},

View File

@@ -48,6 +48,19 @@
"none": "Κανένας",
"sleep": "Ύπνος"
}
},
"humidifier": {
"mode": {
"auto": "Αυτόματο",
"away": "Εκτός",
"baby": "Μωρό",
"boost": "Ενίσχυση",
"comfort": "Άνεση",
"eco": "Eco",
"home": "Σπίτι",
"normal": "Κανονικός",
"sleep": "Ύπνος"
}
}
},
"state_badge": {
@@ -386,6 +399,10 @@
"reverse": "Αντιστροφή",
"speed": "Ταχύτητα"
},
"humidifier": {
"humidity": "Επιθυμητή υγρασία",
"mode": "Λειτουργία"
},
"light": {
"brightness": "Φωτεινότητα",
"color_temperature": "Θερμοκρασία χρώματος",
@@ -409,6 +426,7 @@
"activate": "Ενεργοποίηση"
},
"script": {
"cancel": "Ακύρωση",
"execute": "Εκτέλεση"
},
"service": {
@@ -442,7 +460,7 @@
"attributes": {
"air_pressure": "Πίεση αέρα",
"humidity": "Υγρασία",
"precipitation": "Κατακρήμνιση",
"precipitation": "Υετός",
"temperature": "Θερμοκρασία",
"visibility": "Ορατότητα",
"wind_speed": "Ταχύτητα ανέμου"
@@ -496,6 +514,9 @@
"clear": "Εκκαθάριση",
"show_areas": "Εμφάνιση περιοχών"
},
"data-table": {
"search": "Αναζήτηση"
},
"date-range-picker": {
"end_date": "Ημερομηνία λήξης",
"select": "Επιλογή",
@@ -805,6 +826,13 @@
"introduction": "Χρησιμοποιήστε αυτοματισμούς για να ζωντανέψουν το σπίτι σας",
"load_error_not_editable": "Μόνο οι αυτοματισμοί στο automations.yaml είναι επεξεργάσιμοι.",
"load_error_unknown": "Σφάλμα κατά τη φόρτωση αυτοματισμού ({err_no}).",
"max": {
"queued": "Μήκος ουράς"
},
"modes": {
"documentation": "τεκμηρίωση αυτοματισμού",
"restart": "Επανεκκίνηση"
},
"save": "Αποθήκευση",
"triggers": {
"add": "Προσθήκη εναύσματος",
@@ -1247,6 +1275,7 @@
"delete_button": "Διαγραφή {integration}",
"delete_confirm": "Είστε σίγουρος ότι θέλετε να διαγραφεί αυτή η ενοποίηση;",
"device_unavailable": "συσκευή μη διαθέσιμη",
"documentation": "Τεκμηρίωση",
"entity_unavailable": "οντότητα μη διαθέσιμη",
"firmware": "Υλικολογισμικό: {version}",
"hub": "Συνδεδεμένο μέσω",
@@ -1293,7 +1322,8 @@
"new": "Ρυθμίστε νέα ενοποίηση",
"none": "Δεν υπάρχει διαμόρφωση ακόμα",
"note_about_integrations": "Δεν μπορούν όλες οι ενσωματώσεις να διαμορφωθούν από το UI ακόμη.",
"note_about_website_reference": "Περισσότερα είναι διαθέσιμα στο"
"note_about_website_reference": "Περισσότερα είναι διαθέσιμα στο",
"search": "Αναζήτηση ενσωματώσεων"
},
"introduction": "Εδώ είναι δυνατή η διαμόρφωση του Home Assistant και των εξαρτημάτων. Δεν είναι δυνατή η διαμόρφωση όλων από την διεπαφή χρήστη (UI) αλλά εργαζόμαστε πάνω σε αυτό.",
"logs": {
@@ -1388,6 +1418,7 @@
"introduction": "Εδώ μπορείτε να ορίσετε οντότητες που δεν ανήκουν σε κάποια συσκευή.",
"without_device": "Οντότητες χωρίς συσκευές"
},
"icon": "Εικονίδιο",
"introduction": "Χρησιμοποιήστε σκηνές για να ζωντανέψουν το σπίτι σας",
"load_error_not_editable": "Μόνο σκηνές στο scenes.yaml είναι επεξεργάσιμες.",
"load_error_unknown": "Σφάλμα κατά τη φόρτωση της σκηνής ({err_no}).",
@@ -1421,9 +1452,20 @@
"delete_confirm": "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτή τη δέσμη ενεργειών;",
"delete_script": "Διαγραφή δέσμης ενεργειών",
"header": "Δέσμη ενεργειών: {name}",
"icon": "Εικονίδιο",
"introduction": "Χρησιμοποιήστε δέσμες ενεργειών για να εκτελέσετε μια ακολουθία ενεργειών.",
"link_available_actions": "Μάθετε περισσότερα σχετικά με τις διαθέσιμες ενέργειες.",
"load_error_not_editable": "Μόνο οι δέσμες ενεργειών που βρίσκονται μέσα στο scripts.yaml είναι επεξεργάσιμες",
"max": {
"queued": "Μήκος ουράς"
},
"modes": {
"documentation": "τεκμηρίωση δέσμης ενεργειών",
"parallel": "Παράλληλα",
"queued": "Στην ουρά",
"restart": "Επανεκκίνηση",
"single": "Μονό (προεπιλογή)"
},
"sequence": "Ακολουθία",
"sequence_sentence": "Η ακολουθία των ενεργειών αυτής της δέσμης ενεργειών."
},
@@ -1508,6 +1550,7 @@
},
"zha": {
"add_device_page": {
"discovered_text": "Οι συσκευές θα εμφανιστούν εδώ μόλις ανακαλυφθούν.",
"discovery_text": "Οι ανακαλυφθείσες συσκευές θα εμφανιστούν εδώ. Ακολουθήστε τις οδηγίες για τις συσκευές σας και τοποθετήστε τις συσκευές στη λειτουργία αντιστοίχισης.",
"header": "Zigbee Home Automation - Προσθήκη Συσκευών",
"search_again": "Αναζήτηση ξανά",
@@ -1517,6 +1560,7 @@
"caption": "Προσθήκη Συσκευών",
"description": "Προσθήκη συσκετών στο δίκτυο Zigbee"
},
"button": "Διαμόρφωση",
"caption": "ZHA",
"cluster_attributes": {
"attributes_of_cluster": "Χαρακτηριστικά της επιλεγμένης συστοιχίας",
@@ -1764,6 +1808,10 @@
"add_item": "Προσθήκη στοιχείου",
"checked_items": "Επιλεγμένα στοιχεία",
"clear_items": "Εκκαθάριση επιλεγμένων στοιχείων"
},
"starting": {
"description": "Ο Home Assistant ξεκινά, περιμένετε ...",
"header": "Ο Home Assistant ξεκινά..."
}
},
"changed_toast": {
@@ -1827,6 +1875,7 @@
"name": "Όνομα",
"no_theme": "Χωρίς θέμα",
"refresh_interval": "Χρονικό διάστημα ανανέωσης",
"search": "Αναζήτηση",
"show_icon": "Εμφάνιση εικονιδίου;",
"show_name": "Εμφάνιση ονόματος;",
"show_state": "Εμφάνιση κατάστασης;",
@@ -1847,6 +1896,9 @@
"horizontal-stack": {
"name": "Οριζόντια διάταξη"
},
"humidifier": {
"name": "Υγραντήρας"
},
"iframe": {
"name": "Ιστοσελίδα"
},
@@ -1921,7 +1973,8 @@
"edit_lovelace": {
"edit_title": "Επεξεργασία τίτλου",
"explanation": "Αυτός ο τίτλος εμφανίζεται πάνω από όλες τις καρτέλες σας στο Lovelace.",
"header": "Τίτλος του περιβάλλοντος εργασίας σας Lovelace"
"header": "Τίτλος του περιβάλλοντος εργασίας σας Lovelace",
"title": "Τίτλος"
},
"edit_view": {
"add": "Προσθήκη προβολής",
@@ -2084,6 +2137,7 @@
},
"trusted_networks": {
"abort": {
"not_allowed": "Ο υπολογιστής σας δεν είναι αποδεκτός.",
"not_whitelisted": "Ο υπολογιστής σας δεν είναι στη λίστα επιτρεπόμενων."
},
"step": {
@@ -2256,6 +2310,9 @@
"not_used": "Δεν έχει χρησιμοποιηθεί ποτέ",
"token_title": "Ανανέωση διακριτικού για το {clientId}"
},
"suspend": {
"header": "Αυτόματο κλείσιμο σύνδεσης"
},
"themes": {
"dropdown_label": "Θέμα",
"error_no_theme": "Δεν υπάρχουν διαθέσιμα θέματα.",

View File

@@ -528,6 +528,7 @@
"show_areas": "Show areas"
},
"data-table": {
"no-data": "No data",
"search": "Search"
},
"date-range-picker": {
@@ -951,10 +952,10 @@
"description": "The mode controls what happens when the automation is triggered while the actions are still running from a previous trigger. Check the {documentation_link} for more info.",
"documentation": "automation documentation",
"label": "Mode",
"parallel": "Parallel (default)",
"parallel": "Parallel",
"queued": "Queued",
"restart": "Restart",
"single": "Single"
"single": "Single (default)"
},
"move_down": "Move down",
"move_up": "Move up",
@@ -1815,7 +1816,7 @@
"discovered_text": "Devices will show up here once discovered.",
"discovery_text": "Discovered devices will show up here. Follow the instructions for your device(s) and place the device(s) in pairing mode.",
"header": "Zigbee Home Automation - Add Devices",
"no_devices_found": "No devices where found, make sure they are in paring mode and keep them awake while discovering is running.",
"no_devices_found": "No devices were found, make sure they are in paring mode and keep them awake while discovering is running.",
"pairing_mode": "Make sure your devices are in pairing mode. Check the instructions of your device on how to do this.",
"search_again": "Search Again",
"spinner": "Searching for ZHA Zigbee devices..."
@@ -2339,6 +2340,7 @@
},
"edit_card": {
"add": "Add Card",
"confirm_cancel": "Are you sure you want to cancel?",
"delete": "Delete Card",
"duplicate": "Duplicate Card",
"edit": "Edit",
@@ -2349,7 +2351,9 @@
"pick_card_view_title": "Which card would you like to add to your {name} view?",
"show_code_editor": "Show Code Editor",
"show_visual_editor": "Show Visual Editor",
"toggle_editor": "Toggle Editor"
"toggle_editor": "Toggle Editor",
"typed_header": "{type} Card Configuration",
"unsaved_changes": "You have unsaved changes"
},
"edit_lovelace": {
"edit_title": "Edit title",
@@ -2442,6 +2446,8 @@
"entity": "Entity",
"entity_id": "Entity ID",
"last_changed": "Last Changed",
"no_data": "No unused entities found",
"search": "Search entities",
"select_to_add": "Select the entities you want to add to a card and then click the add card button.",
"title": "Unused entities"
},

View File

@@ -430,6 +430,8 @@
"activate": "Activar"
},
"script": {
"cancel": "Cancelar",
"cancel_multiple": "Cancelar {number}",
"execute": "Ejecutar"
},
"service": {
@@ -526,6 +528,7 @@
"show_areas": "Mostrar áreas"
},
"data-table": {
"no-data": "Sin datos",
"search": "Buscar"
},
"date-range-picker": {
@@ -941,6 +944,19 @@
"introduction": "Utiliza automatizaciones para darle vida a tu hogar.",
"load_error_not_editable": "Solo las automatizaciones en automations.yaml son editables.",
"load_error_unknown": "Error al cargar la automatización ({err_no}).",
"max": {
"parallel": "Número máximo de ejecuciones paralelas",
"queued": "Longitud de la cola"
},
"modes": {
"description": "El modo controla lo que sucede cuando se activa la automatización mientras las acciones aún se ejecutan desde una activación anterior. Consulta la {documentation_link} para obtener más información.",
"documentation": "documentación de automatización",
"label": "Modo",
"parallel": "Paralelo",
"queued": "En cola",
"restart": "Reiniciar",
"single": "Único (predeterminado)"
},
"move_down": "Mover hacia abajo",
"move_up": "Mover hacia arriba",
"save": "Guardar",
@@ -1649,6 +1665,7 @@
"introduction": "Las entidades que no pertenecen a un dispositivo se pueden configurar aquí.",
"without_device": "Entidades sin dispositivo"
},
"icon": "Icono",
"introduction": "Usa escenas para dar vida a tu hogar.",
"load_error_not_editable": "Solo las escenas de scenes.yaml son editables.",
"load_error_unknown": "Error al cargar la escena ({err_no}).",
@@ -1682,9 +1699,26 @@
"delete_confirm": "¿Seguro que quieres eliminar este script?",
"delete_script": "Eliminar script",
"header": "Script: {name}",
"icon": "Icono",
"id": "ID de la entidad",
"id_already_exists": "Este ID ya existe",
"id_already_exists_save_error": "No puedes guardar este script porque el ID no es único, elije otro ID o déjalo en blanco para generar uno automáticamente.",
"introduction": "Utiliza scripts para ejecutar una secuencia de acciones.",
"link_available_actions": "Saber más sobre las acciones disponibles.",
"load_error_not_editable": "Solo los scripts dentro de scripts.yaml son editables.",
"max": {
"parallel": "Número máximo de ejecuciones paralelas",
"queued": "Longitud de la cola"
},
"modes": {
"description": "El modo controla lo que sucede cuando se invoca el script mientras aún se ejecuta desde una o más invocaciones anteriores. Consulta la {documentation_link} para obtener más información.",
"documentation": "documentación de script",
"label": "Modo",
"parallel": "Paralelo",
"queued": "En cola",
"restart": "Reiniciar",
"single": "Único (predeterminado)"
},
"sequence": "Secuencia",
"sequence_sentence": "La secuencia de acciones de este script."
},
@@ -2306,6 +2340,7 @@
},
"edit_card": {
"add": "Añadir tarjeta",
"confirm_cancel": "¿Estás seguro de que quieres cancelar?",
"delete": "Eliminar tarjeta",
"duplicate": "Duplicar tarjeta",
"edit": "Editar",
@@ -2316,7 +2351,9 @@
"pick_card_view_title": "¿Qué tarjeta te gustaría añadir a tu vista {name} ?",
"show_code_editor": "Mostrar editor de código",
"show_visual_editor": "Mostrar editor visual",
"toggle_editor": "Alternar editor"
"toggle_editor": "Alternar editor",
"typed_header": "{type} Configuración de tarjeta",
"unsaved_changes": "Tienes cambios sin guardar"
},
"edit_lovelace": {
"edit_title": "Editar título",
@@ -2409,6 +2446,8 @@
"entity": "Entidad",
"entity_id": "ID de entidad",
"last_changed": "Última modificación",
"no_data": "No se han encontrado entidades sin utilizar",
"search": "Buscar entidades",
"select_to_add": "Selecciona las entidades que quieres añadir a una tarjeta y, a continuación, haz clic en el botón Añadir tarjeta.",
"title": "Entidades no utilizadas"
},
@@ -2511,6 +2550,7 @@
},
"trusted_networks": {
"abort": {
"not_allowed": "Tu equipo no está permitido.",
"not_whitelisted": "Tu equipo no está en la lista de autorizados."
},
"step": {

View File

@@ -324,6 +324,9 @@
"save": "Gorde"
},
"components": {
"data-table": {
"no-data": "Daturik ez"
},
"relative_time": {
"duration": {
"day": "{count} {count, plural,\n one {egun}\n other {egun}\n}",
@@ -744,6 +747,7 @@
},
"trusted_networks": {
"abort": {
"not_allowed": "Zure ordenagailua ez dago baimenduta.",
"not_whitelisted": "Zure ordenagailua ez dago baimenduta."
},
"step": {

View File

@@ -430,6 +430,8 @@
"activate": "Aktivoi"
},
"script": {
"cancel": "Peruuta",
"cancel_multiple": "Peruuta {number}",
"execute": "Suorita"
},
"service": {
@@ -525,6 +527,10 @@
"clear": "Tyhjennä",
"show_areas": "Näytä alueet"
},
"data-table": {
"no-data": "Ei dataa",
"search": "Hae"
},
"date-range-picker": {
"end_date": "Päättymispäivä",
"select": "Valitse",
@@ -938,6 +944,19 @@
"introduction": "Käytä automaatioita herättääksesi kotisi eloon",
"load_error_not_editable": "Vain automaatiot tiedostossa automations.yaml ovat muokattavissa.",
"load_error_unknown": "Virhe ladatessa automaatiota ( {err_no} )",
"max": {
"parallel": "Rinnakkaisten ajojen enimmäismäärä",
"queued": "Jonon pituus"
},
"modes": {
"description": "Tila määrittää, mitä tapahtuu, kun automaatio käynnistyy, kun toiminnot ovat edelleen käynnissä edellisestä käynnistyksestä. Lisätietoja osoitteessa {documentation_link}.",
"documentation": "automaation dokumentaatio",
"label": "Tila",
"parallel": "Rinnakkain",
"queued": "Jonossa",
"restart": "Käynnistä uudelleen",
"single": "Yksittäinen (oletus)"
},
"move_down": "Siirrä alaspäin",
"move_up": "Siirrä ylöspäin",
"save": "Tallenna",
@@ -1356,6 +1375,7 @@
"confirm_text": "Sinun tulisi poistaa ne Lovelace-käyttöliittymästä ja automaatioista, jos ne sisältävät näitä kohteita.",
"confirm_title": "Haluatko poistaa {number} kohdetta?"
},
"search": "Hae kohteita",
"selected": "{number} valittuna",
"status": {
"disabled": "Poistettu käytöstä",
@@ -1386,7 +1406,8 @@
"entity_id": "Kohde ID",
"name": "Nimi",
"type": "Tyyppi"
}
},
"no_helpers": "Näyttää siltä, että sinulla ei ole vielä avustajia!"
},
"types": {
"input_boolean": "Kytkin",
@@ -1431,6 +1452,7 @@
"delete_confirm": "Haluatko varmasti poistaa tämän integraation?",
"device_unavailable": "laite ei saatavissa",
"devices": "{count} {count, plural,\n one {laite}\n other {laitteet}\n}",
"documentation": "Dokumentointi",
"entities": "{count} {count, plural,\n one {kohde}\n other {kohteet}\n}",
"entity_unavailable": "kohde ei saatavilla",
"firmware": "Laiteohjelmisto: {version}",
@@ -1489,7 +1511,8 @@
"note_about_integrations": "Kaikkia integraatioita ei voi vielä määrittää käyttöliittymän kautta.",
"note_about_website_reference": "Lisää saatavilla",
"rename_dialog": "Muokkaa tämän määritysmerkinnän nimeä",
"rename_input_label": "Merkinnän nimi"
"rename_input_label": "Merkinnän nimi",
"search": "Etsi integraatioita"
},
"introduction": "Täällä voit säätää Home Assistanttia ja sen komponentteja. Huomioithan, ettei kaikkea voi vielä säätää käyttöliittymän kautta, mutta teemme jatkuvasti töitä sen mahdollistamiseksi.",
"logs": {
@@ -1642,6 +1665,7 @@
"introduction": "Kohteet, jotka eivät kuulu laitteisiin, voidaan asettaa täällä.",
"without_device": "Kohteet ilman laitetta"
},
"icon": "Kuvake",
"introduction": "Käytä tilanteita herättääksesi kotisi eloon.",
"load_error_not_editable": "Vain tilanteet tiedostossa scenes.yaml ovat muokattavissa.",
"load_error_unknown": "Virhe ladattaessa tilannetta ({err_no}).",
@@ -1675,9 +1699,25 @@
"delete_confirm": "Haluatko varmasti poistaa tämän skriptin?",
"delete_script": "Poista skripti",
"header": "Skripti: {name}",
"icon": "Kuvake",
"id": "Kohde ID",
"id_already_exists": "Tämä tunnus on jo olemassa",
"id_already_exists_save_error": "Et voi tallentaa tätä skriptiä, koska tunnus ei ole yksilöivä. Valitse toinen tunnus tai jätä se tyhjäksi, jolloin se luodaan automaattisesti.",
"introduction": "Käytä scriptejä suorittaaksesi toimintasarjan.",
"link_available_actions": "Lisätietoja saatavilla olevista toiminnoista",
"load_error_not_editable": "Vain scripts.yaml-tiedostossa olevat skriptit ovat muokattavissa.",
"max": {
"parallel": "Rinnakkaisten ajojen enimmäismäärä",
"queued": "Jonon pituus"
},
"modes": {
"documentation": "skriptin dokumentaatio",
"label": "Tila",
"parallel": "Rinnakkain",
"queued": "Jonossa",
"restart": "Käynnistä uudelleen",
"single": "Yksittäinen (oletus)"
},
"sequence": "Järjestys",
"sequence_sentence": "Skriptin toimintojen järjestys."
},
@@ -2193,6 +2233,7 @@
"name": "Nimi",
"no_theme": "Ei teemaa",
"refresh_interval": "Päivitysväli",
"search": "Hae",
"secondary_info_attribute": "Toissijainen info-attribuutti",
"show_icon": "Näytä kuvake?",
"show_name": "Näytä nimi?",
@@ -2298,6 +2339,7 @@
},
"edit_card": {
"add": "Lisää kortti",
"confirm_cancel": "Haluatko varmasti peruuttaa?",
"delete": "Poista kortti",
"duplicate": "Kopioi kortti",
"edit": "Muokkaa",
@@ -2308,12 +2350,15 @@
"pick_card_view_title": "Minkä kortin haluat lisätä {name} -näkymääsi?",
"show_code_editor": "Näytä koodieditori",
"show_visual_editor": "Näytä visuaalinen editori",
"toggle_editor": "Vaihda editori"
"toggle_editor": "Vaihda editori",
"typed_header": "{type}-kortin kokoonpano",
"unsaved_changes": "Sinulla on tallentamattomia muutoksia"
},
"edit_lovelace": {
"edit_title": "Muokkaa otsikkoa",
"explanation": "Tämä otsikko on esillä näkymien yläpuolella Lovelace-käyttöliittymässä.",
"header": "Lovelace-käyttöliittymän otsikko"
"header": "Lovelace-käyttöliittymän otsikko",
"title": "Otsikko"
},
"edit_view": {
"add": "Lisää näkymä",
@@ -2400,6 +2445,8 @@
"entity": "Kohde",
"entity_id": "Kohde ID",
"last_changed": "Viimeksi muutettu",
"no_data": "Käyttämättömiä kohteita ei löytynyt",
"search": "Hae kohteita",
"select_to_add": "Valitse kohteet, jotka haluat lisätä korttiin, ja napsauta sitten Lisää kortti -painiketta.",
"title": "Käyttämättömät entiteetit"
},
@@ -2502,6 +2549,7 @@
},
"trusted_networks": {
"abort": {
"not_allowed": "Tietokone ei ole sallittu.",
"not_whitelisted": "Tietokonettasi ei ole sallittu."
},
"step": {
@@ -2677,6 +2725,10 @@
"not_used": "Ei ole koskaan käytetty",
"token_title": "Päivitä tunnus kohteelle {clientId}"
},
"suspend": {
"description": "Suljetaanko yhteys palvelimeen 5 minuuttia piilottamisen jälkeen?",
"header": "Sulje yhteys automaattisesti"
},
"themes": {
"dropdown_label": "Teema",
"error_no_theme": "Ei teemoja käytettävissä.",

View File

@@ -430,6 +430,8 @@
"activate": "Activer"
},
"script": {
"cancel": "Annuler",
"cancel_multiple": "Annuler {number}",
"execute": "Exécuter"
},
"service": {
@@ -526,6 +528,7 @@
"show_areas": "Afficher les pièces"
},
"data-table": {
"no-data": "Pas de données",
"search": "Chercher"
},
"date-range-picker": {
@@ -938,9 +941,22 @@
"edit_ui": "Modifier avec l'interface utilisateur",
"edit_yaml": "Modifier en tant que YAML",
"enable_disable": "Activer/Désactiver l'automatisation",
"introduction": "Utilisez les automatisations pour donner vie à votre maison",
"introduction": "Utiliser les automatisations pour donner vie à votre maison.",
"load_error_not_editable": "Seules les automatisations dans automations.yaml sont modifiables.",
"load_error_unknown": "Erreur lors du chargement de l'automatisation ( {err_no} ).",
"max": {
"parallel": "Nombre maximal de parcours parallèles",
"queued": "Longueur de la file d'attente"
},
"modes": {
"description": "Le mode contrôle ce qui se passe lorsque lautomatisation est déclenchée alors que les actions sont toujours en cours dexécution à partir dun déclencheur précédent. Consultez le {documentation_link} pour plus dinformations.",
"documentation": "documentation d'automatisation",
"label": "Mode",
"parallel": "Parallèle",
"queued": "En attente",
"restart": "Redémarrer",
"single": "Unique (par défaut)"
},
"move_down": "Déplacer vers le bas",
"move_up": "Déplacer vers le haut",
"save": "Sauvegarder",
@@ -1649,6 +1665,7 @@
"introduction": "Les entités n'appartenant pas à un périphérique peuvent être définies ici.",
"without_device": "Entités sans appareil"
},
"icon": "Icône",
"introduction": "Utilisez des scènes pour donner vie à votre maison.",
"load_error_not_editable": "Seules les scènes de scenes.yaml sont modifiables.",
"load_error_unknown": "Erreur de chargement de la scène ({err_no})",
@@ -1682,9 +1699,26 @@
"delete_confirm": "Êtes-vous sûr de vouloir supprimer ce script?",
"delete_script": "Supprimer le script",
"header": "Script: {name}",
"icon": "Icône",
"id": "ID de l'entité",
"id_already_exists": "Cet ID existe déjà",
"id_already_exists_save_error": "Vous ne pouvez pas enregistrer ce script car l'ID n'est pas unique, choisissez un autre ID ou laissez-le vide pour en générer automatiquement un.",
"introduction": "Utiliser des scripts pour exécuter une séquence d'actions.",
"link_available_actions": "En savoir plus sur les actions disponibles.",
"load_error_not_editable": "Seuls les scripts dans scripts.yaml sont modifiables.",
"max": {
"parallel": "Nombre maximal de parcours parallèles",
"queued": "Longueur de la file d'attente"
},
"modes": {
"description": "Le mode contrôle ce qui se passe lorsque le script est appelé alors quil est toujours en cours dexécution à partir dune ou plusieurs invocations précédentes. Consultez le {documentation_link} pour plus dinformations.",
"documentation": "documentation script",
"label": "Mode",
"parallel": "Parallèle",
"queued": "En attente",
"restart": "Redémarrer",
"single": "Unique (par défaut)"
},
"sequence": "Séquence",
"sequence_sentence": "La séquence d'actions de ce script."
},
@@ -2306,6 +2340,7 @@
},
"edit_card": {
"add": "Ajouter une action",
"confirm_cancel": "Êtes-vous sûrs de vouloir annuler ?",
"delete": "Supprimer",
"duplicate": "Dupliquer la carte",
"edit": "Modifier",
@@ -2316,7 +2351,9 @@
"pick_card_view_title": "Quelle carte souhaitez-vous ajouter à votre vue {name} ?",
"show_code_editor": "Afficher l'éditeur de code",
"show_visual_editor": "Afficher l'éditeur visuel",
"toggle_editor": "Permuter léditeur"
"toggle_editor": "Permuter léditeur",
"typed_header": "{type} Configuration de la carte",
"unsaved_changes": "Vous avez des changements non enregistrés"
},
"edit_lovelace": {
"edit_title": "Éditer le titre",
@@ -2409,6 +2446,8 @@
"entity": "Entité",
"entity_id": "ID de l'entité",
"last_changed": "Dernière modification",
"no_data": "Aucune entité inutilisée trouvée",
"search": "Rechercher des entités",
"select_to_add": "Sélectionner les entités que vous souhaitez ajouter à une carte, puis cliquez sur le bouton Ajouter une carte.",
"title": "Entités inutilisées"
},
@@ -2511,6 +2550,7 @@
},
"trusted_networks": {
"abort": {
"not_allowed": "Votre ordinateur n'est pas autorisé.",
"not_whitelisted": "Votre ordinateur n'est pas en liste blanche."
},
"step": {

View File

@@ -430,6 +430,8 @@
"activate": "הפעל"
},
"script": {
"cancel": "בטל",
"cancel_multiple": "בטל {number}",
"execute": "הפעל"
},
"service": {
@@ -526,6 +528,7 @@
"show_areas": "הצג אזורים"
},
"data-table": {
"no-data": "אין נתונים",
"search": "חיפוש"
},
"date-range-picker": {
@@ -941,6 +944,19 @@
"introduction": "השתמש/י באוטומציות להפיח חיים בביתך.",
"load_error_not_editable": "רק אוטומציה ב automations.yaml ניתנים לעריכה.",
"load_error_unknown": "שגיאה בטעינת האוטומציה ( {err_no} ).",
"max": {
"parallel": "המספר המרבי של ריצות מקבילות",
"queued": "אורך התור"
},
"modes": {
"description": "המצב שולט במתרחש כאשר האוטומציה מופעלת בזמן שהפעולות עדיין פועלות מהטריגר הקודם. עיין ב {documentation_link} למידע נוסף.",
"documentation": "תיעוד אוטומציה",
"label": "מצב",
"parallel": "במקביל",
"queued": "בתור",
"restart": "אתחול",
"single": "יחיד (ברירת מחדל)"
},
"move_down": "הזז למטה",
"move_up": "הזז למעלה",
"save": "שמור",
@@ -1582,7 +1598,7 @@
"refresh_body": "אתה צריך לרענן את הדף כדי להשלים את ההסרה, האם אתה רוצה לרענן עכשיו?",
"refresh_header": "האם אתה רוצה לרענן?",
"types": {
"css": "סגנון עיצוב",
"css": "Stylesheet",
"html": "HTML (הוצא משימוש)",
"js": "קובץ JavaScript (הוצא משימוש)",
"module": "JavaScript Module"
@@ -1649,6 +1665,7 @@
"introduction": "ניתן להגדיר כאן ישויות שאינן שייכות להתקנים.",
"without_device": "ישויות ללא מכשיר"
},
"icon": "סמל",
"introduction": "השתמש בסצינות כדי להחיות את הבית שלך.",
"load_error_not_editable": "רק סצינות ב scenes.yaml ניתנות לעריכה.",
"load_error_unknown": "שגיאה בטעינת סצנה ({err_no}).",
@@ -1682,9 +1699,26 @@
"delete_confirm": "האם אתה בטוח שברצונך למחוק את הסקריפט הזה?",
"delete_script": "מחק סקריפט",
"header": "סקריפט: {name}",
"icon": "סמל",
"id": "מזהה ישות",
"id_already_exists": "מזהה זה כבר קיים",
"id_already_exists_save_error": "אינך יכול לשמור סקריפט זה מכיוון שהמזהה אינו ייחודי, בחר מזהה אחר או השאר אותו ריק כדי ליצור אוטומטית.",
"introduction": "השתמש בסקריפטים כדי לבצע רצף של פעולות.",
"link_available_actions": "למד עוד אודות פעולות זמינות.",
"load_error_not_editable": "רק סקריפטים בתוך קובץ scripts.yaml ניתנים לעריכה.",
"max": {
"parallel": "המספר המרבי של ריצות מקבילות",
"queued": "אורך התור"
},
"modes": {
"description": "המצב שולט במה שקורה כאשר מופעל סקריפט בזמן שהוא עדיין פועל מהפעלה קודמת אחת או יותר. עיין ב {documentation_link} למידע נוסף.",
"documentation": "תיעוד סקריפט",
"label": "מצב",
"parallel": "מַקְבִּיל",
"queued": "בתור",
"restart": "אתחול",
"single": "יחיד (ברירת מחדל)"
},
"sequence": "סדר פעולות",
"sequence_sentence": "רצף הפעולות של סקריפט זה."
},
@@ -2057,12 +2091,12 @@
"title": "מצבים"
},
"templates": {
"description": "התבניות מוצגות באמצעות מנוע התבניות Jinja2 עם כמה תוספים ספציפיים של Home Assistant.",
"editor": "עורך התבניות",
"jinja_documentation": "תיעוד תבנית Jinja2",
"template_extensions": "הרחבות תבנית של Home Assistant",
"description": "Templates are rendered using the Jinja2 template engine with some Home Assistant specific extensions.",
"editor": "Template editor",
"jinja_documentation": "Jinja2 template documentation",
"template_extensions": "Home Assistant template extensions",
"title": "תבניות",
"unknown_error_template": "שגיאה לא ידועה בעיבוד התבנית"
"unknown_error_template": "Unknown error rendering template"
}
}
},
@@ -2306,6 +2340,7 @@
},
"edit_card": {
"add": "הוסף כרטיסייה",
"confirm_cancel": "האם אתה בטוח שברצונך לבטל?",
"delete": "מחק",
"duplicate": "שכפול כרטיס",
"edit": "ערוך",
@@ -2316,7 +2351,9 @@
"pick_card_view_title": "איזה כרטיס ברצונך להוסיף לתצוגת {name}?",
"show_code_editor": "הצג עורך קוד",
"show_visual_editor": "הצג עורך ויזואלי",
"toggle_editor": "החלף מצב עורך"
"toggle_editor": "החלף מצב עורך",
"typed_header": "תצורת כרטיס {type}",
"unsaved_changes": "יש לך שינויים שלא נשמרו"
},
"edit_lovelace": {
"edit_title": "ערוך כותרת",
@@ -2409,6 +2446,8 @@
"entity": "ישות",
"entity_id": "מזהה ישות",
"last_changed": "שונה לאחרונה",
"no_data": "לא נמצאו ישויות שאינן בשימוש",
"search": "חיפוש ישויות",
"select_to_add": "בחר את הישויות שברצונך להוסיף לכרטיס ולחץ על כפתור הוסף כרטיס.",
"title": "ישויות שאינן בשימוש"
},
@@ -2511,6 +2550,7 @@
},
"trusted_networks": {
"abort": {
"not_allowed": "המחשב שלך אינו מורשה.",
"not_whitelisted": "המחשב שלך אינו רשום ברשימת ההיתרים."
},
"step": {

View File

@@ -48,6 +48,19 @@
"none": "Nincs",
"sleep": "Alvás"
}
},
"humidifier": {
"mode": {
"auto": "Automatikus",
"away": "Távol",
"baby": "Baba",
"boost": "Turbo",
"comfort": "Komfort",
"eco": "Takarékos",
"home": "Otthon",
"normal": "Normál",
"sleep": "Alvás"
}
}
},
"state_badge": {
@@ -388,6 +401,12 @@
"reverse": "Fordított",
"speed": "Sebesség"
},
"humidifier": {
"humidity": "Kívánt páratartalom",
"mode": "Mód",
"on_entity": "{name} be",
"target_humidity_entity": "{name} kívánt páratartalom"
},
"light": {
"brightness": "Fényerő",
"color_temperature": "Színhőmérséklet",
@@ -411,6 +430,8 @@
"activate": "Aktiválás"
},
"script": {
"cancel": "Mégse",
"cancel_multiple": "Mégse {number}",
"execute": "Futtatás"
},
"service": {
@@ -506,6 +527,15 @@
"clear": "Törlés",
"show_areas": "Területek megjelenítése"
},
"data-table": {
"no-data": "Nincs adat",
"search": "Keresés"
},
"date-range-picker": {
"end_date": "Befejezés dátuma",
"select": "Kiválasztás",
"start_date": "Kezdés dátuma"
},
"device-picker": {
"clear": "Törlés",
"device": "Eszköz",
@@ -694,10 +724,11 @@
},
"zha_device_info": {
"buttons": {
"add": "Eszközök hozzáadása",
"add": "Eszközök hozzáadása ezen az eszközön keresztül",
"clusters": "Klaszterek Kezelése",
"reconfigure": "Eszköz újrakonfigurálása",
"remove": "Eszköz eltávolítása",
"zigbee_information": "Zigbee Információk"
"zigbee_information": "Zigbee eszköz aláírása"
},
"confirmations": {
"remove": "Biztosan el akarod távolítani az eszközt?"
@@ -717,7 +748,7 @@
"unknown": "Ismeretlen",
"zha_device_card": {
"area_picker_label": "Terület",
"device_name_placeholder": "Felhasználó által megadott név",
"device_name_placeholder": "Eszköznév módosítása",
"update_name_button": "Név frissítése"
}
}
@@ -913,6 +944,18 @@
"introduction": "Használj automatizálásokat otthonod életre keltéséhez",
"load_error_not_editable": "Csak az automations.yaml fájlban megadott automatizálások szerkeszthetők.",
"load_error_unknown": "Hiba az automatizálás betöltésekor ({err_no}).",
"max": {
"parallel": "A párhuzamos futtatások maximális száma",
"queued": "Várólista hossza"
},
"modes": {
"documentation": "automatizálási dokumentáció",
"label": "Mód",
"parallel": "Párhuzamos",
"queued": "Várólistás",
"restart": "Újraindítás",
"single": "Egyszeri (alapértelmezett)"
},
"move_down": "Le",
"move_up": "Fel",
"save": "Mentés",
@@ -1331,6 +1374,7 @@
"confirm_text": "El kell távolítanod őket a Lovelace konfigurációból és az automatizálásokból, ha tartalmazzák ezeket az entitásokat.",
"confirm_title": "El szeretnél távolítani {number} entitást?"
},
"search": "Entitások keresése",
"selected": "{number} kiválasztva",
"status": {
"disabled": "Letiltott",
@@ -1361,7 +1405,8 @@
"entity_id": "Entitás ID",
"name": "Név",
"type": "Típus"
}
},
"no_helpers": "Úgy tűnik, még nincs egy segítőd sem!"
},
"types": {
"input_boolean": "Váltás",
@@ -1373,7 +1418,9 @@
},
"info": {
"built_using": "Buildelve:",
"caption": "Infó",
"custom_uis": "Egyéni felhasználói felületek:",
"description": "Információ a Home Assistant telepítésedről",
"developed_by": "Egy csomó fantasztikus ember által kifejlesztve.",
"documentation": "Dokumentáció",
"frontend": "frontend-ui",
@@ -1389,6 +1436,9 @@
"system_health_error": "A rendszerállapot összetevő nincs betöltve. Add hozzá a 'system_health:' sort a configuration.yaml fájlhoz.",
"title": "Infó"
},
"integration_panel_move": {
"link_integration_page": "integrációk oldal"
},
"integrations": {
"add_integration": "Integráció hozzáadása",
"caption": "Integrációk",
@@ -1399,6 +1449,7 @@
"delete_confirm": "Biztosan törölni szeretnéd ezt az integrációt?",
"device_unavailable": "eszköz nem érhető el",
"devices": "{count} {count, plural,\n one {eszköz}\n other {eszköz}\n}",
"documentation": "Dokumentáció",
"entities": "{count} {count, plural,\n one {entitás}\n other {entitás}\n}",
"entity_unavailable": "entitás nem érhető el",
"firmware": "Firmware: {version}",
@@ -1457,11 +1508,14 @@
"note_about_integrations": "Még nem minden integráció konfigurálható a felhasználói felületen keresztül.",
"note_about_website_reference": "Továbbiak érhetőek el itt: ",
"rename_dialog": "A konfigurációs bejegyzés nevének szerkesztése",
"rename_input_label": "Bejegyzés neve"
"rename_input_label": "Bejegyzés neve",
"search": "Integrációk keresése"
},
"introduction": "Itt a komponenseket és a Home Assistant szervert lehet beállítani. Még nem lehet mindent a felületről, de dolgozunk rajta.",
"logs": {
"caption": "Napló",
"clear": "Törlés",
"description": "A Home Assistant naplófájlok megtekintése",
"details": "Naplózás részletessége ({level})",
"load_full_log": "Teljes Home Assistant napló betöltése",
"loading_log": "Hibanapló betöltése...",
@@ -1549,6 +1603,7 @@
}
},
"mqtt": {
"button": "Beállítás",
"description_listen": "Téma figyelése",
"description_publish": "Csomag közzététele",
"listening_to": "Figyelés:",
@@ -1607,6 +1662,7 @@
"introduction": "Az eszköz nélküli entitások itt állíthatók be.",
"without_device": "Eszköz nélküli entitások"
},
"icon": "Ikon",
"introduction": "Használj jeleneteket otthonod életre keltéséhez.",
"load_error_not_editable": "Csak a scenes.yaml fájlban megadott jelenetek szerkeszthetők.",
"load_error_unknown": "Hiba a jelenet betöltésekor ({err_no}).",
@@ -1640,9 +1696,24 @@
"delete_confirm": "Biztosan törölni szeretnéd ezt a szkriptet?",
"delete_script": "Szkript törlése",
"header": "Szkript: {name}",
"icon": "Ikon",
"id": "Entitás ID",
"id_already_exists": "Ez az ID már létezik",
"introduction": "Használj szkripteket műveletsorozatok végrehajtásához.",
"link_available_actions": "Tudj meg többet az elérhető műveletekről.",
"load_error_not_editable": "Csak a scripts.yaml fájlban megadott szkriptek szerkeszthetők.",
"max": {
"parallel": "A párhuzamos futtatások maximális száma",
"queued": "Várólista hossza"
},
"modes": {
"documentation": "szkript dokumentáció",
"label": "Mód",
"parallel": "Párhuzamos",
"queued": "Várólistás",
"restart": "Újraindítás",
"single": "Egyszeri (alapértelmezett)"
},
"sequence": "Sorrend",
"sequence_sentence": "A szkript műveleti sorrendje."
},
@@ -1669,6 +1740,11 @@
"core": "Lokáció és testreszabások újratöltése",
"group": "Csoportok újratöltése",
"heading": "YAML konfiguráció újratöltése",
"input_boolean": "Bemeneti logikai változók újratöltése",
"input_datetime": "Időpont bemenetek újratöltése",
"input_number": "Szám bemenetek újratöltése",
"input_select": "Választási bemenetek újratöltése",
"input_text": "Bemeneti szövegek újratöltése",
"introduction": "A Home Assistant bizonyos részei újraindítás nélkül újratölthetőek. Újratöltéskor az aktuálisan betöltött YAML konfiguráció helyére betöltődik az új.",
"person": "Személyek újratöltése",
"scene": "Jelenetek újratöltése",
@@ -1731,6 +1807,7 @@
},
"zha": {
"add_device_page": {
"discovered_text": "Az eszközök itt fognak megjelenni, ha felfedezésre kerültek.",
"discovery_text": "A felfedezett eszközök itt fognak megjelenni. A készülékek használati utasításai alapján állítsd őket párosítási módba.",
"header": "Zigbee Home Automation - Eszközök hozzáadása",
"search_again": "Keresés Újra",
@@ -1740,6 +1817,7 @@
"caption": "Eszközök hozzáadása",
"description": "Eszközök hozzáadása a Zigbee hálózathoz"
},
"button": "Beállítás",
"caption": "ZHA",
"cluster_attributes": {
"attributes_of_cluster": "A kiválasztott klaszter attribútumai",
@@ -1818,6 +1896,9 @@
"header": "Hálózat menedzsment",
"introduction": "Parancsok, amik kihatnak az egész hálózatra"
},
"network": {
"caption": "Hálózat"
},
"node_management": {
"header": "Eszköz kezelés",
"help_node_dropdown": "Válassz egy eszközt az eszközönkénti beállítások megtekintéséhez.",
@@ -1857,6 +1938,7 @@
"no_zones_created_yet": "Úgy tűnik, még nem hoztál létre zónákat."
},
"zwave": {
"button": "Beállítás",
"caption": "Z-Wave",
"common": {
"index": "Index",
@@ -1890,6 +1972,7 @@
"true": "Igaz"
},
"node_management": {
"header": "Z-Wave csomópontkezelés",
"nodes": "Csomópontok"
},
"ozw_log": {
@@ -1901,15 +1984,16 @@
"add_node_secure": "Biztonságos csomópont hozzáadása",
"cancel_command": "Parancs megszakítása",
"heal_network": "Hálózati struktúra feltérképezése",
"node_info": "Node információ",
"node_info": "Csomópont információ",
"refresh_entity": "Entitás frissítése",
"refresh_node": "Csomópont frissítése",
"remove_node": "Csomópont eltávolítása",
"save_config": "Konfiguráció mentése",
"soft_reset": "Soft Reset",
"start_network": "Hálózat indítása",
"stop_network": "Hálózat leállítása",
"test_network": "Hálózat tesztelése",
"test_node": "Teszt Node"
"test_node": "Teszt csomópont"
},
"values": {
"header": "Csomópont értékek"
@@ -1986,11 +2070,23 @@
},
"history": {
"period": "Időtartam",
"ranges": {
"last_week": "Múlt hét",
"this_week": "Aktuális hét",
"today": "Ma",
"yesterday": "Tegnap"
},
"showing_entries": "Bejegyzések megjelenítése"
},
"logbook": {
"entries_not_found": "Nincsenek naplóbejegyzések.",
"period": "Időszak",
"ranges": {
"last_week": "Múlt hét",
"this_week": "Aktuális hét",
"today": "Ma",
"yesterday": "Tegnap"
},
"showing_entries": "Bejegyzések megjelenítése"
},
"lovelace": {
@@ -2028,7 +2124,7 @@
"clear_items": "Bejelölt tételek törlése"
},
"starting": {
"description": "A Home Assistant indítása folyamatban van, kérlek várj.",
"description": "A Home Assistant indítása folyamatban van, kérlek várj...",
"header": "A Home Assistant indítása folyamatban van..."
}
},
@@ -2106,6 +2202,7 @@
"name": "Név",
"no_theme": "Nincs téma",
"refresh_interval": "Frissítési időköz",
"search": "Keresés",
"secondary_info_attribute": "Másodlagos információ attribútum",
"show_icon": "Ikon megjelenítése?",
"show_name": "Név megjelenítése?",
@@ -2130,6 +2227,9 @@
"description": "A Vízszintes Készlet kártya lehetővé teszi több kártya egymás mellé rendezését egy oszlopon belül.",
"name": "Vízszintes Készlet"
},
"humidifier": {
"name": "Párásító"
},
"iframe": {
"description": "A Weblap kártya lehetővé teszi a kedvenc weboldalad beágyazását a Home Assistant-ba.",
"name": "Weboldal"
@@ -2207,6 +2307,7 @@
},
"edit_card": {
"add": "Kártya hozzáadása",
"confirm_cancel": "Biztosan meg szeretnéd szakítani?",
"delete": "Kártya törlése",
"duplicate": "Kártya duplikálása",
"edit": "Szerkesztés",
@@ -2217,12 +2318,15 @@
"pick_card_view_title": "Melyik kártyát szeretnéd hozzáadni a(z) {name} nézethez?",
"show_code_editor": "Kódszerkesztő megjelenítése",
"show_visual_editor": "Vizuális szerkesztő megjelenítése",
"toggle_editor": "Szerkesztő"
"toggle_editor": "Szerkesztő",
"typed_header": "{típusú} Kártya Konfiguráció",
"unsaved_changes": "Vannak nem mentett módosítások"
},
"edit_lovelace": {
"edit_title": "Cím szerkesztése",
"explanation": "Ez a cím jelenik meg minden nézet felett a Lovelace felhasználói felületen.",
"header": "Lovelace UI címe"
"header": "Lovelace UI címe",
"title": "Cím"
},
"edit_view": {
"add": "Nézet hozzáadása",
@@ -2309,6 +2413,8 @@
"entity": "Entitás",
"entity_id": "Entitás ID",
"last_changed": "Utoljára változott",
"no_data": "Nincsenek nem használt entitások",
"search": "Entitások keresése",
"select_to_add": "Válaszd ki azokat az entitásokat, amelyeket hozzá akarsz adni egy kártyához, majd kattints a kártya hozzáadása gombra.",
"title": "Nem használt entitások"
},
@@ -2411,6 +2517,7 @@
},
"trusted_networks": {
"abort": {
"not_allowed": "A számítógéped nem engedélyezett.",
"not_whitelisted": "A számítógéped nem engedélyezett."
},
"step": {
@@ -2586,6 +2693,10 @@
"not_used": "Sosem használt",
"token_title": "{clientId} frissítési tokenje"
},
"suspend": {
"description": "Lezárjuk a kapcsolatot a szerverrel, ha 5 percig rejtve van a felület?",
"header": "Kapcsolat automatikus bontása"
},
"themes": {
"dropdown_label": "Téma",
"error_no_theme": "Nincsenek elérhető témák.",

View File

@@ -205,6 +205,7 @@
"stopped": "Stöðvuð"
},
"default": {
"off": "Slökkt",
"on": "Á",
"unavailable": "Ekki tiltækt",
"unknown": "Óþekkt"
@@ -402,6 +403,8 @@
"activate": "Virkja"
},
"script": {
"cancel": "Hætta við",
"cancel_multiple": "Hætta við {number}",
"execute": "Framkvæma"
},
"service": {
@@ -489,6 +492,9 @@
"clear": "Hreinsa",
"show_areas": "Birta svæði"
},
"data-table": {
"search": "Leita"
},
"date-range-picker": {
"end_date": "Loka dagsetning",
"select": "Velja",
@@ -568,6 +574,7 @@
"time": "Tími"
},
"input_number": {
"box": "Innsláttarreitur",
"max": "Hámarksgildi",
"min": "Lágmarksgildi",
"mode": "Birtingarmáti",
@@ -607,6 +614,7 @@
"title": "Uppfærslu leiðbeiningar"
},
"vacuum": {
"locate": "Staðsetja",
"pause": "Hlé",
"start": "Byrja",
"status": "Staða",
@@ -645,6 +653,7 @@
"unknown": "Óþekkt",
"zha_device_card": {
"area_picker_label": "Svæði",
"device_name_placeholder": "Breyta nafni á tæki",
"update_name_button": "Uppfæra nafn"
}
}
@@ -686,6 +695,7 @@
"description": "Yfirlit yfir öll svæði á heimilinu þínu.",
"editor": {
"create": "STOFNA",
"default_name": "Nýtt svæði",
"delete": "EYÐA",
"name": "Nafn",
"name_required": "Nafn er skilyrt",
@@ -817,10 +827,16 @@
"label": "Lýsing",
"placeholder": "Valfrjáls lýsing"
},
"edit_ui": "Breyta í viðmóti",
"edit_yaml": "Breyta sem YAML",
"enable_disable": "Virkja/slökkva á sjálfvirkni",
"introduction": "Notaðu sjálfvirkni til að glæða húsið þitt lífi",
"load_error_not_editable": "Eingöngu er hægt að breyta sjálfvirkni í automations.yaml",
"load_error_unknown": "Villa kom upp við að hlaða inn sjálfvirkni ({err_no}).",
"modes": {
"label": "Hamur",
"restart": "Endurræsa"
},
"move_down": "Færa niður",
"move_up": "Færa upp",
"save": "Vista",
@@ -966,6 +982,7 @@
"description_login": "Innskráð(ur) sem {email}",
"description_not_login": "Ekki skráð(ur) inn",
"dialog_certificate": {
"certificate_information": "Upplýsingar um skilríki",
"close": "Loka",
"fingerprint": "Fingrafar skilríkis:"
},
@@ -1055,9 +1072,11 @@
"actions": {
"caption": "Þegar eitthvað er ræst af kveikju..."
},
"automations": "Sjálfvirkni",
"conditions": {
"caption": "Bara framkvæma eitthvað ef..."
},
"no_automations": "Engin sjálfvirkni",
"triggers": {
"caption": "Framkvæma eitthvað þegar..."
}
@@ -1070,6 +1089,7 @@
"device": "Tæki",
"integration": "Samþætting",
"manufacturer": "Framleiðandi",
"model": "Gerð",
"no_area": "Ekkert svæði",
"no_devices": "Engin tæki"
},
@@ -1121,6 +1141,7 @@
"button": "Fjarlægja val",
"confirm_title": "Viltu fjarlægja {number} einingar?"
},
"search": "Leita í einingum",
"selected": "{number} valin",
"status": {
"disabled": "Afvirkjað",
@@ -1155,6 +1176,7 @@
}
},
"info": {
"built_using": "Byggt með",
"caption": "Upplýsingar",
"documentation": "Skjölun",
"icons_by": "Smátákn eftir",
@@ -1214,7 +1236,9 @@
"integration_not_found": "Samþætting fannst ekki.",
"new": "Setja upp nýja samþættingu",
"none": "Ekkert skilgreint sem stendur",
"none_found": "Engar samþættingar fundust"
"none_found": "Engar samþættingar fundust",
"note_about_integrations": "Það er ekki er hægt að stilla allar samþættingar í gegnum viðmótið ennþá.",
"search": "Leita í samþættingum"
},
"introduction": "Hér er mögulegt að stilla af íhluti og Home Assistant. Því miður er ekki hægt að breyta öllu í gegnum viðmótið ennþá, en við erum að vinna í því.",
"logs": {
@@ -1319,8 +1343,10 @@
"entities": {
"add": "Bæta við einingu",
"delete": "Eyða einingu",
"header": "Einingar"
"header": "Einingar",
"without_device": "Einingar án tækja"
},
"icon": "Táknmynd",
"load_error_not_editable": "Það er eingöngu hægt að breyta senum í scenes.yaml.",
"name": "Nafn",
"save": "Vista"
@@ -1345,7 +1371,13 @@
"description": "Búa til og breyta skriftum",
"editor": {
"alias": "Nafn",
"link_available_actions": "Læra meira um tiltækar aðgerðir."
"icon": "Táknmynd",
"link_available_actions": "Læra meira um tiltækar aðgerðir.",
"modes": {
"label": "Hamur",
"restart": "Endurræsa"
},
"sequence": "Röð"
},
"picker": {
"headers": {
@@ -1508,10 +1540,12 @@
"node_management": {
"add_to_group": "Bæta í hóp",
"entity_info": "Upplýsingar um einingu",
"group": "Hópur"
"group": "Hópur",
"remove_from_group": "Fjarlægja úr hóp"
},
"ozw_log": {
"header": "OZW annáll"
"header": "OZW annáll",
"load": "Hlaða"
},
"services": {
"cancel_command": "Hætta við skipun",
@@ -1545,7 +1579,9 @@
},
"states": {
"current_entities": "Tiltækar einingar",
"entity": "Eining",
"more_info": "Frekari upplýsingar",
"no_entities": "Engar einingar",
"set_state": "Setja stöðu",
"state": "Staða",
"title": "Stöður"
@@ -1652,6 +1688,7 @@
"minimum": "Lágmark",
"name": "Nafn",
"no_theme": "Ekkert þema",
"search": "Leita",
"show_icon": "Birta táknmynd?",
"show_name": "Birta nafn?",
"show_state": "Birta stöðu?",
@@ -1693,6 +1730,7 @@
"name": "Mynd"
},
"plant-status": {
"description": "Staða plöntu kortið er fyrir alla grasafræðingana þarna úti.",
"name": "Staða plöntu"
},
"sensor": {
@@ -1718,6 +1756,7 @@
},
"edit_card": {
"add": "Bæta við spjaldi",
"confirm_cancel": "Ertu viss um að þú viljir hætta við?",
"delete": "Eyða",
"edit": "Breyta",
"header": "Stillingar spjalds",
@@ -1726,10 +1765,12 @@
"pick_card": "Veldu spjald sem þú vilt bæta við.",
"show_code_editor": "Birta kóða ritil",
"show_visual_editor": "Birta sjónrænan ritil",
"toggle_editor": "Víxla ritli"
"toggle_editor": "Víxla ritli",
"unsaved_changes": "Þú ert með óvistaðar breytingar"
},
"edit_lovelace": {
"edit_title": "Breyta titli"
"edit_title": "Breyta titli",
"title": "Titill"
},
"edit_view": {
"add": "Bæta við sýn",
@@ -1748,6 +1789,7 @@
"migrate": "Uppfæra stillingar"
},
"raw_editor": {
"error_save_yaml": "Ekki tókst að vista YAML: {error}",
"header": "Breyta stillingum",
"save": "Vista",
"saved": "Vistað",
@@ -1865,6 +1907,7 @@
},
"trusted_networks": {
"abort": {
"not_allowed": "Tölvan þín er ekki leyfð.",
"not_whitelisted": "Tölvan þín er ekki hvítlistuð."
},
"step": {

View File

@@ -430,6 +430,8 @@
"activate": "Attiva"
},
"script": {
"cancel": "Annulla",
"cancel_multiple": "Annulla {number}",
"execute": "Esegui"
},
"service": {
@@ -525,6 +527,10 @@
"clear": "Cancella",
"show_areas": "Mostra le aree"
},
"data-table": {
"no-data": "Nessun dato",
"search": "Ricerca"
},
"date-range-picker": {
"end_date": "Data di fine",
"select": "Selezionare",
@@ -938,6 +944,19 @@
"introduction": "Usa le automazioni per dare vita alla tua casa.",
"load_error_not_editable": "Solo le Automazioni in automations.yaml sono modificabili.",
"load_error_unknown": "Errore durante il caricamento dell'Automazione ({err_no}).",
"max": {
"parallel": "Numero massimo di esecuzioni parallele",
"queued": "Lunghezza della coda"
},
"modes": {
"description": "La modalità controlla cosa succede quando l'automazione viene attivata mentre le azioni sono ancora in esecuzione da una attivazione precedente. Controllare {documentation_link} per maggiori informazioni.",
"documentation": "documentazione di automazione",
"label": "Modalità",
"parallel": "Parallelo",
"queued": "In coda",
"restart": "Riavviare",
"single": "Singolo (predefinito)"
},
"move_down": "Sposta sotto",
"move_up": "Sposta sopra",
"save": "Salva",
@@ -1356,6 +1375,7 @@
"confirm_text": "Dovresti rimuoverli dalla configurazione di Lovelace e dalle automazioni se contengono queste entità.",
"confirm_title": "Vuoi rimuovere {number} entità?"
},
"search": "Cerca entità",
"selected": "{number} selezionato",
"status": {
"disabled": "Disabilitato",
@@ -1386,7 +1406,8 @@
"entity_id": "ID Entità",
"name": "Nome",
"type": "Tipo"
}
},
"no_helpers": "Sembra che tu non abbia ancora nessun aiutante!"
},
"types": {
"input_boolean": "Commutatore",
@@ -1490,7 +1511,8 @@
"note_about_integrations": "Non tutte le integrazioni possono ancora essere configurate tramite l'interfaccia utente.",
"note_about_website_reference": "Ulteriori informazioni sono disponibili su ",
"rename_dialog": "Modifica il nome di questa voce di configurazione",
"rename_input_label": "Nome della voce"
"rename_input_label": "Nome della voce",
"search": "Cerca integrazioni"
},
"introduction": "Qui è possibile configurare i componenti e Home Assistant. Non è ancora possibile configurare tutto dall'Interfaccia Utente, ma ci stiamo lavorando.",
"logs": {
@@ -1643,6 +1665,7 @@
"introduction": "Le entità che non appartengono a un dispositivo possono essere impostate qui.",
"without_device": "Entità senza dispositivo"
},
"icon": "Icona",
"introduction": "Usa le scene per dare vita alla tua casa.",
"load_error_not_editable": "Solo le scene in scene.yaml sono modificabili.",
"load_error_unknown": "Errore durante il caricamento della scena ({err_no}).",
@@ -1676,9 +1699,26 @@
"delete_confirm": "Sei sicuro di voler eliminare questo script?",
"delete_script": "Elimina script",
"header": "Script: {name}",
"icon": "Icona",
"id": "ID Entità",
"id_already_exists": "Questo ID esiste già",
"id_already_exists_save_error": "Non è possibile salvare questo script perché l'ID non è univoco, scegliere un altro ID o lasciarlo vuoto per generarne automaticamente uno.",
"introduction": "Utilizzare gli script per eseguire una sequenza di azioni.",
"link_available_actions": "Ulteriori informazioni sulle azioni disponibili.",
"load_error_not_editable": "Solo gli script all'interno di scripts.yaml sono modificabili.",
"max": {
"parallel": "Numero massimo di esecuzioni parallele",
"queued": "Lunghezza della coda"
},
"modes": {
"description": "La modalità controlla cosa succede quando lo script viene invocato mentre è ancora in esecuzione da una o più invocazioni precedenti. Controllare il {documentation_link} per maggiori informazioni.",
"documentation": "documentazione dello script",
"label": "Modalità",
"parallel": "Parallelo",
"queued": "In coda",
"restart": "Riavviare",
"single": "Singolo (predefinito)"
},
"sequence": "Sequenza",
"sequence_sentence": "Sequenza di azioni di questo script."
},
@@ -1776,7 +1816,7 @@
"discovered_text": "I dispositivi verranno visualizzati qui una volta scoperti.",
"discovery_text": "I dispositivi rilevati verranno visualizzati qui. Seguire le istruzioni per il / i dispositivo / i e posizionare il / i dispositivo / i in modalità accoppiamento.",
"header": "Zigbee Home Automation - Aggiungi dispositivi",
"no_devices_found": "Nessun dispositivo trovato, assicurati che siano in modalità di associazione e tienili svegli mentre la scansione è in esecuzione.",
"no_devices_found": "Nessun dispositivo trovato, assicurati che siano in modalità di associazione e tienili attivi mentre la scansione è in esecuzione.",
"pairing_mode": "Assicurati che i tuoi dispositivi siano in modalità di associazione. Controlla le istruzioni del tuo dispositivo su come eseguire questa operazione.",
"search_again": "Cerca di nuovo",
"spinner": "Ricerca di dispositivi ZHA Zigbee ..."
@@ -2194,6 +2234,7 @@
"name": "Nome",
"no_theme": "Nessun tema",
"refresh_interval": "Intervallo di aggiornamento",
"search": "Ricerca",
"secondary_info_attribute": "Attributo informazioni secondarie",
"show_icon": "Mostrare l'icona?",
"show_name": "Mostrare il nome?",
@@ -2299,6 +2340,7 @@
},
"edit_card": {
"add": "Aggiungi scheda",
"confirm_cancel": "Sei sicuro di voler annullare?",
"delete": "Elimina scheda",
"duplicate": "Duplica scheda",
"edit": "Modifica",
@@ -2309,12 +2351,15 @@
"pick_card_view_title": "Quale scheda vorresti aggiungere alla tua vista {name}?",
"show_code_editor": "Mostra Editor di Codice",
"show_visual_editor": "Mostra Editor Visivo",
"toggle_editor": "Attiva / disattiva l'editor"
"toggle_editor": "Attiva / disattiva l'editor",
"typed_header": "{type} Configurazione Scheda",
"unsaved_changes": "Sono state apportate modifiche non salvate"
},
"edit_lovelace": {
"edit_title": "Modifica titolo",
"explanation": "Questo titolo è mostrato sopra tutte le tue viste nell'Interfaccia Utente di Lovelace.",
"header": "Titolo della tua interfaccia utente di Lovelace"
"header": "Titolo della tua interfaccia utente di Lovelace",
"title": "Titolo"
},
"edit_view": {
"add": "Aggiungi vista",
@@ -2401,6 +2446,8 @@
"entity": "Entità",
"entity_id": "ID entità",
"last_changed": "Ultima modifica",
"no_data": "Trovate entità non utilizzate",
"search": "Cerca entità",
"select_to_add": "Selezionare le entità che si desidera aggiungere a una scheda, quindi fare clic sul pulsante Aggiungi scheda.",
"title": "Entità non utilizzate"
},
@@ -2503,6 +2550,7 @@
},
"trusted_networks": {
"abort": {
"not_allowed": "Il tuo computer non è consentito.",
"not_whitelisted": "Il tuo computer non è nella whitelist."
},
"step": {

View File

@@ -430,6 +430,8 @@
"activate": "활성화"
},
"script": {
"cancel": "취소",
"cancel_multiple": "{number} 개 취소",
"execute": "실행"
},
"service": {
@@ -526,6 +528,7 @@
"show_areas": "영역 표시"
},
"data-table": {
"no-data": "데이터가 없습니다",
"search": "검색"
},
"date-range-picker": {
@@ -941,6 +944,19 @@
"introduction": "자동화를 사용하여 집에 생기를 불어넣으세요",
"load_error_not_editable": "automations.yaml 의 자동화만 편집할 수 있습니다.",
"load_error_unknown": "자동화를 읽어오는 도중 오류가 발생했습니다 ({err_no}).",
"max": {
"parallel": "최대 병렬 실행 수",
"queued": "대기열 길이"
},
"modes": {
"description": "모드는 자동화가 이전 트리거에서 동작이 실행되는 동안 트리거될 때 실행되는 작업을 제어합니다. 자세한 내용은 {documentation_link} 을(를) 확인해주세요.",
"documentation": "자동화 문서",
"label": "모드",
"parallel": "병렬",
"queued": "대기",
"restart": "재시작",
"single": "단일 (기본값)"
},
"move_down": "아래로 이동",
"move_up": "위로 이동",
"save": "저장하기",
@@ -1649,6 +1665,7 @@
"introduction": "기기에 속하지 않은 구성요소는 여기에서 설정할 수 있습니다.",
"without_device": "기기가 없는 구성요소"
},
"icon": "아이콘",
"introduction": "씬을 사용하여 집에 생기를 불어넣으세요",
"load_error_not_editable": "scenes.yaml 의 씬 만 편집할 수 있습니다.",
"load_error_unknown": "씬 불러오기 오류: ({err_no}).",
@@ -1682,9 +1699,26 @@
"delete_confirm": "이 스크립트를 삭제하시겠습니까?",
"delete_script": "스크립트 삭제",
"header": "스크립트: {name}",
"icon": "아이콘",
"id": "구성요소 ID",
"id_already_exists": "ID 가 이미 존재합니다",
"id_already_exists_save_error": "고유한 ID 가 아니므로 이 스크립트를 저장할 수 없습니다. 다른 ID 를 선택하거나 자동생성하려면 비워두세요.",
"introduction": "스크립트를 사용하여 동작의 시퀀스를 실행합니다.",
"link_available_actions": "사용가능한 동작에 대해 더 알아보기.",
"load_error_not_editable": "scripts.yaml 의 스크립트만 편집할 수 있습니다.",
"max": {
"parallel": "최대 병렬 실행 수",
"queued": "대기열 길이"
},
"modes": {
"description": "모드는 스크립트가 하나 이상의 이전 호출에서 계속 실행되는 동안 스크립트가 호출될 때 실행되는 작업을 제어합니다. 자세한 내용은 {documentation_link} 을(를) 확인해주세요.",
"documentation": "스크립트 문서",
"label": "모드",
"parallel": "병렬",
"queued": "대기",
"restart": "재시작",
"single": "단일 (기본값)"
},
"sequence": "시퀀스",
"sequence_sentence": "이 스크립트의 동작 시퀀스."
},
@@ -2306,6 +2340,7 @@
},
"edit_card": {
"add": "카드 추가하기",
"confirm_cancel": "취소하시겠습니까?",
"delete": "카드 삭제",
"duplicate": "카드 복사",
"edit": "편집",
@@ -2316,7 +2351,9 @@
"pick_card_view_title": "{name} 뷰에 어떤 카드를 추가하시겠습니까?",
"show_code_editor": "코드 편집기 보기",
"show_visual_editor": "비주얼 편집기 보기",
"toggle_editor": "에디터 전환"
"toggle_editor": "에디터 전환",
"typed_header": "{type} 카드 구성",
"unsaved_changes": "저장하지 않은 변경 사항이 있습니다"
},
"edit_lovelace": {
"edit_title": "제목 편집",
@@ -2409,6 +2446,8 @@
"entity": "구성요소",
"entity_id": "구성요소 ID",
"last_changed": "최근 변경 됨",
"no_data": "미사용 구성요소가 없습니다",
"search": "구성요소 검색",
"select_to_add": "카드에 추가 할 구성요소를 선택한 다음, 카드 추가 버튼을 클릭해주세요.",
"title": "미사용 구성요소"
},
@@ -2511,6 +2550,7 @@
},
"trusted_networks": {
"abort": {
"not_allowed": "이 컴퓨터는 허용 목록에 등록되지 않았습니다.",
"not_whitelisted": "이 컴퓨터는 허용 목록에 등록되어 있지 않습니다."
},
"step": {

View File

@@ -430,6 +430,8 @@
"activate": "Aktivéieren"
},
"script": {
"cancel": "Ofbriechen",
"cancel_multiple": "{number} ofbriechen",
"execute": "Ausféieren"
},
"service": {
@@ -525,6 +527,10 @@
"clear": "Läschen",
"show_areas": "Beräicher uweisen"
},
"data-table": {
"no-data": "Keng Donnée",
"search": "Sichen"
},
"date-range-picker": {
"end_date": "End Datum",
"select": "Auswielen",
@@ -938,6 +944,16 @@
"introduction": "Benotzt Automatismen fir däin Haus zum Liewen ze bréngen",
"load_error_not_editable": "Nëmmen Automatiounen am automations.yaml kënnen editéiert ginn.",
"load_error_unknown": "Feeler beim luede vun der Automatioun ({err_no}).",
"max": {
"parallel": "Max. Unzuel vun parallelen Duerchleef."
},
"modes": {
"documentation": "Dokumentatioun vum Automatisme",
"label": "Modus",
"parallel": "Parrallel",
"restart": "Neistart",
"single": "Eenzel (Standard)"
},
"move_down": "No ënne réckelen",
"move_up": "No uewe réckelen",
"save": "Späicheren",
@@ -1356,6 +1372,7 @@
"confirm_text": "Du solls déi vun der Lovelace Konfiguratioun an Automatisme läschen falls se dës Entitéiten enthalen.",
"confirm_title": "Wëllt dir {number} Entitéite läschen?"
},
"search": "Entitéite sichen",
"selected": "{number} ausgewielt",
"status": {
"disabled": "Deaktivéiert",
@@ -1386,7 +1403,8 @@
"entity_id": "ID vun der Entitéit",
"name": "Numm",
"type": "Typ"
}
},
"no_helpers": "Et gesäit sou aus wéi wann nach keng Helpers erstallt goufen."
},
"types": {
"input_boolean": "Ëmschalten",
@@ -1431,6 +1449,7 @@
"delete_confirm": "Sécher fir dës Integratioun ze läsche?",
"device_unavailable": "Apparat net erreechbar",
"devices": "{count} {count, plural,\n one {Apparat}\n other {Apparaten}\n}",
"documentation": "Dokumentatioun",
"entities": "{count} {count, plural,\n one {Entitéit}\n other {Entitéiten}\n}",
"entity_unavailable": "Entitéit net erreechbar",
"firmware": "Firmware: {version}",
@@ -1489,7 +1508,8 @@
"note_about_integrations": "Net all Integratioune könne nach via den Benotzer Interface konfiguréiert ginn.",
"note_about_website_reference": "Méi sin der disponibel op der ",
"rename_dialog": "Numm vun dësem Objet läschen",
"rename_input_label": "Numm"
"rename_input_label": "Numm",
"search": "Integratioune sichen"
},
"introduction": "Hei ass et méiglech är Komponenten vum Home Assistant ze konfiguréieren. Net alles ass méiglech fir iwwert den Interface anzestellen, mee mir schaffen drun.",
"logs": {
@@ -1642,6 +1662,7 @@
"introduction": "Entitéiten déi zu kengem Apparat gehéiere kënnen hei definéiert ginn.",
"without_device": "Entitéiten ouni Apparater"
},
"icon": "Ikon",
"introduction": "Benotzt Zeene fir äert Haus zum Liewen ze bréngen",
"load_error_not_editable": "Nëmme Zeene am scenes.yaml kënnen editéiert ginn.",
"load_error_unknown": "Feeler beim luede vun der Zeen ({err_no}).",
@@ -1675,9 +1696,23 @@
"delete_confirm": "Sécher fir dësen Skript ze läsche?",
"delete_script": "Skript läschen",
"header": "Skript: {name}",
"icon": "Ikon",
"id": "ID vun der Entitéit",
"id_already_exists": "Dës ID gëtt et schonn",
"id_already_exists_save_error": "Du kanns dëse Skript net späicheren well d'ID net eenzegarteg ass. Wiel eng aaner ID aus oder loss se eidel fir automatesch eng z'erstellen.",
"introduction": "Benotzt Skripter fir eng Sequenz vun Aktiounen auszeféieren.",
"link_available_actions": "Méi iwwert verfügbar Aktioune liesen.",
"load_error_not_editable": "Nëmme Skripten am scripts.yaml kënnen editéiert ginn.",
"max": {
"parallel": "Max. Unzuel vun parallelen Duerchleef."
},
"modes": {
"documentation": "Dokumentatioun vum Skript",
"label": "Modus",
"parallel": "Parrallel",
"restart": "Neistart",
"single": "Eenzel (Standard)"
},
"sequence": "Sequenz",
"sequence_sentence": "D'Sequenz vun Aktiounen an dësem Skript."
},
@@ -2188,6 +2223,7 @@
"name": "Numm",
"no_theme": "Kee Thema",
"refresh_interval": "Aktualiséierungs Intervall",
"search": "Sichen",
"secondary_info_attribute": "Sekundär Informatiouns Attribut",
"show_icon": "Ikon uweisen?",
"show_name": "Numm uweisen?",
@@ -2293,6 +2329,7 @@
},
"edit_card": {
"add": "Kaart dobäisetzen",
"confirm_cancel": "Sécher fir ofzebriechen ?",
"delete": "Kaart läschen",
"duplicate": "Kaart Replikéieren",
"edit": "Änneren",
@@ -2303,12 +2340,15 @@
"pick_card_view_title": "Wéieng Kaart wëllt dir zu ärer {name}Usiicht dobäisetzen?",
"show_code_editor": "Code Editeur uweisen",
"show_visual_editor": "Visuellen Editeur uweisen",
"toggle_editor": "Editeur ëmschalten"
"toggle_editor": "Editeur ëmschalten",
"typed_header": "{type} Kaart Konfiguratioun",
"unsaved_changes": "Du hues ongespäichert Ännerungen"
},
"edit_lovelace": {
"edit_title": "Titel änneren",
"explanation": "Dësen Titel gëtt iwwert den Usiichte vu Lovelace ugewisen.",
"header": "Titel vun ärem Lovelace Benotzer Interface"
"header": "Titel vun ärem Lovelace Benotzer Interface",
"title": "Titel"
},
"edit_view": {
"add": "Vue dobäisetzen",
@@ -2395,6 +2435,8 @@
"entity": "Entitéit",
"entity_id": "ID vun der Entitéit",
"last_changed": "Läscht Ännerung",
"no_data": "Keng onbenotzten Entitéite fonnt",
"search": "Entitéite sichen",
"select_to_add": "Wielt d'Entitéite aus déi zu enger Kaart dobäigesaat solle ginn an klickt den Kaart dobäisetzen Knäppchen",
"title": "Onbenotzten Entitéiten"
},
@@ -2497,6 +2539,7 @@
},
"trusted_networks": {
"abort": {
"not_allowed": "Däi Computer ass net erlaabt.",
"not_whitelisted": "Äre Computer ass net fräigeschalt."
},
"step": {
@@ -2672,6 +2715,10 @@
"not_used": "Nach nie benotzt ginn",
"token_title": "Jeton erneiren fir {clientId}"
},
"suspend": {
"description": "Soll d'Verbindung automateschzougemaach gin nodeems se 5 Minutten verstoppt war?",
"header": "Verbindung autmatesch zoumaachen"
},
"themes": {
"dropdown_label": "Thema",
"error_no_theme": "Keen Thema disponibel",

Some files were not shown because too many files have changed in this diff Show More