Optimize script editor (#5650)

This commit is contained in:
Bram Kragten 2020-04-30 20:40:23 +02:00 committed by GitHub
parent ee889d59d4
commit 8484f7595a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 44 deletions

View File

@ -12,6 +12,13 @@ import "./ha-automation-editor";
import "./ha-automation-picker"; import "./ha-automation-picker";
import { debounce } from "../../../common/util/debounce"; import { debounce } from "../../../common/util/debounce";
const equal = (a: AutomationEntity[], b: AutomationEntity[]): boolean => {
if (a.length !== b.length) {
return false;
}
return a.every((automation, index) => automation === b[index]);
};
@customElement("ha-config-automation") @customElement("ha-config-automation")
class HaConfigAutomation extends HassRouterPage { class HaConfigAutomation extends HassRouterPage {
@property() public hass!: HomeAssistant; @property() public hass!: HomeAssistant;
@ -26,7 +33,7 @@ class HaConfigAutomation extends HassRouterPage {
private _debouncedUpdateAutomations = debounce((pageEl) => { private _debouncedUpdateAutomations = debounce((pageEl) => {
const newAutomations = this._getAutomations(this.hass.states); const newAutomations = this._getAutomations(this.hass.states);
if (!this._equal(newAutomations, pageEl.automations)) { if (!equal(newAutomations, pageEl.automations)) {
pageEl.automations = newAutomations; pageEl.automations = newAutomations;
} }
}, 10); }, 10);
@ -82,13 +89,6 @@ class HaConfigAutomation extends HassRouterPage {
pageEl.automationId = automationId === "new" ? null : 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 { declare global {

View File

@ -1,4 +1,4 @@
import { HassEntities, HassEntity } from "home-assistant-js-websocket"; import { HassEntities } from "home-assistant-js-websocket";
import { customElement, property, PropertyValues } from "lit-element"; import { customElement, property, PropertyValues } from "lit-element";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateDomain } from "../../../common/entity/compute_state_domain";
@ -9,6 +9,15 @@ import {
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
import "./ha-script-editor"; import "./ha-script-editor";
import "./ha-script-picker"; import "./ha-script-picker";
import { debounce } from "../../../common/util/debounce";
import { ScriptEntity } from "../../../data/script";
const equal = (a: ScriptEntity[], b: ScriptEntity[]): boolean => {
if (a.length !== b.length) {
return false;
}
return a.every((enityA, index) => enityA === b[index]);
};
@customElement("ha-config-script") @customElement("ha-config-script")
class HaConfigScript extends HassRouterPage { class HaConfigScript extends HassRouterPage {
@ -20,7 +29,7 @@ class HaConfigScript extends HassRouterPage {
@property() public showAdvanced!: boolean; @property() public showAdvanced!: boolean;
@property() public scripts: HassEntity[] = []; @property() public scripts: ScriptEntity[] = [];
protected routerOptions: RouterOptions = { protected routerOptions: RouterOptions = {
defaultPage: "dashboard", defaultPage: "dashboard",
@ -35,15 +44,18 @@ class HaConfigScript extends HassRouterPage {
}, },
}; };
private _computeScripts = memoizeOne((states: HassEntities) => { private _debouncedUpdateScripts = debounce((pageEl) => {
const scripts: HassEntity[] = []; const newScript = this._getScripts(this.hass.states);
Object.values(states).forEach((state) => { if (!equal(newScript, pageEl.scripts)) {
if (computeStateDomain(state) === "script" && !state.attributes.hidden) { pageEl.scripts = newScript;
scripts.push(state); }
} }, 10);
});
return scripts; private _getScripts = memoizeOne((states: HassEntities): ScriptEntity[] => {
return Object.values(states).filter(
(entity) =>
computeStateDomain(entity) === "script" && !entity.attributes.hidden
) as ScriptEntity[];
}); });
protected firstUpdated(changedProps) { protected firstUpdated(changedProps) {
@ -59,7 +71,11 @@ class HaConfigScript extends HassRouterPage {
pageEl.showAdvanced = this.showAdvanced; pageEl.showAdvanced = this.showAdvanced;
if (this.hass) { if (this.hass) {
pageEl.scripts = this._computeScripts(this.hass.states); if (!pageEl.scripts || !changedProps) {
pageEl.scripts = this._getScripts(this.hass.states);
} else if (changedProps && changedProps.has("hass")) {
this._debouncedUpdateScripts(pageEl);
}
} }
if ( if (
@ -68,13 +84,7 @@ class HaConfigScript extends HassRouterPage {
) { ) {
pageEl.creatingNew = undefined; pageEl.creatingNew = undefined;
const scriptEntityId = this.routeTail.path.substr(1); const scriptEntityId = this.routeTail.path.substr(1);
pageEl.creatingNew = scriptEntityId === "new"; pageEl.scriptEntityId = scriptEntityId === "new" ? null : scriptEntityId;
pageEl.script =
scriptEntityId === "new"
? undefined
: pageEl.scripts.find(
(entity: HassEntity) => entity.entity_id === scriptEntityId
);
} }
} }
} }

View File

@ -22,7 +22,6 @@ import {
deleteScript, deleteScript,
getScriptEditorInitData, getScriptEditorInitData,
ScriptConfig, ScriptConfig,
ScriptEntity,
} from "../../../data/script"; } from "../../../data/script";
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
import "../../../layouts/ha-app-layout"; import "../../../layouts/ha-app-layout";
@ -36,16 +35,14 @@ import { configSections } from "../ha-panel-config";
export class HaScriptEditor extends LitElement { export class HaScriptEditor extends LitElement {
@property() public hass!: HomeAssistant; @property() public hass!: HomeAssistant;
@property() public script!: ScriptEntity; @property() public scriptEntityId!: string;
@property() public route!: Route;
@property() public isWide?: boolean; @property() public isWide?: boolean;
@property() public narrow!: boolean; @property() public narrow!: boolean;
@property() public route!: Route;
@property() public creatingNew?: boolean;
@property() private _config?: ScriptConfig; @property() private _config?: ScriptConfig;
@property() private _dirty?: boolean; @property() private _dirty?: boolean;
@ -61,7 +58,7 @@ export class HaScriptEditor extends LitElement {
.backCallback=${() => this._backTapped()} .backCallback=${() => this._backTapped()}
.tabs=${configSections.automation} .tabs=${configSections.automation}
> >
${this.creatingNew ${!this.scriptEntityId
? "" ? ""
: html` : html`
<paper-icon-button <paper-icon-button
@ -161,18 +158,18 @@ export class HaScriptEditor extends LitElement {
protected updated(changedProps: PropertyValues): void { protected updated(changedProps: PropertyValues): void {
super.updated(changedProps); super.updated(changedProps);
const oldScript = changedProps.get("script") as ScriptEntity; const oldScript = changedProps.get("scriptEntityId");
if ( if (
changedProps.has("script") && changedProps.has("scriptEntityId") &&
this.script && this.scriptEntityId &&
this.hass && this.hass &&
// Only refresh config if we picked a new script. If same ID, don't fetch it. // Only refresh config if we picked a new script. If same ID, don't fetch it.
(!oldScript || oldScript.entity_id !== this.script.entity_id) (!oldScript || oldScript !== this.scriptEntityId)
) { ) {
this.hass this.hass
.callApi<ScriptConfig>( .callApi<ScriptConfig>(
"GET", "GET",
`config/script/config/${computeObjectId(this.script.entity_id)}` `config/script/config/${computeObjectId(this.scriptEntityId)}`
) )
.then( .then(
(config) => { (config) => {
@ -202,7 +199,11 @@ export class HaScriptEditor extends LitElement {
); );
} }
if (changedProps.has("creatingNew") && this.creatingNew && this.hass) { if (
changedProps.has("scriptEntityId") &&
!this.scriptEntityId &&
this.hass
) {
const initData = getScriptEditorInitData(); const initData = getScriptEditorInitData();
this._dirty = !!initData; this._dirty = !!initData;
this._config = { this._config = {
@ -259,19 +260,19 @@ export class HaScriptEditor extends LitElement {
} }
private async _delete() { private async _delete() {
await deleteScript(this.hass, computeObjectId(this.script.entity_id)); await deleteScript(this.hass, computeObjectId(this.scriptEntityId));
history.back(); history.back();
} }
private _saveScript(): void { private _saveScript(): void {
const id = this.creatingNew const id = this.scriptEntityId
? "" + Date.now() ? computeObjectId(this.scriptEntityId)
: computeObjectId(this.script.entity_id); : Date.now();
this.hass!.callApi("POST", "config/script/config/" + id, this._config).then( this.hass!.callApi("POST", "config/script/config/" + id, this._config).then(
() => { () => {
this._dirty = false; this._dirty = false;
if (this.creatingNew) { if (!this.scriptEntityId) {
navigate(this, `/config/script/edit/${id}`, true); navigate(this, `/config/script/edit/${id}`, true);
} }
}, },