mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 17:26:42 +00:00
Merge pull request #10162 from home-assistant/dev
This commit is contained in:
commit
736e117eca
@ -111,8 +111,7 @@
|
||||
],
|
||||
"unused-imports/no-unused-imports": "error",
|
||||
"lit/attribute-value-entities": "off",
|
||||
"lit/no-template-map": "off",
|
||||
"lit/no-template-arrow": "warn"
|
||||
"lit/no-template-map": "off"
|
||||
},
|
||||
"plugins": ["disable", "unused-imports"],
|
||||
"processor": "disable/disable"
|
||||
|
@ -1,9 +1,6 @@
|
||||
const gulp = require("gulp");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const env = require("../env");
|
||||
const paths = require("../paths");
|
||||
|
||||
require("./clean.js");
|
||||
require("./gen-icons-json.js");
|
||||
|
@ -4,9 +4,6 @@ const del = require("del");
|
||||
const path = require("path");
|
||||
const gulp = require("gulp");
|
||||
const fs = require("fs");
|
||||
const merge = require("gulp-merge-json");
|
||||
const rename = require("gulp-rename");
|
||||
const transform = require("gulp-json-transform");
|
||||
const paths = require("../paths");
|
||||
|
||||
const outDir = "build/locale-data";
|
||||
|
2
setup.py
2
setup.py
@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name="home-assistant-frontend",
|
||||
version="20211004.0",
|
||||
version="20211006.0",
|
||||
description="The Home Assistant frontend",
|
||||
url="https://github.com/home-assistant/frontend",
|
||||
author="The Home Assistant Authors",
|
||||
|
@ -115,7 +115,7 @@ export const applyThemesOnElement = (
|
||||
}
|
||||
|
||||
const newTheme =
|
||||
themeRules && cacheKey
|
||||
Object.keys(themeRules).length && cacheKey
|
||||
? PROCESSED_THEMES[cacheKey] || processTheme(cacheKey, themeRules)
|
||||
: undefined;
|
||||
|
||||
|
@ -180,10 +180,10 @@ export function fuzzyScore(
|
||||
wordLow
|
||||
);
|
||||
|
||||
let row = 1;
|
||||
let row: number;
|
||||
let column = 1;
|
||||
let patternPos = patternStart;
|
||||
let wordPos = wordStart;
|
||||
let patternPos: number;
|
||||
let wordPos: number;
|
||||
|
||||
const hasStrongFirstMatch = [false];
|
||||
|
||||
|
@ -34,7 +34,7 @@ export class HaDeviceSelector extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.value=${this.value}
|
||||
.label=${this.label}
|
||||
.deviceFilter=${(device) => this._filterDevices(device)}
|
||||
.deviceFilter=${this._filterDevices}
|
||||
.includeDeviceClasses=${this.selector.device.entity?.device_class
|
||||
? [this.selector.device.entity.device_class]
|
||||
: undefined}
|
||||
@ -46,7 +46,7 @@ export class HaDeviceSelector extends LitElement {
|
||||
></ha-device-picker>`;
|
||||
}
|
||||
|
||||
private _filterDevices(device: DeviceRegistryEntry): boolean {
|
||||
private _filterDevices = (device: DeviceRegistryEntry): boolean => {
|
||||
if (
|
||||
this.selector.device?.manufacturer &&
|
||||
device.manufacturer !== this.selector.device.manufacturer
|
||||
@ -70,7 +70,7 @@ export class HaDeviceSelector extends LitElement {
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private async _loadConfigEntries() {
|
||||
this._configEntries = (await getConfigEntries(this.hass)).filter(
|
||||
|
@ -27,7 +27,7 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
|
||||
.hass=${this.hass}
|
||||
.value=${this.value}
|
||||
.label=${this.label}
|
||||
.entityFilter=${(entity) => this._filterEntities(entity)}
|
||||
.entityFilter=${this._filterEntities}
|
||||
.disabled=${this.disabled}
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>`;
|
||||
@ -48,7 +48,7 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
|
||||
];
|
||||
}
|
||||
|
||||
private _filterEntities(entity: HassEntity): boolean {
|
||||
private _filterEntities = (entity: HassEntity): boolean => {
|
||||
if (this.selector.entity?.domain) {
|
||||
if (computeStateDomain(entity) !== this.selector.entity.domain) {
|
||||
return false;
|
||||
@ -72,7 +72,7 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -69,10 +69,9 @@ export class HaTargetSelector extends SubscribeMixin(LitElement) {
|
||||
return html`<ha-target-picker
|
||||
.hass=${this.hass}
|
||||
.value=${this.value}
|
||||
.deviceFilter=${(device) => this._filterDevices(device)}
|
||||
.entityRegFilter=${(entity: EntityRegistryEntry) =>
|
||||
this._filterRegEntities(entity)}
|
||||
.entityFilter=${(entity: HassEntity) => this._filterEntities(entity)}
|
||||
.deviceFilter=${this._filterDevices}
|
||||
.entityRegFilter=${this._filterRegEntities}
|
||||
.entityFilter=${this._filterEntities}
|
||||
.includeDeviceClasses=${this.selector.target.entity?.device_class
|
||||
? [this.selector.target.entity.device_class]
|
||||
: undefined}
|
||||
@ -83,7 +82,7 @@ export class HaTargetSelector extends SubscribeMixin(LitElement) {
|
||||
></ha-target-picker>`;
|
||||
}
|
||||
|
||||
private _filterEntities(entity: HassEntity): boolean {
|
||||
private _filterEntities = (entity: HassEntity): boolean => {
|
||||
if (
|
||||
this.selector.target.entity?.integration ||
|
||||
this.selector.target.device?.integration
|
||||
@ -98,18 +97,18 @@ export class HaTargetSelector extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private _filterRegEntities(entity: EntityRegistryEntry): boolean {
|
||||
private _filterRegEntities = (entity: EntityRegistryEntry): boolean => {
|
||||
if (this.selector.target.entity?.integration) {
|
||||
if (entity.platform !== this.selector.target.entity.integration) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private _filterDevices(device: DeviceRegistryEntry): boolean {
|
||||
private _filterDevices = (device: DeviceRegistryEntry): boolean => {
|
||||
if (
|
||||
this.selector.target.device?.manufacturer &&
|
||||
device.manufacturer !== this.selector.target.device.manufacturer
|
||||
@ -135,7 +134,7 @@ export class HaTargetSelector extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private async _loadConfigEntries() {
|
||||
this._configEntries = (await getConfigEntries(this.hass)).filter(
|
||||
|
@ -511,8 +511,7 @@ export class HaAutomationTracer extends LitElement {
|
||||
className: isError ? "error" : undefined,
|
||||
};
|
||||
}
|
||||
// null means it was stopped by a condition
|
||||
if (entry) {
|
||||
|
||||
entries.push(html`
|
||||
<ha-timeline
|
||||
lastItem
|
||||
@ -522,7 +521,6 @@ export class HaAutomationTracer extends LitElement {
|
||||
${entry.description}
|
||||
</ha-timeline>
|
||||
`);
|
||||
}
|
||||
|
||||
return html`${entries}`;
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ export class QuickBar extends LitElement {
|
||||
: this._entityItems;
|
||||
|
||||
if (items && this._filter && this._filter !== " ") {
|
||||
items = this._filterItems(items || [], this._filter);
|
||||
items = this._filterItems(items, this._filter);
|
||||
}
|
||||
|
||||
return html`
|
||||
|
@ -113,7 +113,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.route=${this.route}
|
||||
.backCallback=${() => this._backTapped()}
|
||||
.backCallback=${this._backTapped}
|
||||
.tabs=${configSections.automation}
|
||||
>
|
||||
<ha-button-menu
|
||||
@ -435,7 +435,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
this._dirty = true;
|
||||
}
|
||||
|
||||
private _backTapped(): void {
|
||||
private _backTapped = (): void => {
|
||||
if (this._dirty) {
|
||||
showConfirmationDialog(this, {
|
||||
text: this.hass!.localize(
|
||||
@ -448,7 +448,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
} else {
|
||||
history.back();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private async _duplicate() {
|
||||
if (this._dirty) {
|
||||
|
@ -135,7 +135,7 @@ class HaAutomationPicker extends LitElement {
|
||||
template: (_info, automation: any) => html`
|
||||
<mwc-button
|
||||
.automation=${automation}
|
||||
@click=${(ev) => this._runActions(ev)}
|
||||
@click=${this._runActions}
|
||||
.disabled=${UNAVAILABLE_STATES.includes(automation.state)}
|
||||
>
|
||||
${this.hass.localize("ui.card.automation.trigger")}
|
||||
@ -313,10 +313,10 @@ class HaAutomationPicker extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private _runActions(ev) {
|
||||
private _runActions = (ev) => {
|
||||
const entityId = ev.currentTarget.automation.entity_id;
|
||||
triggerAutomationActions(this.hass, entityId);
|
||||
}
|
||||
};
|
||||
|
||||
private _createNew() {
|
||||
if (
|
||||
|
@ -90,7 +90,7 @@ export class HaAutomationTrace extends LitElement {
|
||||
}
|
||||
|
||||
const actionButtons = html`
|
||||
<mwc-icon-button label="Refresh" @click=${() => this._loadTraces()}>
|
||||
<mwc-icon-button label="Refresh" @click=${this._refreshTraces}>
|
||||
<ha-svg-icon .path=${mdiRefresh}></ha-svg-icon>
|
||||
</mwc-icon-button>
|
||||
<mwc-icon-button
|
||||
@ -111,7 +111,7 @@ export class HaAutomationTrace extends LitElement {
|
||||
.tabs=${configSections.automation}
|
||||
>
|
||||
${this.narrow
|
||||
? html`<span slot="header"> ${title} </span>
|
||||
? html`<span slot="header">${title}</span>
|
||||
<div slot="toolbar-icon">${actionButtons}</div>`
|
||||
: ""}
|
||||
<div class="toolbar">
|
||||
@ -335,6 +335,10 @@ export class HaAutomationTrace extends LitElement {
|
||||
this._selected = ev.detail;
|
||||
}
|
||||
|
||||
private _refreshTraces() {
|
||||
this._loadTraces();
|
||||
}
|
||||
|
||||
private async _loadTraces(runId?: string) {
|
||||
this._traces = await loadTraces(this.hass, "automation", this.automationId);
|
||||
// Newest will be on top.
|
||||
|
@ -78,7 +78,7 @@ class DialogThingtalk extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.placeholders=${this._placeholders}
|
||||
.opened=${this._opened}
|
||||
.skip=${() => this._skip()}
|
||||
.skip=${this._skip}
|
||||
@opened-changed=${this._openedChanged}
|
||||
@placeholders-filled=${this._handlePlaceholders}
|
||||
>
|
||||
@ -229,10 +229,10 @@ class DialogThingtalk extends LitElement {
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
private _skip() {
|
||||
private _skip = () => {
|
||||
this._params!.callback(undefined);
|
||||
this.closeDialog();
|
||||
}
|
||||
};
|
||||
|
||||
private _openedChanged(ev: PolymerChangedEvent<boolean>): void {
|
||||
if (!ev.detail.value) {
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable lit/no-template-arrow */
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
|
@ -127,13 +127,13 @@ class HaBlueprintOverview extends LitElement {
|
||||
title=${this.hass.localize(
|
||||
"ui.panel.config.blueprint.overview.use_blueprint"
|
||||
)}
|
||||
@click=${(ev) => this._createNew(ev)}
|
||||
@click=${this._createNew}
|
||||
>
|
||||
<ha-svg-icon .path=${mdiRobot}></ha-svg-icon>
|
||||
</mwc-icon-button>`
|
||||
: html`<mwc-button
|
||||
.blueprint=${blueprint}
|
||||
@click=${(ev) => this._createNew(ev)}
|
||||
@click=${this._createNew}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.blueprint.overview.use_blueprint"
|
||||
@ -154,7 +154,7 @@ class HaBlueprintOverview extends LitElement {
|
||||
? "ui.panel.config.blueprint.overview.share_blueprint"
|
||||
: "ui.panel.config.blueprint.overview.share_blueprint_no_url"
|
||||
)}
|
||||
@click=${(ev) => this._share(ev)}
|
||||
@click=${this._share}
|
||||
><ha-svg-icon .path=${mdiShareVariant}></ha-svg-icon
|
||||
></mwc-icon-button>`,
|
||||
},
|
||||
@ -169,7 +169,7 @@ class HaBlueprintOverview extends LitElement {
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.blueprint.overview.delete_blueprint"
|
||||
)}
|
||||
@click=${(ev) => this._delete(ev)}
|
||||
@click=${this._delete}
|
||||
><ha-svg-icon .path=${mdiDelete}></ha-svg-icon
|
||||
></mwc-icon-button>`,
|
||||
},
|
||||
@ -275,12 +275,12 @@ class HaBlueprintOverview extends LitElement {
|
||||
fireEvent(this, "reload-blueprints");
|
||||
}
|
||||
|
||||
private _createNew(ev) {
|
||||
private _createNew = (ev) => {
|
||||
const blueprint = ev.currentTarget.blueprint as BlueprintMetaDataPath;
|
||||
createNewFunctions[blueprint.domain](blueprint);
|
||||
}
|
||||
};
|
||||
|
||||
private _share(ev) {
|
||||
private _share = (ev) => {
|
||||
const blueprint = ev.currentTarget.blueprint;
|
||||
const params = new URLSearchParams();
|
||||
params.append("redirect", "blueprint_import");
|
||||
@ -288,9 +288,9 @@ class HaBlueprintOverview extends LitElement {
|
||||
window.open(
|
||||
`https://my.home-assistant.io/create-link/?${params.toString()}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
private async _delete(ev) {
|
||||
private _delete = async (ev) => {
|
||||
const blueprint = ev.currentTarget.blueprint;
|
||||
if (
|
||||
!(await showConfirmationDialog(this, {
|
||||
@ -306,7 +306,7 @@ class HaBlueprintOverview extends LitElement {
|
||||
}
|
||||
await deleteBlueprint(this.hass, blueprint.domain, blueprint.path);
|
||||
fireEvent(this, "reload-blueprints");
|
||||
}
|
||||
};
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return haStyle;
|
||||
|
@ -99,16 +99,12 @@ export class CloudRemotePref extends LitElement {
|
||||
)}</mwc-button
|
||||
>
|
||||
</a>
|
||||
${remote_certificate
|
||||
? html`
|
||||
<div class="spacer"></div>
|
||||
<mwc-button @click=${this._openCertInfo}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.certificate_info"
|
||||
)}
|
||||
</mwc-button>
|
||||
`
|
||||
: ""}
|
||||
</div>
|
||||
</ha-card>
|
||||
`;
|
||||
|
@ -36,7 +36,7 @@ export class DialogEnergyBatterySettings
|
||||
this._params = params;
|
||||
this._source = params.source
|
||||
? { ...params.source }
|
||||
: (this._source = emptyBatteryEnergyPreference());
|
||||
: emptyBatteryEnergyPreference();
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
|
@ -42,7 +42,7 @@ export class DialogEnergyGasSettings
|
||||
this._params = params;
|
||||
this._source = params.source
|
||||
? { ...params.source }
|
||||
: (this._source = emptyGasEnergyPreference());
|
||||
: emptyGasEnergyPreference();
|
||||
this._costs = this._source.entity_energy_price
|
||||
? "entity"
|
||||
: this._source.number_energy_price
|
||||
|
@ -46,10 +46,9 @@ export class DialogEnergyGridFlowSettings
|
||||
this._params = params;
|
||||
this._source = params.source
|
||||
? { ...params.source }
|
||||
: (this._source =
|
||||
params.direction === "from"
|
||||
: params.direction === "from"
|
||||
? emptyFlowFromGridSourceEnergyPreference()
|
||||
: emptyFlowToGridSourceEnergyPreference());
|
||||
: emptyFlowToGridSourceEnergyPreference();
|
||||
this._costs = this._source.entity_energy_price
|
||||
? "entity"
|
||||
: this._source.number_energy_price
|
||||
|
@ -49,7 +49,7 @@ export class DialogEnergySolarSettings
|
||||
this._fetchSolarForecastConfigEntries();
|
||||
this._source = params.source
|
||||
? { ...params.source }
|
||||
: (this._source = emptySolarEnergyPreference());
|
||||
: emptySolarEnergyPreference();
|
||||
this._forecast = this._source.config_entry_solar_forecast !== null;
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ export class ZHANetworkVisualizationPage extends LitElement {
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.zha.visualization.zoom_label"
|
||||
)}
|
||||
.deviceFilter=${(device) => this._filterDevices(device)}
|
||||
.deviceFilter=${this._filterDevices}
|
||||
@value-changed=${this._onZoomToDevice}
|
||||
></ha-device-picker>
|
||||
<div class="controls">
|
||||
@ -359,7 +359,7 @@ export class ZHANetworkVisualizationPage extends LitElement {
|
||||
await refreshTopology(this.hass);
|
||||
}
|
||||
|
||||
private _filterDevices(device: DeviceRegistryEntry): boolean {
|
||||
private _filterDevices = (device: DeviceRegistryEntry): boolean => {
|
||||
if (!this.hass) {
|
||||
return false;
|
||||
}
|
||||
@ -371,7 +371,7 @@ export class ZHANetworkVisualizationPage extends LitElement {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private _handleCheckboxChange(ev: Event) {
|
||||
this._autoZoom = (ev.target as HaCheckbox).checked;
|
||||
|
@ -493,7 +493,9 @@ class HaConfigZwave extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||
}
|
||||
|
||||
computeEntities(selectedNode) {
|
||||
if (!this.nodes || selectedNode === -1) return -1;
|
||||
if (!this.nodes || selectedNode === -1) {
|
||||
return -1;
|
||||
}
|
||||
const nodeid = this.nodes[this.selectedNode].attributes.node_id;
|
||||
const hass = this.hass;
|
||||
return Object.keys(this.hass.states)
|
||||
@ -512,7 +514,9 @@ class HaConfigZwave extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||
}
|
||||
|
||||
selectedNodeChanged(selectedNode) {
|
||||
if (selectedNode === -1) return;
|
||||
if (selectedNode === -1) {
|
||||
return;
|
||||
}
|
||||
this.selectedEntity = -1;
|
||||
|
||||
this.hass
|
||||
@ -573,7 +577,9 @@ class HaConfigZwave extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||
}
|
||||
|
||||
selectedEntityChanged(selectedEntity) {
|
||||
if (selectedEntity === -1) return;
|
||||
if (selectedEntity === -1) {
|
||||
return;
|
||||
}
|
||||
this.hass
|
||||
.callApi(
|
||||
"GET",
|
||||
@ -640,12 +646,16 @@ class HaConfigZwave extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||
}
|
||||
|
||||
computeRefreshEntityServiceData(selectedEntity) {
|
||||
if (selectedEntity === -1) return -1;
|
||||
if (selectedEntity === -1) {
|
||||
return -1;
|
||||
}
|
||||
return { entity_id: this.entities[selectedEntity].entity_id };
|
||||
}
|
||||
|
||||
computePollIntensityServiceData(entityPollingIntensity) {
|
||||
if (!this.selectedNode === -1 || this.selectedEntity === -1) return -1;
|
||||
if (this.selectedNode === -1 || this.selectedEntity === -1) {
|
||||
return -1;
|
||||
}
|
||||
return {
|
||||
node_id: this.nodes[this.selectedNode].attributes.node_id,
|
||||
value_id: this.entities[this.selectedEntity].attributes.value_id,
|
||||
|
@ -300,12 +300,13 @@ class ZwaveGroups extends LocalizeMixin(PolymerElement) {
|
||||
|
||||
_computeAssocServiceData(selectedGroup, type) {
|
||||
if (
|
||||
!this.groups === -1 ||
|
||||
!this.groups ||
|
||||
selectedGroup === -1 ||
|
||||
this.selectedNode === -1 ||
|
||||
this._selectedTargetNode === -1
|
||||
)
|
||||
) {
|
||||
return -1;
|
||||
}
|
||||
return {
|
||||
node_id: this.nodes[this.selectedNode].attributes.node_id,
|
||||
association: type,
|
||||
|
@ -65,7 +65,7 @@ class DialogSystemLogDetail extends LitElement {
|
||||
this._manifest &&
|
||||
(this._manifest.is_built_in ||
|
||||
// Custom components with our offical docs should not link to our docs
|
||||
!this._manifest.documentation.includes("www.home-assistant.io"));
|
||||
!this._manifest.documentation.includes("://www.home-assistant.io"));
|
||||
|
||||
return html`
|
||||
<ha-dialog open @closed=${this.closeDialog} hideActions .heading=${true}>
|
||||
|
@ -77,7 +77,7 @@ class HaSceneDashboard extends LitElement {
|
||||
title=${this.hass.localize(
|
||||
"ui.panel.config.scene.picker.activate_scene"
|
||||
)}
|
||||
@click=${(ev: Event) => this._activateScene(ev)}
|
||||
@click=${this._activateScene}
|
||||
>
|
||||
<ha-svg-icon .path=${mdiPlay}></ha-svg-icon>
|
||||
</mwc-icon-button>
|
||||
@ -213,7 +213,7 @@ class HaSceneDashboard extends LitElement {
|
||||
fireEvent(this, "hass-more-info", { entityId });
|
||||
}
|
||||
|
||||
private async _activateScene(ev) {
|
||||
private _activateScene = async (ev) => {
|
||||
ev.stopPropagation();
|
||||
const scene = ev.currentTarget.scene as SceneEntity;
|
||||
await activateScene(this.hass, scene.entity_id);
|
||||
@ -225,7 +225,7 @@ class HaSceneDashboard extends LitElement {
|
||||
),
|
||||
});
|
||||
forwardHaptic("light");
|
||||
}
|
||||
};
|
||||
|
||||
private _showHelp() {
|
||||
showAlertDialog(this, {
|
||||
|
@ -201,7 +201,7 @@ export class HaSceneEditor extends SubscribeMixin(
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.route=${this.route}
|
||||
.backCallback=${() => this._backTapped()}
|
||||
.backCallback=${this._backTapped}
|
||||
.tabs=${configSections.automation}
|
||||
>
|
||||
<ha-button-menu
|
||||
@ -698,7 +698,7 @@ export class HaSceneEditor extends SubscribeMixin(
|
||||
}
|
||||
}
|
||||
|
||||
private _backTapped(): void {
|
||||
private _backTapped = (): void => {
|
||||
if (this._dirty) {
|
||||
showConfirmationDialog(this, {
|
||||
text: this.hass!.localize(
|
||||
@ -711,7 +711,7 @@ export class HaSceneEditor extends SubscribeMixin(
|
||||
} else {
|
||||
this._goBack();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private _goBack(): void {
|
||||
applyScene(this.hass, this._storedStates);
|
||||
|
@ -87,7 +87,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.route=${this.route}
|
||||
.backCallback=${() => this._backTapped()}
|
||||
.backCallback=${this._backTapped}
|
||||
.tabs=${configSections.automation}
|
||||
>
|
||||
<ha-button-menu
|
||||
@ -578,7 +578,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
this._dirty = true;
|
||||
}
|
||||
|
||||
private _backTapped(): void {
|
||||
private _backTapped = (): void => {
|
||||
if (this._dirty) {
|
||||
showConfirmationDialog(this, {
|
||||
text: this.hass!.localize(
|
||||
@ -591,7 +591,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
} else {
|
||||
history.back();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private async _duplicate() {
|
||||
if (this._dirty) {
|
||||
|
@ -79,7 +79,7 @@ class HaScriptPicker extends LitElement {
|
||||
title=${this.hass.localize(
|
||||
"ui.panel.config.script.picker.run_script"
|
||||
)}
|
||||
@click=${(ev: Event) => this._runScript(ev)}
|
||||
@click=${this._runScript}
|
||||
>
|
||||
<ha-svg-icon .path=${mdiPlay}></ha-svg-icon>
|
||||
</mwc-icon-button>
|
||||
@ -234,7 +234,7 @@ class HaScriptPicker extends LitElement {
|
||||
this._filterValue = undefined;
|
||||
}
|
||||
|
||||
private async _runScript(ev) {
|
||||
private _runScript = async (ev) => {
|
||||
ev.stopPropagation();
|
||||
const script = ev.currentTarget.script as HassEntity;
|
||||
await triggerScript(this.hass, script.entity_id);
|
||||
@ -245,7 +245,7 @@ class HaScriptPicker extends LitElement {
|
||||
computeStateName(script)
|
||||
),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private _showInfo(ev) {
|
||||
ev.stopPropagation();
|
||||
|
@ -88,7 +88,7 @@ export class HaScriptTrace extends LitElement {
|
||||
}
|
||||
|
||||
const actionButtons = html`
|
||||
<mwc-icon-button label="Refresh" @click=${() => this._loadTraces()}>
|
||||
<mwc-icon-button label="Refresh" @click=${this._refreshTraces}>
|
||||
<ha-svg-icon .path=${mdiRefresh}></ha-svg-icon>
|
||||
</mwc-icon-button>
|
||||
<mwc-icon-button
|
||||
@ -321,6 +321,10 @@ export class HaScriptTrace extends LitElement {
|
||||
this._selected = ev.detail;
|
||||
}
|
||||
|
||||
private _refreshTraces() {
|
||||
this._loadTraces();
|
||||
}
|
||||
|
||||
private async _loadTraces(runId?: string) {
|
||||
this._traces = await loadTraces(
|
||||
this.hass,
|
||||
|
@ -107,8 +107,7 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
||||
type: "icon-button",
|
||||
template: (_write, tag: any) => html` <mwc-icon-button
|
||||
.tag=${tag}
|
||||
@click=${(ev: Event) =>
|
||||
this._openWrite((ev.currentTarget as any).tag)}
|
||||
@click=${this._handleWriteClick}
|
||||
title=${this.hass.localize("ui.panel.config.tag.write")}
|
||||
>
|
||||
<ha-svg-icon .path=${mdiContentDuplicate}></ha-svg-icon>
|
||||
@ -120,8 +119,7 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
||||
type: "icon-button",
|
||||
template: (_automation, tag: any) => html` <mwc-icon-button
|
||||
.tag=${tag}
|
||||
@click=${(ev: Event) =>
|
||||
this._createAutomation((ev.currentTarget as any).tag)}
|
||||
@click=${this._handleAutomationClick}
|
||||
title=${this.hass.localize("ui.panel.config.tag.create_automation")}
|
||||
>
|
||||
<ha-svg-icon .path=${mdiRobot}></ha-svg-icon>
|
||||
@ -132,8 +130,7 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
||||
type: "icon-button",
|
||||
template: (_settings, tag: any) => html` <mwc-icon-button
|
||||
.tag=${tag}
|
||||
@click=${(ev: Event) =>
|
||||
this._openDialog((ev.currentTarget as any).tag)}
|
||||
@click=${this._handleEditClick}
|
||||
title=${this.hass.localize("ui.panel.config.tag.edit")}
|
||||
>
|
||||
<ha-svg-icon .path=${mdiCog}></ha-svg-icon>
|
||||
@ -209,6 +206,25 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
||||
`;
|
||||
}
|
||||
|
||||
private _handleWriteClick = (ev: Event) =>
|
||||
this._openWrite((ev.currentTarget as any).tag);
|
||||
|
||||
private _handleAutomationClick = (ev: Event) => {
|
||||
const tag = (ev.currentTarget as any).tag;
|
||||
const data = {
|
||||
alias: this.hass.localize(
|
||||
"ui.panel.config.tag.automation_title",
|
||||
"name",
|
||||
tag.name || tag.id
|
||||
),
|
||||
trigger: [{ platform: "tag", tag_id: tag.id } as TagTrigger],
|
||||
};
|
||||
showAutomationEditor(data);
|
||||
};
|
||||
|
||||
private _handleEditClick = (ev: Event) =>
|
||||
this._openDialog((ev.currentTarget as any).tag);
|
||||
|
||||
private _showHelp() {
|
||||
showAlertDialog(this, {
|
||||
title: this.hass.localize("ui.panel.config.tag.caption"),
|
||||
@ -251,18 +267,6 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
||||
});
|
||||
}
|
||||
|
||||
private _createAutomation(tag: Tag) {
|
||||
const data = {
|
||||
alias: this.hass.localize(
|
||||
"ui.panel.config.tag.automation_title",
|
||||
"name",
|
||||
tag.name || tag.id
|
||||
),
|
||||
trigger: [{ platform: "tag", tag_id: tag.id } as TagTrigger],
|
||||
};
|
||||
showAutomationEditor(data);
|
||||
}
|
||||
|
||||
private _addTag() {
|
||||
this._openDialog();
|
||||
}
|
||||
|
@ -41,7 +41,6 @@ class HaPanelDevStatistics extends LitElement {
|
||||
this._validateStatistics();
|
||||
}
|
||||
|
||||
/* eslint-disable lit/no-template-arrow */
|
||||
private _columns = memoizeOne(
|
||||
(localize): DataTableColumnContainer => ({
|
||||
state: {
|
||||
@ -82,16 +81,13 @@ class HaPanelDevStatistics extends LitElement {
|
||||
issue.data
|
||||
) || issue.type
|
||||
)
|
||||
: ""}`,
|
||||
: "No issues"}`,
|
||||
},
|
||||
fix: {
|
||||
title: "",
|
||||
template: (_, data: any) =>
|
||||
html`${data.issues
|
||||
? html`<mwc-button
|
||||
@click=${(ev) => this._fixIssue(ev)}
|
||||
.data=${data.issues}
|
||||
>
|
||||
? html`<mwc-button @click=${this._fixIssue} .data=${data.issues}>
|
||||
Fix issue
|
||||
</mwc-button>`
|
||||
: ""}`,
|
||||
@ -99,7 +95,6 @@ class HaPanelDevStatistics extends LitElement {
|
||||
},
|
||||
})
|
||||
);
|
||||
/* eslint-enable lit/no-template-arrow */
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
@ -150,7 +145,7 @@ class HaPanelDevStatistics extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private _fixIssue(ev) {
|
||||
private _fixIssue = (ev) => {
|
||||
const issues = (ev.currentTarget.data as StatisticsValidationResult[]).sort(
|
||||
(itemA, itemB) =>
|
||||
(FIX_ISSUES_ORDER[itemA.type] ?? 99) -
|
||||
@ -236,7 +231,7 @@ class HaPanelDevStatistics extends LitElement {
|
||||
text: "Fixing this issue is not supported yet.",
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
|
@ -164,21 +164,6 @@ export class HuiEnergyDevicesGraphCard
|
||||
)
|
||||
);
|
||||
|
||||
const statisticsData = Object.values(this._data!);
|
||||
let endTime: Date;
|
||||
|
||||
endTime = new Date(
|
||||
Math.max(
|
||||
...statisticsData.map((stats) =>
|
||||
stats.length ? new Date(stats[stats.length - 1].start).getTime() : 0
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (!endTime || endTime > new Date()) {
|
||||
endTime = new Date();
|
||||
}
|
||||
|
||||
const data: Array<ChartDataset<"bar", ParsedDataType<"bar">>["data"]> = [];
|
||||
const borderColor: string[] = [];
|
||||
const backgroundColor: string[] = [];
|
||||
|
@ -220,21 +220,7 @@ export class HuiEnergyGasGraphCard
|
||||
|
||||
this._unit = getEnergyGasUnit(this.hass, energyData.prefs) || "m³";
|
||||
|
||||
const statisticsData = Object.values(energyData.stats);
|
||||
const datasets: ChartDataset<"bar">[] = [];
|
||||
let endTime: Date;
|
||||
|
||||
endTime = new Date(
|
||||
Math.max(
|
||||
...statisticsData.map((stats) =>
|
||||
stats.length ? new Date(stats[stats.length - 1].start).getTime() : 0
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (!endTime || endTime > new Date()) {
|
||||
endTime = new Date();
|
||||
}
|
||||
|
||||
const computedStyles = getComputedStyle(this);
|
||||
const gasColor = computedStyles
|
||||
|
@ -226,21 +226,7 @@ export class HuiEnergySolarGraphCard
|
||||
}
|
||||
}
|
||||
|
||||
const statisticsData = Object.values(energyData.stats);
|
||||
const datasets: ChartDataset<"bar">[] = [];
|
||||
let endTime: Date;
|
||||
|
||||
endTime = new Date(
|
||||
Math.max(
|
||||
...statisticsData.map((stats) =>
|
||||
stats.length ? new Date(stats[stats.length - 1].start).getTime() : 0
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (!endTime || endTime > new Date()) {
|
||||
endTime = new Date();
|
||||
}
|
||||
|
||||
const computedStyles = getComputedStyle(this);
|
||||
const solarColor = computedStyles
|
||||
|
@ -88,7 +88,7 @@ export class HuiEnergyUsageGraphCard
|
||||
)}
|
||||
chart-type="bar"
|
||||
></ha-chart-base>
|
||||
${!this._chartData.datasets.length
|
||||
${!this._chartData.datasets.some((dataset) => dataset.data.length)
|
||||
? html`<div class="no-data">
|
||||
${isToday(this._start)
|
||||
? "There is no data to show. It can take up to 2 hours for new data to arrive after you configure your energy dashboard."
|
||||
@ -228,6 +228,8 @@ export class HuiEnergyUsageGraphCard
|
||||
);
|
||||
|
||||
private async _getStatistics(energyData: EnergyData): Promise<void> {
|
||||
const datasets: ChartDataset<"bar">[] = [];
|
||||
|
||||
const statistics: {
|
||||
to_grid?: string[];
|
||||
from_grid?: string[];
|
||||
@ -283,33 +285,9 @@ export class HuiEnergyUsageGraphCard
|
||||
energyData.start
|
||||
);
|
||||
|
||||
const statisticsData = Object.values(energyData.stats);
|
||||
|
||||
const datasets: ChartDataset<"bar">[] = [];
|
||||
let endTime: Date;
|
||||
|
||||
this._start = energyData.start;
|
||||
this._end = energyData.end || endOfToday();
|
||||
|
||||
if (statisticsData.length === 0) {
|
||||
this._chartData = {
|
||||
datasets,
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
endTime = new Date(
|
||||
Math.max(
|
||||
...statisticsData.map((stats) =>
|
||||
stats.length ? new Date(stats[stats.length - 1].start).getTime() : 0
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (endTime > new Date()) {
|
||||
endTime = new Date();
|
||||
}
|
||||
|
||||
const combinedData: {
|
||||
to_grid?: { [statId: string]: { [start: string]: number } };
|
||||
to_battery?: { [statId: string]: { [start: string]: number } };
|
||||
|
@ -104,12 +104,7 @@ class HuiTimestampDisplay extends LitElement {
|
||||
this._relative =
|
||||
this._format === "relative"
|
||||
? relativeTime(this.ts, this.hass!.locale)
|
||||
: (this._relative = relativeTime(
|
||||
new Date(),
|
||||
this.hass!.locale,
|
||||
this.ts,
|
||||
false
|
||||
));
|
||||
: relativeTime(new Date(), this.hass!.locale, this.ts, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,8 +90,7 @@ export class HuiCreateDialogCard
|
||||
</ha-header-bar>
|
||||
<mwc-tab-bar
|
||||
.activeIndex=${this._currTabIndex}
|
||||
@MDCTabBar:activated=${(ev: CustomEvent) =>
|
||||
this._handleTabChanged(ev)}
|
||||
@MDCTabBar:activated=${this._handleTabChanged}
|
||||
>
|
||||
<mwc-tab
|
||||
.label=${this.hass!.localize(
|
||||
|
@ -218,7 +218,7 @@ class HaPanelMy extends LitElement {
|
||||
|
||||
protected render() {
|
||||
if (this._error) {
|
||||
let error = "Unknown error";
|
||||
let error: string;
|
||||
switch (this._error) {
|
||||
case "not_supported":
|
||||
error =
|
||||
|
@ -1091,10 +1091,14 @@
|
||||
"title": "Unexpected unit of measurement",
|
||||
"description": "The following entities do not have the expected units of measurement 'kWh', 'm³' or 'ft³':"
|
||||
},
|
||||
"entity_unexpected_unit_price": {
|
||||
"entity_unexpected_unit_energy_price": {
|
||||
"title": "Unexpected unit of measurement",
|
||||
"description": "The following entities do not have the expected units of measurement ''{currency}/kWh'' or ''{currency}/Wh'':"
|
||||
},
|
||||
"entity_unexpected_unit_gas_price": {
|
||||
"title": "Unexpected unit of measurement",
|
||||
"description": "The following entities do not have the expected units of measurement ''{currency}/kWh'', ''{currency}/Wh'', ''{currency}/m³'' or ''{currency}/ft³'':"
|
||||
},
|
||||
"entity_unexpected_state_class": {
|
||||
"title": "Unexpected state class",
|
||||
"description": "The following entities do not have the expected state class:"
|
||||
|
@ -124,7 +124,7 @@ hassAttributeUtil.LOGIC_STATE_ATTRIBUTES = {
|
||||
},
|
||||
state_class: {
|
||||
type: "array",
|
||||
options: { sensor: ["measurement"] },
|
||||
options: { sensor: ["measurement", "total", "total_increasing"] },
|
||||
description: "State class",
|
||||
domains: ["sensor"],
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user