mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-29 12:16:39 +00:00
Convert customize to LitElement + "real" entity picker + option to directly jump to entity (#8180)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
0a3172dfdb
commit
8bfe583a20
@ -1,111 +0,0 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
|
||||||
/* eslint-plugin-disable lit */
|
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
|
||||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
|
||||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
|
||||||
import { sortStatesByName } from "../../../common/entity/states_sort_by_name";
|
|
||||||
import "../../../layouts/hass-tabs-subpage";
|
|
||||||
import LocalizeMixin from "../../../mixins/localize-mixin";
|
|
||||||
import "../../../styles/polymer-ha-style";
|
|
||||||
import { documentationUrl } from "../../../util/documentation-url";
|
|
||||||
import "../ha-config-section";
|
|
||||||
import "../ha-entity-config";
|
|
||||||
import { configSections } from "../ha-panel-config";
|
|
||||||
import "./ha-form-customize";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @appliesMixin LocalizeMixin
|
|
||||||
*/
|
|
||||||
class HaConfigCustomize extends LocalizeMixin(PolymerElement) {
|
|
||||||
static get template() {
|
|
||||||
return html`
|
|
||||||
<style include="ha-style"></style>
|
|
||||||
<hass-tabs-subpage
|
|
||||||
hass="[[hass]]"
|
|
||||||
narrow="[[narrow]]"
|
|
||||||
route="[[route]]"
|
|
||||||
back-path="/config"
|
|
||||||
tabs="[[_computeTabs()]]"
|
|
||||||
show-advanced="[[showAdvanced]]"
|
|
||||||
>
|
|
||||||
<div class$="[[computeClasses(isWide)]]">
|
|
||||||
<ha-config-section is-wide="[[isWide]]">
|
|
||||||
<span slot="header">
|
|
||||||
[[localize('ui.panel.config.customize.picker.header')]]
|
|
||||||
</span>
|
|
||||||
<span slot="introduction">
|
|
||||||
[[localize('ui.panel.config.customize.picker.introduction')]]
|
|
||||||
<br />
|
|
||||||
<a
|
|
||||||
href="[[_computeDocumentationUrl(hass)]]"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
>
|
|
||||||
[[localize("ui.panel.config.customize.picker.documentation")]]
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<ha-entity-config
|
|
||||||
hass="[[hass]]"
|
|
||||||
label="[[localize('ui.panel.config.customize.picker.entity')]]"
|
|
||||||
entities="[[entities]]"
|
|
||||||
config="[[entityConfig]]"
|
|
||||||
>
|
|
||||||
</ha-entity-config>
|
|
||||||
</ha-config-section>
|
|
||||||
</div>
|
|
||||||
</hass-tabs-subpage>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get properties() {
|
|
||||||
return {
|
|
||||||
hass: Object,
|
|
||||||
isWide: Boolean,
|
|
||||||
narrow: Boolean,
|
|
||||||
route: Object,
|
|
||||||
showAdvanced: Boolean,
|
|
||||||
entities: {
|
|
||||||
type: Array,
|
|
||||||
computed: "computeEntities(hass)",
|
|
||||||
},
|
|
||||||
|
|
||||||
entityConfig: {
|
|
||||||
type: Object,
|
|
||||||
value: {
|
|
||||||
component: "ha-form-customize",
|
|
||||||
computeSelectCaption: (stateObj) =>
|
|
||||||
computeStateName(stateObj) +
|
|
||||||
" (" +
|
|
||||||
computeStateDomain(stateObj) +
|
|
||||||
")",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
computeClasses(isWide) {
|
|
||||||
return isWide ? "content" : "content narrow";
|
|
||||||
}
|
|
||||||
|
|
||||||
_backTapped() {
|
|
||||||
history.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
_computeTabs() {
|
|
||||||
return configSections.advanced;
|
|
||||||
}
|
|
||||||
|
|
||||||
computeEntities(hass) {
|
|
||||||
return Object.keys(hass.states)
|
|
||||||
.map((key) => hass.states[key])
|
|
||||||
.sort(sortStatesByName);
|
|
||||||
}
|
|
||||||
|
|
||||||
_computeDocumentationUrl(hass) {
|
|
||||||
return documentationUrl(
|
|
||||||
hass,
|
|
||||||
"/docs/configuration/customizing-devices/#customization-using-the-ui"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
customElements.define("ha-config-customize", HaConfigCustomize);
|
|
91
src/panels/config/customize/ha-config-customize.ts
Normal file
91
src/panels/config/customize/ha-config-customize.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit-element";
|
||||||
|
import "../../../components/ha-card";
|
||||||
|
import "../../../layouts/hass-loading-screen";
|
||||||
|
import "../../../layouts/hass-tabs-subpage";
|
||||||
|
import { HomeAssistant, Route } from "../../../types";
|
||||||
|
import { documentationUrl } from "../../../util/documentation-url";
|
||||||
|
import "../ha-config-section";
|
||||||
|
import "../ha-entity-config";
|
||||||
|
import { configSections } from "../ha-panel-config";
|
||||||
|
import "./ha-form-customize";
|
||||||
|
|
||||||
|
class HaConfigCustomize extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property() public isWide?: boolean;
|
||||||
|
|
||||||
|
@property() public narrow?: boolean;
|
||||||
|
|
||||||
|
@property() public route!: Route;
|
||||||
|
|
||||||
|
@property() private _selectedEntityId = "";
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<style include="ha-style"></style>
|
||||||
|
<hass-tabs-subpage
|
||||||
|
.hass=${this.hass}
|
||||||
|
.narrow=${this.narrow}
|
||||||
|
.route=${this.route}
|
||||||
|
back-path="/config"
|
||||||
|
.tabs=${configSections.advanced}
|
||||||
|
>
|
||||||
|
<ha-config-section .isWide=${this.isWide}>
|
||||||
|
<span slot="header">
|
||||||
|
${this.hass.localize("ui.panel.config.customize.picker.header")}
|
||||||
|
</span>
|
||||||
|
<span slot="introduction">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.customize.picker.introduction"
|
||||||
|
)}
|
||||||
|
<br />
|
||||||
|
<a
|
||||||
|
href=${documentationUrl(
|
||||||
|
this.hass,
|
||||||
|
"/docs/configuration/customizing-devices/#customization-using-the-ui"
|
||||||
|
)}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.customize.picker.documentation"
|
||||||
|
)}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
<ha-entity-config
|
||||||
|
.hass=${this.hass}
|
||||||
|
.selectedEntityId=${this._selectedEntityId}
|
||||||
|
>
|
||||||
|
</ha-entity-config>
|
||||||
|
</ha-config-section>
|
||||||
|
</div>
|
||||||
|
</hass-tabs-subpage>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(changedProps) {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
|
||||||
|
if (!this.route.path.includes("/edit/")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const routeSegments = this.route.path.split("/edit/");
|
||||||
|
this._selectedEntityId = routeSegments.length > 1 ? routeSegments[1] : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult {
|
||||||
|
return css`
|
||||||
|
a {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define("ha-config-customize", HaConfigCustomize);
|
@ -12,7 +12,7 @@ import hassAttributeUtil from "../../../util/hass-attributes-util";
|
|||||||
import "../ha-form-style";
|
import "../ha-form-style";
|
||||||
import "./ha-form-customize-attributes";
|
import "./ha-form-customize-attributes";
|
||||||
|
|
||||||
class HaFormCustomize extends LocalizeMixin(PolymerElement) {
|
export class HaFormCustomize extends LocalizeMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
return html`
|
return html`
|
||||||
<style include="iron-flex ha-style ha-form-style">
|
<style include="iron-flex ha-style ha-form-style">
|
||||||
@ -73,26 +73,28 @@ class HaFormCustomize extends LocalizeMixin(PolymerElement) {
|
|||||||
attributes="{{newAttributes}}"
|
attributes="{{newAttributes}}"
|
||||||
></ha-form-customize-attributes>
|
></ha-form-customize-attributes>
|
||||||
</template>
|
</template>
|
||||||
<div class="form-group">
|
<template is="dom-if" if="[[entity]]">
|
||||||
<paper-dropdown-menu
|
<div class="form-group">
|
||||||
label="[[localize('ui.panel.config.customize.pick_attribute')]]"
|
<paper-dropdown-menu
|
||||||
class="flex"
|
label="[[localize('ui.panel.config.customize.pick_attribute')]]"
|
||||||
dynamic-align=""
|
class="flex"
|
||||||
>
|
dynamic-align=""
|
||||||
<paper-listbox
|
|
||||||
slot="dropdown-content"
|
|
||||||
selected="{{selectedNewAttribute}}"
|
|
||||||
>
|
>
|
||||||
<template
|
<paper-listbox
|
||||||
is="dom-repeat"
|
slot="dropdown-content"
|
||||||
items="[[newAttributesOptions]]"
|
selected="{{selectedNewAttribute}}"
|
||||||
as="option"
|
|
||||||
>
|
>
|
||||||
<paper-item>[[option]]</paper-item>
|
<template
|
||||||
</template>
|
is="dom-repeat"
|
||||||
</paper-listbox>
|
items="[[newAttributesOptions]]"
|
||||||
</paper-dropdown-menu>
|
as="option"
|
||||||
</div>
|
>
|
||||||
|
<paper-item>[[option]]</paper-item>
|
||||||
|
</template>
|
||||||
|
</paper-listbox>
|
||||||
|
</paper-dropdown-menu>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,222 +0,0 @@
|
|||||||
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 "../../components/ha-circular-progress";
|
|
||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
|
||||||
/* eslint-plugin-disable lit */
|
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
|
||||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
|
||||||
import "../../components/ha-card";
|
|
||||||
import "../../styles/polymer-ha-style";
|
|
||||||
|
|
||||||
class HaEntityConfig extends PolymerElement {
|
|
||||||
static get template() {
|
|
||||||
return html`
|
|
||||||
<style include="iron-flex ha-style">
|
|
||||||
ha-card {
|
|
||||||
direction: ltr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-picker {
|
|
||||||
@apply --layout-horizontal;
|
|
||||||
padding-bottom: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-placeholder {
|
|
||||||
@apply --layout-vertical;
|
|
||||||
@apply --layout-center-center;
|
|
||||||
height: 96px;
|
|
||||||
}
|
|
||||||
|
|
||||||
[hidden]: {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-actions {
|
|
||||||
@apply --layout-horizontal;
|
|
||||||
@apply --layout-justified;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<ha-card>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="device-picker">
|
|
||||||
<paper-dropdown-menu
|
|
||||||
label="[[label]]"
|
|
||||||
class="flex"
|
|
||||||
disabled="[[!entities.length]]"
|
|
||||||
>
|
|
||||||
<paper-listbox
|
|
||||||
slot="dropdown-content"
|
|
||||||
selected="{{selectedEntity}}"
|
|
||||||
>
|
|
||||||
<template is="dom-repeat" items="[[entities]]" as="state">
|
|
||||||
<paper-item>[[computeSelectCaption(state)]]</paper-item>
|
|
||||||
</template>
|
|
||||||
</paper-listbox>
|
|
||||||
</paper-dropdown-menu>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-container">
|
|
||||||
<template is="dom-if" if="[[computeShowPlaceholder(formState)]]">
|
|
||||||
<div class="form-placeholder">
|
|
||||||
<template is="dom-if" if="[[computeShowNoDevices(formState)]]">
|
|
||||||
No entities found! :-(
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template is="dom-if" if="[[computeShowSpinner(formState)]]">
|
|
||||||
<ha-circular-progress
|
|
||||||
active=""
|
|
||||||
alt="[[formState]]"
|
|
||||||
></ha-circular-progress>
|
|
||||||
[[formState]]
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<div hidden$="[[!computeShowForm(formState)]]" id="form"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-actions">
|
|
||||||
<mwc-button
|
|
||||||
on-click="saveEntity"
|
|
||||||
disabled="[[computeShowPlaceholder(formState)]]"
|
|
||||||
>SAVE</mwc-button
|
|
||||||
>
|
|
||||||
<template is="dom-if" if="[[allowDelete]]">
|
|
||||||
<mwc-button
|
|
||||||
class="warning"
|
|
||||||
on-click="deleteEntity"
|
|
||||||
disabled="[[computeShowPlaceholder(formState)]]"
|
|
||||||
>DELETE</mwc-button
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</ha-card>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get properties() {
|
|
||||||
return {
|
|
||||||
hass: {
|
|
||||||
type: Object,
|
|
||||||
observer: "hassChanged",
|
|
||||||
},
|
|
||||||
|
|
||||||
label: {
|
|
||||||
type: String,
|
|
||||||
value: "Device",
|
|
||||||
},
|
|
||||||
|
|
||||||
entities: {
|
|
||||||
type: Array,
|
|
||||||
observer: "entitiesChanged",
|
|
||||||
},
|
|
||||||
|
|
||||||
allowDelete: {
|
|
||||||
type: Boolean,
|
|
||||||
value: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
selectedEntity: {
|
|
||||||
type: Number,
|
|
||||||
value: -1,
|
|
||||||
observer: "entityChanged",
|
|
||||||
},
|
|
||||||
|
|
||||||
formState: {
|
|
||||||
type: String,
|
|
||||||
// no-devices, loading, saving, editing
|
|
||||||
value: "no-devices",
|
|
||||||
},
|
|
||||||
|
|
||||||
config: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
super.connectedCallback();
|
|
||||||
this.formEl = document.createElement(this.config.component);
|
|
||||||
this.formEl.hass = this.hass;
|
|
||||||
this.$.form.appendChild(this.formEl);
|
|
||||||
this.entityChanged(this.selectedEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
computeSelectCaption(stateObj) {
|
|
||||||
return this.config.computeSelectCaption
|
|
||||||
? this.config.computeSelectCaption(stateObj)
|
|
||||||
: computeStateName(stateObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
computeShowNoDevices(formState) {
|
|
||||||
return formState === "no-devices";
|
|
||||||
}
|
|
||||||
|
|
||||||
computeShowSpinner(formState) {
|
|
||||||
return formState === "loading" || formState === "saving";
|
|
||||||
}
|
|
||||||
|
|
||||||
computeShowPlaceholder(formState) {
|
|
||||||
return formState !== "editing";
|
|
||||||
}
|
|
||||||
|
|
||||||
computeShowForm(formState) {
|
|
||||||
return formState === "editing";
|
|
||||||
}
|
|
||||||
|
|
||||||
hassChanged(hass) {
|
|
||||||
if (this.formEl) {
|
|
||||||
this.formEl.hass = hass;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
entitiesChanged(entities, oldEntities) {
|
|
||||||
if (entities.length === 0) {
|
|
||||||
this.formState = "no-devices";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!oldEntities) {
|
|
||||||
this.selectedEntity = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const oldEntityId = oldEntities[this.selectedEntity].entity_id;
|
|
||||||
|
|
||||||
const newIndex = entities.findIndex(function (ent) {
|
|
||||||
return ent.entity_id === oldEntityId;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (newIndex === -1) {
|
|
||||||
this.selectedEntity = 0;
|
|
||||||
} else if (newIndex !== this.selectedEntity) {
|
|
||||||
// Entity moved index
|
|
||||||
this.selectedEntity = newIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
entityChanged(index) {
|
|
||||||
if (!this.entities || !this.formEl) return;
|
|
||||||
const entity = this.entities[index];
|
|
||||||
if (!entity) return;
|
|
||||||
|
|
||||||
this.formState = "loading";
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
||||||
const el = this;
|
|
||||||
this.formEl.loadEntity(entity).then(function () {
|
|
||||||
el.formState = "editing";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
saveEntity() {
|
|
||||||
this.formState = "saving";
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
||||||
const el = this;
|
|
||||||
this.formEl.saveEntity().then(function () {
|
|
||||||
el.formState = "editing";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define("ha-entity-config", HaEntityConfig);
|
|
124
src/panels/config/ha-entity-config.ts
Normal file
124
src/panels/config/ha-entity-config.ts
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import "@material/mwc-button";
|
||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
PropertyValues,
|
||||||
|
query,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit-element";
|
||||||
|
import "../../components/buttons/ha-progress-button";
|
||||||
|
import "../../components/entity/ha-entity-picker";
|
||||||
|
import "../../components/ha-card";
|
||||||
|
import "../../components/ha-circular-progress";
|
||||||
|
import { haStyle } from "../../resources/styles";
|
||||||
|
import "../../styles/polymer-ha-style";
|
||||||
|
import type { HomeAssistant } from "../../types";
|
||||||
|
import { HaFormCustomize } from "./customize/ha-form-customize";
|
||||||
|
|
||||||
|
@customElement("ha-entity-config")
|
||||||
|
export class HaEntityConfig extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property() public selectedEntityId!: string;
|
||||||
|
|
||||||
|
// False if no entity is selected or currently saving or loading
|
||||||
|
@property() private _formEditState = false;
|
||||||
|
|
||||||
|
@query("#form") private _form!: HaFormCustomize;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<ha-card>
|
||||||
|
<div class="card-content">
|
||||||
|
<ha-entity-picker
|
||||||
|
.hass=${this.hass}
|
||||||
|
.value=${this.selectedEntityId}
|
||||||
|
.configValue=${"entity"}
|
||||||
|
@change=${this._selectedEntityChanged}
|
||||||
|
allow-custom-entity
|
||||||
|
hideClearIcon
|
||||||
|
>
|
||||||
|
</ha-entity-picker>
|
||||||
|
|
||||||
|
<div class="form-container">
|
||||||
|
<ha-form-customize .hass=${this.hass} .id=${"form"}>
|
||||||
|
</ha-form-customize>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-actions">
|
||||||
|
<ha-progress-button
|
||||||
|
@click=${this._saveEntity}
|
||||||
|
.disabled=${!this._formEditState}
|
||||||
|
>
|
||||||
|
${this.hass.localize("ui.common.save")}
|
||||||
|
</ha-progress-button>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updated(changedProps: PropertyValues) {
|
||||||
|
super.updated(changedProps);
|
||||||
|
if (
|
||||||
|
changedProps.has("selectedEntityId") &&
|
||||||
|
changedProps.get("selectedEntityId") !== this.selectedEntityId
|
||||||
|
) {
|
||||||
|
this._selectEntity(this.selectedEntityId);
|
||||||
|
this.requestUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _selectedEntityChanged(ev) {
|
||||||
|
this._selectEntity(ev.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _selectEntity(entityId?: string) {
|
||||||
|
if (!this._form || !entityId) return;
|
||||||
|
const entity = this.hass.states[entityId];
|
||||||
|
if (!entity) return;
|
||||||
|
|
||||||
|
this._formEditState = false;
|
||||||
|
await this._form.loadEntity(entity);
|
||||||
|
this._formEditState = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _saveEntity(ev) {
|
||||||
|
if (!this._formEditState) return;
|
||||||
|
this._formEditState = false;
|
||||||
|
const button = ev.target;
|
||||||
|
button.progress = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this._form.saveEntity();
|
||||||
|
this._formEditState = true;
|
||||||
|
button.actionSuccess();
|
||||||
|
} catch {
|
||||||
|
button.actionError();
|
||||||
|
} finally {
|
||||||
|
button.progress = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult[] {
|
||||||
|
return [
|
||||||
|
haStyle,
|
||||||
|
css`
|
||||||
|
ha-card {
|
||||||
|
direction: ltr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-placeholder {
|
||||||
|
height: 96px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -1108,8 +1108,7 @@
|
|||||||
"picker": {
|
"picker": {
|
||||||
"header": "Customizations",
|
"header": "Customizations",
|
||||||
"introduction": "Tweak per-entity attributes. Added/edited customizations will take effect immediately. Removed customizations will take effect when the entity is updated.",
|
"introduction": "Tweak per-entity attributes. Added/edited customizations will take effect immediately. Removed customizations will take effect when the entity is updated.",
|
||||||
"documentation": "Customization documentation",
|
"documentation": "Customization documentation"
|
||||||
"entity": "Entity"
|
|
||||||
},
|
},
|
||||||
"warning": {
|
"warning": {
|
||||||
"include_sentence": "It seems that your configuration.yaml doesn't properly",
|
"include_sentence": "It seems that your configuration.yaml doesn't properly",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user