mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-02 00:27:49 +01:00
Use form instead of schema for element-sub-editor (#30210)
* Use form instead of schema for element-sub-editor * fix after merge dev
This commit is contained in:
@@ -41,20 +41,22 @@ const cardConfigStruct = assign(
|
||||
})
|
||||
);
|
||||
|
||||
const SUB_SCHEMA = [
|
||||
{ name: "entity", selector: { entity: {} }, required: true },
|
||||
{
|
||||
name: "name",
|
||||
selector: { entity_name: {} },
|
||||
context: {
|
||||
entity: "entity",
|
||||
const SUB_FORM = {
|
||||
schema: [
|
||||
{ name: "entity", selector: { entity: {} }, required: true },
|
||||
{
|
||||
name: "name",
|
||||
selector: { entity_name: {} },
|
||||
context: {
|
||||
entity: "entity",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "color",
|
||||
selector: { ui_color: {} },
|
||||
},
|
||||
] as const;
|
||||
{
|
||||
name: "color",
|
||||
selector: { ui_color: {} },
|
||||
},
|
||||
] as const,
|
||||
};
|
||||
|
||||
const SCHEMA = [{ name: "title", selector: { text: {} } }] as const;
|
||||
|
||||
@@ -127,7 +129,7 @@ export class HuiDistributionCardEditor
|
||||
<hui-sub-element-editor
|
||||
.hass=${this.hass}
|
||||
.config=${this._subElementEditorConfig}
|
||||
.schema=${SUB_SCHEMA}
|
||||
.form=${SUB_FORM}
|
||||
@go-back=${this._goBack}
|
||||
@config-changed=${this._handleSubElementChanged}
|
||||
>
|
||||
|
||||
@@ -29,7 +29,6 @@ import {
|
||||
import type { EntityBadgeConfig } from "../../badges/types";
|
||||
import type { LovelaceBadgeEditor } from "../../types";
|
||||
import { ACTION_RELATED_CONTEXT } from "../../components/hui-action-editor";
|
||||
import "../hui-sub-element-editor";
|
||||
import { actionConfigStruct } from "../structs/action-struct";
|
||||
import { baseLovelaceBadgeConfig } from "../structs/base-badge-struct";
|
||||
import { entityNameStruct } from "../structs/entity-name-struct";
|
||||
|
||||
@@ -41,56 +41,58 @@ const cardConfigStruct = assign(
|
||||
})
|
||||
);
|
||||
|
||||
const SUB_SCHEMA = [
|
||||
{ name: "entity", selector: { entity: {} }, required: true },
|
||||
{
|
||||
name: "name",
|
||||
selector: { entity_name: {} },
|
||||
context: {
|
||||
entity: "entity",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "grid",
|
||||
name: "",
|
||||
schema: [
|
||||
{
|
||||
name: "icon",
|
||||
selector: {
|
||||
icon: {},
|
||||
},
|
||||
context: {
|
||||
icon_entity: "entity",
|
||||
},
|
||||
},
|
||||
{ name: "show_last_changed", selector: { boolean: {} } },
|
||||
{ name: "show_state", selector: { boolean: {} }, default: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "tap_action",
|
||||
selector: {
|
||||
ui_action: {
|
||||
default_action: "more-info",
|
||||
const SUB_FORM = {
|
||||
schema: [
|
||||
{ name: "entity", selector: { entity: {} }, required: true },
|
||||
{
|
||||
name: "name",
|
||||
selector: { entity_name: {} },
|
||||
context: {
|
||||
entity: "entity",
|
||||
},
|
||||
},
|
||||
context: ACTION_RELATED_CONTEXT,
|
||||
},
|
||||
{
|
||||
name: "",
|
||||
type: "optional_actions",
|
||||
flatten: true,
|
||||
schema: (["hold_action", "double_tap_action"] as const).map((action) => ({
|
||||
name: action,
|
||||
{
|
||||
type: "grid",
|
||||
name: "",
|
||||
schema: [
|
||||
{
|
||||
name: "icon",
|
||||
selector: {
|
||||
icon: {},
|
||||
},
|
||||
context: {
|
||||
icon_entity: "entity",
|
||||
},
|
||||
},
|
||||
{ name: "show_last_changed", selector: { boolean: {} } },
|
||||
{ name: "show_state", selector: { boolean: {} }, default: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "tap_action",
|
||||
selector: {
|
||||
ui_action: {
|
||||
default_action: "none" as const,
|
||||
default_action: "more-info",
|
||||
},
|
||||
},
|
||||
context: ACTION_RELATED_CONTEXT,
|
||||
})),
|
||||
},
|
||||
] as const;
|
||||
},
|
||||
{
|
||||
name: "",
|
||||
type: "optional_actions",
|
||||
flatten: true,
|
||||
schema: (["hold_action", "double_tap_action"] as const).map((action) => ({
|
||||
name: action,
|
||||
selector: {
|
||||
ui_action: {
|
||||
default_action: "none" as const,
|
||||
},
|
||||
},
|
||||
context: ACTION_RELATED_CONTEXT,
|
||||
})),
|
||||
},
|
||||
] as const,
|
||||
};
|
||||
|
||||
const SCHEMA = [
|
||||
{ name: "title", selector: { text: {} } },
|
||||
@@ -144,7 +146,7 @@ export class HuiGlanceCardEditor
|
||||
<hui-sub-element-editor
|
||||
.hass=${this.hass}
|
||||
.config=${this._subElementEditorConfig}
|
||||
.schema=${SUB_SCHEMA}
|
||||
.form=${SUB_FORM}
|
||||
@go-back=${this._goBack}
|
||||
@config-changed=${this._handleSubEntityChanged}
|
||||
>
|
||||
|
||||
@@ -43,16 +43,18 @@ const cardConfigStruct = assign(
|
||||
})
|
||||
);
|
||||
|
||||
const SUB_SCHEMA = [
|
||||
{ name: "entity", selector: { entity: {} }, required: true },
|
||||
{
|
||||
name: "name",
|
||||
selector: { entity_name: {} },
|
||||
context: {
|
||||
entity: "entity",
|
||||
const SUB_FORM = {
|
||||
schema: [
|
||||
{ name: "entity", selector: { entity: {} }, required: true },
|
||||
{
|
||||
name: "name",
|
||||
selector: { entity_name: {} },
|
||||
context: {
|
||||
entity: "entity",
|
||||
},
|
||||
},
|
||||
},
|
||||
] as const;
|
||||
] as const,
|
||||
};
|
||||
|
||||
@customElement("hui-history-graph-card-editor")
|
||||
export class HuiHistoryGraphCardEditor
|
||||
@@ -131,7 +133,7 @@ export class HuiHistoryGraphCardEditor
|
||||
<hui-sub-element-editor
|
||||
.hass=${this.hass}
|
||||
.config=${this._subElementEditorConfig}
|
||||
.schema=${SUB_SCHEMA}
|
||||
.form=${SUB_FORM}
|
||||
@go-back=${this._goBack}
|
||||
@config-changed=${this._handleSubEntityChanged}
|
||||
>
|
||||
|
||||
@@ -21,7 +21,10 @@ import { hasLocation } from "../../../../common/entity/has_location";
|
||||
import type { LocalizeFunc } from "../../../../common/translations/localize";
|
||||
import { orderProperties } from "../../../../common/util/order-properties";
|
||||
import "../../../../components/ha-form/ha-form";
|
||||
import type { SchemaUnion } from "../../../../components/ha-form/types";
|
||||
import type {
|
||||
HaFormSchema,
|
||||
SchemaUnion,
|
||||
} from "../../../../components/ha-form/types";
|
||||
import { MAP_CARD_MARKER_LABEL_MODES } from "../../../../components/map/ha-map";
|
||||
import "../../../../components/ha-formfield";
|
||||
import "../../../../components/ha-selector/ha-selector-select";
|
||||
@@ -152,9 +155,9 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
|
||||
] as const
|
||||
);
|
||||
|
||||
private _subSchema = memoizeOne(
|
||||
(localize: LocalizeFunc, entityId: string, includeEntities: string[]) =>
|
||||
[
|
||||
private _subForm = memoizeOne(
|
||||
(localize: LocalizeFunc, entityId: string, includeEntities: string[]) => ({
|
||||
schema: [
|
||||
{
|
||||
name: "entity",
|
||||
selector: {
|
||||
@@ -207,7 +210,20 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
|
||||
{ name: "focus", default: true, selector: { boolean: {} } },
|
||||
],
|
||||
},
|
||||
] as const
|
||||
] as const,
|
||||
computeLabel: (item: HaFormSchema) => {
|
||||
if (item.name === "focus") {
|
||||
return localize("ui.panel.lovelace.editor.card.map.focus");
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
computeHelper: (item: HaFormSchema) => {
|
||||
if (item.name === "focus") {
|
||||
return localize("ui.panel.lovelace.editor.card.map.focus_helper");
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
public setConfig(config: MapCardConfig): void {
|
||||
@@ -258,7 +274,7 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
|
||||
<hui-sub-element-editor
|
||||
.hass=${this.hass}
|
||||
.config=${this._subElementEditorConfig}
|
||||
.schema=${this._subSchema(
|
||||
.form=${this._subForm(
|
||||
this.hass.localize,
|
||||
entityId,
|
||||
this._locationEntities
|
||||
|
||||
@@ -176,55 +176,54 @@ export class HuiPictureGlanceCardEditor
|
||||
] as const satisfies HaFormSchema[]
|
||||
);
|
||||
|
||||
private _subSchema = memoizeOne(
|
||||
(entityId: string) =>
|
||||
[
|
||||
{ name: "entity", selector: { entity: {} }, required: true },
|
||||
{
|
||||
type: "grid",
|
||||
name: "",
|
||||
schema: [
|
||||
{
|
||||
name: "icon",
|
||||
selector: {
|
||||
icon: {},
|
||||
},
|
||||
context: {
|
||||
icon_entity: "entity",
|
||||
},
|
||||
private _subForm = memoizeOne((entityId: string) => ({
|
||||
schema: [
|
||||
{ name: "entity", selector: { entity: {} }, required: true },
|
||||
{
|
||||
type: "grid",
|
||||
name: "",
|
||||
schema: [
|
||||
{
|
||||
name: "icon",
|
||||
selector: {
|
||||
icon: {},
|
||||
},
|
||||
{ name: "show_state", selector: { boolean: {} } },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "tap_action",
|
||||
selector: {
|
||||
ui_action: {
|
||||
default_action: DOMAINS_TOGGLE.has(computeDomain(entityId))
|
||||
? "toggle"
|
||||
: "more-info",
|
||||
context: {
|
||||
icon_entity: "entity",
|
||||
},
|
||||
},
|
||||
context: ACTION_RELATED_CONTEXT,
|
||||
{ name: "show_state", selector: { boolean: {} } },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "tap_action",
|
||||
selector: {
|
||||
ui_action: {
|
||||
default_action: DOMAINS_TOGGLE.has(computeDomain(entityId))
|
||||
? "toggle"
|
||||
: "more-info",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "",
|
||||
type: "optional_actions",
|
||||
flatten: true,
|
||||
schema: (["hold_action", "double_tap_action"] as const).map(
|
||||
(action) => ({
|
||||
name: action,
|
||||
selector: {
|
||||
ui_action: {
|
||||
default_action: "none" as const,
|
||||
},
|
||||
context: ACTION_RELATED_CONTEXT,
|
||||
},
|
||||
{
|
||||
name: "",
|
||||
type: "optional_actions",
|
||||
flatten: true,
|
||||
schema: (["hold_action", "double_tap_action"] as const).map(
|
||||
(action) => ({
|
||||
name: action,
|
||||
selector: {
|
||||
ui_action: {
|
||||
default_action: "none" as const,
|
||||
},
|
||||
context: ACTION_RELATED_CONTEXT,
|
||||
})
|
||||
),
|
||||
},
|
||||
] as const
|
||||
);
|
||||
},
|
||||
context: ACTION_RELATED_CONTEXT,
|
||||
})
|
||||
),
|
||||
},
|
||||
] as const,
|
||||
}));
|
||||
|
||||
public setConfig(config: PictureGlanceCardConfig): void {
|
||||
assert(config, cardConfigStruct);
|
||||
@@ -242,7 +241,7 @@ export class HuiPictureGlanceCardEditor
|
||||
<hui-sub-element-editor
|
||||
.hass=${this.hass}
|
||||
.config=${this._subElementEditorConfig}
|
||||
.schema=${this._subSchema(
|
||||
.form=${this._subForm(
|
||||
(this._subElementEditorConfig.elementConfig! as EntityConfig).entity
|
||||
)}
|
||||
@go-back=${this._goBack}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { customElement } from "lit/decorators";
|
||||
import { assert, assign, boolean, object, optional, string } from "superstruct";
|
||||
import "../../../../components/ha-form/ha-form";
|
||||
import type {
|
||||
EntityBadgeConfig,
|
||||
StateLabelBadgeConfig,
|
||||
} from "../../badges/types";
|
||||
import "../hui-sub-element-editor";
|
||||
import { actionConfigStruct } from "../structs/action-struct";
|
||||
import { baseLovelaceBadgeConfig } from "../structs/base-badge-struct";
|
||||
import "./hui-card-features-editor";
|
||||
import { HuiEntityBadgeEditor } from "./hui-entity-badge-editor";
|
||||
|
||||
const badgeConfigStruct = assign(
|
||||
|
||||
@@ -1,25 +1,34 @@
|
||||
import type { PropertyValues } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import type { HaFormSchema } from "../../../components/ha-form/types";
|
||||
import type { LovelaceConfigForm } from "../types";
|
||||
import type { HuiFormEditor } from "./config-elements/hui-form-editor";
|
||||
import { HuiElementEditor } from "./hui-element-editor";
|
||||
|
||||
@customElement("hui-form-element-editor")
|
||||
export class HuiFormElementEditor extends HuiElementEditor {
|
||||
@property({ attribute: false }) public schema!: HaFormSchema[];
|
||||
@property({ attribute: false }) public form!: LovelaceConfigForm;
|
||||
|
||||
protected async getConfigForm(): Promise<LovelaceConfigForm | undefined> {
|
||||
return { schema: this.schema };
|
||||
return this.form;
|
||||
}
|
||||
|
||||
protected updated(changedProperties: PropertyValues): void {
|
||||
super.updated(changedProperties);
|
||||
if (changedProperties.has("schema") && this._configElement) {
|
||||
if (changedProperties.has("form") && this._configElement) {
|
||||
// Propagate schema changes directly to the existing form editor element
|
||||
// so dynamic changes (e.g. disabled flags based on selected entity) are
|
||||
// reflected without needing to tear down and recreate the editor.
|
||||
(this._configElement as HuiFormEditor).schema = this.schema;
|
||||
const { schema, assertConfig, computeLabel, computeHelper } = this.form;
|
||||
(this._configElement as HuiFormEditor).schema = schema;
|
||||
if (computeLabel) {
|
||||
(this._configElement as HuiFormEditor).computeLabel = computeLabel;
|
||||
}
|
||||
if (computeHelper) {
|
||||
(this._configElement as HuiFormEditor).computeHelper = computeHelper;
|
||||
}
|
||||
if (assertConfig) {
|
||||
(this._configElement as HuiFormEditor).assertConfig = assertConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import type { HuiElementEditor } from "./hui-element-editor";
|
||||
import "./hui-form-element-editor";
|
||||
import "./picture-element-editor/hui-picture-element-element-editor";
|
||||
import type { GUIModeChangedEvent, SubElementEditorConfig } from "./types";
|
||||
import type { LovelaceConfigForm } from "../types";
|
||||
|
||||
declare global {
|
||||
interface HASSDomEvents {
|
||||
@@ -28,7 +29,7 @@ export class HuiSubElementEditor extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public config!: SubElementEditorConfig;
|
||||
|
||||
@property({ attribute: false }) public schema?;
|
||||
@property({ attribute: false }) public form?: LovelaceConfigForm;
|
||||
|
||||
@state() private _guiModeAvailable = true;
|
||||
|
||||
@@ -84,13 +85,13 @@ export class HuiSubElementEditor extends LitElement {
|
||||
private _renderEditor() {
|
||||
const type = this.config.type;
|
||||
|
||||
if (this.schema) {
|
||||
if (this.form) {
|
||||
return html`
|
||||
<hui-form-element-editor
|
||||
class="editor"
|
||||
.hass=${this.hass}
|
||||
.value=${this.config.elementConfig}
|
||||
.schema=${this.schema}
|
||||
.form=${this.form}
|
||||
.context=${this.config.context}
|
||||
@config-changed=${this._handleConfigChanged}
|
||||
></hui-form-element-editor>
|
||||
|
||||
@@ -9220,7 +9220,6 @@
|
||||
"cover": "Cover",
|
||||
"fill": "Fill"
|
||||
},
|
||||
"focus": "Focus",
|
||||
"hold_action": "Hold behavior",
|
||||
"hours_to_show": "Hours to show",
|
||||
"days_to_show": "Days to show",
|
||||
@@ -9296,6 +9295,8 @@
|
||||
"name": "Map",
|
||||
"geo_location_sources": "Geolocation sources",
|
||||
"no_geo_location_sources": "No geolocation sources available",
|
||||
"focus": "Focus",
|
||||
"focus_helper": "Include this entity when calculating the autofit",
|
||||
"appearance": "Appearance",
|
||||
"theme_mode": "Theme mode",
|
||||
"theme_modes": {
|
||||
|
||||
Reference in New Issue
Block a user