mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 19:26:36 +00:00
commit
c55291dd18
@ -96,7 +96,8 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<ha-demo><div id="ha-init-skeleton"></div></ha-demo>
|
<div id="ha-init-skeleton"></div>
|
||||||
|
<ha-demo></ha-demo>
|
||||||
<script>
|
<script>
|
||||||
var _gaq = [["_setAccount", "UA-57927901-5"], ["_trackPageview"]];
|
var _gaq = [["_setAccount", "UA-57927901-5"], ["_trackPageview"]];
|
||||||
(function(d, t) {
|
(function(d, t) {
|
||||||
|
2
setup.py
2
setup.py
@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="home-assistant-frontend",
|
name="home-assistant-frontend",
|
||||||
version="20190315.0",
|
version="20190315.1",
|
||||||
description="The Home Assistant frontend",
|
description="The Home Assistant frontend",
|
||||||
url="https://github.com/home-assistant/home-assistant-polymer",
|
url="https://github.com/home-assistant/home-assistant-polymer",
|
||||||
author="The Home Assistant Authors",
|
author="The Home Assistant Authors",
|
||||||
|
@ -11,7 +11,7 @@ interface CloudStatusBase {
|
|||||||
cloud: "disconnected" | "connecting" | "connected";
|
cloud: "disconnected" | "connecting" | "connected";
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CertificateInformation {
|
export interface CertificateInformation {
|
||||||
common_name: string;
|
common_name: string;
|
||||||
expire_date: string;
|
expire_date: string;
|
||||||
fingerprint: string;
|
fingerprint: string;
|
||||||
|
@ -176,6 +176,7 @@ class HaMoreInfoDialog extends DialogMixin(PolymerElement) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.hass.user.is_admin) {
|
||||||
try {
|
try {
|
||||||
const info = await this.hass.callWS({
|
const info = await this.hass.callWS({
|
||||||
type: "config/entity_registry/get",
|
type: "config/entity_registry/get",
|
||||||
@ -186,6 +187,7 @@ class HaMoreInfoDialog extends DialogMixin(PolymerElement) {
|
|||||||
this._registryInfo = null;
|
this._registryInfo = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_dialogOpenChanged(newVal) {
|
_dialogOpenChanged(newVal) {
|
||||||
if (!newVal && this.stateObj) {
|
if (!newVal && this.stateObj) {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { fireEvent } from "../common/dom/fire_event";
|
|
||||||
import applyThemesOnElement from "../common/dom/apply_themes_on_element";
|
import applyThemesOnElement from "../common/dom/apply_themes_on_element";
|
||||||
|
|
||||||
import { demoConfig } from "./demo_config";
|
import { demoConfig } from "./demo_config";
|
||||||
@ -146,9 +145,6 @@ export const provideHass = (
|
|||||||
dockedSidebar: false,
|
dockedSidebar: false,
|
||||||
moreInfoEntityId: null as any,
|
moreInfoEntityId: null as any,
|
||||||
async callService(domain, service, data) {
|
async callService(domain, service, data) {
|
||||||
fireEvent(elements[0], "hass-notification", {
|
|
||||||
message: `Called service ${domain}/${service}`,
|
|
||||||
});
|
|
||||||
if (data && "entity_id" in data) {
|
if (data && "entity_id" in data) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
ensureArray(data.entity_id).map((ent) =>
|
ensureArray(data.entity_id).map((ent) =>
|
||||||
|
@ -40,8 +40,8 @@
|
|||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<home-assistant>
|
|
||||||
<div id='ha-init-skeleton'></div>
|
<div id='ha-init-skeleton'></div>
|
||||||
|
<home-assistant>
|
||||||
</home-assistant>
|
</home-assistant>
|
||||||
<% if (!latestBuild) { %>
|
<% if (!latestBuild) { %>
|
||||||
<script src="/static/custom-elements-es5-adapter.js"></script>
|
<script src="/static/custom-elements-es5-adapter.js"></script>
|
||||||
|
@ -54,7 +54,7 @@ export class HomeAssistantAppEl extends ext(HassBaseMixin(LitElement), [
|
|||||||
></app-location>
|
></app-location>
|
||||||
${this._panelUrl === undefined || this._route === undefined
|
${this._panelUrl === undefined || this._route === undefined
|
||||||
? ""
|
? ""
|
||||||
: hass && hass.states && hass.config && hass.panels && hass.services
|
: hass && hass.states && hass.config && hass.services
|
||||||
? html`
|
? html`
|
||||||
<home-assistant-main
|
<home-assistant-main
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
|
@ -15,12 +15,12 @@ import { haStyle } from "../resources/styles";
|
|||||||
|
|
||||||
@customElement("hass-loading-screen")
|
@customElement("hass-loading-screen")
|
||||||
class HassLoadingScreen extends LitElement {
|
class HassLoadingScreen extends LitElement {
|
||||||
@property() public isRoot? = false;
|
@property({ type: Boolean }) public rootnav? = false;
|
||||||
|
|
||||||
protected render(): TemplateResult | void {
|
protected render(): TemplateResult | void {
|
||||||
return html`
|
return html`
|
||||||
<app-toolbar>
|
<app-toolbar>
|
||||||
${this.isRoot
|
${this.rootnav
|
||||||
? html`
|
? html`
|
||||||
<ha-menu-button></ha-menu-button>
|
<ha-menu-button></ha-menu-button>
|
||||||
`
|
`
|
||||||
|
@ -13,14 +13,13 @@ const extractPage = (path: string, defaultPage: string) => {
|
|||||||
: path.substr(1, subpathStart - 1);
|
: path.substr(1, subpathStart - 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface RouteOptions {
|
export interface RouteOptions {
|
||||||
tag: string;
|
tag: string;
|
||||||
load: () => Promise<unknown>;
|
load: () => Promise<unknown>;
|
||||||
cache?: boolean;
|
cache?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RouterOptions {
|
export interface RouterOptions {
|
||||||
isRoot?: boolean;
|
|
||||||
defaultPage?: string;
|
defaultPage?: string;
|
||||||
preloadAll?: boolean;
|
preloadAll?: boolean;
|
||||||
cacheAll?: boolean;
|
cacheAll?: boolean;
|
||||||
@ -34,17 +33,19 @@ export interface RouterOptions {
|
|||||||
const LOADING_SCREEN_THRESHOLD = 400; // ms
|
const LOADING_SCREEN_THRESHOLD = 400; // ms
|
||||||
|
|
||||||
export class HassRouterPage extends UpdatingElement {
|
export class HassRouterPage extends UpdatingElement {
|
||||||
protected static routerOptions: RouterOptions = { routes: {} };
|
@property() public route?: Route;
|
||||||
|
|
||||||
protected static finalize() {
|
protected routerOptions!: RouterOptions;
|
||||||
super.finalize();
|
|
||||||
this._routerOptions = this.routerOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static _routerOptions: RouterOptions;
|
/**
|
||||||
|
* Optional variable to define extra routes dynamically.
|
||||||
@property() public route!: Route;
|
* It is preferred to use static routes.
|
||||||
|
*/
|
||||||
|
protected extraRoutes?: {
|
||||||
|
[route: string]: RouteOptions;
|
||||||
|
};
|
||||||
private _currentPage = "";
|
private _currentPage = "";
|
||||||
|
private _currentLoadProm?: Promise<void>;
|
||||||
private _cache = {};
|
private _cache = {};
|
||||||
|
|
||||||
protected update(changedProps: PropertyValues) {
|
protected update(changedProps: PropertyValues) {
|
||||||
@ -52,15 +53,13 @@ export class HassRouterPage extends UpdatingElement {
|
|||||||
|
|
||||||
if (!changedProps.has("route")) {
|
if (!changedProps.has("route")) {
|
||||||
if (this.lastChild) {
|
if (this.lastChild) {
|
||||||
this._updatePageEl(this.lastChild, changedProps);
|
this.updatePageEl(this.lastChild, changedProps);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const route = this.route;
|
const route = this.route;
|
||||||
|
const routerOptions = this.routerOptions || { routes: {} };
|
||||||
const routerOptions = (this.constructor as typeof HassRouterPage)
|
|
||||||
._routerOptions;
|
|
||||||
const defaultPage = routerOptions.defaultPage || "";
|
const defaultPage = routerOptions.defaultPage || "";
|
||||||
|
|
||||||
if (route && route.path === "") {
|
if (route && route.path === "") {
|
||||||
@ -71,22 +70,22 @@ export class HassRouterPage extends UpdatingElement {
|
|||||||
|
|
||||||
if (this._currentPage === newPage) {
|
if (this._currentPage === newPage) {
|
||||||
if (this.lastChild) {
|
if (this.lastChild) {
|
||||||
this._updatePageEl(this.lastChild, changedProps);
|
this.updatePageEl(this.lastChild, changedProps);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const routeOptions = routerOptions.routes[newPage];
|
||||||
|
|
||||||
|
if (!routeOptions) {
|
||||||
|
this._currentPage = "";
|
||||||
|
if (this.lastChild) {
|
||||||
|
this.removeChild(this.lastChild);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._currentPage = newPage;
|
this._currentPage = newPage;
|
||||||
|
|
||||||
const routeOptions = routerOptions.routes[newPage];
|
|
||||||
|
|
||||||
if (!routeOptions) {
|
|
||||||
if (this.lastChild) {
|
|
||||||
this._updatePageEl(this.lastChild, changedProps);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadProm = routeOptions.load();
|
const loadProm = routeOptions.load();
|
||||||
|
|
||||||
// Check when loading the page source failed.
|
// Check when loading the page source failed.
|
||||||
@ -125,13 +124,12 @@ export class HassRouterPage extends UpdatingElement {
|
|||||||
if (this.lastChild) {
|
if (this.lastChild) {
|
||||||
this.removeChild(this.lastChild);
|
this.removeChild(this.lastChild);
|
||||||
}
|
}
|
||||||
|
this.appendChild(this.createLoadingScreen());
|
||||||
const loadingEl = document.createElement("hass-loading-screen");
|
|
||||||
loadingEl.isRoot = routerOptions.isRoot;
|
|
||||||
this.appendChild(loadingEl);
|
|
||||||
}, LOADING_SCREEN_THRESHOLD);
|
}, LOADING_SCREEN_THRESHOLD);
|
||||||
|
|
||||||
loadProm.then(() => {
|
this._currentLoadProm = loadProm.then(
|
||||||
|
() => {
|
||||||
|
this._currentLoadProm = undefined;
|
||||||
// Check if we're still trying to show the same page.
|
// Check if we're still trying to show the same page.
|
||||||
if (this._currentPage !== newPage) {
|
if (this._currentPage !== newPage) {
|
||||||
return;
|
return;
|
||||||
@ -139,21 +137,56 @@ export class HassRouterPage extends UpdatingElement {
|
|||||||
|
|
||||||
created = true;
|
created = true;
|
||||||
this._createPanel(routerOptions, newPage, routeOptions);
|
this._createPanel(routerOptions, newPage, routeOptions);
|
||||||
});
|
},
|
||||||
|
() => {
|
||||||
|
this._currentLoadProm = undefined;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProps: PropertyValues) {
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
|
|
||||||
const options = (this.constructor as typeof HassRouterPage)._routerOptions;
|
const options = this.routerOptions;
|
||||||
|
|
||||||
if (options.preloadAll) {
|
if (options && options.preloadAll) {
|
||||||
Object.values(options.routes).forEach((route) => route.load());
|
Object.values(options.routes).forEach((route) => route.load());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _updatePageEl(_pageEl, _changedProps?: PropertyValues) {
|
protected createLoadingScreen() {
|
||||||
|
return document.createElement("hass-loading-screen");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rebuild the current panel.
|
||||||
|
*
|
||||||
|
* Promise will resolve when rebuilding is done and DOM updated.
|
||||||
|
*/
|
||||||
|
protected async rebuild(): Promise<void> {
|
||||||
|
const oldRoute = this.route;
|
||||||
|
|
||||||
|
if (oldRoute === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.route = undefined;
|
||||||
|
await this.updateComplete;
|
||||||
|
// Make sure that the parent didn't override this in the meanwhile.
|
||||||
|
if (this.route === undefined) {
|
||||||
|
this.route = oldRoute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Promise that resolves when the page has rendered.
|
||||||
|
*/
|
||||||
|
protected get pageRendered(): Promise<void> {
|
||||||
|
return this.updateComplete.then(() => this._currentLoadProm);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updatePageEl(_pageEl, _changedProps?: PropertyValues) {
|
||||||
// default we do nothing
|
// default we do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +201,7 @@ export class HassRouterPage extends UpdatingElement {
|
|||||||
|
|
||||||
const panelEl =
|
const panelEl =
|
||||||
this._cache[page] || document.createElement(routeOptions.tag);
|
this._cache[page] || document.createElement(routeOptions.tag);
|
||||||
this._updatePageEl(panelEl);
|
this.updatePageEl(panelEl);
|
||||||
this.appendChild(panelEl);
|
this.appendChild(panelEl);
|
||||||
|
|
||||||
if (routerOptions.cacheAll || routeOptions.cache) {
|
if (routerOptions.cacheAll || routeOptions.cache) {
|
||||||
|
@ -1,118 +1,96 @@
|
|||||||
import { property, customElement } from "lit-element";
|
import { property, customElement, PropertyValues } from "lit-element";
|
||||||
import { PolymerElement } from "@polymer/polymer";
|
import { PolymerElement } from "@polymer/polymer";
|
||||||
|
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant, Panels } from "../types";
|
||||||
import { HassRouterPage, RouterOptions } from "./hass-router-page";
|
import {
|
||||||
|
HassRouterPage,
|
||||||
|
RouterOptions,
|
||||||
|
RouteOptions,
|
||||||
|
} from "./hass-router-page";
|
||||||
|
|
||||||
|
const CACHE_COMPONENTS = ["lovelace", "states"];
|
||||||
|
const COMPONENTS = {
|
||||||
|
calendar: () =>
|
||||||
|
import(/* webpackChunkName: "panel-calendar" */ "../panels/calendar/ha-panel-calendar"),
|
||||||
|
config: () =>
|
||||||
|
import(/* webpackChunkName: "panel-config" */ "../panels/config/ha-panel-config"),
|
||||||
|
custom: () =>
|
||||||
|
import(/* webpackChunkName: "panel-custom" */ "../panels/custom/ha-panel-custom"),
|
||||||
|
"dev-event": () =>
|
||||||
|
import(/* webpackChunkName: "panel-dev-event" */ "../panels/dev-event/ha-panel-dev-event"),
|
||||||
|
"dev-info": () =>
|
||||||
|
import(/* webpackChunkName: "panel-dev-info" */ "../panels/dev-info/ha-panel-dev-info"),
|
||||||
|
"dev-mqtt": () =>
|
||||||
|
import(/* webpackChunkName: "panel-dev-mqtt" */ "../panels/dev-mqtt/ha-panel-dev-mqtt"),
|
||||||
|
"dev-service": () =>
|
||||||
|
import(/* webpackChunkName: "panel-dev-service" */ "../panels/dev-service/ha-panel-dev-service"),
|
||||||
|
"dev-state": () =>
|
||||||
|
import(/* webpackChunkName: "panel-dev-state" */ "../panels/dev-state/ha-panel-dev-state"),
|
||||||
|
"dev-template": () =>
|
||||||
|
import(/* webpackChunkName: "panel-dev-template" */ "../panels/dev-template/ha-panel-dev-template"),
|
||||||
|
lovelace: () =>
|
||||||
|
import(/* webpackChunkName: "panel-lovelace" */ "../panels/lovelace/ha-panel-lovelace"),
|
||||||
|
states: () =>
|
||||||
|
import(/* webpackChunkName: "panel-states" */ "../panels/states/ha-panel-states"),
|
||||||
|
history: () =>
|
||||||
|
import(/* webpackChunkName: "panel-history" */ "../panels/history/ha-panel-history"),
|
||||||
|
iframe: () =>
|
||||||
|
import(/* webpackChunkName: "panel-iframe" */ "../panels/iframe/ha-panel-iframe"),
|
||||||
|
kiosk: () =>
|
||||||
|
import(/* webpackChunkName: "panel-kiosk" */ "../panels/kiosk/ha-panel-kiosk"),
|
||||||
|
logbook: () =>
|
||||||
|
import(/* webpackChunkName: "panel-logbook" */ "../panels/logbook/ha-panel-logbook"),
|
||||||
|
mailbox: () =>
|
||||||
|
import(/* webpackChunkName: "panel-mailbox" */ "../panels/mailbox/ha-panel-mailbox"),
|
||||||
|
map: () =>
|
||||||
|
import(/* webpackChunkName: "panel-map" */ "../panels/map/ha-panel-map"),
|
||||||
|
profile: () =>
|
||||||
|
import(/* webpackChunkName: "panel-profile" */ "../panels/profile/ha-panel-profile"),
|
||||||
|
"shopping-list": () =>
|
||||||
|
import(/* webpackChunkName: "panel-shopping-list" */ "../panels/shopping-list/ha-panel-shopping-list"),
|
||||||
|
};
|
||||||
|
|
||||||
|
const getRoutes = (panels: Panels): RouterOptions => {
|
||||||
|
const routes: { [route: string]: RouteOptions } = {};
|
||||||
|
|
||||||
|
Object.values(panels).forEach((panel) => {
|
||||||
|
routes[panel.url_path] = {
|
||||||
|
load: COMPONENTS[panel.component_name],
|
||||||
|
tag: `ha-panel-${panel.component_name}`,
|
||||||
|
cache: CACHE_COMPONENTS.includes(panel.component_name),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
showLoading: true,
|
||||||
|
routes,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
@customElement("partial-panel-resolver")
|
@customElement("partial-panel-resolver")
|
||||||
class PartialPanelResolver extends HassRouterPage {
|
class PartialPanelResolver extends HassRouterPage {
|
||||||
protected static routerOptions: RouterOptions = {
|
|
||||||
isRoot: true,
|
|
||||||
showLoading: true,
|
|
||||||
routes: {
|
|
||||||
calendar: {
|
|
||||||
tag: "ha-panel-calendar",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-calendar" */ "../panels/calendar/ha-panel-calendar"),
|
|
||||||
},
|
|
||||||
config: {
|
|
||||||
tag: "ha-panel-config",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-config" */ "../panels/config/ha-panel-config"),
|
|
||||||
},
|
|
||||||
custom: {
|
|
||||||
tag: "ha-panel-custom",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-custom" */ "../panels/custom/ha-panel-custom"),
|
|
||||||
},
|
|
||||||
"dev-event": {
|
|
||||||
tag: "ha-panel-dev-event",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-dev-event" */ "../panels/dev-event/ha-panel-dev-event"),
|
|
||||||
},
|
|
||||||
"dev-info": {
|
|
||||||
tag: "ha-panel-dev-info",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-dev-info" */ "../panels/dev-info/ha-panel-dev-info"),
|
|
||||||
},
|
|
||||||
"dev-mqtt": {
|
|
||||||
tag: "ha-panel-dev-mqtt",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-dev-mqtt" */ "../panels/dev-mqtt/ha-panel-dev-mqtt"),
|
|
||||||
},
|
|
||||||
"dev-service": {
|
|
||||||
tag: "ha-panel-dev-service",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-dev-service" */ "../panels/dev-service/ha-panel-dev-service"),
|
|
||||||
},
|
|
||||||
"dev-state": {
|
|
||||||
tag: "ha-panel-dev-state",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-dev-state" */ "../panels/dev-state/ha-panel-dev-state"),
|
|
||||||
},
|
|
||||||
"dev-template": {
|
|
||||||
tag: "ha-panel-dev-template",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-dev-template" */ "../panels/dev-template/ha-panel-dev-template"),
|
|
||||||
},
|
|
||||||
lovelace: {
|
|
||||||
cache: true,
|
|
||||||
tag: "ha-panel-lovelace",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-lovelace" */ "../panels/lovelace/ha-panel-lovelace"),
|
|
||||||
},
|
|
||||||
states: {
|
|
||||||
cache: true,
|
|
||||||
tag: "ha-panel-states",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-states" */ "../panels/states/ha-panel-states"),
|
|
||||||
},
|
|
||||||
history: {
|
|
||||||
tag: "ha-panel-history",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-history" */ "../panels/history/ha-panel-history"),
|
|
||||||
},
|
|
||||||
iframe: {
|
|
||||||
tag: "ha-panel-iframe",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-iframe" */ "../panels/iframe/ha-panel-iframe"),
|
|
||||||
},
|
|
||||||
kiosk: {
|
|
||||||
tag: "ha-panel-kiosk",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-kiosk" */ "../panels/kiosk/ha-panel-kiosk"),
|
|
||||||
},
|
|
||||||
logbook: {
|
|
||||||
tag: "ha-panel-logbook",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-logbook" */ "../panels/logbook/ha-panel-logbook"),
|
|
||||||
},
|
|
||||||
mailbox: {
|
|
||||||
tag: "ha-panel-mailbox",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-mailbox" */ "../panels/mailbox/ha-panel-mailbox"),
|
|
||||||
},
|
|
||||||
map: {
|
|
||||||
tag: "ha-panel-map",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-map" */ "../panels/map/ha-panel-map"),
|
|
||||||
},
|
|
||||||
profile: {
|
|
||||||
tag: "ha-panel-profile",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-profile" */ "../panels/profile/ha-panel-profile"),
|
|
||||||
},
|
|
||||||
"shopping-list": {
|
|
||||||
tag: "ha-panel-shopping-list",
|
|
||||||
load: () =>
|
|
||||||
import(/* webpackChunkName: "panel-shopping-list" */ "../panels/shopping-list/ha-panel-shopping-list"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@property() public hass?: HomeAssistant;
|
@property() public hass?: HomeAssistant;
|
||||||
@property() public narrow?: boolean;
|
@property() public narrow?: boolean;
|
||||||
|
|
||||||
protected _updatePageEl(el) {
|
protected updated(changedProps: PropertyValues) {
|
||||||
|
if (!changedProps.has("hass")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldHass = changedProps.get("hass") as this["hass"];
|
||||||
|
|
||||||
|
if (!oldHass || oldHass.panels !== this.hass!.panels) {
|
||||||
|
this._updateRoutes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected createLoadingScreen() {
|
||||||
|
const el = super.createLoadingScreen();
|
||||||
|
el.rootnav = true;
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updatePageEl(el) {
|
||||||
const hass = this.hass!;
|
const hass = this.hass!;
|
||||||
|
|
||||||
if ("setProperties" in el) {
|
if ("setProperties" in el) {
|
||||||
@ -130,6 +108,17 @@ class PartialPanelResolver extends HassRouterPage {
|
|||||||
el.panel = hass.panels[hass.panelUrl];
|
el.panel = hass.panels[hass.panelUrl];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _updateRoutes() {
|
||||||
|
this.routerOptions = getRoutes(this.hass!.panels);
|
||||||
|
await this.rebuild();
|
||||||
|
await this.pageRendered;
|
||||||
|
|
||||||
|
const initEl = document.getElementById("ha-init-skeleton");
|
||||||
|
if (initEl) {
|
||||||
|
initEl.parentElement!.removeChild(initEl);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -13,7 +13,6 @@ import "@polymer/paper-toggle-button/paper-toggle-button";
|
|||||||
import "@polymer/paper-item/paper-item-body";
|
import "@polymer/paper-item/paper-item-body";
|
||||||
// tslint:disable-next-line
|
// tslint:disable-next-line
|
||||||
import { PaperToggleButtonElement } from "@polymer/paper-toggle-button/paper-toggle-button";
|
import { PaperToggleButtonElement } from "@polymer/paper-toggle-button/paper-toggle-button";
|
||||||
import "../../../components/buttons/ha-call-api-button";
|
|
||||||
|
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
@ -22,7 +21,7 @@ import {
|
|||||||
disconnectCloudRemote,
|
disconnectCloudRemote,
|
||||||
CloudStatusLoggedIn,
|
CloudStatusLoggedIn,
|
||||||
} from "../../../data/cloud";
|
} from "../../../data/cloud";
|
||||||
import format_date_time from "../../../common/datetime/format_date_time";
|
import { showCloudCertificateDialog } from "./show-dialog-cloud-certificate";
|
||||||
|
|
||||||
@customElement("cloud-remote-pref")
|
@customElement("cloud-remote-pref")
|
||||||
export class CloudRemotePref extends LitElement {
|
export class CloudRemotePref extends LitElement {
|
||||||
@ -64,46 +63,36 @@ export class CloudRemotePref extends LitElement {
|
|||||||
@change="${this._toggleChanged}"
|
@change="${this._toggleChanged}"
|
||||||
></paper-toggle-button>
|
></paper-toggle-button>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
Home Assistant Cloud provides you with a secure remote connection to
|
Home Assistant Cloud provides a secure remote connection to your
|
||||||
your instance while away from home. Your instance
|
instance while away from home. Your instance
|
||||||
${remote_connected ? "is" : "will be"} available at
|
${remote_connected ? "is" : "will be"} available at
|
||||||
<a href="https://${remote_domain}" target="_blank">
|
<a href="https://${remote_domain}" target="_blank">
|
||||||
https://${remote_domain}</a
|
https://${remote_domain}</a
|
||||||
>.
|
>.
|
||||||
${!remote_certificate
|
|
||||||
? ""
|
|
||||||
: html`
|
|
||||||
<div class="data-row">
|
|
||||||
<paper-item-body two-line>
|
|
||||||
Certificate expiration date
|
|
||||||
<div secondary>Will be automatically renewed</div>
|
|
||||||
</paper-item-body>
|
|
||||||
<div class="data-value">
|
|
||||||
${format_date_time(
|
|
||||||
new Date(remote_certificate.expire_date),
|
|
||||||
this.hass!.language
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="data-row">
|
|
||||||
<paper-item-body>
|
|
||||||
Certificate fingerprint
|
|
||||||
</paper-item-body>
|
|
||||||
<div class="data-value">
|
|
||||||
${remote_certificate.fingerprint}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<a href="https://www.nabucasa.com/config/remote/" target="_blank">
|
<a href="https://www.nabucasa.com/config/remote/" target="_blank">
|
||||||
<mwc-button>Learn how it works</mwc-button>
|
<mwc-button>Learn how it works</mwc-button>
|
||||||
</a>
|
</a>
|
||||||
|
${remote_certificate
|
||||||
|
? html`
|
||||||
|
<div class="spacer"></div>
|
||||||
|
<mwc-button @click=${this._openCertInfo}>
|
||||||
|
Certificate Info
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
</paper-card>
|
</paper-card>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _openCertInfo() {
|
||||||
|
showCloudCertificateDialog(this, {
|
||||||
|
certificateInfo: this.cloudStatus!.remote_certificate!,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private async _toggleChanged(ev) {
|
private async _toggleChanged(ev) {
|
||||||
const toggle = ev.target as PaperToggleButtonElement;
|
const toggle = ev.target as PaperToggleButtonElement;
|
||||||
|
|
||||||
@ -127,12 +116,6 @@ export class CloudRemotePref extends LitElement {
|
|||||||
.preparing {
|
.preparing {
|
||||||
padding: 0 16px 16px;
|
padding: 0 16px 16px;
|
||||||
}
|
}
|
||||||
.data-row {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.data-value {
|
|
||||||
padding: 16px 0;
|
|
||||||
}
|
|
||||||
a {
|
a {
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
@ -141,17 +124,11 @@ export class CloudRemotePref extends LitElement {
|
|||||||
right: 8px;
|
right: 8px;
|
||||||
top: 16px;
|
top: 16px;
|
||||||
}
|
}
|
||||||
ha-call-api-button {
|
.card-actions {
|
||||||
color: var(--primary-color);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
.unlock {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
|
||||||
padding-top: 16px;
|
|
||||||
}
|
}
|
||||||
.unlock > div {
|
.spacer {
|
||||||
flex: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
89
src/panels/config/cloud/dialog-cloud-certificate.ts
Normal file
89
src/panels/config/cloud/dialog-cloud-certificate.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import {
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
property,
|
||||||
|
} from "lit-element";
|
||||||
|
|
||||||
|
import "@material/mwc-button";
|
||||||
|
import "@polymer/paper-dialog/paper-dialog";
|
||||||
|
// This is not a duplicate import, one is for types, one is for element.
|
||||||
|
// tslint:disable-next-line
|
||||||
|
import { PaperDialogElement } from "@polymer/paper-dialog/paper-dialog";
|
||||||
|
|
||||||
|
import { HomeAssistant } from "../../../types";
|
||||||
|
import { haStyle } from "../../../resources/styles";
|
||||||
|
import { CloudCertificateParams as CloudCertificateDialogParams } from "./show-dialog-cloud-certificate";
|
||||||
|
import format_date_time from "../../../common/datetime/format_date_time";
|
||||||
|
|
||||||
|
@customElement("dialog-cloud-certificate")
|
||||||
|
class DialogCloudCertificate extends LitElement {
|
||||||
|
public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property()
|
||||||
|
private _params?: CloudCertificateDialogParams;
|
||||||
|
|
||||||
|
public async showDialog(params: CloudCertificateDialogParams) {
|
||||||
|
this._params = params;
|
||||||
|
// Wait till dialog is rendered.
|
||||||
|
await this.updateComplete;
|
||||||
|
this._dialog.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this._params) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
const { certificateInfo } = this._params;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<paper-dialog with-backdrop>
|
||||||
|
<h2>Certificate Information</h2>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
Certificate expiration date:
|
||||||
|
${format_date_time(
|
||||||
|
new Date(certificateInfo.expire_date),
|
||||||
|
this.hass!.language
|
||||||
|
)}<br />
|
||||||
|
(Will be automatically renewed)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Certificate fingerprint: ${certificateInfo.fingerprint}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="paper-dialog-buttons">
|
||||||
|
<mwc-button @click="${this._closeDialog}">CLOSE</mwc-button>
|
||||||
|
</div>
|
||||||
|
</paper-dialog>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private get _dialog(): PaperDialogElement {
|
||||||
|
return this.shadowRoot!.querySelector("paper-dialog")!;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _closeDialog() {
|
||||||
|
this._dialog.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult[] {
|
||||||
|
return [
|
||||||
|
haStyle,
|
||||||
|
css`
|
||||||
|
paper-dialog {
|
||||||
|
width: 535px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"dialog-cloud-certificate": DialogCloudCertificate;
|
||||||
|
}
|
||||||
|
}
|
18
src/panels/config/cloud/show-dialog-cloud-certificate.ts
Normal file
18
src/panels/config/cloud/show-dialog-cloud-certificate.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
|
import { CertificateInformation } from "../../../data/cloud";
|
||||||
|
|
||||||
|
export interface CloudCertificateParams {
|
||||||
|
certificateInfo: CertificateInformation;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const showCloudCertificateDialog = (
|
||||||
|
element: HTMLElement,
|
||||||
|
webhookDialogParams: CloudCertificateParams
|
||||||
|
): void => {
|
||||||
|
fireEvent(element, "show-dialog", {
|
||||||
|
dialogTag: "dialog-cloud-certificate",
|
||||||
|
dialogImport: () =>
|
||||||
|
import(/* webpackChunkName: "dialog-cloud-certificate" */ "./dialog-cloud-certificate"),
|
||||||
|
dialogParams: webhookDialogParams,
|
||||||
|
});
|
||||||
|
};
|
@ -8,7 +8,11 @@ import { HassRouterPage, RouterOptions } from "../../layouts/hass-router-page";
|
|||||||
|
|
||||||
@customElement("ha-panel-config")
|
@customElement("ha-panel-config")
|
||||||
class HaPanelConfig extends HassRouterPage {
|
class HaPanelConfig extends HassRouterPage {
|
||||||
protected static routerOptions: RouterOptions = {
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public _wideSidebar: boolean = false;
|
||||||
|
@property() public _wide: boolean = false;
|
||||||
|
|
||||||
|
protected routerOptions: RouterOptions = {
|
||||||
defaultPage: "dashboard",
|
defaultPage: "dashboard",
|
||||||
cacheAll: true,
|
cacheAll: true,
|
||||||
preloadAll: true,
|
preloadAll: true,
|
||||||
@ -81,9 +85,6 @@ class HaPanelConfig extends HassRouterPage {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@property() public hass!: HomeAssistant;
|
|
||||||
@property() public _wideSidebar: boolean = false;
|
|
||||||
@property() public _wide: boolean = false;
|
|
||||||
@property() private _cloudStatus?: CloudStatus;
|
@property() private _cloudStatus?: CloudStatus;
|
||||||
|
|
||||||
private _listeners: Array<() => void> = [];
|
private _listeners: Array<() => void> = [];
|
||||||
@ -119,7 +120,7 @@ class HaPanelConfig extends HassRouterPage {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _updatePageEl(el) {
|
protected updatePageEl(el) {
|
||||||
el.route = this.route;
|
el.route = this.route;
|
||||||
el.hass = this.hass;
|
el.hass = this.hass;
|
||||||
el.isWide = this.hass.dockedSidebar ? this._wideSidebar : this._wide;
|
el.isWide = this.hass.dockedSidebar ? this._wideSidebar : this._wide;
|
||||||
|
@ -65,14 +65,13 @@ export class HuiMarkdownCard extends LitElement implements LovelaceCard {
|
|||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
return css`
|
return css`
|
||||||
:host {
|
:host {
|
||||||
/* start paper-font-headline style */
|
/* start paper-font-body1 style */
|
||||||
font-family: "Roboto", "Noto", sans-serif;
|
font-family: "Roboto", "Noto", sans-serif;
|
||||||
-webkit-font-smoothing: antialiased; /* OS X subpixel AA bleed bug */
|
-webkit-font-smoothing: antialiased; /* OS X subpixel AA bleed bug */
|
||||||
text-rendering: optimizeLegibility;
|
font-size: 14px;
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
letter-spacing: -0.012em;
|
line-height: 20px;
|
||||||
/* end paper-font-headline style */
|
/* end paper-font-body1 style */
|
||||||
}
|
}
|
||||||
ha-markdown {
|
ha-markdown {
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -85,7 +85,7 @@ class LovelacePanel extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hass-loading-screen></hass-loading-screen>
|
<hass-loading-screen rootnav></hass-loading-screen>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,7 +606,8 @@
|
|||||||
"caption": "ZHA",
|
"caption": "ZHA",
|
||||||
"description": "ניהול רשת Zigbee לאוטומציה ביתית",
|
"description": "ניהול רשת Zigbee לאוטומציה ביתית",
|
||||||
"services": {
|
"services": {
|
||||||
"reconfigure": "התקן מחדש את התקן ה ZHA. השתמש באפשרות זו אם אתה נתקל בבעיות בהתקן. אם ההתקן המדובר הוא התקן המופעל באמצעות סוללות, ודא שהוא ער ויכול לקבל פקודות בעת שימוש בשירות זה."
|
"reconfigure": "התקן מחדש את התקן ה ZHA. השתמש באפשרות זו אם אתה נתקל בבעיות בהתקן. אם ההתקן המדובר הוא התקן המופעל באמצעות סוללות, ודא שהוא ער ויכול לקבל פקודות בעת שימוש בשירות זה.",
|
||||||
|
"updateDeviceName": "הגדר שם מותאם אישית עבור התקן זה במאגר ההתקנים."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"area_registry": {
|
"area_registry": {
|
||||||
@ -616,7 +617,9 @@
|
|||||||
"header": "מאגר האזורים",
|
"header": "מאגר האזורים",
|
||||||
"introduction": "אזורים משמשים לארגון המיקום של ההתקנים. Home Assistant יעשה שימוש במידע זה בכדי לסייע לך בארגון הממשק, ההרשאות והאינטגרציות שלך עם מערכות אחרות.",
|
"introduction": "אזורים משמשים לארגון המיקום של ההתקנים. Home Assistant יעשה שימוש במידע זה בכדי לסייע לך בארגון הממשק, ההרשאות והאינטגרציות שלך עם מערכות אחרות.",
|
||||||
"introduction2": "כדי למקם התקנים באזור זה, השתמש בקישור הבא כדי לנווט אל דף האינטגרציות ולאחר מכן לחץ על אינטגרציה מוגדרת כדי להגיע לכרטיסי המכשיר.",
|
"introduction2": "כדי למקם התקנים באזור זה, השתמש בקישור הבא כדי לנווט אל דף האינטגרציות ולאחר מכן לחץ על אינטגרציה מוגדרת כדי להגיע לכרטיסי המכשיר.",
|
||||||
"integrations_page": "דף אינטגרציות"
|
"integrations_page": "דף אינטגרציות",
|
||||||
|
"no_areas": "נראה שאין לך אזורים עדיין!",
|
||||||
|
"create_area": "צור אזור"
|
||||||
},
|
},
|
||||||
"no_areas": "נראה שעדיין אין אזורים!",
|
"no_areas": "נראה שעדיין אין אזורים!",
|
||||||
"create_area": "צור איזור",
|
"create_area": "צור איזור",
|
||||||
@ -830,11 +833,13 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"name": "שם",
|
"name": "שם",
|
||||||
"username": "שם משתמש",
|
"username": "שם משתמש",
|
||||||
"password": "סיסמה"
|
"password": "סיסמה",
|
||||||
|
"password_confirm": "אשר סיסמה"
|
||||||
},
|
},
|
||||||
"create_account": "צור חשבון",
|
"create_account": "צור חשבון",
|
||||||
"error": {
|
"error": {
|
||||||
"required_fields": "מלא את כל השדות הדרושים"
|
"required_fields": "מלא את כל השדות הדרושים",
|
||||||
|
"password_not_match": "הסיסמאות אינן תואמות"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1156,5 +1161,10 @@
|
|||||||
"auto": "Auto"
|
"auto": "Auto"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"groups": {
|
||||||
|
"system-admin": "מנהלים",
|
||||||
|
"system-users": "משתמשים",
|
||||||
|
"system-read-only": "משתמשים לקריאה בלבד"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -606,7 +606,8 @@
|
|||||||
"caption": "ZHA",
|
"caption": "ZHA",
|
||||||
"description": "Zigbee Home Automation hálózat menedzsment",
|
"description": "Zigbee Home Automation hálózat menedzsment",
|
||||||
"services": {
|
"services": {
|
||||||
"reconfigure": "A ZHA készülék újratelepítése (eszköz rendbehozatala). Ezt a funkciót használd, ha problémáid vannak a készülékkel. Ha a kérdéses eszköz akkumulátoros, győződj meg róla, hogy nincs alvó állapotban és fogadja a parancsokat, amikor ezt a szolgáltatást használod."
|
"reconfigure": "A ZHA készülék újratelepítése (eszköz rendbehozatala). Ezt a funkciót használd, ha problémáid vannak a készülékkel. Ha a kérdéses eszköz akkumulátoros, győződj meg róla, hogy nincs alvó állapotban és fogadja a parancsokat, amikor ezt a szolgáltatást használod.",
|
||||||
|
"updateDeviceName": "Egyedi név beállítása ehhez az eszközhöz az eszköz nyilvántartásban"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"area_registry": {
|
"area_registry": {
|
||||||
@ -616,9 +617,11 @@
|
|||||||
"header": "Terület Nyilvántartás",
|
"header": "Terület Nyilvántartás",
|
||||||
"introduction": "A területekkel az eszközök elhelyezkedés szerint rendszerezhetők. Ezen információk felhasználásával a Home Assistant segíteni tud előkészíteni a felületet, a jogosultságokat és az integrációt más rendszerekkel.",
|
"introduction": "A területekkel az eszközök elhelyezkedés szerint rendszerezhetők. Ezen információk felhasználásával a Home Assistant segíteni tud előkészíteni a felületet, a jogosultságokat és az integrációt más rendszerekkel.",
|
||||||
"introduction2": "Az eszközök területekbe történő elhelyezéséhez használd az alábbi linket az integrációs oldalra való navigáláshoz, majd kattints egy konfigurált integrációra az eszközkártyák eléréséhez.",
|
"introduction2": "Az eszközök területekbe történő elhelyezéséhez használd az alábbi linket az integrációs oldalra való navigáláshoz, majd kattints egy konfigurált integrációra az eszközkártyák eléréséhez.",
|
||||||
"integrations_page": "Integrációk oldal"
|
"integrations_page": "Integrációk oldal",
|
||||||
|
"no_areas": "Úgy tűnik, nem hoztál még létre egy területet sem!",
|
||||||
|
"create_area": "TERÜLET LÉTREHOZÁSA"
|
||||||
},
|
},
|
||||||
"no_areas": "Úgy tűnik nem hoztál létre még egy területet sem!",
|
"no_areas": "Úgy tűnik, nem hoztál még létre egy területet sem!",
|
||||||
"create_area": "TERÜLET LÉTREHOZÁSA",
|
"create_area": "TERÜLET LÉTREHOZÁSA",
|
||||||
"editor": {
|
"editor": {
|
||||||
"default_name": "Új Terület",
|
"default_name": "Új Terület",
|
||||||
@ -830,11 +833,13 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"name": "Név",
|
"name": "Név",
|
||||||
"username": "Felhasználónév",
|
"username": "Felhasználónév",
|
||||||
"password": "Jelszó"
|
"password": "Jelszó",
|
||||||
|
"password_confirm": "Jelszó megerősítése"
|
||||||
},
|
},
|
||||||
"create_account": "Fiók Létrehozása",
|
"create_account": "Fiók Létrehozása",
|
||||||
"error": {
|
"error": {
|
||||||
"required_fields": "Töltsd ki az összes szükséges mezőt"
|
"required_fields": "Töltsd ki az összes szükséges mezőt",
|
||||||
|
"password_not_match": "A jelszavak nem egyeznek"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1156,5 +1161,10 @@
|
|||||||
"auto": "Automatikus"
|
"auto": "Automatikus"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"groups": {
|
||||||
|
"system-admin": "Adminisztrátorok",
|
||||||
|
"system-users": "Felhasználók",
|
||||||
|
"system-read-only": "Csak olvasható felhasználók"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -606,7 +606,8 @@
|
|||||||
"caption": "ZHA",
|
"caption": "ZHA",
|
||||||
"description": "Zigbee 홈 자동화 네트워크 관리",
|
"description": "Zigbee 홈 자동화 네트워크 관리",
|
||||||
"services": {
|
"services": {
|
||||||
"reconfigure": "ZHA 장치를 다시 구성 합니다. (장치 복구). 장치에 문제가 있는 경우 사용해주세요. 장치가 배터리로 작동하는 경우, 이 서비스를 사용할 때 장치가 켜져있고 통신이 가능한 상태인지 확인해주세요."
|
"reconfigure": "ZHA 장치를 다시 구성 합니다. (장치 복구). 장치에 문제가 있는 경우 사용해주세요. 장치가 배터리로 작동하는 경우, 이 서비스를 사용할 때 장치가 켜져있고 통신이 가능한 상태인지 확인해주세요.",
|
||||||
|
"updateDeviceName": "이 장치의 사용자 정의 이름을 장치 레지스트리에 설정합니다."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"area_registry": {
|
"area_registry": {
|
||||||
@ -616,7 +617,9 @@
|
|||||||
"header": "영역 등록",
|
"header": "영역 등록",
|
||||||
"introduction": "영역은 장치가있는 위치를 구성하는데 사용합니다. 이 정보는 Home Assistant 의 인터페이스 정리, 권한 및 다른 시스템과의 통합 구성에 도움을 줍니다.",
|
"introduction": "영역은 장치가있는 위치를 구성하는데 사용합니다. 이 정보는 Home Assistant 의 인터페이스 정리, 권한 및 다른 시스템과의 통합 구성에 도움을 줍니다.",
|
||||||
"introduction2": "특정 영역에 장치를 배치하려면 아래 링크를 따라 통합 구성요소 페이지로 이동 한 다음, 설정된 구성요소의 장치를 클릭하여 영역을 설정 할 수 있습니다.",
|
"introduction2": "특정 영역에 장치를 배치하려면 아래 링크를 따라 통합 구성요소 페이지로 이동 한 다음, 설정된 구성요소의 장치를 클릭하여 영역을 설정 할 수 있습니다.",
|
||||||
"integrations_page": "통합 구성요소 페이지"
|
"integrations_page": "통합 구성요소 페이지",
|
||||||
|
"no_areas": "등록된 영역이 없습니다. 거실, 침실과 같이 영역을 등록해보세요!",
|
||||||
|
"create_area": "영역 만들기"
|
||||||
},
|
},
|
||||||
"no_areas": "등록된 영역이 없습니다. 거실, 침실과 같이 영역을 등록해보세요!",
|
"no_areas": "등록된 영역이 없습니다. 거실, 침실과 같이 영역을 등록해보세요!",
|
||||||
"create_area": "영역 만들기",
|
"create_area": "영역 만들기",
|
||||||
@ -830,11 +833,13 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"name": "이름",
|
"name": "이름",
|
||||||
"username": "사용자 이름",
|
"username": "사용자 이름",
|
||||||
"password": "비밀번호"
|
"password": "비밀번호",
|
||||||
|
"password_confirm": "비밀번호 확인"
|
||||||
},
|
},
|
||||||
"create_account": "계정 만들기",
|
"create_account": "계정 만들기",
|
||||||
"error": {
|
"error": {
|
||||||
"required_fields": "필수 입력란을 모두 채워주세요"
|
"required_fields": "필수 입력란을 모두 채워주세요",
|
||||||
|
"password_not_match": "비밀번호가 일치하지 않습니다"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1156,5 +1161,10 @@
|
|||||||
"auto": "자동"
|
"auto": "자동"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"groups": {
|
||||||
|
"system-admin": "관리자",
|
||||||
|
"system-users": "사용자",
|
||||||
|
"system-read-only": "읽기 전용 사용자"
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user