mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-01 13:37:47 +00:00
commit
4b2edde81b
@ -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";
|
||||
},
|
||||
};
|
||||
|
@ -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",
|
||||
|
@ -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"])
|
||||
)
|
||||
);
|
||||
|
@ -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),
|
||||
|
@ -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}`;
|
||||
|
@ -6,6 +6,6 @@ const { isProdBuild } = require("../build-scripts/env.js");
|
||||
const latestBuild = true;
|
||||
|
||||
module.exports = createCastConfig({
|
||||
isProdBuild,
|
||||
isProdBuild: isProdBuild(),
|
||||
latestBuild,
|
||||
});
|
||||
|
BIN
demo/public/stub_config/bedroom.png
Normal file
BIN
demo/public/stub_config/bedroom.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 111 KiB |
BIN
demo/public/stub_config/floorplan.png
Normal file
BIN
demo/public/stub_config/floorplan.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
demo/public/stub_config/kitchen.png
Normal file
BIN
demo/public/stub_config/kitchen.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 115 KiB |
BIN
demo/public/stub_config/t-shirt-promo.png
Normal file
BIN
demo/public/stub_config/t-shirt-promo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 185 KiB |
@ -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,
|
||||
});
|
||||
|
BIN
gallery/public/images/album_cover_2.jpg
Normal file
BIN
gallery/public/images/album_cover_2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
@ -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(
|
||||
|
@ -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 = [
|
||||
{
|
||||
|
@ -6,6 +6,6 @@ const { isProdBuild } = require("../build-scripts/env.js");
|
||||
const latestBuild = false;
|
||||
|
||||
module.exports = createHassioConfig({
|
||||
isProdBuild,
|
||||
isProdBuild: isProdBuild(),
|
||||
latestBuild,
|
||||
});
|
||||
|
2
setup.py
2
setup.py
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -56,7 +56,8 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
|
||||
lovelaceConfig,
|
||||
maxEntities,
|
||||
entities,
|
||||
entitiesFill
|
||||
entitiesFill,
|
||||
["light", "switch"]
|
||||
);
|
||||
|
||||
return {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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" },
|
||||
};
|
||||
|
@ -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",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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"),
|
||||
|
@ -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;
|
||||
|
@ -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 d’actualitzar la pàgina per completar l’eliminació. 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}"
|
||||
}
|
||||
|
@ -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}"
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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}"
|
||||
}
|
||||
|
@ -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}"
|
||||
}
|
||||
|
@ -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}"
|
||||
}
|
||||
|
@ -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}"
|
||||
}
|
||||
|
@ -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} недоступен."
|
||||
}
|
||||
|
@ -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} 不可用"
|
||||
}
|
||||
|
@ -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}"
|
||||
}
|
||||
|
@ -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,
|
||||
})
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user