Merge pull request #5198 from home-assistant/dev

20200313.0
This commit is contained in:
Bram Kragten 2020-03-13 20:39:21 +01:00 committed by GitHub
commit 4b2edde81b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 314 additions and 158 deletions

View File

@ -1,6 +1,14 @@
module.exports = {
isProdBuild: process.env.NODE_ENV === "production",
isStatsBuild: process.env.STATS === "1",
isTravis: process.env.TRAVIS === "true",
isNetlify: process.env.NETLIFY === "true",
isProdBuild() {
return process.env.NODE_ENV === "production";
},
isStatsBuild() {
return process.env.STATS === "1";
},
isTravis() {
return process.env.TRAVIS === "true";
},
isNetlify() {
return process.env.NETLIFY === "true";
},
};

View File

@ -42,7 +42,7 @@ gulp.task(
"copy-static",
"webpack-prod-app",
...// Don't compress running tests
(envVars.isTravis ? [] : ["compress-app"]),
(envVars.isTravis() ? [] : ["compress-app"]),
gulp.parallel(
"gen-pages-prod",
"gen-index-app-prod",

View File

@ -29,6 +29,6 @@ gulp.task(
gulp.parallel("gen-icons-hassio", "gen-icons-mdi"),
"webpack-prod-hassio",
...// Don't compress running tests
(envVars.isTravis ? [] : ["compress-hassio"])
(envVars.isTravis() ? [] : ["compress-hassio"])
)
);

View File

@ -292,10 +292,11 @@ gulp.task(
function fingerprintTranslationFiles() {
// Fingerprint full file of each language
const files = fs.readdirSync(fullDir);
for (let i = 0; i < files.length; i++) {
fingerprints[files[i].split(".")[0]] = {
// In dev we create fake hashes
hash: env.isProdBuild
hash: env.isProdBuild()
? crypto
.createHash("md5")
.update(fs.readFileSync(path.join(fullDir, files[i]), "utf-8"))
@ -332,7 +333,7 @@ gulp.task(
gulp.series(
"clean-translations",
"ensure-translations-build-dir",
env.isProdBuild ? (done) => done() : "create-test-translation",
env.isProdBuild() ? (done) => done() : "create-test-translation",
"build-master-translation",
"build-merged-translations",
gulp.parallel(...splitTasks),

View File

@ -155,7 +155,7 @@ const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
`/static/translations/${englishFilename}`
] = `build-translations/output/${englishFilename}`;
Object.keys(translationMetadata.fragments).forEach((fragment) => {
translationMetadata.fragments.forEach((fragment) => {
workBoxTranslationsTemplatedURLs[
`/static/translations/${fragment}/${englishFilename}`
] = `build-translations/output/${fragment}/${englishFilename}`;

View File

@ -6,6 +6,6 @@ const { isProdBuild } = require("../build-scripts/env.js");
const latestBuild = true;
module.exports = createCastConfig({
isProdBuild,
isProdBuild: isProdBuild(),
latestBuild,
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

View File

@ -6,7 +6,7 @@ const { isProdBuild, isStatsBuild } = require("../build-scripts/env.js");
const latestBuild = true;
module.exports = createDemoConfig({
isProdBuild,
isStatsBuild,
isProdBuild: isProdBuild(),
isStatsBuild: isStatsBuild(),
latestBuild,
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View File

@ -7,7 +7,7 @@ export const createMediaPlayerEntities = () => [
media_title: "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)",
media_artist: "Technohead",
supported_features: 64063,
entity_picture: "/images/album_cover.jpg",
entity_picture: "/images/album_cover_2.jpg",
media_duration: 300,
media_position: 50,
media_position_updated_at: new Date(

View File

@ -4,6 +4,7 @@ import { PolymerElement } from "@polymer/polymer/polymer-element";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
import { createMediaPlayerEntities } from "../data/media_players";
import "../../../src/panels/lovelace/cards/hui-media-control-card";
const CONFIGS = [
{

View File

@ -6,6 +6,6 @@ const { isProdBuild } = require("../build-scripts/env.js");
const latestBuild = false;
module.exports = createHassioConfig({
isProdBuild,
isProdBuild: isProdBuild(),
latestBuild,
});

View File

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

View File

@ -14,7 +14,7 @@ export const SUPPORT_SELECT_SOURCE = 2048;
export const SUPPORT_STOP = 4096;
export const SUPPORTS_PLAY = 16384;
export const SUPPORT_SELECT_SOUND_MODE = 65536;
export const CONTRAST_RATIO = 3.5;
export const CONTRAST_RATIO = 4.5;
export interface MediaPlayerThumbnail {
content_type: string;

View File

@ -56,7 +56,8 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
lovelaceConfig,
maxEntities,
entities,
entitiesFill
entitiesFill,
["light", "switch"]
);
return {

View File

@ -51,10 +51,11 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
lovelaceConfig,
maxEntities,
entities,
entitiesFill
entitiesFill,
["light", "switch", "sensor"]
);
return { entities: foundEntities };
return { title: "My Title", entities: foundEntities };
}
@property() private _config?: EntitiesCardConfig;

View File

@ -312,8 +312,8 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
line-height: calc(var(--base-unit) * 0.3);
position: absolute;
width: calc(var(--base-unit) * 4);
height: calc(var(--base-unit) * 2.1);
top: calc(var(--base-unit) * 1.2);
height: var(--base-unit);
top: var(--base-unit);
margin-left: auto;
margin-right: auto;
}
@ -322,6 +322,7 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
}
.gauge-data #percent {
font-size: calc(var(--base-unit) * 0.55);
line-height: calc(var(--base-unit) * 0.55);
}
.gauge-data #name {
padding-top: calc(var(--base-unit) * 0.15);

View File

@ -47,7 +47,7 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard {
lovelaceConfig: LovelaceConfig,
entities?: string[],
entitiesFill?: string[]
): object {
): GlanceCardConfig {
const includeDomains = ["sensor"];
const maxEntities = 3;
const foundEntities = findEntities(
@ -59,7 +59,7 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard {
includeDomains
);
return { entities: foundEntities };
return { type: "glance", entities: foundEntities };
}
@property() public hass?: HomeAssistant;

View File

@ -12,7 +12,7 @@ import {
import { classMap } from "lit-html/directives/class-map";
import { styleMap } from "lit-html/directives/style-map";
import Vibrant from "node-vibrant";
import { Palette } from "node-vibrant/lib/color";
import { Swatch } from "node-vibrant/lib/color";
import "@polymer/paper-icon-button/paper-icon-button";
import "@polymer/paper-progress/paper-progress";
// tslint:disable-next-line: no-duplicate-imports
@ -59,6 +59,107 @@ function getContrastRatio(
return Math.round((contrast(rgb1, rgb2) + Number.EPSILON) * 100) / 100;
}
// How much the total diff between 2 RGB colors can be
// to be considered similar.
const COLOR_SIMILARITY_THRESHOLD = 150;
// For debug purposes, is being tree shaken.
const DEBUG_COLOR = __DEV__ && false;
const logColor = (
color: Swatch,
label: string = `${color.getHex()} - ${color.getPopulation()}`
) =>
// tslint:disable-next-line:no-console
console.log(
`%c${label}`,
`color: ${color.getBodyTextColor()}; background-color: ${color.getHex()}`
);
const customGenerator = (colors: Swatch[]) => {
colors.sort((colorA, colorB) => colorB.population - colorA.population);
const backgroundColor = colors[0];
let foregroundColor: string | undefined;
const contrastRatios = new Map<Swatch, number>();
const approvedContrastRatio = (color: Swatch) => {
if (!contrastRatios.has(color)) {
contrastRatios.set(
color,
getContrastRatio(backgroundColor.rgb, color.rgb)
);
}
return contrastRatios.get(color)! > CONTRAST_RATIO;
};
// We take each next color and find one that has better contrast.
for (let i = 1; i < colors.length && foregroundColor === undefined; i++) {
// If this color matches, score, take it.
if (approvedContrastRatio(colors[i])) {
if (DEBUG_COLOR) {
logColor(colors[i], "PICKED");
}
foregroundColor = colors[i].hex;
break;
}
// This color has the wrong contrast ratio, but it is the right color.
// Let's find similar colors that might have the right contrast ratio
const currentColor = colors[i];
if (DEBUG_COLOR) {
logColor(colors[i], "Finding similar color with better contrast");
}
for (let j = i + 1; j < colors.length; j++) {
const compareColor = colors[j];
// difference. 0 is same, 765 max difference
const diffScore =
Math.abs(currentColor.rgb[0] - compareColor.rgb[0]) +
Math.abs(currentColor.rgb[1] - compareColor.rgb[1]) +
Math.abs(currentColor.rgb[2] - compareColor.rgb[2]);
if (DEBUG_COLOR) {
logColor(colors[j], `${colors[j].hex} - ${diffScore}`);
}
if (diffScore > COLOR_SIMILARITY_THRESHOLD) {
continue;
}
if (approvedContrastRatio(compareColor)) {
if (DEBUG_COLOR) {
logColor(compareColor, "PICKED");
}
foregroundColor = compareColor.hex;
break;
}
}
}
if (foregroundColor === undefined) {
foregroundColor = backgroundColor.bodyTextColor;
}
if (DEBUG_COLOR) {
// tslint:disable-next-line:no-console
console.log();
// tslint:disable-next-line:no-console
console.log(
"%cPicked colors",
`color: ${foregroundColor}; background-color: ${backgroundColor.hex}; font-weight: bold; padding: 16px;`
);
colors.forEach((color) => logColor(color));
// tslint:disable-next-line:no-console
console.log();
}
return [foregroundColor, backgroundColor.hex];
};
interface ControlButton {
icon: string;
action: string;
@ -594,50 +695,11 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
}
Vibrant.from(this._image)
.quality(1)
.useGenerator(customGenerator)
.getPalette()
.then((palette: Palette) => {
const paletteColors: any[] = [];
Object.keys(palette).forEach((color) => {
paletteColors.push({
hex: palette[color]!.getHex(),
rgb: palette[color]!.getRgb(),
textColor: palette[color]!.getBodyTextColor(),
population: palette[color]!.getPopulation(),
});
});
if (!paletteColors.length) {
this._foregroundColor = undefined;
this._backgroundColor = undefined;
return;
}
paletteColors.sort((colorA, colorB) => {
if (colorA.population > colorB.population) {
return -1;
}
if (colorA.population < colorB.population) {
return 1;
}
return 0;
});
this._backgroundColor = paletteColors[0].hex;
for (let i = 1; i < paletteColors.length; i++) {
if (
getContrastRatio(paletteColors[0].rgb, paletteColors[i].rgb) >=
CONTRAST_RATIO
) {
this._foregroundColor = paletteColors[i].hex;
return;
}
}
this._foregroundColor = paletteColors[0].textColor;
.then(([foreground, background]: [string, string]) => {
this._backgroundColor = background;
this._foregroundColor = foreground;
})
.catch((err: any) => {
// tslint:disable-next-line:no-console

View File

@ -32,8 +32,7 @@ export class HuiPictureCard extends LitElement implements LovelaceCard {
}
public static getStubConfig(): object {
return {
image:
"https://www.home-assistant.io/images/merchandise/shirt-frontpage.png",
image: "https://demo.home-assistant.io/stub_config/t-shirt-promo.png",
tap_action: { action: "none" },
hold_action: { action: "none" },
};

View File

@ -25,26 +25,30 @@ class HuiPictureElementsCard extends LitElement implements LovelaceCard {
lovelaceConfig: LovelaceConfig,
entities?: string[],
entitiesFill?: string[]
): object {
): PictureElementsCardConfig {
const maxEntities = 1;
const foundEntities = findEntities(
hass,
lovelaceConfig,
maxEntities,
entities,
entitiesFill
entitiesFill,
["sensor", "binary_sensor"]
);
return {
type: "picture-elements",
elements: [
{
type: "state-badge",
entity: foundEntities[0] || "",
style: "position: absolute, transform: translate(-50%, -50%)",
style: {
top: "32%",
left: "40%",
},
},
],
image:
"https://www.home-assistant.io/images/merchandise/shirt-frontpage.png",
image: "https://demo.home-assistant.io/stub_config/floorplan.png",
};
}

View File

@ -52,13 +52,13 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard {
lovelaceConfig,
maxEntities,
entities,
entitiesFill
entitiesFill,
["light", "switch"]
);
return {
entity: foundEntities[0] || "",
image:
"https://www.home-assistant.io/images/merchandise/shirt-frontpage.png",
image: "https://demo.home-assistant.io/stub_config/bedroom.png",
};
}

View File

@ -49,19 +49,21 @@ class HuiPictureGlanceCard extends LitElement implements LovelaceCard {
lovelaceConfig: LovelaceConfig,
entities?: string[],
entitiesFill?: string[]
): object {
): PictureGlanceCardConfig {
const maxEntities = 2;
const foundEntities = findEntities(
hass,
lovelaceConfig,
maxEntities,
entities,
entitiesFill
entitiesFill,
["sensor", "binary_sensor"]
);
return {
image:
"https://www.home-assistant.io/images/merchandise/shirt-frontpage.png",
type: "picture-glance",
title: "Kitchen",
image: "https://demo.home-assistant.io/stub_config/kitchen.png",
entities: foundEntities,
};
}

View File

@ -115,7 +115,7 @@ export interface GlanceCardConfig extends LovelaceCardConfig {
show_icon?: boolean;
title?: string;
theme?: string;
entities: ConfigEntity[];
entities: Array<string | ConfigEntity>;
columns?: number;
state_color?: boolean;
}
@ -177,7 +177,7 @@ export interface PictureElementsCardConfig extends LovelaceCardConfig {
camera_image?: string;
camera_view?: HuiImage["cameraView"];
state_image?: {};
state_filter: string[];
state_filter?: string[];
aspect_ratio?: string;
entity?: string;
elements: LovelaceElementConfig[];
@ -202,13 +202,13 @@ export interface PictureEntityCardConfig extends LovelaceCardConfig {
}
export interface PictureGlanceCardConfig extends LovelaceCardConfig {
entities: PictureGlanceEntityConfig[];
entities: Array<string | PictureGlanceEntityConfig>;
title?: string;
image?: string;
camera_image?: string;
camera_view?: HuiImage["cameraView"];
state_image?: {};
state_filter: string[];
state_filter?: string[];
aspect_ratio?: string;
entity?: string;
tap_action?: ActionConfig;

View File

@ -44,7 +44,7 @@ const addEntities = (entities: Set<string>, obj) => {
if (obj.entity) {
addEntityId(entities, obj.entity);
}
if (obj.entities) {
if (obj.entities && Array.isArray(obj.entities)) {
obj.entities.forEach((entity) => addEntityId(entities, entity));
}
if (obj.card) {

View File

@ -30,6 +30,10 @@ class HuiMarquee extends LitElement {
protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
if (changedProperties.has("text") && this._animating) {
this._animating = false;
}
if (
changedProperties.has("active") &&
this.active &&
@ -69,6 +73,7 @@ class HuiMarquee extends LitElement {
position: relative;
align-items: center;
height: 1em;
contain: strict;
}
.marquee-inner {
@ -77,7 +82,6 @@ class HuiMarquee extends LitElement {
right: 0;
text-overflow: ellipsis;
overflow: hidden;
animation: marquee 10s linear infinite paused;
}
:host(.hovering) .marquee-inner {
@ -88,13 +92,10 @@ class HuiMarquee extends LitElement {
:host([animating]) .marquee-inner {
left: initial;
right: initial;
animation: marquee 10s linear infinite;
}
:host([animating]) > div {
animation-play-state: running;
}
span {
:host([animating]) .marquee-inner span {
padding-right: 16px;
}

View File

@ -5,7 +5,6 @@ import "../cards/hui-glance-card";
import "../cards/hui-history-graph-card";
import "../cards/hui-horizontal-stack-card";
import "../cards/hui-light-card";
import "../cards/hui-media-control-card";
import "../cards/hui-sensor-card";
import "../cards/hui-thermostat-card";
import "../cards/hui-vertical-stack-card";
@ -25,7 +24,6 @@ const ALWAYS_LOADED_TYPES = new Set([
"history-graph",
"horizontal-stack",
"light",
"media-control",
"sensor",
"thermostat",
"vertical-stack",
@ -36,6 +34,7 @@ const LAZY_LOAD_TYPES = {
"alarm-panel": () => import("../cards/hui-alarm-panel-card"),
"empty-state": () => import("../cards/hui-empty-state-card"),
"entity-filter": () => import("../cards/hui-entity-filter-card"),
"media-control": () => import("../cards/hui-media-control-card"),
"picture-elements": () => import("../cards/hui-picture-elements-card"),
"picture-entity": () => import("../cards/hui-picture-entity-card"),
"picture-glance": () => import("../cards/hui-picture-glance-card"),

View File

@ -2,22 +2,31 @@ import { HomeAssistant } from "../../../types";
import { Condition } from "../common/validate-condition";
import { ActionConfig } from "../../../data/lovelace";
export interface LovelaceElementConfig {
interface LovelaceElementConfigBase {
type: string;
style: object;
}
export type LovelaceElementConfig =
| ConditionalElementConfig
| IconElementConfig
| ImageElementConfig
| ServiceButtonElementConfig
| StateBadgeElementConfig
| StateIconElementConfig
| StateLabelElementConfig;
export interface LovelaceElement extends HTMLElement {
hass?: HomeAssistant;
setConfig(config: LovelaceElementConfig): void;
}
export interface ConditionalElementConfig extends LovelaceElementConfig {
export interface ConditionalElementConfig extends LovelaceElementConfigBase {
conditions: Condition[];
elements: LovelaceElementConfig[];
elements: LovelaceElementConfigBase[];
}
export interface IconElementConfig extends LovelaceElementConfig {
export interface IconElementConfig extends LovelaceElementConfigBase {
entity?: string;
name?: string;
tap_action?: ActionConfig;
@ -26,7 +35,7 @@ export interface IconElementConfig extends LovelaceElementConfig {
icon: string;
}
export interface ImageElementConfig extends LovelaceElementConfig {
export interface ImageElementConfig extends LovelaceElementConfigBase {
entity?: string;
tap_action?: ActionConfig;
hold_action?: ActionConfig;
@ -39,13 +48,13 @@ export interface ImageElementConfig extends LovelaceElementConfig {
aspect_ratio?: string;
}
export interface ServiceButtonElementConfig extends LovelaceElementConfig {
export interface ServiceButtonElementConfig extends LovelaceElementConfigBase {
title?: string;
service?: string;
service_data?: object;
}
export interface StateBadgeElementConfig extends LovelaceElementConfig {
export interface StateBadgeElementConfig extends LovelaceElementConfigBase {
entity: string;
title?: string;
tap_action?: ActionConfig;
@ -53,7 +62,7 @@ export interface StateBadgeElementConfig extends LovelaceElementConfig {
double_tap_action?: ActionConfig;
}
export interface StateIconElementConfig extends LovelaceElementConfig {
export interface StateIconElementConfig extends LovelaceElementConfigBase {
entity: string;
tap_action?: ActionConfig;
hold_action?: ActionConfig;
@ -62,7 +71,7 @@ export interface StateIconElementConfig extends LovelaceElementConfig {
state_color?: boolean;
}
export interface StateLabelElementConfig extends LovelaceElementConfig {
export interface StateLabelElementConfig extends LovelaceElementConfigBase {
entity: string;
attribute?: string;
prefix?: string;

View File

@ -649,8 +649,12 @@
"name": "Nom"
},
"input_datetime": {
"date": "Data",
"datetime": "Data i hora",
"has_date": "Data",
"has_time": "Hora"
"has_time": "Hora",
"mode": "Què vols introduir",
"time": "Hora"
},
"input_number": {
"max": "Valor màxim",
@ -1299,7 +1303,8 @@
"device": "Dispositiu",
"integration": "Integració",
"manufacturer": "Fabricant",
"model": "Model"
"model": "Model",
"no_devices": "Sense dispositius"
},
"description": "Gestiona els dispositius connectats",
"details": "Aquí tens tots els detalls del dispositiu.",
@ -1395,6 +1400,7 @@
},
"picker": {
"headers": {
"entity_id": "ID de l'entitat",
"name": "Nom",
"type": "Tipus"
}
@ -1487,6 +1493,7 @@
"require_admin": "Només administrador",
"show_sidebar": "Mostra a la barra lateral",
"title": "Títol de la barra lateral",
"title_required": "El títol és necessari.",
"update": "Actualitza",
"url": "URL"
},
@ -1494,6 +1501,7 @@
"add_dashboard": "Afegeix panell",
"headers": {
"conf_mode": "Mètode de configuració",
"default": "Per defecte",
"filename": "Nom de l'arxiu",
"require_admin": "Només administrador",
"sidebar": "Mostra a la barra lateral",
@ -1524,7 +1532,8 @@
"headers": {
"type": "Tipus",
"url": "URL"
}
},
"no_resources": "Sense recursos"
},
"refresh_body": "Has dactualitzar la pàgina per completar leliminació. Vols actualitzar-la ara?",
"refresh_header": "Vols actualitzar?",
@ -2060,13 +2069,17 @@
"name": "Panell d'alarma"
},
"button": {
"description": "La targeta botó et permet afegir botons per realitzar diferents tasques.",
"name": "Botó"
},
"conditional": {
"card": "Targeta",
"conditions": "Condicions",
"current_state": "actual",
"name": "Condicional"
"description": "La targeta condicional mostra una altra targeta en funció dels estats d'una entitat.",
"name": "Condicional",
"state_equal": "L'estat és igual a",
"state_not_equal": "L'estat NO és igual a"
},
"config": {
"optional": "Opcional",
@ -2103,6 +2116,7 @@
"icon": "Icona",
"icon_height": "Alçada de la icona",
"image": "Ruta de la imatge",
"manual": "Manual",
"maximum": "Màxim",
"minimum": "Mínim",
"name": "Nom",
@ -2216,7 +2230,10 @@
"move_right": "Desplaça la visualització cap a la dreta",
"tab_badges": "Etiquetes",
"tab_settings": "Configuració",
"tab_visibility": "Visibilitat"
"tab_visibility": "Visibilitat",
"visibility": {
"select_users": "Selecciona quins usuaris podran veure aquesta vista a la navegació"
}
},
"header": "Editar la interfície d'usuari (UI)",
"menu": {
@ -2287,9 +2304,12 @@
},
"views": {
"confirm_delete": "Estàs segur que vols eliminar aquesta visualització?",
"confirm_delete_existing_cards": "Si elimines aquesta vista, també s'eliminaran les targetes que conté",
"confirm_delete_text": "Estàs segur que vols eliminar la vista '{name}'?",
"existing_cards": "No pots suprimir una visualització si conté targetes, elimina-les primer."
},
"warning": {
"attribute_not_found": "L'atribut {attribute} de {entity} no està disponible.",
"entity_non_numeric": "Entitat no numèrica: {entity}",
"entity_not_found": "Entitat no disponible: {entity}"
}

View File

@ -1317,7 +1317,8 @@
"device": "Gerät",
"integration": "Integration",
"manufacturer": "Hersteller",
"model": "Modell"
"model": "Modell",
"no_devices": "keine Geräte"
},
"description": "Verwalte verbundene Geräte",
"details": "Hier sind alle Details deines Geräts.",
@ -1559,7 +1560,8 @@
"headers": {
"type": "Typ",
"url": "Url"
}
},
"no_resources": "keine Ressourcen"
},
"refresh_body": "Sie müssen die Seite aktualisieren, um das Entfernen abzuschließen. Möchten Sie jetzt aktualisieren?",
"refresh_header": "Möchten Sie aktualisieren?",
@ -2275,7 +2277,10 @@
"move_right": "Ansicht nach rechts verschieben",
"tab_badges": "Abzeichen",
"tab_settings": "Einstellungen",
"tab_visibility": "Sichtweite"
"tab_visibility": "Sichtweite",
"visibility": {
"select_users": "Wähle aus, welche Benutzer diese Ansicht in der Navigation sehen sollen"
}
},
"header": "Benutzeroberfläche bearbeiten",
"menu": {
@ -2352,6 +2357,7 @@
"existing_cards": "Sie können eine Ansicht mit Karten nicht löschen. Entfernen Sie zuerst die Karten."
},
"warning": {
"attribute_not_found": "Attribut {attribute} nicht verfügbar in: {entity}",
"entity_non_numeric": "Die Entität ist nicht-numerisch: {entity}",
"entity_not_found": "Entität nicht verfügbar: {entity}"
}

View File

@ -674,8 +674,8 @@
"options": "Options"
},
"input_text": {
"max": "Maximum lenght",
"min": "Minimum lenght",
"max": "Maximum length",
"min": "Minimum length",
"mode": "Display mode",
"password": "Password",
"pattern": "Regex pattern for client-side validation",
@ -1508,18 +1508,19 @@
"yaml": "YAML file"
},
"confirm_delete": "Are you sure you want to delete this dashboard?",
"default_dashboard": "This is the default dashboard",
"detail": {
"create": "Create",
"delete": "Delete",
"dismiss": "Close",
"edit_dashboard": "Edit dashboard",
"icon": "Sidebar icon",
"icon": "Icon",
"new_dashboard": "Add new dashboard",
"remove_default": "Remove as default on this device",
"require_admin": "Admin only",
"set_default": "Set as default on this device",
"show_sidebar": "Show in sidebar",
"title": "Sidebar title",
"title": "Title",
"title_required": "Title is required.",
"update": "Update",
"url": "Url",

View File

@ -1317,7 +1317,8 @@
"device": "Dispositivo",
"integration": "Integración",
"manufacturer": "Fabricante",
"model": "Modelo"
"model": "Modelo",
"no_devices": "Sin dispositivos"
},
"description": "Administrar dispositivos conectados",
"details": "Aquí están todos los detalles de tu dispositivo.",
@ -1559,7 +1560,8 @@
"headers": {
"type": "Tipo",
"url": "Url"
}
},
"no_resources": "Sin recursos"
},
"refresh_body": "Tienes que actualizar la página para completar la eliminación, ¿deseas actualizar ahora?",
"refresh_header": "¿Quieres actualizar?",
@ -2275,7 +2277,10 @@
"move_right": "Mover vista a la derecha",
"tab_badges": "Insignias",
"tab_settings": "Configuración",
"tab_visibility": "Visibilidad"
"tab_visibility": "Visibilidad",
"visibility": {
"select_users": "Selecciona qué usuarios deberían ver esta vista en la navegación"
}
},
"header": "Editar la interfaz de usuario",
"menu": {
@ -2352,6 +2357,7 @@
"existing_cards": "No puedes eliminar una vista que tiene tarjetas. Elimina las tarjetas primero."
},
"warning": {
"attribute_not_found": "El atributo {attribute} no está disponible en: {entity}",
"entity_non_numeric": "La entidad no es numérica: {entity}",
"entity_not_found": "La entidad no está disponible: {entity}"
}

View File

@ -2200,6 +2200,7 @@
"existing_cards": "Vous ne pouvez pas supprimer une vue contenant des cartes. Retirez d'abord les cartes."
},
"warning": {
"attribute_not_found": "Attribut {attribute} non disponible dans: {entity}",
"entity_non_numeric": "L'entité est non numérique: {entity}",
"entity_not_found": "Entité non disponible: {entity}"
}

View File

@ -1317,7 +1317,8 @@
"device": "Enhet",
"integration": "Integrering",
"manufacturer": "Produsent",
"model": "Modell"
"model": "Modell",
"no_devices": "Ingen enheter"
},
"description": "Administrer tilkoblede enheter",
"details": "Her er alle detaljer for enheten.",
@ -1559,7 +1560,8 @@
"headers": {
"type": "Type",
"url": "Url"
}
},
"no_resources": "Ingen ressurser"
},
"refresh_body": "Du må oppdatere siden for å fullføre fjerningen, vil du oppdatere nå?",
"refresh_header": "Vil du oppdatere?",
@ -2275,7 +2277,10 @@
"move_right": "Flytt visning til høyre",
"tab_badges": "Merker",
"tab_settings": "Innstillinger",
"tab_visibility": "Synlighet"
"tab_visibility": "Synlighet",
"visibility": {
"select_users": "Velg hvilke brukere som skal se denne visningen i navigasjonen"
}
},
"header": "Rediger brukergrensesnitt",
"menu": {
@ -2352,6 +2357,7 @@
"existing_cards": "Du kan ikke slette en visning som har kort i den. Fjern kortene først."
},
"warning": {
"attribute_not_found": "Attributtet {attributt} er ikke tilgjengelig i: {entity}",
"entity_non_numeric": "Entiteten er ikke-numerisk: {entity}",
"entity_not_found": "Entitet ikke tilgjengelig: {entity}"
}

View File

@ -651,9 +651,12 @@
"name": "Nazwa"
},
"input_datetime": {
"datetime": "Data i godzina",
"date": "Data",
"datetime": "Data i czas",
"has_date": "Data",
"has_time": "Czas"
"has_time": "Czas",
"mode": "Co chcesz wprowadzić?",
"time": "Czas"
},
"input_number": {
"box": "Pole wprowadzania danych",
@ -1314,7 +1317,8 @@
"device": "Urządzenie",
"integration": "Integracja",
"manufacturer": "Producent",
"model": "Model"
"model": "Model",
"no_devices": "Brak urządzeń"
},
"description": "Zarządzaj podłączonymi urządzeniami",
"details": "Oto wszystkie szczegóły dotyczące twojego urządzenia.",
@ -1494,11 +1498,11 @@
},
"introduction": "Tutaj możesz skonfigurować Home Assistant'a i jego komponenty. Nie wszystkie opcje można konfigurować z interfejsu użytkownika, ale pracujemy nad tym.",
"lovelace": {
"caption": "Dashboard'y interfejsu użytkownika Lovelace",
"caption": "Dashboardy Lovelace",
"dashboards": {
"cant_edit_default": "Standardowego dashboardu Lovelace nie można edytować za pomocą interfejsu użytkownika. Możesz go ukryć, ustawiając jako domyślny inny dashboard.",
"cant_edit_yaml": "Dasboard'y zdefiniowane w plikach YAML nie mogą być edytowane z poziomu interfejsu użytkownika. Zmień je w pliku configuration.yaml.",
"caption": "Dashboard'y",
"caption": "Dashboardy",
"conf_mode": {
"storage": "Konfigurowalny z interfejsu użytkownika",
"yaml": "Plik YAML"
@ -1512,9 +1516,9 @@
"icon": "Ikona w pasku bocznym",
"new_dashboard": "Dodaj nowy dashboard",
"remove_default": "Nie używaj jako domyślny na tym urządzeniu",
"require_admin": "Tylko administrator",
"require_admin": "Tylko dla administratorów",
"set_default": "Ustaw jako domyślny na tym urządzeniu",
"show_sidebar": "Pokaż na pasku bocznym",
"show_sidebar": "Wyświetlanie na pasku bocznym",
"title": "Tytuł w pasku bocznym",
"title_required": "Tytuł jest wymagany.",
"update": "Aktualizuj",
@ -1528,13 +1532,13 @@
"default": "Domyślny",
"filename": "Nazwa pliku",
"require_admin": "Tylko administrator",
"sidebar": "Pokaż na pasku bocznym",
"sidebar": "Na pasku bocznym",
"title": "Tytuł"
},
"open": "Otwórz dashboard"
"open": "Otwórz"
}
},
"description": "Konfiguruj dashboard'y interfejsu użytkownika Lovelace",
"description": "Konfiguruj dashboardy interfejsu użytkownika Lovelace",
"resources": {
"cant_edit_yaml": "Korzystasz z interfejsu użytkownika Lovelace w trybie YAML, dlatego nie możesz zarządzać zasobami za pomocą interfejsu użytkownika. Zarządzaj nimi w pliku configuration.yaml.",
"caption": "Zasoby",
@ -1556,7 +1560,8 @@
"headers": {
"type": "Typ",
"url": "URL"
}
},
"no_resources": "Brak zasobów"
},
"refresh_body": "Musisz odświeżyć stronę, aby zakończyć usuwanie, czy chcesz teraz odświeżyć?",
"refresh_header": "Czy chcesz odświeżyć?",
@ -2272,7 +2277,10 @@
"move_right": "Przesuń widok w prawo",
"tab_badges": "Odznaki",
"tab_settings": "Ustawienia",
"tab_visibility": "Widoczność"
"tab_visibility": "Widoczność",
"visibility": {
"select_users": "Wybierz, którzy użytkownicy powinni mieć dostęp do tego widoku"
}
},
"header": "Edycja interfejsu użytkownika",
"menu": {
@ -2307,8 +2315,8 @@
"para": "Domyślnie Home Assistant będzie zarządzać interfejsem użytkownika, aktualizując go, gdy pojawią się nowe encje lub komponenty Lovelace. Jeśli przejmiesz kontrolę, Home Assistant nie będzie już automatycznie wprowadzać dla ciebie zmian.",
"para_sure": "Na pewno chcesz przejąć kontrolę nad interfejsem użytkownika?",
"save": "Przejmuję kontrolę",
"yaml_config": "Aby rozpocząć, zapoznaj się z aktualną konfiguracją tego dashboard'u:",
"yaml_control": "Aby zarządzać w trybie YAML, utwórz plik o nazwie podanej w konfiguracji dla tego dashboard'u lub domyślny 'ui-lovelace.yaml'.",
"yaml_config": "Aby rozpocząć, zapoznaj się z aktualną konfiguracją tego dashboardu:",
"yaml_control": "Aby zarządzać w trybie YAML, utwórz plik o nazwie podanej w konfiguracji dla tego dashboardu lub domyślny 'ui-lovelace.yaml'.",
"yaml_mode": "Używasz trybu YAML, co oznacza, że nie możesz zmienić konfiguracji Lovelace z poziomu interfejsu użytkownika. Jeśli chcesz zarządzać Lovelace z poziomu interfejsu użytkownika, usuń 'mode: yaml' z konfiguracji Lovelace w pliku 'configuration.yaml'."
},
"suggest_card": {
@ -2349,6 +2357,7 @@
"existing_cards": "Nie można usunąć widoku zawierającego karty. Najpierw usuń karty."
},
"warning": {
"attribute_not_found": "Atrybut {attribute} jest niedostępny dla: {entity}",
"entity_non_numeric": "Encja nie jest numeryczna: {entity}",
"entity_not_found": "Encja niedostępna: {entity}"
}

View File

@ -1316,7 +1316,8 @@
"device": "Устройство",
"integration": "Интеграция",
"manufacturer": "Производитель",
"model": "Модель"
"model": "Модель",
"no_devices": "Нет устройств"
},
"description": "Управляйте подключенными устройствами",
"details": "Здесь приведена вся доступная информация об этом устройстве.",
@ -1518,7 +1519,7 @@
"set_default": "Установить по умолчанию на этом устройстве",
"show_sidebar": "Показывать на боковой панели",
"title": "Название для боковой панели",
"title_required": "Название указывается обязательно.",
"title_required": "Обязательное поле",
"update": "Обновить",
"url": "URL-адрес",
"url_error_msg": "URL не может содержать пробелы или специальные символы, кроме символов _ и -"
@ -1549,7 +1550,7 @@
"type": "Тип ресурса",
"update": "Обновить",
"url": "URL-адрес",
"url_error_msg": "URL-адрес является обязательным полем.",
"url_error_msg": "Обязательное поле",
"warning_header": "Будьте осторожны!",
"warning_text": "Добавление ресурсов может быть опасным. Убедитесь, что Вы знаете источник ресурса и доверяете ему. Плохие ресурсы могут нанести серьёзный вред Вашей системе."
},
@ -1558,7 +1559,8 @@
"headers": {
"type": "Тип",
"url": "URL-адрес"
}
},
"no_resources": "Нет ресурсов"
},
"refresh_body": "Вы должны обновить страницу, чтобы завершить удаление. Обновить сейчас?",
"refresh_header": "Обновить страницу?",
@ -2267,7 +2269,10 @@
"move_right": "Переместить вкладку вправо",
"tab_badges": "Значки",
"tab_settings": "Настройки",
"tab_visibility": "Видимость"
"tab_visibility": "Видимость",
"visibility": {
"select_users": "Выберите, какие пользователи должны видеть эту вкладку"
}
},
"header": "Редактирование интерфейса",
"menu": {
@ -2343,6 +2348,7 @@
"existing_cards": "Прежде чем удалять вкладку, удалите из нее все карточки."
},
"warning": {
"attribute_not_found": "Атрибут {attribute} недоступен в {entity}",
"entity_non_numeric": "Объект не является числом: {entity}",
"entity_not_found": "Объект {entity} недоступен."
}

View File

@ -1317,7 +1317,8 @@
"device": "设备",
"integration": "集成",
"manufacturer": "制造商",
"model": "型号"
"model": "型号",
"no_devices": "没有设备"
},
"description": "管理已连接的设备",
"details": "这是设备的所有详细信息。",
@ -1559,7 +1560,8 @@
"headers": {
"type": "类型",
"url": "网址"
}
},
"no_resources": "没有资源"
},
"refresh_body": "您必须刷新页面才能完成删除,是否要立即刷新?",
"refresh_header": "要刷新吗?",
@ -2275,7 +2277,10 @@
"move_right": "向右移动视图",
"tab_badges": "徽章",
"tab_settings": "设置",
"tab_visibility": "可见性"
"tab_visibility": "可见性",
"visibility": {
"select_users": "选择要让哪些用户在导航中看到此视图"
}
},
"header": "编辑 UI",
"menu": {
@ -2352,6 +2357,7 @@
"existing_cards": "无法删除包含卡片的视图。请先移除卡片。"
},
"warning": {
"attribute_not_found": "属性 {attribute} 对 {entity} 不可用",
"entity_non_numeric": "实体 {entity} 非数值",
"entity_not_found": "实体 {entity} 不可用"
}

View File

@ -510,7 +510,7 @@
"air_pressure": "大氣壓",
"humidity": "濕度",
"temperature": "溫度",
"visibility": "能見度",
"visibility": "顯示選項",
"wind_speed": "風速"
},
"cardinal_direction": {
@ -770,7 +770,7 @@
"unknown": "未知",
"zha_device_card": {
"area_picker_label": "分區",
"device_name_placeholder": "使用者姓氏",
"device_name_placeholder": "設備命名",
"update_name_button": "更新名稱"
}
}
@ -1317,7 +1317,8 @@
"device": "設備",
"integration": "整合",
"manufacturer": "廠牌",
"model": "型號"
"model": "型號",
"no_devices": "沒有設備"
},
"description": "管理已連線設備",
"details": "此處顯示設備所有詳細資訊。",
@ -1412,7 +1413,7 @@
"header": "設定 Home Assistant",
"helpers": {
"caption": "助手",
"description": "可協助建立自動化的元素",
"description": "可協助建立自動化的元素",
"dialog": {
"add_helper": "新增助手",
"add_platform": "新增 {platform}",
@ -1503,7 +1504,7 @@
"cant_edit_yaml": "於 YAML 中定義的主面板無法藉由 UI 編輯,請於 Configuration.yaml 進行更改。",
"caption": "主面板",
"conf_mode": {
"storage": "UI 控制",
"storage": "UI 控制",
"yaml": "YAML 檔案"
},
"confirm_delete": "確定要刪除此主面板?",
@ -1559,14 +1560,15 @@
"headers": {
"type": "類別",
"url": "網址"
}
},
"no_resources": "沒有資源"
},
"refresh_body": "必須更新頁面以完成移除、要立即更新?",
"refresh_header": "是否要更新?",
"types": {
"css": "Stylesheet",
"html": "HTML已棄用)",
"js": "JavaScript 檔案(已棄用)",
"html": "HTML不再適用)",
"js": "JavaScript 檔案(不再適用)",
"module": "JavaScript 模組"
}
}
@ -2273,9 +2275,12 @@
"header_name": "{name}面板設定",
"move_left": "向左移動視圖",
"move_right": "向右移動視圖",
"tab_badges": "標圖示",
"tab_badges": "標圖示",
"tab_settings": "設定",
"tab_visibility": "能見度"
"tab_visibility": "顯示選項",
"visibility": {
"select_users": "選擇可觀看此面板的使用者"
}
},
"header": "編輯 UI",
"menu": {
@ -2321,7 +2326,7 @@
},
"view": {
"panel_mode": {
"description": "將會以全寬繪製第一張卡,視圖中其他面板將不進行呈現。",
"description": "將會以全寬度製作第一張面板,視圖中其他面板將不進行呈現。",
"title": "面板模式?"
}
}
@ -2352,6 +2357,7 @@
"existing_cards": "無法刪除內含面板的視圖,請先移除面板。"
},
"warning": {
"attribute_not_found": "無法使用屬性 {attribute} 之物件:{entity}",
"entity_non_numeric": "物件為非數字:{entity}",
"entity_not_found": "物件不可用:{entity}"
}

View File

@ -5,8 +5,8 @@ const { isProdBuild, isStatsBuild } = require("./build-scripts/env.js");
const configs = [
createAppConfig({
isProdBuild,
isStatsBuild,
isProdBuild: isProdBuild(),
isStatsBuild: isStatsBuild(),
latestBuild: true,
}),
];
@ -14,8 +14,8 @@ const configs = [
if (isProdBuild && !isStatsBuild) {
configs.push(
createAppConfig({
isProdBuild,
isStatsBuild,
isProdBuild: isProdBuild(),
isStatsBuild: isStatsBuild(),
latestBuild: false,
})
);