mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-01 13:37:47 +00:00
Merge pull request #5620 from home-assistant/dev
This commit is contained in:
commit
eb4ba4fc78
@ -2,36 +2,10 @@ build
|
||||
build-translations/*
|
||||
translations/*
|
||||
node_modules/*
|
||||
npm-debug.log
|
||||
.DS_Store
|
||||
hass_frontend/*
|
||||
.reify-cache
|
||||
demo/hademo-icons.html
|
||||
|
||||
# Python stuff
|
||||
*.py[cod]
|
||||
*.egg
|
||||
*.egg-info
|
||||
|
||||
# venv stuff
|
||||
pyvenv.cfg
|
||||
pip-selfcheck.json
|
||||
venv
|
||||
.venv
|
||||
lib
|
||||
bin
|
||||
dist
|
||||
|
||||
# vscode
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
|
||||
# Cast dev settings
|
||||
src/cast/dev_const.ts
|
||||
|
||||
# Secrets
|
||||
.lokalise_token
|
||||
yarn-error.log
|
||||
|
||||
#asdf
|
||||
.tool-versions
|
||||
|
@ -32,6 +32,7 @@ import {
|
||||
import "../../../../src/layouts/loading-screen";
|
||||
import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config";
|
||||
import "./hc-layout";
|
||||
import "@material/mwc-button/mwc-button";
|
||||
|
||||
@customElement("hc-cast")
|
||||
class HcCast extends LitElement {
|
||||
|
@ -24,6 +24,7 @@ import "./hassio-addon-config";
|
||||
import "./hassio-addon-info";
|
||||
import "./hassio-addon-logs";
|
||||
import "./hassio-addon-network";
|
||||
import "../../../src/layouts/hass-subpage";
|
||||
|
||||
@customElement("hassio-addon-view")
|
||||
class HassioAddonView extends LitElement {
|
||||
|
@ -132,7 +132,7 @@ class HassioSnapshots extends LitElement {
|
||||
(addon, idx) => html`
|
||||
<paper-checkbox
|
||||
.idx=${idx}
|
||||
.checked="{{item.checked}}"
|
||||
.checked=${addon.checked}
|
||||
@checked-changed=${this._addonChecked}
|
||||
>
|
||||
${addon.name}
|
||||
@ -202,7 +202,6 @@ class HassioSnapshots extends LitElement {
|
||||
.icon=${snapshot.type === "full"
|
||||
? "hassio:package-variant-closed"
|
||||
: "hassio:package-variant"}
|
||||
.
|
||||
.icon-class="snapshot"
|
||||
></hassio-card-content>
|
||||
</div>
|
||||
|
10
package.json
10
package.json
@ -8,12 +8,12 @@
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"build": "script/build_frontend",
|
||||
"lint:eslint": "eslint '{**/src,src}/**/*.{js,ts,html}' --ignore-path .gitignore",
|
||||
"format:eslint": "eslint '{**/src,src}/**/*.{js,ts,html}' --fix --ignore-path .gitignore",
|
||||
"lint:prettier": "prettier '{**/src,src}/**/*.{js,ts,json,css,md}' --check",
|
||||
"format:prettier": "prettier '{**/src,src}/**/*.{js,ts,json,css,md}' --write",
|
||||
"lint:eslint": "eslint '**/src/**/*.{js,ts,html}' --ignore-path .gitignore",
|
||||
"format:eslint": "eslint '**/src/**/*.{js,ts,html}' --fix --ignore-path .gitignore",
|
||||
"lint:prettier": "prettier '**/src/**/*.{js,ts,json,css,md}' --check",
|
||||
"format:prettier": "prettier '**/src/**/*.{js,ts,json,css,md}' --write",
|
||||
"lint:types": "tsc",
|
||||
"lint:lit": "lit-analyzer '{**/src,src}/**/*.ts'",
|
||||
"lint:lit": "lit-analyzer '**/src/**/*.ts'",
|
||||
"lint": "npm run lint:eslint && npm run lint:prettier && npm run lint:types",
|
||||
"format": "npm run format:eslint && npm run format:prettier",
|
||||
"mocha": "node_modules/.bin/ts-mocha -p test-mocha/tsconfig.test.json --opts test-mocha/mocha.opts",
|
||||
|
2
setup.py
2
setup.py
@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name="home-assistant-frontend",
|
||||
version="20200422.0",
|
||||
version="20200424.0",
|
||||
description="The Home Assistant frontend",
|
||||
url="https://github.com/home-assistant/home-assistant-polymer",
|
||||
author="The Home Assistant Authors",
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { UNAVAILABLE, UNKNOWN } from "../../data/entity";
|
||||
import { atLeastCachedVersion } from "../config/version";
|
||||
import { formatDate } from "../datetime/format_date";
|
||||
import { formatDateTime } from "../datetime/format_date_time";
|
||||
import { formatTime } from "../datetime/format_time";
|
||||
import { LocalizeFunc } from "../translations/localize";
|
||||
import { computeStateDomain } from "./compute_state_domain";
|
||||
import { UNKNOWN, UNAVAILABLE } from "../../data/entity";
|
||||
import { atLeastCachedVersion } from "../config/version";
|
||||
|
||||
const legacyComputeStateDisplay = (
|
||||
localize: LocalizeFunc,
|
||||
@ -96,7 +96,6 @@ export const computeStateDisplay = (
|
||||
return legacyComputeStateDisplay(localize, stateObj, language);
|
||||
}
|
||||
|
||||
// Real code.
|
||||
if (stateObj.state === UNKNOWN || stateObj.state === UNAVAILABLE) {
|
||||
return localize(`state.default.${stateObj.state}`);
|
||||
}
|
||||
@ -141,9 +140,15 @@ export const computeStateDisplay = (
|
||||
return formatDateTime(date, language);
|
||||
}
|
||||
|
||||
const deviceClass = stateObj.attributes.device_class || "_";
|
||||
return (
|
||||
localize(`component.${domain}.state.${deviceClass}.${stateObj.state}`) ||
|
||||
// Return device class translation
|
||||
(stateObj.attributes.device_class &&
|
||||
localize(
|
||||
`component.${domain}.state.${stateObj.attributes.device_class}.${stateObj.state}`
|
||||
)) ||
|
||||
// Return default translation
|
||||
localize(`component.${domain}.state._.${stateObj.state}`) ||
|
||||
// We don't know! Return the raw state.
|
||||
stateObj.state
|
||||
);
|
||||
};
|
||||
|
@ -1,3 +1,5 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
LitElement,
|
||||
property,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import memoizeOne from "memoize-one";
|
||||
@ -91,12 +92,13 @@ class HaEntityPicker extends LitElement {
|
||||
|
||||
@property() public entityFilter?: HaEntityPickerEntityFilterFunc;
|
||||
|
||||
@property({ type: Boolean }) private _opened?: boolean;
|
||||
@property({ type: Boolean }) private _opened = false;
|
||||
|
||||
@property() private _hass?: HomeAssistant;
|
||||
@query("vaadin-combo-box-light") private _comboBox!: HTMLElement;
|
||||
|
||||
private _getStates = memoizeOne(
|
||||
(
|
||||
_opened: boolean,
|
||||
hass: this["hass"],
|
||||
includeDomains: this["includeDomains"],
|
||||
excludeDomains: this["excludeDomains"],
|
||||
@ -147,27 +149,28 @@ class HaEntityPicker extends LitElement {
|
||||
);
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
super.updated(changedProps);
|
||||
|
||||
if (changedProps.has("hass") && !this._opened) {
|
||||
this._hass = this.hass;
|
||||
if (changedProps.has("_opened") && this._opened) {
|
||||
const states = this._getStates(
|
||||
this._opened,
|
||||
this.hass,
|
||||
this.includeDomains,
|
||||
this.excludeDomains,
|
||||
this.entityFilter,
|
||||
this.includeDeviceClasses
|
||||
);
|
||||
(this._comboBox as any).items = states;
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const states = this._getStates(
|
||||
this._hass,
|
||||
this.includeDomains,
|
||||
this.excludeDomains,
|
||||
this.entityFilter,
|
||||
this.includeDeviceClasses
|
||||
);
|
||||
if (!this.hass) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
return html`
|
||||
<vaadin-combo-box-light
|
||||
item-value-path="entity_id"
|
||||
item-label-path="entity_id"
|
||||
.items=${states}
|
||||
.value=${this._value}
|
||||
.allowCustomValue=${this.allowCustomEntity}
|
||||
.renderer=${rowRenderer}
|
||||
@ -176,8 +179,8 @@ class HaEntityPicker extends LitElement {
|
||||
>
|
||||
<paper-input
|
||||
.autofocus=${this.autofocus}
|
||||
.label=${this.label === undefined && this._hass
|
||||
? this._hass.localize("ui.components.entity.entity-picker.entity")
|
||||
.label=${this.label === undefined
|
||||
? this.hass.localize("ui.components.entity.entity-picker.entity")
|
||||
: this.label}
|
||||
.value=${this._value}
|
||||
.disabled=${this.disabled}
|
||||
@ -190,7 +193,7 @@ class HaEntityPicker extends LitElement {
|
||||
${this.value
|
||||
? html`
|
||||
<paper-icon-button
|
||||
aria-label=${this.hass!.localize(
|
||||
aria-label=${this.hass.localize(
|
||||
"ui.components.entity.entity-picker.clear"
|
||||
)}
|
||||
slot="suffix"
|
||||
@ -203,20 +206,17 @@ class HaEntityPicker extends LitElement {
|
||||
</paper-icon-button>
|
||||
`
|
||||
: ""}
|
||||
${states.length > 0
|
||||
? html`
|
||||
<paper-icon-button
|
||||
aria-label=${this.hass!.localize(
|
||||
"ui.components.entity.entity-picker.show_entities"
|
||||
)}
|
||||
slot="suffix"
|
||||
class="toggle-button"
|
||||
.icon=${this._opened ? "hass:menu-up" : "hass:menu-down"}
|
||||
>
|
||||
Toggle
|
||||
</paper-icon-button>
|
||||
`
|
||||
: ""}
|
||||
|
||||
<paper-icon-button
|
||||
aria-label=${this.hass.localize(
|
||||
"ui.components.entity.entity-picker.show_entities"
|
||||
)}
|
||||
slot="suffix"
|
||||
class="toggle-button"
|
||||
.icon=${this._opened ? "hass:menu-up" : "hass:menu-down"}
|
||||
>
|
||||
Toggle
|
||||
</paper-icon-button>
|
||||
</paper-input>
|
||||
</vaadin-combo-box-light>
|
||||
`;
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
} from "lit-element";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import secondsToDuration from "../../common/datetime/seconds_to_duration";
|
||||
import { computeStateDisplay } from "../../common/entity/compute_state_display";
|
||||
import { computeStateDomain } from "../../common/entity/compute_state_domain";
|
||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||
import { domainIcon } from "../../common/entity/domain_icon";
|
||||
@ -18,7 +19,6 @@ import { stateIcon } from "../../common/entity/state_icon";
|
||||
import { timerTimeRemaining } from "../../common/entity/timer_time_remaining";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import "../ha-label-badge";
|
||||
import { computeStateDisplay } from "../../common/entity/compute_state_display";
|
||||
|
||||
@customElement("ha-state-label-badge")
|
||||
export class HaStateLabelBadge extends LitElement {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
|
@ -110,7 +110,7 @@ class HaClimateState extends LocalizeMixin(PolymerElement) {
|
||||
}
|
||||
|
||||
_localizeState(localize, stateObj) {
|
||||
const stateString = localize(`state.climate.${stateObj.state}`);
|
||||
const stateString = localize(`component.climate.state._.${stateObj.state}`);
|
||||
return stateObj.attributes.hvac_action
|
||||
? `${localize(
|
||||
`state_attributes.climate.hvac_action.${stateObj.attributes.hvac_action}`
|
||||
|
@ -4,6 +4,7 @@ import { ripple } from "@material/mwc-ripple/ripple-directive";
|
||||
import { customElement, html, TemplateResult } from "lit-element";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import type { Constructor } from "../types";
|
||||
import "./ha-icon";
|
||||
|
||||
const MwcFab = customElements.get("mwc-fab") as Constructor<Fab>;
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@polymer/iron-icon/iron-icon";
|
||||
import "@polymer/paper-checkbox/paper-checkbox";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-item/paper-icon-item";
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import "../paper-time-input";
|
||||
import { HaFormElement, HaFormTimeData, HaFormTimeSchema } from "./ha-form";
|
||||
|
||||
@customElement("ha-form-positive_time_period_dict")
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* eslint-disable lit/no-invalid-html */
|
||||
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
@ -96,7 +95,7 @@ export class HaRelatedItems extends SubscribeMixin(LitElement) {
|
||||
)}:
|
||||
</h3>
|
||||
<a
|
||||
href="/config/integrations#config_entry=${relatedConfigEntryId}"
|
||||
href=${`/config/integrations#config_entry=${relatedConfigEntryId}`}
|
||||
@click=${this._close}
|
||||
>
|
||||
${this.hass.localize(`component.${entry.domain}.title`)}:
|
||||
|
@ -76,7 +76,7 @@ class HaVacuumState extends LocalizeMixin(PolymerElement) {
|
||||
? this.localize(
|
||||
`ui.card.vacuum.actions.${STATES_INTERCEPTABLE[state].action}`
|
||||
)
|
||||
: this.localize(`state.vacuum.${state}`);
|
||||
: this.localize(`component.vacuum._.${state}`);
|
||||
}
|
||||
|
||||
_callService(ev) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
/* eslint-plugin-disable lit */
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||
import LocalizeMixin from "../mixins/localize-mixin";
|
||||
|
||||
/*
|
||||
@ -32,7 +33,7 @@ class HaWaterHeaterState extends LocalizeMixin(PolymerElement) {
|
||||
</style>
|
||||
|
||||
<div class="target">
|
||||
<span class="state-label"> [[_localizeState(stateObj.state)]] </span>
|
||||
<span class="state-label"> [[_localizeState(stateObj)]] </span>
|
||||
[[computeTarget(hass, stateObj)]]
|
||||
</div>
|
||||
|
||||
@ -67,8 +68,8 @@ class HaWaterHeaterState extends LocalizeMixin(PolymerElement) {
|
||||
return "";
|
||||
}
|
||||
|
||||
_localizeState(state) {
|
||||
return this.localize(`state.water_heater.${state}`) || state;
|
||||
_localizeState(stateObj) {
|
||||
return computeStateDisplay(this.hass.localize, stateObj);
|
||||
}
|
||||
}
|
||||
customElements.define("ha-water_heater-state", HaWaterHeaterState);
|
||||
|
@ -17,6 +17,7 @@ import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { compare } from "../../common/string/compare";
|
||||
import { fetchUsers, User } from "../../data/user";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import "./ha-user-badge";
|
||||
|
||||
class HaUserPicker extends LitElement {
|
||||
public hass?: HomeAssistant;
|
||||
|
@ -8,12 +8,12 @@ import {
|
||||
getConfigFlowHandlers,
|
||||
handleConfigFlowStep,
|
||||
} from "../../data/config_flow";
|
||||
import { domainToName } from "../../data/integration";
|
||||
import {
|
||||
DataEntryFlowDialogParams,
|
||||
loadDataEntryFlowDialog,
|
||||
showFlowDialog,
|
||||
} from "./show-dialog-data-entry-flow";
|
||||
import { domainToName } from "../../data/integration";
|
||||
|
||||
export const loadConfigFlowDialog = loadDataEntryFlowDialog;
|
||||
|
||||
|
@ -16,12 +16,12 @@ import { styleMap } from "lit-html/directives/style-map";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import "../../common/search/search-input";
|
||||
import { LocalizeFunc } from "../../common/translations/localize";
|
||||
import "../../components/ha-icon-next";
|
||||
import { domainToName } from "../../data/integration";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { FlowConfig } from "./show-dialog-data-entry-flow";
|
||||
import { configFlowContentStyles } from "./styles";
|
||||
import { domainToName } from "../../data/integration";
|
||||
import { LocalizeFunc } from "../../common/translations/localize";
|
||||
|
||||
interface HandlerObj {
|
||||
name: string;
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import {
|
||||
css,
|
||||
CSSResultArray,
|
||||
@ -8,11 +9,11 @@ import {
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import "../../components/dialog/ha-paper-dialog";
|
||||
import { domainToName } from "../../data/integration";
|
||||
import { PolymerChangedEvent } from "../../polymer-types";
|
||||
import { haStyleDialog } from "../../resources/styles";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { HaDomainTogglerDialogParams } from "./show-dialog-domain-toggler";
|
||||
import { domainToName } from "../../data/integration";
|
||||
|
||||
@customElement("dialog-domain-toggler")
|
||||
class DomainTogglerDialog extends LitElement {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import {
|
||||
@ -72,6 +73,7 @@ class DialogBox extends LitElement {
|
||||
autofocus
|
||||
.value=${this._value}
|
||||
@value-changed=${this._valueChanged}
|
||||
@keyup=${this._handleKeyUp}
|
||||
.label=${this._params.inputLabel
|
||||
? this._params.inputLabel
|
||||
: ""}
|
||||
@ -112,6 +114,12 @@ class DialogBox extends LitElement {
|
||||
this._params = undefined;
|
||||
}
|
||||
|
||||
private _handleKeyUp(ev: KeyboardEvent) {
|
||||
if (ev.keyCode === 13) {
|
||||
this._confirm();
|
||||
}
|
||||
}
|
||||
|
||||
private async _confirm(): Promise<void> {
|
||||
if (this._params!.confirm) {
|
||||
this._params!.confirm(this._value);
|
||||
|
@ -185,7 +185,7 @@ class MoreInfoClimate extends LitElement {
|
||||
.map(
|
||||
(mode) => html`
|
||||
<paper-item item-name=${mode}>
|
||||
${hass.localize(`state.climate.${mode}`)}
|
||||
${hass.localize(`component.climate.state._.${mode}`)}
|
||||
</paper-item>
|
||||
`
|
||||
)}
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
} from "lit-element";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/ha-attributes";
|
||||
import "../../../components/map/ha-map";
|
||||
import { showZoneEditor } from "../../../data/zone";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import "../../../components/ha-attributes";
|
||||
import { TimerEntity } from "../../../data/timer";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
|
||||
|
@ -246,7 +246,7 @@ class MoreInfoWaterHeater extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||
}
|
||||
|
||||
_localizeOperationMode(localize, mode) {
|
||||
return localize(`state.water_heater.${mode}`) || mode;
|
||||
return localize(`component.water_heater.state._.${mode}`) || mode;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,23 +1,24 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import {
|
||||
LitElement,
|
||||
css,
|
||||
html,
|
||||
CSSResult,
|
||||
TemplateResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||
import "../../components/ha-dialog";
|
||||
import "../../components/ha-switch";
|
||||
import { computeDeviceName } from "../../data/device_registry";
|
||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||
import { haStyleDialog } from "../../resources/styles";
|
||||
import type { HaSwitch } from "../../components/ha-switch";
|
||||
import { computeDeviceName } from "../../data/device_registry";
|
||||
import { fetchMQTTDebugInfo, MQTTDeviceDebugInfo } from "../../data/mqtt";
|
||||
import { haStyleDialog } from "../../resources/styles";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { MQTTDeviceDebugInfoDialogParams } from "./show-dialog-mqtt-device-debug-info";
|
||||
import { MQTTDeviceDebugInfo, fetchMQTTDebugInfo } from "../../data/mqtt";
|
||||
import "./mqtt-messages";
|
||||
import "./mqtt-discovery-payload";
|
||||
import "./mqtt-messages";
|
||||
import { MQTTDeviceDebugInfoDialogParams } from "./show-dialog-mqtt-device-debug-info";
|
||||
|
||||
@customElement("dialog-mqtt-device-debug-info")
|
||||
class DialogMQTTDeviceDebugInfo extends LitElement {
|
||||
|
@ -1,11 +1,11 @@
|
||||
import {
|
||||
LitElement,
|
||||
html,
|
||||
TemplateResult,
|
||||
customElement,
|
||||
property,
|
||||
} from "lit-element";
|
||||
import { safeDump } from "js-yaml";
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
|
||||
@customElement("mqtt-discovery-payload")
|
||||
class MQTTDiscoveryPayload extends LitElement {
|
||||
|
@ -1,11 +1,11 @@
|
||||
import {
|
||||
LitElement,
|
||||
html,
|
||||
TemplateResult,
|
||||
customElement,
|
||||
property,
|
||||
} from "lit-element";
|
||||
import { safeDump } from "js-yaml";
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { MQTTMessage } from "../../data/mqtt";
|
||||
|
||||
@customElement("mqtt-messages")
|
||||
|
@ -7,10 +7,11 @@ import {
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { computeStateDisplay } from "../../common/entity/compute_state_display";
|
||||
import { domainToName } from "../../data/integration";
|
||||
import { PersitentNotificationEntity } from "../../data/persistent_notification";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import "./notification-item-template";
|
||||
import { domainToName } from "../../data/integration";
|
||||
|
||||
@customElement("configurator-notification-item")
|
||||
export class HuiConfiguratorNotificationItem extends LitElement {
|
||||
@ -38,8 +39,10 @@ export class HuiConfiguratorNotificationItem extends LitElement {
|
||||
</div>
|
||||
|
||||
<mwc-button slot="actions" @click="${this._handleClick}"
|
||||
>${this.hass.localize(
|
||||
`state.configurator.${this.notification.state}`
|
||||
>${computeStateDisplay(
|
||||
this.hass.localize,
|
||||
this.notification,
|
||||
this.hass.language
|
||||
)}</mwc-button
|
||||
>
|
||||
</notification-item-template>
|
||||
|
@ -1,3 +1,5 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@polymer/paper-tooltip/paper-tooltip";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
@ -8,6 +10,7 @@ import {
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { navigate } from "../common/navigate";
|
||||
import "../components/data-table/ha-data-table";
|
||||
import type {
|
||||
DataTableColumnContainer,
|
||||
@ -17,9 +20,6 @@ import type {
|
||||
import type { HomeAssistant, Route } from "../types";
|
||||
import "./hass-tabs-subpage";
|
||||
import type { PageNavigation } from "./hass-tabs-subpage";
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import { navigate } from "../common/navigate";
|
||||
import "@polymer/paper-tooltip/paper-tooltip";
|
||||
|
||||
@customElement("hass-tabs-subpage-data-table")
|
||||
export class HaTabsSubpageDataTable extends LitElement {
|
||||
|
@ -16,6 +16,7 @@ import { navigate } from "../common/navigate";
|
||||
import "../components/ha-menu-button";
|
||||
import "../components/ha-paper-icon-button-arrow-prev";
|
||||
import { HomeAssistant, Route } from "../types";
|
||||
import "../components/ha-icon";
|
||||
|
||||
export interface PageNavigation {
|
||||
path: string;
|
||||
@ -228,6 +229,10 @@ class HassTabsSubpage extends LitElement {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
:host(:not([narrow])) #toolbar-icon {
|
||||
min-width: 40px;
|
||||
}
|
||||
|
||||
ha-menu-button,
|
||||
ha-paper-icon-button-arrow-prev,
|
||||
::slotted([slot="toolbar-icon"]) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import "@polymer/app-route/app-location";
|
||||
import { html, property, PropertyValues } from "lit-element";
|
||||
import { setHAVersion } from "../common/config/version";
|
||||
import { navigate } from "../common/navigate";
|
||||
import { getStorageDefaultPanelUrlPath } from "../data/panel";
|
||||
import "../resources/custom-card-support";
|
||||
@ -12,7 +13,6 @@ import {
|
||||
} from "../util/register-service-worker";
|
||||
import "./ha-init-page";
|
||||
import "./home-assistant-main";
|
||||
import { setHAVersion } from "../common/config/version";
|
||||
|
||||
export class HomeAssistantAppEl extends HassElement {
|
||||
@property() private _route?: Route;
|
||||
|
@ -24,10 +24,10 @@ import {
|
||||
import { subscribeUser } from "../data/ws-user";
|
||||
import { litLocalizeLiteMixin } from "../mixins/lit-localize-lite-mixin";
|
||||
import { HassElement } from "../state/hass-element";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { registerServiceWorker } from "../util/register-service-worker";
|
||||
import "./onboarding-create-user";
|
||||
import "./onboarding-loading";
|
||||
import { HomeAssistant } from "../types";
|
||||
|
||||
interface OnboardingEvent<T extends ValidOnboardingStep> {
|
||||
type: T;
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
subscribeConfigFlowInProgress,
|
||||
} from "../data/config_flow";
|
||||
import { DataEntryFlowProgress } from "../data/data_entry_flow";
|
||||
import { domainToName } from "../data/integration";
|
||||
import { onboardIntegrationStep } from "../data/onboarding";
|
||||
import {
|
||||
loadConfigFlowDialog,
|
||||
@ -28,7 +29,6 @@ import {
|
||||
import { HomeAssistant } from "../types";
|
||||
import "./action-badge";
|
||||
import "./integration-badge";
|
||||
import { domainToName } from "../data/integration";
|
||||
|
||||
@customElement("onboarding-integrations")
|
||||
class OnboardingIntegrations extends LitElement {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-listbox/paper-listbox";
|
||||
|
@ -6,6 +6,8 @@ import { PolymerChangedEvent } from "../../../../../polymer-types";
|
||||
import { HomeAssistant } from "../../../../../types";
|
||||
import { ActionElement } from "../ha-automation-action-row";
|
||||
|
||||
const includeDomains = ["scene"];
|
||||
|
||||
@customElement("ha-automation-action-scene")
|
||||
export class HaSceneAction extends LitElement implements ActionElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@ -24,7 +26,7 @@ export class HaSceneAction extends LitElement implements ActionElement {
|
||||
.hass=${this.hass}
|
||||
.value=${scene}
|
||||
@value-changed=${this._entityPicked}
|
||||
.includeDomains=${["scene"]}
|
||||
.includeDomains=${includeDomains}
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
`;
|
||||
|
@ -34,6 +34,8 @@ export class HaServiceAction extends LitElement implements ActionElement {
|
||||
return { service: "", data: {} };
|
||||
}
|
||||
|
||||
private _domain = memoizeOne((service: string) => [computeDomain(service)]);
|
||||
|
||||
private _getServiceData = memoizeOne((service: string) => {
|
||||
if (!service) {
|
||||
return [];
|
||||
@ -85,7 +87,7 @@ export class HaServiceAction extends LitElement implements ActionElement {
|
||||
.value=${entity_id}
|
||||
.label=${entity.description}
|
||||
@value-changed=${this._entityPicked}
|
||||
.includeDomains=${[computeDomain(service)]}
|
||||
.includeDomains=${this._domain(service)}
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
`
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-listbox/paper-listbox";
|
||||
import type { PaperListboxElement } from "@polymer/paper-listbox/paper-listbox";
|
||||
@ -7,6 +8,7 @@ import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-card";
|
||||
import type { Condition } from "../../../../data/automation";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import "../../../../components/ha-yaml-editor";
|
||||
import "./types/ha-automation-condition-and";
|
||||
import "./types/ha-automation-condition-device";
|
||||
import "./types/ha-automation-condition-numeric_state";
|
||||
|
@ -12,6 +12,8 @@ function zoneAndLocationFilter(stateObj) {
|
||||
return hasLocation(stateObj) && computeStateDomain(stateObj) !== "zone";
|
||||
}
|
||||
|
||||
const includeDomains = ["zone"];
|
||||
|
||||
@customElement("ha-automation-condition-zone")
|
||||
export class HaZoneCondition extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@ -46,7 +48,7 @@ export class HaZoneCondition extends LitElement {
|
||||
@value-changed=${this._zonePicked}
|
||||
.hass=${this.hass}
|
||||
allow-custom-entity
|
||||
.includeDomains=${["zone"]}
|
||||
.includeDomains=${includeDomains}
|
||||
></ha-entity-picker>
|
||||
<label id="eventlabel">
|
||||
${this.hass.localize(
|
||||
|
@ -45,7 +45,9 @@ import { HaDeviceTrigger } from "./trigger/types/ha-automation-trigger-device";
|
||||
export class HaAutomationEditor extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
|
||||
@property() public automation!: AutomationEntity;
|
||||
@property() public automationId!: string;
|
||||
|
||||
@property() public automations!: AutomationEntity[];
|
||||
|
||||
@property() public isWide?: boolean;
|
||||
|
||||
@ -53,15 +55,18 @@ export class HaAutomationEditor extends LitElement {
|
||||
|
||||
@property() public route!: Route;
|
||||
|
||||
@property() public creatingNew?: boolean;
|
||||
|
||||
@property() private _config?: AutomationConfig;
|
||||
|
||||
@property() private _dirty?: boolean;
|
||||
|
||||
@property() private _errors?: string;
|
||||
|
||||
@property() private _entityId?: string;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const stateObj = this._entityId
|
||||
? this.hass.states[this._entityId]
|
||||
: undefined;
|
||||
return html`
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
@ -70,7 +75,7 @@ export class HaAutomationEditor extends LitElement {
|
||||
.backCallback=${() => this._backTapped()}
|
||||
.tabs=${configSections.automation}
|
||||
>
|
||||
${this.creatingNew
|
||||
${!this.automationId
|
||||
? ""
|
||||
: html`
|
||||
<paper-icon-button
|
||||
@ -82,153 +87,162 @@ export class HaAutomationEditor extends LitElement {
|
||||
@click=${this._deleteConfirm}
|
||||
></paper-icon-button>
|
||||
`}
|
||||
${this._errors ? html` <div class="errors">${this._errors}</div> ` : ""}
|
||||
${this._config
|
||||
? html`
|
||||
${this.narrow
|
||||
? html` <span slot="header">${this._config?.alias}</span> `
|
||||
: ""}
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
${!this.narrow
|
||||
? html` <span slot="header">${this._config.alias}</span> `
|
||||
<div class="content">
|
||||
${this._errors
|
||||
? html` <div class="errors">${this._errors}</div> `
|
||||
: ""}
|
||||
<span slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.introduction"
|
||||
)}
|
||||
</span>
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<paper-input
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.alias"
|
||||
)}
|
||||
name="alias"
|
||||
.value=${this._config.alias}
|
||||
@value-changed=${this._valueChanged}
|
||||
>
|
||||
</paper-input>
|
||||
<ha-textarea
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.label"
|
||||
)}
|
||||
.placeholder=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.placeholder"
|
||||
)}
|
||||
name="description"
|
||||
.value=${this._config.description}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-textarea>
|
||||
</div>
|
||||
${this.creatingNew
|
||||
? ""
|
||||
: html`
|
||||
<div
|
||||
class="card-actions layout horizontal justified center"
|
||||
>
|
||||
<div class="layout horizontal center">
|
||||
<ha-entity-toggle
|
||||
.hass=${this.hass}
|
||||
.stateObj=${this.automation}
|
||||
></ha-entity-toggle>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.enable_disable"
|
||||
)}
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
${!this.narrow
|
||||
? html` <span slot="header">${this._config.alias}</span> `
|
||||
: ""}
|
||||
<span slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.introduction"
|
||||
)}
|
||||
</span>
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<paper-input
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.alias"
|
||||
)}
|
||||
name="alias"
|
||||
.value=${this._config.alias}
|
||||
@value-changed=${this._valueChanged}
|
||||
>
|
||||
</paper-input>
|
||||
<ha-textarea
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.label"
|
||||
)}
|
||||
.placeholder=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.placeholder"
|
||||
)}
|
||||
name="description"
|
||||
.value=${this._config.description}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-textarea>
|
||||
</div>
|
||||
${stateObj
|
||||
? html`
|
||||
<div
|
||||
class="card-actions layout horizontal justified center"
|
||||
>
|
||||
<div class="layout horizontal center">
|
||||
<ha-entity-toggle
|
||||
.hass=${this.hass}
|
||||
.stateObj=${stateObj}
|
||||
></ha-entity-toggle>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.enable_disable"
|
||||
)}
|
||||
</div>
|
||||
<mwc-button
|
||||
@click=${this._excuteAutomation}
|
||||
.stateObj=${stateObj}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.card.automation.trigger"
|
||||
)}
|
||||
</mwc-button>
|
||||
</div>
|
||||
<mwc-button @click=${this._excuteAutomation}>
|
||||
${this.hass.localize("ui.card.automation.trigger")}
|
||||
</mwc-button>
|
||||
</div>
|
||||
`}
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
`
|
||||
: ""}
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.introduction"
|
||||
"ui.panel.config.automation.editor.triggers.header"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/automation/trigger/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-trigger
|
||||
.triggers=${this._config.trigger}
|
||||
@value-changed=${this._triggerChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-trigger>
|
||||
</ha-config-section>
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.introduction"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/automation/trigger/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-trigger
|
||||
.triggers=${this._config.trigger}
|
||||
@value-changed=${this._triggerChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-trigger>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.introduction"
|
||||
"ui.panel.config.automation.editor.conditions.header"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/scripts/conditions/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-condition
|
||||
.conditions=${this._config.condition || []}
|
||||
@value-changed=${this._conditionChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-condition>
|
||||
</ha-config-section>
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.introduction"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/scripts/conditions/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-condition
|
||||
.conditions=${this._config.condition || []}
|
||||
@value-changed=${this._conditionChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-condition>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.introduction"
|
||||
"ui.panel.config.automation.editor.actions.header"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/automation/action/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-action
|
||||
.actions=${this._config.action}
|
||||
@value-changed=${this._actionChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-action>
|
||||
</ha-config-section>
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.introduction"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/automation/action/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-action
|
||||
.actions=${this._config.action}
|
||||
@value-changed=${this._actionChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-action>
|
||||
</ha-config-section>
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
<ha-fab
|
||||
@ -251,19 +265,19 @@ export class HaAutomationEditor extends LitElement {
|
||||
protected updated(changedProps: PropertyValues): void {
|
||||
super.updated(changedProps);
|
||||
|
||||
const oldAutomation = changedProps.get("automation") as AutomationEntity;
|
||||
const oldAutomationId = changedProps.get("automationId");
|
||||
if (
|
||||
changedProps.has("automation") &&
|
||||
this.automation &&
|
||||
changedProps.has("automationId") &&
|
||||
this.automationId &&
|
||||
this.hass &&
|
||||
// Only refresh config if we picked a new automation. If same ID, don't fetch it.
|
||||
(!oldAutomation ||
|
||||
oldAutomation.attributes.id !== this.automation.attributes.id)
|
||||
oldAutomationId !== this.automationId
|
||||
) {
|
||||
this._setEntityId();
|
||||
this.hass
|
||||
.callApi<AutomationConfig>(
|
||||
"GET",
|
||||
`config/automation/config/${this.automation.attributes.id}`
|
||||
`config/automation/config/${this.automationId}`
|
||||
)
|
||||
.then(
|
||||
(config) => {
|
||||
@ -290,13 +304,12 @@ export class HaAutomationEditor extends LitElement {
|
||||
"err_no",
|
||||
resp.status_code
|
||||
),
|
||||
});
|
||||
history.back();
|
||||
}).then(() => history.back());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (changedProps.has("creatingNew") && this.creatingNew && this.hass) {
|
||||
if (changedProps.has("automationId") && !this.automationId && this.hass) {
|
||||
const initData = getAutomationEditorInitData();
|
||||
this._dirty = !!initData;
|
||||
this._config = {
|
||||
@ -310,6 +323,21 @@ export class HaAutomationEditor extends LitElement {
|
||||
...initData,
|
||||
};
|
||||
}
|
||||
|
||||
if (
|
||||
changedProps.has("automations") &&
|
||||
this.automationId &&
|
||||
!this._entityId
|
||||
) {
|
||||
this._setEntityId();
|
||||
}
|
||||
}
|
||||
|
||||
private _setEntityId() {
|
||||
const automation = this.automations.find(
|
||||
(entity: AutomationEntity) => entity.attributes.id === this.automationId
|
||||
);
|
||||
this._entityId = automation?.entity_id;
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent) {
|
||||
@ -348,8 +376,8 @@ export class HaAutomationEditor extends LitElement {
|
||||
this._dirty = true;
|
||||
}
|
||||
|
||||
private _excuteAutomation() {
|
||||
triggerAutomation(this.hass, this.automation.entity_id);
|
||||
private _excuteAutomation(ev: Event) {
|
||||
triggerAutomation(this.hass, (ev.target as any).stateObj.entity_id);
|
||||
}
|
||||
|
||||
private _backTapped(): void {
|
||||
@ -379,14 +407,12 @@ export class HaAutomationEditor extends LitElement {
|
||||
}
|
||||
|
||||
private async _delete() {
|
||||
await deleteAutomation(this.hass, this.automation.attributes.id!);
|
||||
await deleteAutomation(this.hass, this.automationId);
|
||||
history.back();
|
||||
}
|
||||
|
||||
private _saveAutomation(): void {
|
||||
const id = this.creatingNew
|
||||
? "" + Date.now()
|
||||
: this.automation.attributes.id;
|
||||
const id = this.automationId || String(Date.now());
|
||||
this.hass!.callApi(
|
||||
"POST",
|
||||
"config/automation/config/" + id,
|
||||
@ -395,7 +421,7 @@ export class HaAutomationEditor extends LitElement {
|
||||
() => {
|
||||
this._dirty = false;
|
||||
|
||||
if (this.creatingNew) {
|
||||
if (!this.automationId) {
|
||||
navigate(this, `/config/automation/edit/${id}`, true);
|
||||
}
|
||||
},
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import "./ha-automation-editor";
|
||||
import "./ha-automation-picker";
|
||||
import { debounce } from "../../../common/util/debounce";
|
||||
|
||||
@customElement("ha-config-automation")
|
||||
class HaConfigAutomation extends HassRouterPage {
|
||||
@ -23,6 +24,13 @@ class HaConfigAutomation extends HassRouterPage {
|
||||
|
||||
@property() public automations: AutomationEntity[] = [];
|
||||
|
||||
private _debouncedUpdateAutomations = debounce((pageEl) => {
|
||||
const newAutomations = this._getAutomations(this.hass.states);
|
||||
if (!this._equal(newAutomations, pageEl.automations)) {
|
||||
pageEl.automations = newAutomations;
|
||||
}
|
||||
}, 10);
|
||||
|
||||
protected routerOptions: RouterOptions = {
|
||||
defaultPage: "dashboard",
|
||||
routes: {
|
||||
@ -36,19 +44,15 @@ class HaConfigAutomation extends HassRouterPage {
|
||||
},
|
||||
};
|
||||
|
||||
private _computeAutomations = memoizeOne((states: HassEntities) => {
|
||||
const automations: AutomationEntity[] = [];
|
||||
Object.values(states).forEach((state) => {
|
||||
if (
|
||||
computeStateDomain(state) === "automation" &&
|
||||
!state.attributes.hidden
|
||||
) {
|
||||
automations.push(state as AutomationEntity);
|
||||
}
|
||||
});
|
||||
|
||||
return automations;
|
||||
});
|
||||
private _getAutomations = memoizeOne(
|
||||
(states: HassEntities): AutomationEntity[] => {
|
||||
return Object.values(states).filter(
|
||||
(entity) =>
|
||||
computeStateDomain(entity) === "automation" &&
|
||||
!entity.attributes.hidden
|
||||
) as AutomationEntity[];
|
||||
}
|
||||
);
|
||||
|
||||
protected firstUpdated(changedProps) {
|
||||
super.firstUpdated(changedProps);
|
||||
@ -63,25 +67,28 @@ class HaConfigAutomation extends HassRouterPage {
|
||||
pageEl.showAdvanced = this.showAdvanced;
|
||||
|
||||
if (this.hass) {
|
||||
pageEl.automations = this._computeAutomations(this.hass.states);
|
||||
if (!pageEl.automations || !changedProps) {
|
||||
pageEl.automations = this._getAutomations(this.hass.states);
|
||||
} else if (changedProps && changedProps.has("hass")) {
|
||||
this._debouncedUpdateAutomations(pageEl);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(!changedProps || changedProps.has("route")) &&
|
||||
this._currentPage === "edit"
|
||||
) {
|
||||
pageEl.creatingNew = undefined;
|
||||
const automationId = this.routeTail.path.substr(1);
|
||||
pageEl.creatingNew = automationId === "new";
|
||||
pageEl.automation =
|
||||
automationId === "new"
|
||||
? undefined
|
||||
: pageEl.automations.find(
|
||||
(entity: AutomationEntity) =>
|
||||
entity.attributes.id === automationId
|
||||
);
|
||||
pageEl.automationId = automationId === "new" ? null : automationId;
|
||||
}
|
||||
}
|
||||
|
||||
private _equal(a: AutomationEntity[], b: AutomationEntity[]): boolean {
|
||||
if (a.length !== b.length) {
|
||||
return false;
|
||||
}
|
||||
return a.every((automation, index) => automation === b[index]);
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -22,12 +22,13 @@ import {
|
||||
subscribeDeviceRegistry,
|
||||
} from "../../../../data/device_registry";
|
||||
import { subscribeEntityRegistry } from "../../../../data/entity_registry";
|
||||
import { domainToName } from "../../../../data/integration";
|
||||
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
||||
import { PolymerChangedEvent } from "../../../../polymer-types";
|
||||
import { haStyleDialog } from "../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import "../../../../components/entity/ha-entity-picker";
|
||||
import { Placeholder, PlaceholderContainer } from "./dialog-thingtalk";
|
||||
import { domainToName } from "../../../../data/integration";
|
||||
|
||||
declare global {
|
||||
// for fire event
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-listbox/paper-listbox";
|
||||
|
@ -8,6 +8,8 @@ import type { GeoLocationTrigger } from "../../../../../data/automation";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import { handleChangeEvent } from "../ha-automation-trigger-row";
|
||||
|
||||
const includeDomains = ["zone"];
|
||||
|
||||
@customElement("ha-automation-trigger-geo_location")
|
||||
export default class HaGeolocationTrigger extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@ -42,7 +44,7 @@ export default class HaGeolocationTrigger extends LitElement {
|
||||
@value-changed=${this._zonePicked}
|
||||
.hass=${this.hass}
|
||||
allow-custom-entity
|
||||
.includeDomains=${["zone"]}
|
||||
.includeDomains=${includeDomains}
|
||||
></ha-entity-picker>
|
||||
<label id="eventlabel">
|
||||
${this.hass.localize(
|
||||
|
@ -14,6 +14,8 @@ function zoneAndLocationFilter(stateObj) {
|
||||
return hasLocation(stateObj) && computeStateDomain(stateObj) !== "zone";
|
||||
}
|
||||
|
||||
const includeDomains = ["zone"];
|
||||
|
||||
@customElement("ha-automation-trigger-zone")
|
||||
export class HaZoneTrigger extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@ -49,7 +51,7 @@ export class HaZoneTrigger extends LitElement {
|
||||
@value-changed=${this._zonePicked}
|
||||
.hass=${this.hass}
|
||||
allow-custom-entity
|
||||
.includeDomains=${["zone"]}
|
||||
.includeDomains=${includeDomains}
|
||||
></ha-entity-picker>
|
||||
<label id="eventlabel">
|
||||
${this.hass.localize(
|
||||
|
@ -42,7 +42,8 @@ class HaConfigNavigation extends LitElement {
|
||||
<ha-icon .icon=${page.icon} slot="item-icon"></ha-icon>
|
||||
<paper-item-body two-line>
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.${page.component}.caption`
|
||||
page.translationKey ||
|
||||
`ui.panel.config.${page.component}.caption`
|
||||
)}
|
||||
${page.component === "cloud" && (page.info as CloudStatus)
|
||||
? page.info.logged_in
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { DeviceRegistryEntry } from "../../../../data/device_registry";
|
||||
import { removeMQTTDeviceEntry } from "../../../../data/mqtt";
|
||||
import {
|
||||
LitElement,
|
||||
html,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
CSSResult,
|
||||
} from "lit-element";
|
||||
import { DeviceRegistryEntry } from "../../../../data/device_registry";
|
||||
import { removeMQTTDeviceEntry } from "../../../../data/mqtt";
|
||||
import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box";
|
||||
import { showMQTTDeviceDebugInfoDialog } from "../../../../dialogs/mqtt-device-debug-info-dialog/show-dialog-mqtt-device-debug-info";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import { haStyle } from "../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
|
||||
@customElement("ha-device-card-mqtt")
|
||||
export class HaDeviceCardMqtt extends LitElement {
|
||||
|
@ -14,6 +14,7 @@ import {
|
||||
DataTableRowData,
|
||||
RowClickedEvent,
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/entity/ha-state-icon";
|
||||
import { AreaRegistryEntry } from "../../../data/area_registry";
|
||||
import { ConfigEntry } from "../../../data/config_entries";
|
||||
import {
|
||||
@ -25,11 +26,10 @@ import {
|
||||
EntityRegistryEntry,
|
||||
findBatteryEntity,
|
||||
} from "../../../data/entity_registry";
|
||||
import { domainToName } from "../../../data/integration";
|
||||
import "../../../layouts/hass-tabs-subpage-data-table";
|
||||
import "../../../components/entity/ha-state-icon";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import { domainToName } from "../../../data/integration";
|
||||
|
||||
interface DeviceRowData extends DeviceRegistryEntry {
|
||||
device?: DeviceRowData;
|
||||
|
@ -1,4 +1,6 @@
|
||||
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
||||
import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable";
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-tabs/paper-tab";
|
||||
import "@polymer/paper-tabs/paper-tabs";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import {
|
||||
|
@ -22,7 +22,9 @@ import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { domainIcon } from "../../../common/entity/domain_icon";
|
||||
import { stateIcon } from "../../../common/entity/state_icon";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import "../../../common/search/search-input";
|
||||
import { LocalizeFunc } from "../../../common/translations/localize";
|
||||
import type {
|
||||
DataTableColumnContainer,
|
||||
DataTableColumnData,
|
||||
@ -30,6 +32,7 @@ import type {
|
||||
SelectionChangedEvent,
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/ha-icon";
|
||||
import { ConfigEntry, getConfigEntries } from "../../../data/config_entries";
|
||||
import {
|
||||
computeEntityRegistryName,
|
||||
EntityRegistryEntry,
|
||||
@ -37,6 +40,7 @@ import {
|
||||
subscribeEntityRegistry,
|
||||
updateEntityRegistryEntry,
|
||||
} from "../../../data/entity_registry";
|
||||
import { domainToName } from "../../../data/integration";
|
||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import "../../../layouts/hass-loading-screen";
|
||||
import "../../../layouts/hass-tabs-subpage-data-table";
|
||||
@ -49,10 +53,6 @@ import {
|
||||
loadEntityEditorDialog,
|
||||
showEntityEditorDialog,
|
||||
} from "./show-dialog-entity-editor";
|
||||
import { getConfigEntries, ConfigEntry } from "../../../data/config_entries";
|
||||
import { LocalizeFunc } from "../../../common/translations/localize";
|
||||
import { domainToName } from "../../../data/integration";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
|
||||
export interface StateEntity extends EntityRegistryEntry {
|
||||
readonly?: boolean;
|
||||
|
@ -132,13 +132,13 @@ export const configSections: { [name: string]: PageNavigation[] } = {
|
||||
{
|
||||
component: "zha",
|
||||
path: "/config/zha",
|
||||
translationKey: "ui.panel.config.zha.caption",
|
||||
translationKey: "component.zha.title",
|
||||
icon: "hass:zigbee",
|
||||
},
|
||||
{
|
||||
component: "zwave",
|
||||
path: "/config/zwave",
|
||||
translationKey: "ui.panel.config.zwave.caption",
|
||||
translationKey: "component.zwave.title",
|
||||
icon: "hass:z-wave",
|
||||
},
|
||||
],
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@polymer/paper-item/paper-icon-item";
|
||||
import "@polymer/paper-tooltip/paper-tooltip";
|
||||
import {
|
||||
|
@ -1,5 +1,9 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import type { PaperInputElement } from "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
|
@ -1,4 +1,6 @@
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-radio-button/paper-radio-button";
|
||||
import "@polymer/paper-radio-group/paper-radio-group";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
|
@ -1,18 +1,18 @@
|
||||
/* eslint-disable lit/no-invalid-html */
|
||||
import "@polymer/app-route/app-route";
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
PropertyValues,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
html,
|
||||
CSSResult,
|
||||
css,
|
||||
} from "lit-element";
|
||||
import { compare } from "../../../common/string/compare";
|
||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||
import { afterNextRender } from "../../../common/util/render-status";
|
||||
import "../../../components/entity/ha-state-icon";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-fab";
|
||||
@ -38,6 +38,7 @@ import {
|
||||
EntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
} from "../../../data/entity_registry";
|
||||
import { domainToName } from "../../../data/integration";
|
||||
import { showConfigEntrySystemOptionsDialog } from "../../../dialogs/config-entry-system-options/show-dialog-config-entry-system-options";
|
||||
import { showConfigFlowDialog } from "../../../dialogs/config-flow/show-dialog-config-flow";
|
||||
import { showOptionsFlowDialog } from "../../../dialogs/config-flow/show-dialog-options-flow";
|
||||
@ -48,11 +49,9 @@ import {
|
||||
} from "../../../dialogs/generic/show-dialog-box";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import { domainToName } from "../../../data/integration";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { afterNextRender } from "../../../common/util/render-status";
|
||||
|
||||
@customElement("ha-config-integrations")
|
||||
class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
||||
@ -253,6 +252,10 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
||||
? this._configEntries.map((item: any) => {
|
||||
const devices = this._getDevices(item);
|
||||
const entities = this._getEntities(item);
|
||||
const integrationName = domainToName(
|
||||
this.hass.localize,
|
||||
item.domain
|
||||
);
|
||||
return item.source === "ignore"
|
||||
? ""
|
||||
: html`
|
||||
@ -271,10 +274,12 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
||||
/>
|
||||
</div>
|
||||
<h1>
|
||||
${domainToName(this.hass.localize, item.domain)}
|
||||
${integrationName}
|
||||
</h1>
|
||||
<h2>
|
||||
${item.title}
|
||||
${integrationName === item.title
|
||||
? html` `
|
||||
: item.title}
|
||||
</h2>
|
||||
${devices.length || entities.length
|
||||
? html`
|
||||
@ -282,7 +287,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
||||
${devices.length
|
||||
? html`
|
||||
<a
|
||||
href="/config/devices/dashboard?historyBack=1&config_entry=${item.entry_id}"
|
||||
href=${`/config/devices/dashboard?historyBack=1&config_entry=${item.entry_id}`}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.devices",
|
||||
"count",
|
||||
@ -297,7 +302,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
||||
${entities.length
|
||||
? html`
|
||||
<a
|
||||
href="/config/entities?historyBack=1&config_entry=${item.entry_id}"
|
||||
href=${`/config/entities?historyBack=1&config_entry=${item.entry_id}`}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.entities",
|
||||
"count",
|
||||
@ -385,8 +390,9 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
||||
aria-label=${this.hass.localize("ui.panel.config.integrations.new")}
|
||||
title=${this.hass.localize("ui.panel.config.integrations.new")}
|
||||
@click=${this._createFlow}
|
||||
?rtl=${computeRTL(this.hass!)}
|
||||
?is-wide=${this.isWide}
|
||||
?narrow=${this.narrow}
|
||||
?rtl=${computeRTL(this.hass!)}
|
||||
></ha-fab>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
@ -520,7 +526,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
||||
"ui.panel.config.integrations.rename_input_label"
|
||||
),
|
||||
});
|
||||
if (!newName) {
|
||||
if (newName === null) {
|
||||
return;
|
||||
}
|
||||
const newEntry = await updateConfigEntry(this.hass, configEntry.entry_id, {
|
||||
@ -571,6 +577,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
||||
margin-bottom: 64px;
|
||||
}
|
||||
ha-card {
|
||||
max-width: 500px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
@ -642,6 +649,10 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
||||
right: 16px;
|
||||
z-index: 1;
|
||||
}
|
||||
ha-fab[is-wide] {
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
ha-fab[narrow] {
|
||||
bottom: 84px;
|
||||
}
|
||||
@ -649,6 +660,11 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
||||
right: auto;
|
||||
left: 16px;
|
||||
}
|
||||
ha-fab[is-wide].rtl {
|
||||
bottom: 24px;
|
||||
left: 24px;
|
||||
right: auto;
|
||||
}
|
||||
paper-menu-button {
|
||||
color: var(--secondary-text-color);
|
||||
padding: 0;
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
|
@ -1,3 +1,7 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-listbox/paper-listbox";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
@ -8,6 +12,7 @@ import {
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { createCloseHeading } from "../../../../components/ha-dialog";
|
||||
import "../../../../components/ha-paper-dropdown-menu";
|
||||
import {
|
||||
LovelaceResource,
|
||||
LovelaceResourcesMutableParams,
|
||||
|
@ -18,6 +18,8 @@ import { haStyleDialog } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { PersonDetailDialogParams } from "./show-dialog-person-detail";
|
||||
|
||||
const includeDomains = ["device_tracker"];
|
||||
|
||||
class DialogPersonDetail extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
|
||||
@ -106,7 +108,7 @@ class DialogPersonDetail extends LitElement {
|
||||
<ha-entities-picker
|
||||
.hass=${this.hass}
|
||||
.value=${this._deviceTrackers}
|
||||
.include-domains=${["device_tracker"]}
|
||||
.includeDomains=${includeDomains}
|
||||
.pickedEntityLabel=${this.hass.localize(
|
||||
"ui.panel.config.person.detail.device_tracker_picked"
|
||||
)}
|
||||
|
@ -1,5 +1,3 @@
|
||||
import "@polymer/app-layout/app-header/app-header";
|
||||
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-item/paper-icon-item";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
@ -49,7 +47,6 @@ import {
|
||||
SCENE_IGNORED_DOMAINS,
|
||||
} from "../../../data/scene";
|
||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import "../../../layouts/ha-app-layout";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
@ -180,16 +177,14 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
||||
: this.hass.localize("ui.panel.config.scene.editor.default_name");
|
||||
|
||||
return html`
|
||||
<hass-tabs-subpage
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.route=${this.route}
|
||||
.backCallback=${() => this._backTapped()}
|
||||
.tabs=${configSections.automation}
|
||||
>
|
||||
|
||||
${
|
||||
this.creatingNew
|
||||
${this.creatingNew
|
||||
? ""
|
||||
: html`
|
||||
<paper-icon-button
|
||||
@ -200,201 +195,191 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
||||
icon="hass:delete"
|
||||
@click=${this._deleteTapped}
|
||||
></paper-icon-button>
|
||||
`
|
||||
}
|
||||
|
||||
${
|
||||
this._errors
|
||||
? html` <div class="errors">${this._errors}</div> `
|
||||
: ""
|
||||
}
|
||||
${this.narrow ? html` <span slot="header">${name}</span> ` : ""}
|
||||
<div
|
||||
id="root"
|
||||
class="${classMap({
|
||||
rtl: computeRTL(this.hass),
|
||||
})}"
|
||||
>
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
${!this.narrow ? html` <span slot="header">${name}</span> ` : ""}
|
||||
<div slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.introduction"
|
||||
)}
|
||||
</div>
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<paper-input
|
||||
.value=${this.scene ? computeStateName(this.scene) : ""}
|
||||
@value-changed=${this._nameChanged}
|
||||
label=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.name"
|
||||
)}
|
||||
></paper-input>
|
||||
</div>
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<div slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.devices.header"
|
||||
)}
|
||||
</div>
|
||||
<div slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.devices.introduction"
|
||||
)}
|
||||
</div>
|
||||
|
||||
${devices.map(
|
||||
(device) =>
|
||||
html`
|
||||
<ha-card>
|
||||
<div class="card-header">
|
||||
${device.name}
|
||||
<paper-icon-button
|
||||
icon="hass:delete"
|
||||
title="${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.devices.delete"
|
||||
)}"
|
||||
.device=${device.id}
|
||||
@click=${this._deleteDevice}
|
||||
></paper-icon-button>
|
||||
</div>
|
||||
${device.entities.map((entityId) => {
|
||||
const stateObj = this.hass.states[entityId];
|
||||
if (!stateObj) {
|
||||
return html``;
|
||||
}
|
||||
return html`
|
||||
<paper-icon-item
|
||||
.entityId=${entityId}
|
||||
@click=${this._showMoreInfo}
|
||||
class="device-entity"
|
||||
>
|
||||
<state-badge
|
||||
.stateObj=${stateObj}
|
||||
slot="item-icon"
|
||||
></state-badge>
|
||||
<paper-item-body>
|
||||
${computeStateName(stateObj)}
|
||||
</paper-item-body>
|
||||
</paper-icon-item>
|
||||
`;
|
||||
})}
|
||||
</ha-card>
|
||||
`
|
||||
)}
|
||||
|
||||
<ha-card
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.devices.add"
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
<ha-device-picker
|
||||
@value-changed=${this._devicePicked}
|
||||
.hass=${this.hass}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.devices.add"
|
||||
)}
|
||||
></ha-device-picker>
|
||||
</div>
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
|
||||
${
|
||||
this.showAdvanced
|
||||
? html`
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<div slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.header"
|
||||
)}
|
||||
</div>
|
||||
<div slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.introduction"
|
||||
)}
|
||||
</div>
|
||||
${entities.length
|
||||
? html`
|
||||
<ha-card
|
||||
class="entities"
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.without_device"
|
||||
)}
|
||||
>
|
||||
${entities.map((entityId) => {
|
||||
const stateObj = this.hass.states[entityId];
|
||||
if (!stateObj) {
|
||||
return html``;
|
||||
}
|
||||
return html`
|
||||
<paper-icon-item
|
||||
.entityId=${entityId}
|
||||
@click=${this._showMoreInfo}
|
||||
class="device-entity"
|
||||
>
|
||||
<state-badge
|
||||
.stateObj=${stateObj}
|
||||
slot="item-icon"
|
||||
></state-badge>
|
||||
<paper-item-body>
|
||||
${computeStateName(stateObj)}
|
||||
</paper-item-body>
|
||||
<paper-icon-button
|
||||
icon="hass:delete"
|
||||
.entityId=${entityId}
|
||||
.title="${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.delete"
|
||||
)}"
|
||||
@click=${this._deleteEntity}
|
||||
></paper-icon-button>
|
||||
</paper-icon-item>
|
||||
`;
|
||||
})}
|
||||
</ha-card>
|
||||
`
|
||||
: ""}
|
||||
|
||||
<ha-card
|
||||
header=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.add"
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.device_entities"
|
||||
)}
|
||||
<ha-entity-picker
|
||||
@value-changed=${this._entityPicked}
|
||||
.excludeDomains=${SCENE_IGNORED_DOMAINS}
|
||||
.hass=${this.hass}
|
||||
label=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.add"
|
||||
)}
|
||||
></ha-entity-picker>
|
||||
</div>
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
</div>
|
||||
<ha-fab
|
||||
?is-wide="${this.isWide}"
|
||||
?narrow="${this.narrow}"
|
||||
?dirty="${this._dirty}"
|
||||
icon="hass:content-save"
|
||||
.title="${this.hass.localize("ui.panel.config.scene.editor.save")}"
|
||||
@click=${this._saveScene}
|
||||
`}
|
||||
${this._errors ? html` <div class="errors">${this._errors}</div> ` : ""}
|
||||
${this.narrow ? html` <span slot="header">${name}</span> ` : ""}
|
||||
<div
|
||||
id="root"
|
||||
class="${classMap({
|
||||
rtl: computeRTL(this.hass),
|
||||
})}"
|
||||
>
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
${!this.narrow ? html` <span slot="header">${name}</span> ` : ""}
|
||||
<div slot="introduction">
|
||||
${this.hass.localize("ui.panel.config.scene.editor.introduction")}
|
||||
</div>
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<paper-input
|
||||
.value=${this.scene ? computeStateName(this.scene) : ""}
|
||||
@value-changed=${this._nameChanged}
|
||||
label=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.name"
|
||||
)}
|
||||
></paper-input>
|
||||
</div>
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<div slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.devices.header"
|
||||
)}
|
||||
</div>
|
||||
<div slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.devices.introduction"
|
||||
)}
|
||||
</div>
|
||||
|
||||
${devices.map(
|
||||
(device) =>
|
||||
html`
|
||||
<ha-card>
|
||||
<div class="card-header">
|
||||
${device.name}
|
||||
<paper-icon-button
|
||||
icon="hass:delete"
|
||||
title="${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.devices.delete"
|
||||
)}"
|
||||
.device=${device.id}
|
||||
@click=${this._deleteDevice}
|
||||
></paper-icon-button>
|
||||
</div>
|
||||
${device.entities.map((entityId) => {
|
||||
const stateObj = this.hass.states[entityId];
|
||||
if (!stateObj) {
|
||||
return html``;
|
||||
}
|
||||
return html`
|
||||
<paper-icon-item
|
||||
.entityId=${entityId}
|
||||
@click=${this._showMoreInfo}
|
||||
class="device-entity"
|
||||
>
|
||||
<state-badge
|
||||
.stateObj=${stateObj}
|
||||
slot="item-icon"
|
||||
></state-badge>
|
||||
<paper-item-body>
|
||||
${computeStateName(stateObj)}
|
||||
</paper-item-body>
|
||||
</paper-icon-item>
|
||||
`;
|
||||
})}
|
||||
</ha-card>
|
||||
`
|
||||
)}
|
||||
|
||||
<ha-card
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.devices.add"
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
<ha-device-picker
|
||||
@value-changed=${this._devicePicked}
|
||||
.hass=${this.hass}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.devices.add"
|
||||
)}
|
||||
></ha-device-picker>
|
||||
</div>
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
|
||||
${this.showAdvanced
|
||||
? html`
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<div slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.header"
|
||||
)}
|
||||
</div>
|
||||
<div slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.introduction"
|
||||
)}
|
||||
</div>
|
||||
${entities.length
|
||||
? html`
|
||||
<ha-card
|
||||
class="entities"
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.without_device"
|
||||
)}
|
||||
>
|
||||
${entities.map((entityId) => {
|
||||
const stateObj = this.hass.states[entityId];
|
||||
if (!stateObj) {
|
||||
return html``;
|
||||
}
|
||||
return html`
|
||||
<paper-icon-item
|
||||
.entityId=${entityId}
|
||||
@click=${this._showMoreInfo}
|
||||
class="device-entity"
|
||||
>
|
||||
<state-badge
|
||||
.stateObj=${stateObj}
|
||||
slot="item-icon"
|
||||
></state-badge>
|
||||
<paper-item-body>
|
||||
${computeStateName(stateObj)}
|
||||
</paper-item-body>
|
||||
<paper-icon-button
|
||||
icon="hass:delete"
|
||||
.entityId=${entityId}
|
||||
.title="${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.delete"
|
||||
)}"
|
||||
@click=${this._deleteEntity}
|
||||
></paper-icon-button>
|
||||
</paper-icon-item>
|
||||
`;
|
||||
})}
|
||||
</ha-card>
|
||||
`
|
||||
: ""}
|
||||
|
||||
<ha-card
|
||||
header=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.add"
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.device_entities"
|
||||
)}
|
||||
<ha-entity-picker
|
||||
@value-changed=${this._entityPicked}
|
||||
.excludeDomains=${SCENE_IGNORED_DOMAINS}
|
||||
.hass=${this.hass}
|
||||
label=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.add"
|
||||
)}
|
||||
></ha-entity-picker>
|
||||
</div>
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
`
|
||||
: ""}
|
||||
</div>
|
||||
<ha-fab
|
||||
?is-wide=${this.isWide}
|
||||
?narrow=${this.narrow}
|
||||
?dirty=${this._dirty}
|
||||
icon="hass:content-save"
|
||||
.title=${this.hass.localize("ui.panel.config.scene.editor.save")}
|
||||
@click=${this._saveScene}
|
||||
class=${classMap({
|
||||
rtl: computeRTL(this.hass),
|
||||
})}
|
||||
></ha-fab>
|
||||
</ha-app-layout>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import "@material/mwc-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-spinner/paper-spinner";
|
||||
import {
|
||||
css,
|
||||
|
@ -113,7 +113,7 @@ class ZHAConfigDashboard extends LitElement {
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<hass-subpage .header=${this.hass.localize("ui.panel.config.zha.title")}>
|
||||
<hass-subpage .header=${this.hass.localize("component.zha.title")}>
|
||||
<ha-config-section .narrow=${this.narrow} .isWide=${this.isWide}>
|
||||
<div slot="header">
|
||||
${this.hass.localize("ui.panel.config.zha.header")}
|
||||
|
@ -36,12 +36,12 @@ import {
|
||||
ZHADevice,
|
||||
ZHAEntityReference,
|
||||
} from "../../../data/zha";
|
||||
import { showZHADeviceZigbeeInfoDialog } from "../../../dialogs/zha-device-zigbee-signature-dialog/show-dialog-zha-device-zigbee-info";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { addEntitiesToLovelaceView } from "../../lovelace/editor/add-entities-to-view";
|
||||
import { formatAsPaddedHex } from "./functions";
|
||||
import { ItemSelectedEvent, NodeServiceData } from "./types";
|
||||
import { showZHADeviceZigbeeInfoDialog } from "../../../dialogs/zha-device-zigbee-signature-dialog/show-dialog-zha-device-zigbee-info";
|
||||
|
||||
declare global {
|
||||
// for fire event
|
||||
|
@ -8,11 +8,12 @@ import {
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import memoizeOne from "memoize-one";
|
||||
import "../../../components/ha-card";
|
||||
import {
|
||||
domainToName,
|
||||
fetchIntegrationManifests,
|
||||
integrationIssuesUrl,
|
||||
IntegrationManifest,
|
||||
fetchIntegrationManifests,
|
||||
domainToName,
|
||||
} from "../../../data/integration";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
|
||||
|
@ -8,12 +8,12 @@ import {
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import "../../../components/ha-card";
|
||||
import { domainToName } from "../../../data/integration";
|
||||
import {
|
||||
fetchSystemHealthInfo,
|
||||
SystemHealthInfo,
|
||||
} from "../../../data/system_health";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { domainToName } from "../../../data/integration";
|
||||
|
||||
const sortKeys = (a: string, b: string) => {
|
||||
if (a === "homeassistant") {
|
||||
|
@ -10,9 +10,9 @@ import {
|
||||
import "../../../components/dialog/ha-paper-dialog";
|
||||
import {
|
||||
domainToName,
|
||||
fetchIntegrationManifest,
|
||||
integrationIssuesUrl,
|
||||
IntegrationManifest,
|
||||
fetchIntegrationManifest,
|
||||
} from "../../../data/integration";
|
||||
import { getLoggedErrorIntegration } from "../../../data/system_log";
|
||||
import { PolymerChangedEvent } from "../../../polymer-types";
|
||||
|
@ -165,7 +165,7 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
<ha-card
|
||||
.header="${this._config.name ||
|
||||
stateObj.attributes.friendly_name ||
|
||||
this._label(stateObj.state)}"
|
||||
this._stateDisplay(stateObj.state)}"
|
||||
>
|
||||
<ha-label-badge
|
||||
class="${classMap({ [stateObj.state]: true })}"
|
||||
@ -184,7 +184,7 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
@click="${this._handleActionClick}"
|
||||
outlined
|
||||
>
|
||||
${this._label(state)}
|
||||
${this._stateDisplay(state)}
|
||||
</mwc-button>
|
||||
`;
|
||||
})}
|
||||
@ -212,7 +212,9 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
outlined
|
||||
>
|
||||
${value === "clear"
|
||||
? this._label("clear_code")
|
||||
? this.hass!.localize(
|
||||
`ui.card.alarm_control_panel.clear_code`
|
||||
)
|
||||
: value}
|
||||
</mwc-button>
|
||||
`;
|
||||
@ -232,10 +234,9 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
: stateLabel;
|
||||
}
|
||||
|
||||
private _label(state: string): string {
|
||||
return (
|
||||
this.hass!.localize(`state.alarm_control_panel.${state}`) ||
|
||||
this.hass!.localize(`ui.card.alarm_control_panel.${state}`)
|
||||
private _stateDisplay(state: string): string {
|
||||
return this.hass!.localize(
|
||||
`component.alarm_control_panel.state._.${state}`
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
@ -49,7 +50,7 @@ export class HuiEmptyStateCard extends LitElement implements LovelaceCard {
|
||||
</mwc-button>
|
||||
</a>
|
||||
</div>
|
||||
</header-card>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
} from "lit-element";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { stateIcon } from "../../../common/entity/state_icon";
|
||||
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||
@ -128,13 +129,11 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
|
||||
>${"attribute" in this._config
|
||||
? stateObj.attributes[this._config.attribute!] ||
|
||||
this.hass.localize("state.default.unknown")
|
||||
: this.hass.localize(`state.default.${stateObj.state}`) ||
|
||||
this.hass.localize(
|
||||
`state.${this._config.entity.split(".")[0]}.${
|
||||
stateObj.state
|
||||
}`
|
||||
) ||
|
||||
stateObj.state}</span
|
||||
: computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.language
|
||||
)}</span
|
||||
>${showUnit
|
||||
? html`
|
||||
<span class="measurement"
|
||||
|
@ -28,6 +28,7 @@ import { hasAction } from "../common/has-action";
|
||||
import { processConfigEntities } from "../common/process-config-entities";
|
||||
import "../components/hui-warning-element";
|
||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||
import "../components/hui-timestamp-display";
|
||||
import { GlanceCardConfig, GlanceConfigEntity } from "./types";
|
||||
|
||||
@customElement("hui-glance-card")
|
||||
|
@ -14,6 +14,7 @@ import { classMap } from "lit-html/directives/class-map";
|
||||
import { styleMap } from "lit-html/directives/style-map";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { stateIcon } from "../../../common/entity/state_icon";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
@ -154,8 +155,11 @@ export class HuiLightCard extends LitElement implements LovelaceCard {
|
||||
${UNAVAILABLE_STATES.includes(stateObj.state)
|
||||
? html`
|
||||
<div>
|
||||
${this.hass.localize(`state.default.${stateObj.state}`) ||
|
||||
stateObj.state}
|
||||
${computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.language
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
|
@ -37,6 +37,7 @@ import { findEntities } from "../common/find-entites";
|
||||
import { processConfigEntities } from "../common/process-config-entities";
|
||||
import { EntityConfig } from "../entity-rows/types";
|
||||
import { LovelaceCard } from "../types";
|
||||
import "../../../components/ha-card";
|
||||
import { MapCardConfig } from "./types";
|
||||
|
||||
@customElement("hui-map-card")
|
||||
|
@ -45,6 +45,7 @@ import { findEntities } from "../common/find-entites";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import "../components/hui-marquee";
|
||||
import type { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||
import "../components/hui-warning";
|
||||
import { MediaControlCardConfig } from "./types";
|
||||
|
||||
function getContrastRatio(
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import "../../../components/ha-card";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { findEntities } from "../common/find-entites";
|
||||
import { LovelaceElement, LovelaceElementConfig } from "../elements/types";
|
||||
@ -107,7 +108,7 @@ class HuiPictureElementsCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-card .header="${this._config.title}">
|
||||
<ha-card .header=${this._config.title}>
|
||||
<div id="root">
|
||||
<hui-image
|
||||
.hass=${this._hass}
|
||||
|
@ -195,7 +195,9 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
|
||||
? this.hass!.localize(
|
||||
`state_attributes.climate.hvac_action.${stateObj.attributes.hvac_action}`
|
||||
)
|
||||
: this.hass!.localize(`state.climate.${stateObj.state}`)
|
||||
: this.hass!.localize(
|
||||
`component.climate.state._.${stateObj.state}`
|
||||
)
|
||||
}
|
||||
${
|
||||
stateObj.attributes.preset_mode &&
|
||||
@ -384,7 +386,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
|
||||
@action=${this._handleAction}
|
||||
.actionHandler=${actionHandler()}
|
||||
tabindex="0"
|
||||
></ha-icon>
|
||||
></paper-icon-button>
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -8,30 +8,29 @@ import {
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
|
||||
import "../../../components/ha-icon";
|
||||
import "../../../components/ha-card";
|
||||
import "../components/hui-warning";
|
||||
|
||||
import { WeatherForecastCardConfig } from "./types";
|
||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||
import { HomeAssistant, WeatherEntity } from "../../../types";
|
||||
import { findEntities } from "../common/find-entites";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { stateIcon } from "../../../common/entity/state_icon";
|
||||
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||
import { debounce } from "../../../common/util/debounce";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-icon";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import {
|
||||
weatherIcons,
|
||||
getSecondaryWeatherAttribute,
|
||||
getWeatherUnit,
|
||||
weatherIcons,
|
||||
weatherImages,
|
||||
} from "../../../data/weather";
|
||||
import { stateIcon } from "../../../common/entity/state_icon";
|
||||
import { HomeAssistant, WeatherEntity } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { findEntities } from "../common/find-entites";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import "../components/hui-warning";
|
||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||
import { WeatherForecastCardConfig } from "./types";
|
||||
|
||||
const DAY_IN_MILLISECONDS = 86400000;
|
||||
|
||||
@ -185,8 +184,11 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
|
||||
${this._config.name || computeStateName(stateObj)}
|
||||
</div>
|
||||
<div class="state">
|
||||
${this.hass.localize(`state.weather.${stateObj.state}`) ||
|
||||
stateObj.state}
|
||||
${computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.language
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -25,6 +25,7 @@ import {
|
||||
EntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
} from "../../../data/entity_registry";
|
||||
import { domainToName } from "../../../data/integration";
|
||||
import {
|
||||
LovelaceCardConfig,
|
||||
LovelaceConfig,
|
||||
@ -41,7 +42,6 @@ import {
|
||||
} from "../cards/types";
|
||||
import { processEditorEntities } from "../editor/process-editor-entities";
|
||||
import { LovelaceRowConfig, WeblinkConfig } from "../entity-rows/types";
|
||||
import { domainToName } from "../../../data/integration";
|
||||
|
||||
const DEFAULT_VIEW_ENTITY_ID = "group.default_view";
|
||||
const DOMAINS_BADGES = [
|
||||
|
@ -13,6 +13,7 @@ import { classMap } from "lit-html/directives/class-map";
|
||||
import { styleMap } from "lit-html/directives/style-map";
|
||||
import { STATES_OFF } from "../../../common/const";
|
||||
import parseAspectRatio from "../../../common/util/parse-aspect-ratio";
|
||||
import "../../../components/ha-camera-stream";
|
||||
import { fetchThumbnailUrlWithCache } from "../../../data/camera";
|
||||
import { CameraEntity, HomeAssistant } from "../../../types";
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import {
|
||||
css,
|
||||
|
@ -1,4 +1,7 @@
|
||||
import "@material/mwc-button";
|
||||
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-listbox/paper-listbox";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
|
@ -1,3 +1,4 @@
|
||||
import * as Fuse from "fuse.js";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
@ -11,17 +12,14 @@ import {
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import memoizeOne from "memoize-one";
|
||||
import * as Fuse from "fuse.js";
|
||||
|
||||
import { CardPickTarget } from "../types";
|
||||
import { LovelaceCard } from "../../types";
|
||||
import { LovelaceCardConfig, LovelaceConfig } from "../../../../data/lovelace";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../common/search/search-input";
|
||||
import { UNAVAILABLE_STATES } from "../../../../data/entity";
|
||||
import { LovelaceCardConfig, LovelaceConfig } from "../../../../data/lovelace";
|
||||
import {
|
||||
CUSTOM_TYPE_PREFIX,
|
||||
CustomCardEntry,
|
||||
customCards,
|
||||
CUSTOM_TYPE_PREFIX,
|
||||
getCustomCardEntry,
|
||||
} from "../../../../data/lovelace_custom_cards";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
@ -30,9 +28,9 @@ import {
|
||||
computeUsedEntities,
|
||||
} from "../../common/compute-unused-entities";
|
||||
import { createCardElement } from "../../create-element/create-card-element";
|
||||
import { LovelaceCard } from "../../types";
|
||||
import { getCardStubConfig } from "../get-card-stub-config";
|
||||
|
||||
import "../../../../common/search/search-input";
|
||||
import { CardPickTarget } from "../types";
|
||||
|
||||
interface Card {
|
||||
type: string;
|
||||
|
@ -35,11 +35,12 @@ export class HuiDialogMoveCardView extends LitElement {
|
||||
@opened-changed="${this._openedChanged}"
|
||||
>
|
||||
<h2>Choose view to move card</h2>
|
||||
<hui-views-list
|
||||
.lovelaceConfig=${this._params!.lovelace.config}
|
||||
.selected=${this._params!.path![0]}
|
||||
@view-selected=${this._moveCard}>
|
||||
</hui-view-list>
|
||||
<hui-views-list
|
||||
.lovelaceConfig=${this._params!.lovelace.config}
|
||||
.selected=${this._params!.path![0]}
|
||||
@view-selected=${this._moveCard}
|
||||
>
|
||||
</hui-views-list>
|
||||
</ha-paper-dialog>
|
||||
`;
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ const cardConfigStruct = struct({
|
||||
theme: "string?",
|
||||
});
|
||||
|
||||
const includeDomains = ["alarm_control_panel"];
|
||||
|
||||
@customElement("hui-alarm-panel-card-editor")
|
||||
export class HuiAlarmPanelCardEditor extends LitElement
|
||||
implements LovelaceCardEditor {
|
||||
@ -76,7 +78,7 @@ export class HuiAlarmPanelCardEditor extends LitElement
|
||||
.hass=${this.hass}
|
||||
.value="${this._entity}"
|
||||
.configValue=${"entity"}
|
||||
.include-domains=${["alarm_control_panel"]}
|
||||
.includeDomains=${includeDomains}
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
|
@ -22,6 +22,7 @@ import {
|
||||
EditorTarget,
|
||||
EntitiesEditorEvent,
|
||||
} from "../types";
|
||||
import "../../../../components/ha-switch";
|
||||
import { configElementStyle } from "./config-elements-style";
|
||||
|
||||
const cardConfigStruct = struct({
|
||||
|
@ -1,4 +1,5 @@
|
||||
import "@polymer/paper-tabs";
|
||||
import "@polymer/paper-tabs/paper-tab";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
@ -21,6 +22,7 @@ import {
|
||||
ConfigChangedEvent,
|
||||
HuiCardEditor,
|
||||
} from "../card-editor/hui-card-editor";
|
||||
import "../card-editor/hui-card-picker";
|
||||
import { GUIModeChangedEvent } from "../types";
|
||||
|
||||
const conditionStruct = struct({
|
||||
|
@ -30,6 +30,8 @@ const cardConfigStruct = struct({
|
||||
theme: "string?",
|
||||
});
|
||||
|
||||
const includeDomains = ["sensor"];
|
||||
|
||||
@customElement("hui-gauge-card-editor")
|
||||
export class HuiGaugeCardEditor extends LitElement
|
||||
implements LovelaceCardEditor {
|
||||
@ -87,7 +89,7 @@ export class HuiGaugeCardEditor extends LitElement
|
||||
.hass=${this.hass}
|
||||
.value="${this._entity}"
|
||||
.configValue=${"entity"}
|
||||
.include-domains=${["sensor"]}
|
||||
.includeDomains=${includeDomains}
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
|
@ -34,6 +34,8 @@ const cardConfigStruct = struct({
|
||||
double_tap_action: struct.optional(actionConfigStruct),
|
||||
});
|
||||
|
||||
const includeDomains = ["light"];
|
||||
|
||||
@customElement("hui-light-card-editor")
|
||||
export class HuiLightCardEditor extends LitElement
|
||||
implements LovelaceCardEditor {
|
||||
@ -95,7 +97,7 @@ export class HuiLightCardEditor extends LitElement
|
||||
.hass=${this.hass}
|
||||
.value=${this._entity}
|
||||
.configValue=${"entity"}
|
||||
.include-domains=${["light"]}
|
||||
.includeDomains=${includeDomains}
|
||||
@change=${this._valueChanged}
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
|
@ -23,6 +23,7 @@ import {
|
||||
entitiesConfigStruct,
|
||||
EntitiesEditorEvent,
|
||||
} from "../types";
|
||||
import "../../../../components/ha-switch";
|
||||
import { configElementStyle } from "./config-elements-style";
|
||||
|
||||
const cardConfigStruct = struct({
|
||||
|
@ -18,6 +18,8 @@ const cardConfigStruct = struct({
|
||||
entity: "string?",
|
||||
});
|
||||
|
||||
const includeDomains = ["media_player"];
|
||||
|
||||
@customElement("hui-media-control-card-editor")
|
||||
export class HuiMediaControlCardEditor extends LitElement
|
||||
implements LovelaceCardEditor {
|
||||
@ -50,7 +52,7 @@ export class HuiMediaControlCardEditor extends LitElement
|
||||
.hass=${this.hass}
|
||||
.value="${this._entity}"
|
||||
.configValue=${"entity"}
|
||||
.include-domains=${["media_player"]}
|
||||
.includeDomains=${includeDomains}
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
|
@ -41,6 +41,8 @@ const cardConfigStruct = struct({
|
||||
theme: "string?",
|
||||
});
|
||||
|
||||
const includeDomains = ["camera"];
|
||||
|
||||
@customElement("hui-picture-entity-card-editor")
|
||||
export class HuiPictureEntityCardEditor extends LitElement
|
||||
implements LovelaceCardEditor {
|
||||
@ -150,7 +152,7 @@ export class HuiPictureEntityCardEditor extends LitElement
|
||||
.value="${this._camera_image}"
|
||||
.configValue=${"camera_image"}
|
||||
@change="${this._valueChanged}"
|
||||
.include-domains=${["camera"]}
|
||||
.includeDomains=${includeDomains}
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
<div class="side-by-side">
|
||||
|
@ -43,6 +43,8 @@ const cardConfigStruct = struct({
|
||||
theme: "string?",
|
||||
});
|
||||
|
||||
const includeDomains = ["camera"];
|
||||
|
||||
@customElement("hui-picture-glance-card-editor")
|
||||
export class HuiPictureGlanceCardEditor extends LitElement
|
||||
implements LovelaceCardEditor {
|
||||
@ -150,7 +152,7 @@ export class HuiPictureGlanceCardEditor extends LitElement
|
||||
.configValue=${"camera_image"}
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
.include-domains=${["camera"]}
|
||||
.includeDomains=${includeDomains}
|
||||
></ha-entity-picker>
|
||||
<div class="side-by-side">
|
||||
<paper-dropdown-menu
|
||||
|
@ -24,6 +24,8 @@ const cardConfigStruct = struct({
|
||||
theme: "string?",
|
||||
});
|
||||
|
||||
const includeDomains = ["plant"];
|
||||
|
||||
@customElement("hui-plant-status-card-editor")
|
||||
export class HuiPlantStatusCardEditor extends LitElement
|
||||
implements LovelaceCardEditor {
|
||||
@ -65,7 +67,7 @@ export class HuiPlantStatusCardEditor extends LitElement
|
||||
.hass=${this.hass}
|
||||
.value="${this._entity}"
|
||||
.configValue=${"entity"}
|
||||
.include-domains=${["plant"]}
|
||||
.includeDomains=${includeDomains}
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
|
@ -33,6 +33,8 @@ const cardConfigStruct = struct({
|
||||
hours_to_show: "number?",
|
||||
});
|
||||
|
||||
const includeDomains = ["sensor"];
|
||||
|
||||
@customElement("hui-sensor-card-editor")
|
||||
export class HuiSensorCardEditor extends LitElement
|
||||
implements LovelaceCardEditor {
|
||||
@ -96,7 +98,7 @@ export class HuiSensorCardEditor extends LitElement
|
||||
.hass=${this.hass}
|
||||
.value="${this._entity}"
|
||||
.configValue=${"entity"}
|
||||
.include-domains=${["sensor"]}
|
||||
.includeDomains=${includeDomains}
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
|
@ -1,4 +1,6 @@
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-tabs";
|
||||
import "@polymer/paper-tabs/paper-tab";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
@ -19,6 +21,7 @@ import {
|
||||
ConfigChangedEvent,
|
||||
HuiCardEditor,
|
||||
} from "../card-editor/hui-card-editor";
|
||||
import "../card-editor/hui-card-picker";
|
||||
import { GUIModeChangedEvent } from "../types";
|
||||
|
||||
const cardConfigStruct = struct({
|
||||
@ -79,63 +82,61 @@ export class HuiStackCardEditor extends LitElement
|
||||
<paper-tab>
|
||||
<ha-icon icon="hass:plus"></ha-icon>
|
||||
</paper-tab>
|
||||
<paper-tabs>
|
||||
</paper-tabs>
|
||||
</div>
|
||||
|
||||
<div id="editor">
|
||||
${
|
||||
selected < numcards
|
||||
? html`
|
||||
<div id="card-options">
|
||||
<mwc-button
|
||||
@click=${this._toggleMode}
|
||||
.disabled=${!this._guiModeAvailable}
|
||||
class="gui-mode-button"
|
||||
>
|
||||
${this.hass!.localize(
|
||||
!this._cardEditorEl || this._GUImode
|
||||
? "ui.panel.lovelace.editor.edit_card.show_code_editor"
|
||||
: "ui.panel.lovelace.editor.edit_card.show_visual_editor"
|
||||
)}
|
||||
</mwc-button>
|
||||
<paper-icon-button
|
||||
id="move-before"
|
||||
title="Move card before"
|
||||
icon="hass:arrow-left"
|
||||
.disabled=${selected === 0}
|
||||
@click=${this._handleMove}
|
||||
></paper-icon-button>
|
||||
${selected < numcards
|
||||
? html`
|
||||
<div id="card-options">
|
||||
<mwc-button
|
||||
@click=${this._toggleMode}
|
||||
.disabled=${!this._guiModeAvailable}
|
||||
class="gui-mode-button"
|
||||
>
|
||||
${this.hass!.localize(
|
||||
!this._cardEditorEl || this._GUImode
|
||||
? "ui.panel.lovelace.editor.edit_card.show_code_editor"
|
||||
: "ui.panel.lovelace.editor.edit_card.show_visual_editor"
|
||||
)}
|
||||
</mwc-button>
|
||||
<paper-icon-button
|
||||
id="move-before"
|
||||
title="Move card before"
|
||||
icon="hass:arrow-left"
|
||||
.disabled=${selected === 0}
|
||||
@click=${this._handleMove}
|
||||
></paper-icon-button>
|
||||
|
||||
<paper-icon-button
|
||||
id="move-after"
|
||||
title="Move card after"
|
||||
icon="hass:arrow-right"
|
||||
.disabled=${selected === numcards - 1}
|
||||
@click=${this._handleMove}
|
||||
></paper-icon-button>
|
||||
<paper-icon-button
|
||||
id="move-after"
|
||||
title="Move card after"
|
||||
icon="hass:arrow-right"
|
||||
.disabled=${selected === numcards - 1}
|
||||
@click=${this._handleMove}
|
||||
></paper-icon-button>
|
||||
|
||||
<paper-icon-button
|
||||
icon="hass:delete"
|
||||
@click=${this._handleDeleteCard}
|
||||
></paper-icon-button>
|
||||
</div>
|
||||
<paper-icon-button
|
||||
icon="hass:delete"
|
||||
@click=${this._handleDeleteCard}
|
||||
></paper-icon-button>
|
||||
</div>
|
||||
|
||||
<hui-card-editor
|
||||
.hass=${this.hass}
|
||||
.value=${this._config.cards[selected]}
|
||||
.lovelace=${this.lovelace}
|
||||
@config-changed=${this._handleConfigChanged}
|
||||
@GUImode-changed=${this._handleGUIModeChanged}
|
||||
></hui-card-editor>
|
||||
`
|
||||
: html`
|
||||
<hui-card-picker
|
||||
.hass=${this.hass}
|
||||
.lovelace=${this.lovelace}
|
||||
@config-changed="${this._handleCardPicked}"
|
||||
></hui-card-picker>
|
||||
`
|
||||
}
|
||||
<hui-card-editor
|
||||
.hass=${this.hass}
|
||||
.value=${this._config.cards[selected]}
|
||||
.lovelace=${this.lovelace}
|
||||
@config-changed=${this._handleConfigChanged}
|
||||
@GUImode-changed=${this._handleGUIModeChanged}
|
||||
></hui-card-editor>
|
||||
`
|
||||
: html`
|
||||
<hui-card-picker
|
||||
.hass=${this.hass}
|
||||
.lovelace=${this.lovelace}
|
||||
@config-changed="${this._handleCardPicked}"
|
||||
></hui-card-picker>
|
||||
`}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -23,6 +23,8 @@ const cardConfigStruct = struct({
|
||||
theme: "string?",
|
||||
});
|
||||
|
||||
const includeDomains = ["climate"];
|
||||
|
||||
@customElement("hui-thermostat-card-editor")
|
||||
export class HuiThermostatCardEditor extends LitElement
|
||||
implements LovelaceCardEditor {
|
||||
@ -64,7 +66,7 @@ export class HuiThermostatCardEditor extends LitElement
|
||||
.hass=${this.hass}
|
||||
.value="${this._entity}"
|
||||
.configValue=${"entity"}
|
||||
.include-domains=${["climate"]}
|
||||
.includeDomains=${includeDomains}
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
|
@ -8,13 +8,12 @@ import {
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/entity/ha-entity-picker";
|
||||
import "../../../../components/ha-switch";
|
||||
|
||||
import { EntitiesEditorEvent, EditorTarget } from "../types";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import { WeatherForecastCardConfig } from "../../cards/types";
|
||||
import { struct } from "../../common/structs/struct";
|
||||
import "../../components/hui-theme-select-editor";
|
||||
import { LovelaceCardEditor } from "../../types";
|
||||
import { EditorTarget, EntitiesEditorEvent } from "../types";
|
||||
import { configElementStyle } from "./config-elements-style";
|
||||
|
||||
const cardConfigStruct = struct({
|
||||
@ -25,6 +24,8 @@ const cardConfigStruct = struct({
|
||||
show_forecast: "boolean?",
|
||||
});
|
||||
|
||||
const includeDomains = ["weather"];
|
||||
|
||||
@customElement("hui-weather-forecast-card-editor")
|
||||
export class HuiWeatherForecastCardEditor extends LitElement
|
||||
implements LovelaceCardEditor {
|
||||
@ -70,7 +71,7 @@ export class HuiWeatherForecastCardEditor extends LitElement
|
||||
.hass=${this.hass}
|
||||
.value=${this._entity}
|
||||
.configValue=${"entity"}
|
||||
.includeDomains=${["weather"]}
|
||||
.includeDomains=${includeDomains}
|
||||
@change=${this._valueChanged}
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import "@material/mwc-button";
|
||||
import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable";
|
||||
import "@polymer/paper-spinner/paper-spinner";
|
||||
import {
|
||||
css,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user