Use callback instead of changing nested config with sub editor (#22081)

Use callback instead of changing nested config
This commit is contained in:
Paul Bottein 2024-09-25 16:47:38 +02:00 committed by GitHub
parent 291c026da0
commit 4e51c7cf96
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 81 additions and 53 deletions

View File

@ -1,17 +0,0 @@
export function updateNestedObject<T = any>(
obj: T,
path: (number | string)[],
value: any
): T {
if (path.length === 0) return value;
const newObj = (Array.isArray(obj) ? [...obj] : { ...obj }) as T;
const key = path[0];
newObj[key] = updateNestedObject(obj[key], path.slice(1), value);
return newObj;
}
export function findNestedObject(obj: any, path: (number | string)[]) {
if (path.length === 0) return obj;
const key = path[0];
return findNestedObject(obj[key], path.slice(1));
}

View File

@ -30,6 +30,7 @@ import { actionConfigStruct } from "../structs/action-struct";
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
import { configElementStyle } from "./config-elements-style";
import "./hui-entities-editor";
import { EditSubElementEvent } from "../types";
const actions: UiAction[] = ["navigate", "url", "perform-action", "none"];
@ -176,9 +177,22 @@ export class HuiHeadingCardEditor
private _editEntity(ev: HASSDomEvent<{ index: number }>): void {
ev.stopPropagation();
const index = ev.detail.index;
const config = this._config!.entities![index!];
fireEvent(this, "edit-sub-element", {
path: ["entities", ev.detail.index],
config: config,
saveConfig: (newConfig) => this._updateEntity(index, newConfig),
type: "heading-entity",
} as EditSubElementEvent<HeadingEntityConfig>);
}
private _updateEntity(index: number, entity: HeadingEntityConfig) {
const entities = this._config!.entities!.concat();
entities[index] = entity;
const config = { ...this._config!, entities };
fireEvent(this, "config-changed", {
config: config,
});
}

View File

@ -27,7 +27,7 @@ import {
import type { HumidifierCardConfig } from "../../cards/types";
import type { LovelaceCardEditor } from "../../types";
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
import { EditDetailElementEvent } from "../types";
import { EditDetailElementEvent, EditSubElementEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import "./hui-card-features-editor";
import type { FeatureType } from "./hui-card-features-editor";
@ -145,12 +145,28 @@ export class HuiHumidifierCardEditor
}
private _editDetailElement(ev: HASSDomEvent<EditDetailElementEvent>): void {
const index = ev.detail.subElementConfig.index;
const config = this._config!.features![index!];
fireEvent(this, "edit-sub-element", {
path: ["features", ev.detail.subElementConfig.index!],
config: config,
saveConfig: (newConfig) => this._updateFeature(index!, newConfig),
context: {
entity_id: this._config!.entity,
} as LovelaceCardFeatureContext,
},
type: "feature",
} as EditSubElementEvent<
LovelaceCardFeatureConfig,
LovelaceCardFeatureContext
>);
}
private _updateFeature(index: number, feature: LovelaceCardFeatureConfig) {
const features = this._config!.features!.concat();
features[index] = feature;
const config = { ...this._config!, features };
fireEvent(this, "config-changed", {
config: config,
});
}

View File

@ -27,7 +27,7 @@ import {
import type { ThermostatCardConfig } from "../../cards/types";
import type { LovelaceCardEditor } from "../../types";
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
import { EditDetailElementEvent } from "../types";
import { EditDetailElementEvent, EditSubElementEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import "./hui-card-features-editor";
import type { FeatureType } from "./hui-card-features-editor";
@ -143,12 +143,28 @@ export class HuiThermostatCardEditor
}
private _editDetailElement(ev: HASSDomEvent<EditDetailElementEvent>): void {
const index = ev.detail.subElementConfig.index;
const config = this._config!.features![index!];
fireEvent(this, "edit-sub-element", {
path: ["features", ev.detail.subElementConfig.index!],
config: config,
saveConfig: (newConfig) => this._updateFeature(index!, newConfig),
context: {
entity_id: this._config!.entity,
} as LovelaceCardFeatureContext,
},
type: "feature",
} as EditSubElementEvent<
LovelaceCardFeatureConfig,
LovelaceCardFeatureContext
>);
}
private _updateFeature(index: number, feature: LovelaceCardFeatureConfig) {
const features = this._config!.features!.concat();
features[index] = feature;
const config = { ...this._config!, features };
fireEvent(this, "config-changed", {
config: config,
});
}

View File

@ -31,7 +31,7 @@ import type { TileCardConfig } from "../../cards/types";
import type { LovelaceCardEditor } from "../../types";
import { actionConfigStruct } from "../structs/action-struct";
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
import { EditDetailElementEvent } from "../types";
import { EditDetailElementEvent, EditSubElementEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import "./hui-card-features-editor";
@ -246,12 +246,28 @@ export class HuiTileCardEditor
}
private _editDetailElement(ev: HASSDomEvent<EditDetailElementEvent>): void {
const index = ev.detail.subElementConfig.index;
const config = this._config!.features![index!];
fireEvent(this, "edit-sub-element", {
path: ["features", ev.detail.subElementConfig.index!],
config: config,
saveConfig: (newConfig) => this._updateFeature(index!, newConfig),
context: {
entity_id: this._config!.entity,
} as LovelaceCardFeatureContext,
},
type: "feature",
} as EditSubElementEvent<
LovelaceCardFeatureConfig,
LovelaceCardFeatureContext
>);
}
private _updateFeature(index: number, feature: LovelaceCardFeatureConfig) {
const features = this._config!.features!.concat();
features[index] = feature;
const config = { ...this._config!, features };
fireEvent(this, "config-changed", {
config: config,
});
}

