mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 00:06:35 +00:00
Optimize automation editor (#5591)
This commit is contained in:
parent
14330fbd93
commit
a0dae802f2
@ -45,7 +45,9 @@ import { HaDeviceTrigger } from "./trigger/types/ha-automation-trigger-device";
|
|||||||
export class HaAutomationEditor extends LitElement {
|
export class HaAutomationEditor extends LitElement {
|
||||||
@property() public hass!: HomeAssistant;
|
@property() public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property() public automation!: AutomationEntity;
|
@property() public automationId!: string;
|
||||||
|
|
||||||
|
@property() public automations!: AutomationEntity[];
|
||||||
|
|
||||||
@property() public isWide?: boolean;
|
@property() public isWide?: boolean;
|
||||||
|
|
||||||
@ -53,15 +55,18 @@ export class HaAutomationEditor extends LitElement {
|
|||||||
|
|
||||||
@property() public route!: Route;
|
@property() public route!: Route;
|
||||||
|
|
||||||
@property() public creatingNew?: boolean;
|
|
||||||
|
|
||||||
@property() private _config?: AutomationConfig;
|
@property() private _config?: AutomationConfig;
|
||||||
|
|
||||||
@property() private _dirty?: boolean;
|
@property() private _dirty?: boolean;
|
||||||
|
|
||||||
@property() private _errors?: string;
|
@property() private _errors?: string;
|
||||||
|
|
||||||
|
@property() private _entityId?: string;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
|
const stateObj = this._entityId
|
||||||
|
? this.hass.states[this._entityId]
|
||||||
|
: undefined;
|
||||||
return html`
|
return html`
|
||||||
<hass-tabs-subpage
|
<hass-tabs-subpage
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -70,7 +75,7 @@ export class HaAutomationEditor extends LitElement {
|
|||||||
.backCallback=${() => this._backTapped()}
|
.backCallback=${() => this._backTapped()}
|
||||||
.tabs=${configSections.automation}
|
.tabs=${configSections.automation}
|
||||||
>
|
>
|
||||||
${this.creatingNew
|
${!this.automationId
|
||||||
? ""
|
? ""
|
||||||
: html`
|
: html`
|
||||||
<paper-icon-button
|
<paper-icon-button
|
||||||
@ -82,12 +87,15 @@ export class HaAutomationEditor extends LitElement {
|
|||||||
@click=${this._deleteConfirm}
|
@click=${this._deleteConfirm}
|
||||||
></paper-icon-button>
|
></paper-icon-button>
|
||||||
`}
|
`}
|
||||||
${this._errors ? html` <div class="errors">${this._errors}</div> ` : ""}
|
|
||||||
${this._config
|
${this._config
|
||||||
? html`
|
? html`
|
||||||
${this.narrow
|
${this.narrow
|
||||||
? html` <span slot="header">${this._config?.alias}</span> `
|
? html` <span slot="header">${this._config?.alias}</span> `
|
||||||
: ""}
|
: ""}
|
||||||
|
<div class="content">
|
||||||
|
${this._errors
|
||||||
|
? html` <div class="errors">${this._errors}</div> `
|
||||||
|
: ""}
|
||||||
<ha-config-section .isWide=${this.isWide}>
|
<ha-config-section .isWide=${this.isWide}>
|
||||||
${!this.narrow
|
${!this.narrow
|
||||||
? html` <span slot="header">${this._config.alias}</span> `
|
? html` <span slot="header">${this._config.alias}</span> `
|
||||||
@ -120,26 +128,31 @@ export class HaAutomationEditor extends LitElement {
|
|||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
></ha-textarea>
|
></ha-textarea>
|
||||||
</div>
|
</div>
|
||||||
${this.creatingNew
|
${stateObj
|
||||||
? ""
|
? html`
|
||||||
: html`
|
|
||||||
<div
|
<div
|
||||||
class="card-actions layout horizontal justified center"
|
class="card-actions layout horizontal justified center"
|
||||||
>
|
>
|
||||||
<div class="layout horizontal center">
|
<div class="layout horizontal center">
|
||||||
<ha-entity-toggle
|
<ha-entity-toggle
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.stateObj=${this.automation}
|
.stateObj=${stateObj}
|
||||||
></ha-entity-toggle>
|
></ha-entity-toggle>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.enable_disable"
|
"ui.panel.config.automation.editor.enable_disable"
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<mwc-button @click=${this._excuteAutomation}>
|
<mwc-button
|
||||||
${this.hass.localize("ui.card.automation.trigger")}
|
@click=${this._excuteAutomation}
|
||||||
|
.stateObj=${stateObj}
|
||||||
|
>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.card.automation.trigger"
|
||||||
|
)}
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
</div>
|
</div>
|
||||||
`}
|
`
|
||||||
|
: ""}
|
||||||
</ha-card>
|
</ha-card>
|
||||||
</ha-config-section>
|
</ha-config-section>
|
||||||
|
|
||||||
@ -229,6 +242,7 @@ export class HaAutomationEditor extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
></ha-automation-action>
|
></ha-automation-action>
|
||||||
</ha-config-section>
|
</ha-config-section>
|
||||||
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
<ha-fab
|
<ha-fab
|
||||||
@ -251,19 +265,19 @@ export class HaAutomationEditor extends LitElement {
|
|||||||
protected updated(changedProps: PropertyValues): void {
|
protected updated(changedProps: PropertyValues): void {
|
||||||
super.updated(changedProps);
|
super.updated(changedProps);
|
||||||
|
|
||||||
const oldAutomation = changedProps.get("automation") as AutomationEntity;
|
const oldAutomationId = changedProps.get("automationId");
|
||||||
if (
|
if (
|
||||||
changedProps.has("automation") &&
|
changedProps.has("automationId") &&
|
||||||
this.automation &&
|
this.automationId &&
|
||||||
this.hass &&
|
this.hass &&
|
||||||
// Only refresh config if we picked a new automation. If same ID, don't fetch it.
|
// Only refresh config if we picked a new automation. If same ID, don't fetch it.
|
||||||
(!oldAutomation ||
|
oldAutomationId !== this.automationId
|
||||||
oldAutomation.attributes.id !== this.automation.attributes.id)
|
|
||||||
) {
|
) {
|
||||||
|
this._setEntityId();
|
||||||
this.hass
|
this.hass
|
||||||
.callApi<AutomationConfig>(
|
.callApi<AutomationConfig>(
|
||||||
"GET",
|
"GET",
|
||||||
`config/automation/config/${this.automation.attributes.id}`
|
`config/automation/config/${this.automationId}`
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
(config) => {
|
(config) => {
|
||||||
@ -290,13 +304,12 @@ export class HaAutomationEditor extends LitElement {
|
|||||||
"err_no",
|
"err_no",
|
||||||
resp.status_code
|
resp.status_code
|
||||||
),
|
),
|
||||||
});
|
}).then(() => history.back());
|
||||||
history.back();
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changedProps.has("creatingNew") && this.creatingNew && this.hass) {
|
if (changedProps.has("automationId") && !this.automationId && this.hass) {
|
||||||
const initData = getAutomationEditorInitData();
|
const initData = getAutomationEditorInitData();
|
||||||
this._dirty = !!initData;
|
this._dirty = !!initData;
|
||||||
this._config = {
|
this._config = {
|
||||||
@ -310,6 +323,21 @@ export class HaAutomationEditor extends LitElement {
|
|||||||
...initData,
|
...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) {
|
private _valueChanged(ev: CustomEvent) {
|
||||||
@ -348,8 +376,8 @@ export class HaAutomationEditor extends LitElement {
|
|||||||
this._dirty = true;
|
this._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _excuteAutomation() {
|
private _excuteAutomation(ev: Event) {
|
||||||
triggerAutomation(this.hass, this.automation.entity_id);
|
triggerAutomation(this.hass, (ev.target as any).stateObj.entity_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _backTapped(): void {
|
private _backTapped(): void {
|
||||||
@ -379,14 +407,12 @@ export class HaAutomationEditor extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _delete() {
|
private async _delete() {
|
||||||
await deleteAutomation(this.hass, this.automation.attributes.id!);
|
await deleteAutomation(this.hass, this.automationId);
|
||||||
history.back();
|
history.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _saveAutomation(): void {
|
private _saveAutomation(): void {
|
||||||
const id = this.creatingNew
|
const id = this.automationId || String(Date.now());
|
||||||
? "" + Date.now()
|
|
||||||
: this.automation.attributes.id;
|
|
||||||
this.hass!.callApi(
|
this.hass!.callApi(
|
||||||
"POST",
|
"POST",
|
||||||
"config/automation/config/" + id,
|
"config/automation/config/" + id,
|
||||||
@ -395,7 +421,7 @@ export class HaAutomationEditor extends LitElement {
|
|||||||
() => {
|
() => {
|
||||||
this._dirty = false;
|
this._dirty = false;
|
||||||
|
|
||||||
if (this.creatingNew) {
|
if (!this.automationId) {
|
||||||
navigate(this, `/config/automation/edit/${id}`, true);
|
navigate(this, `/config/automation/edit/${id}`, true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import "./ha-automation-editor";
|
import "./ha-automation-editor";
|
||||||
import "./ha-automation-picker";
|
import "./ha-automation-picker";
|
||||||
|
import { debounce } from "../../../common/util/debounce";
|
||||||
|
|
||||||
@customElement("ha-config-automation")
|
@customElement("ha-config-automation")
|
||||||
class HaConfigAutomation extends HassRouterPage {
|
class HaConfigAutomation extends HassRouterPage {
|
||||||
@ -23,6 +24,13 @@ class HaConfigAutomation extends HassRouterPage {
|
|||||||
|
|
||||||
@property() public automations: AutomationEntity[] = [];
|
@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 = {
|
protected routerOptions: RouterOptions = {
|
||||||
defaultPage: "dashboard",
|
defaultPage: "dashboard",
|
||||||
routes: {
|
routes: {
|
||||||
@ -36,19 +44,15 @@ class HaConfigAutomation extends HassRouterPage {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
private _computeAutomations = memoizeOne((states: HassEntities) => {
|
private _getAutomations = memoizeOne(
|
||||||
const automations: AutomationEntity[] = [];
|
(states: HassEntities): AutomationEntity[] => {
|
||||||
Object.values(states).forEach((state) => {
|
return Object.values(states).filter(
|
||||||
if (
|
(entity) =>
|
||||||
computeStateDomain(state) === "automation" &&
|
computeStateDomain(entity) === "automation" &&
|
||||||
!state.attributes.hidden
|
!entity.attributes.hidden
|
||||||
) {
|
) as AutomationEntity[];
|
||||||
automations.push(state as AutomationEntity);
|
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
|
|
||||||
return automations;
|
|
||||||
});
|
|
||||||
|
|
||||||
protected firstUpdated(changedProps) {
|
protected firstUpdated(changedProps) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
@ -63,25 +67,28 @@ class HaConfigAutomation extends HassRouterPage {
|
|||||||
pageEl.showAdvanced = this.showAdvanced;
|
pageEl.showAdvanced = this.showAdvanced;
|
||||||
|
|
||||||
if (this.hass) {
|
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 (
|
if (
|
||||||
(!changedProps || changedProps.has("route")) &&
|
(!changedProps || changedProps.has("route")) &&
|
||||||
this._currentPage === "edit"
|
this._currentPage === "edit"
|
||||||
) {
|
) {
|
||||||
pageEl.creatingNew = undefined;
|
|
||||||
const automationId = this.routeTail.path.substr(1);
|
const automationId = this.routeTail.path.substr(1);
|
||||||
pageEl.creatingNew = automationId === "new";
|
pageEl.automationId = automationId === "new" ? null : automationId;
|
||||||
pageEl.automation =
|
|
||||||
automationId === "new"
|
|
||||||
? undefined
|
|
||||||
: pageEl.automations.find(
|
|
||||||
(entity: AutomationEntity) =>
|
|
||||||
entity.attributes.id === 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 {
|
declare global {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user