View File

@ -12,10 +12,6 @@ import { cache } from "lit/directives/cache";
import { fireEvent, HASSDomEvent } from "../../../common/dom/fire_event";
import { handleStructError } from "../../../common/structs/handle-errors";
import { deepEqual } from "../../../common/util/deep-equal";
import {
findNestedObject,
updateNestedObject,
} from "../../../common/util/nested-object";
import "../../../components/ha-alert";
import "../../../components/ha-circular-progress";
import "../../../components/ha-yaml-editor";
@ -197,14 +193,7 @@ export abstract class HuiElementEditor<
elementConfig: value,
};
const config = updateNestedObject(
this._config,
this._subElementEditorConfig.path!,
value
);
this._config = config;
this._setConfig();
this._subElementEditorConfig.saveElementConfig?.(value);
}
private _goBack(ev): void {
@ -215,22 +204,15 @@ export abstract class HuiElementEditor<
private async _editSubElement(
ev: HASSDomEvent<EditSubElementEvent>
): Promise<void> {
if (!ev.detail.path) {
return;
}
ev.stopPropagation();
const config = findNestedObject(this._config, ev.detail.path);
if (!config) {
throw new Error("Failed to edit config");
}
await import("./hui-sub-element-editor");
this._subElementEditorConfig = {
type: ev.detail.type,
path: ev.detail.path,
elementConfig: config,
elementConfig: ev.detail.config,
context: ev.detail.context,
saveElementConfig: ev.detail.saveConfig,
};
}

View File

@ -92,21 +92,22 @@ export interface BadgePickTarget extends EventTarget {
export interface SubElementEditorConfig {
index?: number;
path?: (string | number)[];
elementConfig?:
| LovelaceRowConfig
| LovelaceHeaderFooterConfig
| LovelaceCardFeatureConfig
| LovelaceElementConfig
| HeadingEntityConfig;
saveElementConfig?: (elementConfig: any) => void;
context?: any;
type: "header" | "footer" | "row" | "feature" | "element" | "heading-entity";
}
export interface EditSubElementEvent {
path: (string | number)[];
export interface EditSubElementEvent<T = any, C = any> {
type: SubElementEditorConfig["type"];
context?: any;
context?: C;
config: T;
saveConfig: (config: T) => void;
}
export interface EditDetailElementEvent {