Fix localize key types related to form schemas (Group 1) (#13258)

This commit is contained in:
Steve Repsher 2022-08-05 09:37:54 -04:00 committed by GitHub
parent d4232a2256
commit 150bc00c31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 516 additions and 443 deletions

View File

@ -35,7 +35,7 @@ export class HaForm extends LitElement implements HaFormElement {
@property({ attribute: false }) public data!: HaFormDataContainer; @property({ attribute: false }) public data!: HaFormDataContainer;
@property({ attribute: false }) public schema!: HaFormSchema[]; @property({ attribute: false }) public schema!: readonly HaFormSchema[];
@property() public error?: Record<string, string>; @property() public error?: Record<string, string>;
@ -44,7 +44,7 @@ export class HaForm extends LitElement implements HaFormElement {
@property() public computeError?: (schema: HaFormSchema, error) => string; @property() public computeError?: (schema: HaFormSchema, error) => string;
@property() public computeLabel?: ( @property() public computeLabel?: (
schema: HaFormSchema, schema: any,
data?: HaFormDataContainer data?: HaFormDataContainer
) => string; ) => string;
@ -168,7 +168,7 @@ export class HaForm extends LitElement implements HaFormElement {
return this.computeHelper ? this.computeHelper(schema) : ""; return this.computeHelper ? this.computeHelper(schema) : "";
} }
private _computeError(error, schema: HaFormSchema | HaFormSchema[]) { private _computeError(error, schema: HaFormSchema | readonly HaFormSchema[]) {
return this.computeError ? this.computeError(error, schema) : error; return this.computeError ? this.computeError(error, schema) : error;
} }

View File

@ -31,7 +31,7 @@ export interface HaFormGridSchema extends HaFormBaseSchema {
type: "grid"; type: "grid";
name: ""; name: "";
column_min_width?: string; column_min_width?: string;
schema: HaFormSchema[]; schema: readonly HaFormSchema[];
} }
export interface HaFormSelector extends HaFormBaseSchema { export interface HaFormSelector extends HaFormBaseSchema {
@ -53,12 +53,15 @@ export interface HaFormIntegerSchema extends HaFormBaseSchema {
export interface HaFormSelectSchema extends HaFormBaseSchema { export interface HaFormSelectSchema extends HaFormBaseSchema {
type: "select"; type: "select";
options: Array<[string, string]>; options: ReadonlyArray<readonly [string, string]>;
} }
export interface HaFormMultiSelectSchema extends HaFormBaseSchema { export interface HaFormMultiSelectSchema extends HaFormBaseSchema {
type: "multi_select"; type: "multi_select";
options: Record<string, string> | string[] | Array<[string, string]>; options:
| Record<string, string>
| readonly string[]
| ReadonlyArray<readonly [string, string]>;
} }
export interface HaFormFloatSchema extends HaFormBaseSchema { export interface HaFormFloatSchema extends HaFormBaseSchema {
@ -78,6 +81,12 @@ export interface HaFormTimeSchema extends HaFormBaseSchema {
type: "positive_time_period_dict"; type: "positive_time_period_dict";
} }
// Type utility to unionize a schema array by flattening any grid schemas
export type SchemaUnion<
SchemaArray extends readonly HaFormSchema[],
Schema = SchemaArray[number]
> = Schema extends HaFormGridSchema ? SchemaUnion<Schema["schema"]> : Schema;
export interface HaFormDataContainer { export interface HaFormDataContainer {
[key: string]: HaFormData; [key: string]: HaFormData;
} }
@ -100,7 +109,7 @@ export type HaFormMultiSelectData = string[];
export type HaFormTimeData = HaDurationData; export type HaFormTimeData = HaDurationData;
export interface HaFormElement extends LitElement { export interface HaFormElement extends LitElement {
schema: HaFormSchema | HaFormSchema[]; schema: HaFormSchema | readonly HaFormSchema[];
data?: HaFormDataContainer | HaFormData; data?: HaFormDataContainer | HaFormData;
label?: string; label?: string;
} }

View File

@ -15,7 +15,7 @@ import "../ha-automation-action";
import "../../../../../components/ha-textfield"; import "../../../../../components/ha-textfield";
import type { ActionElement } from "../ha-automation-action-row"; import type { ActionElement } from "../ha-automation-action-row";
const OPTIONS = ["count", "while", "until"]; const OPTIONS = ["count", "while", "until"] as const;
const getType = (action) => OPTIONS.find((option) => option in action); const getType = (action) => OPTIONS.find((option) => option in action);

View File

@ -1,12 +1,12 @@
import { html, LitElement } from "lit"; import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import type { HaFormSchema } from "../../../../../components/ha-form/types";
import type { WaitAction } from "../../../../../data/script"; import type { WaitAction } from "../../../../../data/script";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { ActionElement } from "../ha-automation-action-row"; import type { ActionElement } from "../ha-automation-action-row";
import "../../../../../components/ha-form/ha-form"; import "../../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
const SCHEMA: HaFormSchema[] = [ const SCHEMA = [
{ {
name: "wait_template", name: "wait_template",
selector: { selector: {
@ -24,7 +24,7 @@ const SCHEMA: HaFormSchema[] = [
name: "continue_on_timeout", name: "continue_on_timeout",
selector: { boolean: {} }, selector: { boolean: {} },
}, },
]; ] as const;
@customElement("ha-automation-action-wait_template") @customElement("ha-automation-action-wait_template")
export class HaWaitAction extends LitElement implements ActionElement { export class HaWaitAction extends LitElement implements ActionElement {
@ -47,7 +47,9 @@ export class HaWaitAction extends LitElement implements ActionElement {
`; `;
} }
private _computeLabelCallback = (schema: HaFormSchema): string => private _computeLabelCallback = (
schema: SchemaUnion<typeof SCHEMA>
): string =>
this.hass.localize( this.hass.localize(
`ui.panel.config.automation.editor.actions.type.wait_template.${ `ui.panel.config.automation.editor.actions.type.wait_template.${
schema.name === "continue_on_timeout" ? "continue_timeout" : schema.name schema.name === "continue_on_timeout" ? "continue_timeout" : schema.name

View File

@ -36,15 +36,15 @@ const OPTIONS = [
"time", "time",
"trigger", "trigger",
"zone", "zone",
]; ] as const;
@customElement("ha-automation-condition-editor") @customElement("ha-automation-condition-editor")
export default class HaAutomationConditionEditor extends LitElement { export default class HaAutomationConditionEditor extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property() condition!: Condition; @property({ attribute: false }) condition!: Condition;
@property() public yamlMode = false; @property({ type: Boolean }) public yamlMode = false;
private _processedCondition = memoizeOne((condition) => private _processedCondition = memoizeOne((condition) =>
expandConditionWithShorthand(condition) expandConditionWithShorthand(condition)

View File

@ -3,9 +3,9 @@ import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import type { HaFormSchema } from "../../../../../components/ha-form/types";
import { NumericStateCondition } from "../../../../../data/automation"; import { NumericStateCondition } from "../../../../../data/automation";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
@customElement("ha-automation-condition-numeric_state") @customElement("ha-automation-condition-numeric_state")
export default class HaNumericStateCondition extends LitElement { export default class HaNumericStateCondition extends LitElement {
@ -19,19 +19,22 @@ export default class HaNumericStateCondition extends LitElement {
}; };
} }
private _schema = memoizeOne((entityId): HaFormSchema[] => [ private _schema = memoizeOne(
{ name: "entity_id", required: true, selector: { entity: {} } }, (entityId) =>
{ [
name: "attribute", { name: "entity_id", required: true, selector: { entity: {} } },
selector: { attribute: { entity_id: entityId } }, {
}, name: "attribute",
{ name: "above", selector: { text: {} } }, selector: { attribute: { entity_id: entityId } },
{ name: "below", selector: { text: {} } }, },
{ { name: "above", selector: { text: {} } },
name: "value_template", { name: "below", selector: { text: {} } },
selector: { text: { multiline: true } }, {
}, name: "value_template",
]); selector: { text: { multiline: true } },
},
] as const
);
public render() { public render() {
const schema = this._schema(this.condition.entity_id); const schema = this._schema(this.condition.entity_id);
@ -53,7 +56,9 @@ export default class HaNumericStateCondition extends LitElement {
fireEvent(this, "value-changed", { value: newTrigger }); fireEvent(this, "value-changed", { value: newTrigger });
} }
private _computeLabelCallback = (schema: HaFormSchema): string => { private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
): string => {
switch (schema.name) { switch (schema.name) {
case "entity_id": case "entity_id":
return this.hass.localize("ui.components.entity.entity-picker.entity"); return this.hass.localize("ui.components.entity.entity-picker.entity");

View File

@ -4,12 +4,12 @@ import memoizeOne from "memoize-one";
import { assert, literal, object, optional, string, union } from "superstruct"; import { assert, literal, object, optional, string, union } from "superstruct";
import { createDurationData } from "../../../../../common/datetime/create_duration_data"; import { createDurationData } from "../../../../../common/datetime/create_duration_data";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import type { HaFormSchema } from "../../../../../components/ha-form/types";
import type { StateCondition } from "../../../../../data/automation"; import type { StateCondition } from "../../../../../data/automation";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import { forDictStruct } from "../../structs"; import { forDictStruct } from "../../structs";
import type { ConditionElement } from "../ha-automation-condition-row"; import type { ConditionElement } from "../ha-automation-condition-row";
import "../../../../../components/ha-form/ha-form"; import "../../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
const stateConditionStruct = object({ const stateConditionStruct = object({
condition: literal("state"), condition: literal("state"),
@ -29,15 +29,18 @@ export class HaStateCondition extends LitElement implements ConditionElement {
return { entity_id: "", state: "" }; return { entity_id: "", state: "" };
} }
private _schema = memoizeOne((entityId) => [ private _schema = memoizeOne(
{ name: "entity_id", required: true, selector: { entity: {} } }, (entityId) =>
{ [
name: "attribute", { name: "entity_id", required: true, selector: { entity: {} } },
selector: { attribute: { entity_id: entityId } }, {
}, name: "attribute",
{ name: "state", selector: { text: {} } }, selector: { attribute: { entity_id: entityId } },
{ name: "for", selector: { duration: {} } }, },
]); { name: "state", selector: { text: {} } },
{ name: "for", selector: { duration: {} } },
] as const
);
public shouldUpdate(changedProperties: PropertyValues) { public shouldUpdate(changedProperties: PropertyValues) {
if (changedProperties.has("condition")) { if (changedProperties.has("condition")) {
@ -80,7 +83,9 @@ export class HaStateCondition extends LitElement implements ConditionElement {
fireEvent(this, "value-changed", { value: newTrigger }); fireEvent(this, "value-changed", { value: newTrigger });
} }
private _computeLabelCallback = (schema: HaFormSchema): string => { private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
): string => {
switch (schema.name) { switch (schema.name) {
case "entity_id": case "entity_id":
return this.hass.localize("ui.components.entity.entity-picker.entity"); return this.hass.localize("ui.components.entity.entity-picker.entity");

View File

@ -6,8 +6,8 @@ import type { SunCondition } from "../../../../../data/automation";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { ConditionElement } from "../ha-automation-condition-row"; import type { ConditionElement } from "../ha-automation-condition-row";
import type { LocalizeFunc } from "../../../../../common/translations/localize"; import type { LocalizeFunc } from "../../../../../common/translations/localize";
import type { HaFormSchema } from "../../../../../components/ha-form/types";
import "../../../../../components/ha-form/ha-form"; import "../../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
@customElement("ha-automation-condition-sun") @customElement("ha-automation-condition-sun")
export class HaSunCondition extends LitElement implements ConditionElement { export class HaSunCondition extends LitElement implements ConditionElement {
@ -19,48 +19,51 @@ export class HaSunCondition extends LitElement implements ConditionElement {
return {}; return {};
} }
private _schema = memoizeOne((localize: LocalizeFunc) => [ private _schema = memoizeOne(
{ (localize: LocalizeFunc) =>
name: "before", [
type: "select", {
required: true, name: "before",
options: [ type: "select",
[ required: true,
"sunrise", options: [
localize( [
"ui.panel.config.automation.editor.conditions.type.sun.sunrise" "sunrise",
), localize(
], "ui.panel.config.automation.editor.conditions.type.sun.sunrise"
[ ),
"sunset", ],
localize( [
"ui.panel.config.automation.editor.conditions.type.sun.sunset" "sunset",
), localize(
], "ui.panel.config.automation.editor.conditions.type.sun.sunset"
], ),
}, ],
{ name: "before_offset", selector: { text: {} } }, ],
{ },
name: "after", { name: "before_offset", selector: { text: {} } },
type: "select", {
required: true, name: "after",
options: [ type: "select",
[ required: true,
"sunrise", options: [
localize( [
"ui.panel.config.automation.editor.conditions.type.sun.sunrise" "sunrise",
), localize(
], "ui.panel.config.automation.editor.conditions.type.sun.sunrise"
[ ),
"sunset", ],
localize( [
"ui.panel.config.automation.editor.conditions.type.sun.sunset" "sunset",
), localize(
], "ui.panel.config.automation.editor.conditions.type.sun.sunset"
], ),
}, ],
{ name: "after_offset", selector: { text: {} } }, ],
]); },
{ name: "after_offset", selector: { text: {} } },
] as const
);
protected render() { protected render() {
const schema = this._schema(this.hass.localize); const schema = this._schema(this.hass.localize);
@ -81,7 +84,9 @@ export class HaSunCondition extends LitElement implements ConditionElement {
fireEvent(this, "value-changed", { value: newTrigger }); fireEvent(this, "value-changed", { value: newTrigger });
} }
private _computeLabelCallback = (schema: HaFormSchema): string => private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
): string =>
this.hass.localize( this.hass.localize(
`ui.panel.config.automation.editor.conditions.type.sun.${schema.name}` `ui.panel.config.automation.editor.conditions.type.sun.${schema.name}`
); );

View File

@ -6,18 +6,10 @@ import type { TimeCondition } from "../../../../../data/automation";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { ConditionElement } from "../ha-automation-condition-row"; import type { ConditionElement } from "../ha-automation-condition-row";
import type { LocalizeFunc } from "../../../../../common/translations/localize"; import type { LocalizeFunc } from "../../../../../common/translations/localize";
import type { HaFormSchema } from "../../../../../components/ha-form/types";
import "../../../../../components/ha-form/ha-form"; import "../../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
const DAYS = { const DAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"] as const;
mon: 1,
tue: 2,
wed: 3,
thu: 4,
fri: 5,
sat: 6,
sun: 7,
};
@customElement("ha-automation-condition-time") @customElement("ha-automation-condition-time")
export class HaTimeCondition extends LitElement implements ConditionElement { export class HaTimeCondition extends LitElement implements ConditionElement {
@ -38,16 +30,8 @@ export class HaTimeCondition extends LitElement implements ConditionElement {
localize: LocalizeFunc, localize: LocalizeFunc,
inputModeAfter?: boolean, inputModeAfter?: boolean,
inputModeBefore?: boolean inputModeBefore?: boolean
): HaFormSchema[] => { ) =>
const modeAfterSchema = inputModeAfter [
? { name: "after", selector: { entity: { domain: "input_datetime" } } }
: { name: "after", selector: { time: {} } };
const modeBeforeSchema = inputModeBefore
? { name: "before", selector: { entity: { domain: "input_datetime" } } }
: { name: "before", selector: { time: {} } };
return [
{ {
name: "mode_after", name: "mode_after",
type: "select", type: "select",
@ -67,7 +51,12 @@ export class HaTimeCondition extends LitElement implements ConditionElement {
], ],
], ],
}, },
modeAfterSchema, {
name: "after",
selector: inputModeAfter
? { entity: { domain: "input_datetime" } }
: { time: {} },
},
{ {
name: "mode_before", name: "mode_before",
type: "select", type: "select",
@ -87,19 +76,26 @@ export class HaTimeCondition extends LitElement implements ConditionElement {
], ],
], ],
}, },
modeBeforeSchema, {
name: "before",
selector: inputModeBefore
? { entity: { domain: "input_datetime" } }
: { time: {} },
},
{ {
type: "multi_select", type: "multi_select",
name: "weekday", name: "weekday",
options: Object.keys(DAYS).map((day) => [ options: DAYS.map(
day, (day) =>
localize( [
`ui.panel.config.automation.editor.conditions.type.time.weekdays.${day}` day,
), localize(
]), `ui.panel.config.automation.editor.conditions.type.time.weekdays.${day}`
),
] as const
),
}, },
]; ] as const
}
); );
protected render() { protected render() {
@ -110,7 +106,7 @@ export class HaTimeCondition extends LitElement implements ConditionElement {
this._inputModeAfter ?? this._inputModeAfter ??
this.condition.after?.startsWith("input_datetime."); this.condition.after?.startsWith("input_datetime.");
const schema: HaFormSchema[] = this._schema( const schema = this._schema(
this.hass.localize, this.hass.localize,
inputModeAfter, inputModeAfter,
inputModeBefore inputModeBefore
@ -152,7 +148,9 @@ export class HaTimeCondition extends LitElement implements ConditionElement {
fireEvent(this, "value-changed", { value: newValue }); fireEvent(this, "value-changed", { value: newValue });
} }
private _computeLabelCallback = (schema: HaFormSchema): string => private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
): string =>
this.hass.localize( this.hass.localize(
`ui.panel.config.automation.editor.conditions.type.time.${schema.name}` `ui.panel.config.automation.editor.conditions.type.time.${schema.name}`
); );

View File

@ -18,7 +18,7 @@ const includeDomains = ["zone"];
export class HaZoneCondition extends LitElement { export class HaZoneCondition extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property() public condition!: ZoneCondition; @property({ attribute: false }) public condition!: ZoneCondition;
public static get defaultConfig() { public static get defaultConfig() {
return { return {

View File

@ -60,7 +60,7 @@ const OPTIONS = [
"time_pattern", "time_pattern",
"webhook", "webhook",
"zone", "zone",
]; ] as const;
export interface TriggerElement extends LitElement { export interface TriggerElement extends LitElement {
trigger: Trigger; trigger: Trigger;
@ -92,7 +92,7 @@ export const handleChangeEvent = (element: TriggerElement, ev: CustomEvent) => {
export default class HaAutomationTriggerRow extends LitElement { export default class HaAutomationTriggerRow extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property() public trigger!: Trigger; @property({ attribute: false }) public trigger!: Trigger;
@state() private _warnings?: string[]; @state() private _warnings?: string[];

View File

@ -6,9 +6,10 @@ import type { CalendarTrigger } from "../../../../../data/automation";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { TriggerElement } from "../ha-automation-trigger-row"; import type { TriggerElement } from "../ha-automation-trigger-row";
import type { HaDurationData } from "../../../../../components/ha-duration-input"; import type { HaDurationData } from "../../../../../components/ha-duration-input";
import type { HaFormSchema } from "../../../../../components/ha-form/types"; import "../../../../../components/ha-form/ha-form";
import { createDurationData } from "../../../../../common/datetime/create_duration_data"; import { createDurationData } from "../../../../../common/datetime/create_duration_data";
import type { LocalizeFunc } from "../../../../../common/translations/localize"; import type { LocalizeFunc } from "../../../../../common/translations/localize";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
@customElement("ha-automation-trigger-calendar") @customElement("ha-automation-trigger-calendar")
export class HaCalendarTrigger extends LitElement implements TriggerElement { export class HaCalendarTrigger extends LitElement implements TriggerElement {
@ -16,52 +17,55 @@ export class HaCalendarTrigger extends LitElement implements TriggerElement {
@property({ attribute: false }) public trigger!: CalendarTrigger; @property({ attribute: false }) public trigger!: CalendarTrigger;
private _schema = memoizeOne((localize: LocalizeFunc) => [ private _schema = memoizeOne(
{ (localize: LocalizeFunc) =>
name: "entity_id", [
required: true, {
selector: { entity: { domain: "calendar" } }, name: "entity_id",
}, required: true,
{ selector: { entity: { domain: "calendar" } },
name: "event", },
type: "select", {
required: true, name: "event",
options: [ type: "select",
[ required: true,
"start", options: [
localize( [
"ui.panel.config.automation.editor.triggers.type.calendar.start" "start",
), localize(
], "ui.panel.config.automation.editor.triggers.type.calendar.start"
[ ),
"end", ],
localize( [
"ui.panel.config.automation.editor.triggers.type.calendar.end" "end",
), localize(
], "ui.panel.config.automation.editor.triggers.type.calendar.end"
], ),
}, ],
{ name: "offset", selector: { duration: {} } }, ],
{ },
name: "offset_type", { name: "offset", selector: { duration: {} } },
type: "select", {
required: true, name: "offset_type",
options: [ type: "select",
[ required: true,
"before", options: [
localize( [
"ui.panel.config.automation.editor.triggers.type.calendar.before" "before",
), localize(
], "ui.panel.config.automation.editor.triggers.type.calendar.before"
[ ),
"after", ],
localize( [
"ui.panel.config.automation.editor.triggers.type.calendar.after" "after",
), localize(
], "ui.panel.config.automation.editor.triggers.type.calendar.after"
], ),
}, ],
]); ],
},
] as const
);
public static get defaultConfig() { public static get defaultConfig() {
return { return {
@ -114,7 +118,9 @@ export class HaCalendarTrigger extends LitElement implements TriggerElement {
fireEvent(this, "value-changed", { value: newTrigger }); fireEvent(this, "value-changed", { value: newTrigger });
} }
private _computeLabelCallback = (schema: HaFormSchema): string => private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
): string =>
this.hass.localize( this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.calendar.${schema.name}` `ui.panel.config.automation.editor.triggers.type.calendar.${schema.name}`
); );

View File

@ -3,10 +3,10 @@ import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import { HaFormSchema } from "../../../../../components/ha-form/types";
import type { GeoLocationTrigger } from "../../../../../data/automation"; import type { GeoLocationTrigger } from "../../../../../data/automation";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { LocalizeFunc } from "../../../../../common/translations/localize"; import type { LocalizeFunc } from "../../../../../common/translations/localize";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
@customElement("ha-automation-trigger-geo_location") @customElement("ha-automation-trigger-geo_location")
export class HaGeolocationTrigger extends LitElement { export class HaGeolocationTrigger extends LitElement {
@ -14,29 +14,32 @@ export class HaGeolocationTrigger extends LitElement {
@property({ attribute: false }) public trigger!: GeoLocationTrigger; @property({ attribute: false }) public trigger!: GeoLocationTrigger;
private _schema = memoizeOne((localize: LocalizeFunc) => [ private _schema = memoizeOne(
{ name: "source", selector: { text: {} } }, (localize: LocalizeFunc) =>
{ name: "zone", selector: { entity: { domain: "zone" } } }, [
{ { name: "source", selector: { text: {} } },
name: "event", { name: "zone", selector: { entity: { domain: "zone" } } },
type: "select", {
required: true, name: "event",
options: [ type: "select",
[ required: true,
"enter", options: [
localize( [
"ui.panel.config.automation.editor.triggers.type.geo_location.enter" "enter",
), localize(
], "ui.panel.config.automation.editor.triggers.type.geo_location.enter"
[ ),
"leave", ],
localize( [
"ui.panel.config.automation.editor.triggers.type.geo_location.leave" "leave",
), localize(
], "ui.panel.config.automation.editor.triggers.type.geo_location.leave"
], ),
}, ],
]); ],
},
] as const
);
public static get defaultConfig() { public static get defaultConfig() {
return { return {
@ -64,7 +67,9 @@ export class HaGeolocationTrigger extends LitElement {
fireEvent(this, "value-changed", { value: newTrigger }); fireEvent(this, "value-changed", { value: newTrigger });
} }
private _computeLabelCallback = (schema: HaFormSchema): string => private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
): string =>
this.hass.localize( this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.geo_location.${schema.name}` `ui.panel.config.automation.editor.triggers.type.geo_location.${schema.name}`
); );

View File

@ -5,8 +5,8 @@ import memoizeOne from "memoize-one";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import type { HassTrigger } from "../../../../../data/automation"; import type { HassTrigger } from "../../../../../data/automation";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { HaFormSchema } from "../../../../../components/ha-form/types";
import type { LocalizeFunc } from "../../../../../common/translations/localize"; import type { LocalizeFunc } from "../../../../../common/translations/localize";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
@customElement("ha-automation-trigger-homeassistant") @customElement("ha-automation-trigger-homeassistant")
export class HaHassTrigger extends LitElement { export class HaHassTrigger extends LitElement {
@ -14,27 +14,30 @@ export class HaHassTrigger extends LitElement {
@property({ attribute: false }) public trigger!: HassTrigger; @property({ attribute: false }) public trigger!: HassTrigger;
private _schema = memoizeOne((localize: LocalizeFunc) => [ private _schema = memoizeOne(
{ (localize: LocalizeFunc) =>
name: "event", [
type: "select", {
required: true, name: "event",
options: [ type: "select",
[ required: true,
"start", options: [
localize( [
"ui.panel.config.automation.editor.triggers.type.homeassistant.start" "start",
), localize(
], "ui.panel.config.automation.editor.triggers.type.homeassistant.start"
[ ),
"shutdown", ],
localize( [
"ui.panel.config.automation.editor.triggers.type.homeassistant.shutdown" "shutdown",
), localize(
], "ui.panel.config.automation.editor.triggers.type.homeassistant.shutdown"
], ),
}, ],
]); ],
},
] as const
);
public static get defaultConfig() { public static get defaultConfig() {
return { return {
@ -60,9 +63,11 @@ export class HaHassTrigger extends LitElement {
fireEvent(this, "value-changed", { value: newTrigger }); fireEvent(this, "value-changed", { value: newTrigger });
} }
private _computeLabelCallback = (schema: HaFormSchema): string => private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
): string =>
this.hass.localize( this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.geo_location.${schema.name}` `ui.panel.config.automation.editor.triggers.type.homeassistant.${schema.name}`
); );
static styles = css` static styles = css`

View File

@ -1,21 +1,22 @@
import { html, LitElement } from "lit"; import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import type { HaFormSchema } from "../../../../../components/ha-form/types"; import "../../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
import { MqttTrigger } from "../../../../../data/automation"; import { MqttTrigger } from "../../../../../data/automation";
import { HomeAssistant } from "../../../../../types"; import { HomeAssistant } from "../../../../../types";
import type { TriggerElement } from "../ha-automation-trigger-row"; import type { TriggerElement } from "../ha-automation-trigger-row";
const SCHEMA: HaFormSchema[] = [ const SCHEMA = [
{ name: "topic", required: true, selector: { text: {} } }, { name: "topic", required: true, selector: { text: {} } },
{ name: "payload", selector: { text: {} } }, { name: "payload", selector: { text: {} } },
]; ] as const;
@customElement("ha-automation-trigger-mqtt") @customElement("ha-automation-trigger-mqtt")
export class HaMQTTTrigger extends LitElement implements TriggerElement { export class HaMQTTTrigger extends LitElement implements TriggerElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property() public trigger!: MqttTrigger; @property({ attribute: false }) public trigger!: MqttTrigger;
public static get defaultConfig() { public static get defaultConfig() {
return { topic: "" }; return { topic: "" };
@ -39,7 +40,9 @@ export class HaMQTTTrigger extends LitElement implements TriggerElement {
fireEvent(this, "value-changed", { value: newTrigger }); fireEvent(this, "value-changed", { value: newTrigger });
} }
private _computeLabelCallback = (schema: HaFormSchema): string => private _computeLabelCallback = (
schema: SchemaUnion<typeof SCHEMA>
): string =>
this.hass.localize( this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.mqtt.${schema.name}` `ui.panel.config.automation.editor.triggers.type.mqtt.${schema.name}`
); );

View File

@ -2,33 +2,36 @@ import "../../../../../components/ha-form/ha-form";
import { html, LitElement, PropertyValues } from "lit"; import { html, LitElement, PropertyValues } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import type { HaFormSchema } from "../../../../../components/ha-form/types";
import { createDurationData } from "../../../../../common/datetime/create_duration_data"; import { createDurationData } from "../../../../../common/datetime/create_duration_data";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import { hasTemplate } from "../../../../../common/string/has-template"; import { hasTemplate } from "../../../../../common/string/has-template";
import type { NumericStateTrigger } from "../../../../../data/automation"; import type { NumericStateTrigger } from "../../../../../data/automation";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
@customElement("ha-automation-trigger-numeric_state") @customElement("ha-automation-trigger-numeric_state")
export class HaNumericStateTrigger extends LitElement { export class HaNumericStateTrigger extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property() public trigger!: NumericStateTrigger; @property({ attribute: false }) public trigger!: NumericStateTrigger;
private _schema = memoizeOne((entityId): HaFormSchema[] => [ private _schema = memoizeOne(
{ name: "entity_id", required: true, selector: { entity: {} } }, (entityId) =>
{ [
name: "attribute", { name: "entity_id", required: true, selector: { entity: {} } },
selector: { attribute: { entity_id: entityId } }, {
}, name: "attribute",
{ name: "above", selector: { text: {} } }, selector: { attribute: { entity_id: entityId } },
{ name: "below", selector: { text: {} } }, },
{ { name: "above", selector: { text: {} } },
name: "value_template", { name: "below", selector: { text: {} } },
selector: { text: { multiline: true } }, {
}, name: "value_template",
{ name: "for", selector: { duration: {} } }, selector: { text: { multiline: true } },
]); },
{ name: "for", selector: { duration: {} } },
] as const
);
public willUpdate(changedProperties: PropertyValues) { public willUpdate(changedProperties: PropertyValues) {
if (!changedProperties.has("trigger")) { if (!changedProperties.has("trigger")) {
@ -73,7 +76,9 @@ export class HaNumericStateTrigger extends LitElement {
fireEvent(this, "value-changed", { value: newTrigger }); fireEvent(this, "value-changed", { value: newTrigger });
} }
private _computeLabelCallback = (schema: HaFormSchema): string => { private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
): string => {
switch (schema.name) { switch (schema.name) {
case "entity_id": case "entity_id":
return this.hass.localize("ui.components.entity.entity-picker.entity"); return this.hass.localize("ui.components.entity.entity-picker.entity");

View File

@ -20,7 +20,7 @@ import { baseTriggerStruct, forDictStruct } from "../../structs";
import { TriggerElement } from "../ha-automation-trigger-row"; import { TriggerElement } from "../ha-automation-trigger-row";
import "../../../../../components/ha-form/ha-form"; import "../../../../../components/ha-form/ha-form";
import { createDurationData } from "../../../../../common/datetime/create_duration_data"; import { createDurationData } from "../../../../../common/datetime/create_duration_data";
import { HaFormSchema } from "../../../../../components/ha-form/types"; import type { SchemaUnion } from "../../../../../components/ha-form/types";
const stateTriggerStruct = assign( const stateTriggerStruct = assign(
baseTriggerStruct, baseTriggerStruct,
@ -38,26 +38,29 @@ const stateTriggerStruct = assign(
export class HaStateTrigger extends LitElement implements TriggerElement { export class HaStateTrigger extends LitElement implements TriggerElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property() public trigger!: StateTrigger; @property({ attribute: false }) public trigger!: StateTrigger;
public static get defaultConfig() { public static get defaultConfig() {
return { entity_id: [] }; return { entity_id: [] };
} }
private _schema = memoizeOne((entityId) => [ private _schema = memoizeOne(
{ (entityId) =>
name: "entity_id", [
required: true, {
selector: { entity: { multiple: true } }, name: "entity_id",
}, required: true,
{ selector: { entity: { multiple: true } },
name: "attribute", },
selector: { attribute: { entity_id: entityId } }, {
}, name: "attribute",
{ name: "from", selector: { text: {} } }, selector: { attribute: { entity_id: entityId } },
{ name: "to", selector: { text: {} } }, },
{ name: "for", selector: { duration: {} } }, { name: "from", selector: { text: {} } },
]); { name: "to", selector: { text: {} } },
{ name: "for", selector: { duration: {} } },
] as const
);
public shouldUpdate(changedProperties: PropertyValues) { public shouldUpdate(changedProperties: PropertyValues) {
if (!changedProperties.has("trigger")) { if (!changedProperties.has("trigger")) {
@ -122,7 +125,9 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
fireEvent(this, "value-changed", { value: newTrigger }); fireEvent(this, "value-changed", { value: newTrigger });
} }
private _computeLabelCallback = (schema: HaFormSchema): string => private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
): string =>
this.hass.localize( this.hass.localize(
schema.name === "entity_id" schema.name === "entity_id"
? "ui.components.entity.entity-picker.entity" ? "ui.components.entity.entity-picker.entity"

View File

@ -5,8 +5,9 @@ import { fireEvent } from "../../../../../common/dom/fire_event";
import type { SunTrigger } from "../../../../../data/automation"; import type { SunTrigger } from "../../../../../data/automation";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { TriggerElement } from "../ha-automation-trigger-row"; import type { TriggerElement } from "../ha-automation-trigger-row";
import type { HaFormSchema } from "../../../../../components/ha-form/types"; import "../../../../../components/ha-form/ha-form";
import type { LocalizeFunc } from "../../../../../common/translations/localize"; import type { LocalizeFunc } from "../../../../../common/translations/localize";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
@customElement("ha-automation-trigger-sun") @customElement("ha-automation-trigger-sun")
export class HaSunTrigger extends LitElement implements TriggerElement { export class HaSunTrigger extends LitElement implements TriggerElement {
@ -14,28 +15,31 @@ export class HaSunTrigger extends LitElement implements TriggerElement {
@property({ attribute: false }) public trigger!: SunTrigger; @property({ attribute: false }) public trigger!: SunTrigger;
private _schema = memoizeOne((localize: LocalizeFunc) => [ private _schema = memoizeOne(
{ (localize: LocalizeFunc) =>
name: "event", [
type: "select", {
required: true, name: "event",
options: [ type: "select",
[ required: true,
"sunrise", options: [
localize( [
"ui.panel.config.automation.editor.triggers.type.sun.sunrise" "sunrise",
), localize(
], "ui.panel.config.automation.editor.triggers.type.sun.sunrise"
[ ),
"sunset", ],
localize( [
"ui.panel.config.automation.editor.triggers.type.sun.sunset" "sunset",
), localize(
], "ui.panel.config.automation.editor.triggers.type.sun.sunset"
], ),
}, ],
{ name: "offset", selector: { text: {} } }, ],
]); },
{ name: "offset", selector: { text: {} } },
] as const
);
public static get defaultConfig() { public static get defaultConfig() {
return { return {
@ -63,7 +67,9 @@ export class HaSunTrigger extends LitElement implements TriggerElement {
fireEvent(this, "value-changed", { value: newTrigger }); fireEvent(this, "value-changed", { value: newTrigger });
} }
private _computeLabelCallback = (schema: HaFormSchema): string => private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
): string =>
this.hass.localize( this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.sun.${schema.name}` `ui.panel.config.automation.editor.triggers.type.sun.${schema.name}`
); );

View File

@ -5,9 +5,9 @@ import type { TimeTrigger } from "../../../../../data/automation";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { TriggerElement } from "../ha-automation-trigger-row"; import type { TriggerElement } from "../ha-automation-trigger-row";
import type { LocalizeFunc } from "../../../../../common/translations/localize"; import type { LocalizeFunc } from "../../../../../common/translations/localize";
import type { HaFormSchema } from "../../../../../components/ha-form/types";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import "../../../../../components/ha-form/ha-form"; import "../../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
@customElement("ha-automation-trigger-time") @customElement("ha-automation-trigger-time")
export class HaTimeTrigger extends LitElement implements TriggerElement { export class HaTimeTrigger extends LitElement implements TriggerElement {
@ -22,7 +22,7 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
} }
private _schema = memoizeOne( private _schema = memoizeOne(
(localize: LocalizeFunc, inputMode?: boolean): HaFormSchema[] => { (localize: LocalizeFunc, inputMode?: boolean) => {
const atSelector = inputMode const atSelector = inputMode
? { entity: { domain: "input_datetime" } } ? { entity: { domain: "input_datetime" } }
: { time: {} }; : { time: {} };
@ -48,7 +48,7 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
], ],
}, },
{ name: "at", selector: atSelector }, { name: "at", selector: atSelector },
]; ] as const;
} }
); );
@ -77,7 +77,7 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
this._inputMode ?? this._inputMode ??
(at?.startsWith("input_datetime.") || at?.startsWith("sensor.")); (at?.startsWith("input_datetime.") || at?.startsWith("sensor."));
const schema: HaFormSchema[] = this._schema(this.hass.localize, inputMode); const schema = this._schema(this.hass.localize, inputMode);
const data = { const data = {
mode: inputMode ? "input" : "value", mode: inputMode ? "input" : "value",
@ -111,7 +111,9 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
fireEvent(this, "value-changed", { value: newValue }); fireEvent(this, "value-changed", { value: newValue });
} }
private _computeLabelCallback = (schema: HaFormSchema): string => private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
): string =>
this.hass.localize( this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.time.${schema.name}` `ui.panel.config.automation.editor.triggers.type.time.${schema.name}`
); );

View File

@ -1,22 +1,23 @@
import { html, LitElement } from "lit"; import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import type { HaFormSchema } from "../../../../../components/ha-form/types"; import "../../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
import type { TimePatternTrigger } from "../../../../../data/automation"; import type { TimePatternTrigger } from "../../../../../data/automation";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { TriggerElement } from "../ha-automation-trigger-row"; import type { TriggerElement } from "../ha-automation-trigger-row";
const SCHEMA: HaFormSchema[] = [ const SCHEMA = [
{ name: "hours", selector: { text: {} } }, { name: "hours", selector: { text: {} } },
{ name: "minutes", selector: { text: {} } }, { name: "minutes", selector: { text: {} } },
{ name: "seconds", selector: { text: {} } }, { name: "seconds", selector: { text: {} } },
]; ] as const;
@customElement("ha-automation-trigger-time_pattern") @customElement("ha-automation-trigger-time_pattern")
export class HaTimePatternTrigger extends LitElement implements TriggerElement { export class HaTimePatternTrigger extends LitElement implements TriggerElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property() public trigger!: TimePatternTrigger; @property({ attribute: false }) public trigger!: TimePatternTrigger;
public static get defaultConfig() { public static get defaultConfig() {
return {}; return {};
@ -40,7 +41,9 @@ export class HaTimePatternTrigger extends LitElement implements TriggerElement {
fireEvent(this, "value-changed", { value: newTrigger }); fireEvent(this, "value-changed", { value: newTrigger });
} }
private _computeLabelCallback = (schema: HaFormSchema): string => private _computeLabelCallback = (
schema: SchemaUnion<typeof SCHEMA>
): string =>
this.hass.localize( this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.time_pattern.${schema.name}` `ui.panel.config.automation.editor.triggers.type.time_pattern.${schema.name}`
); );

View File

@ -8,7 +8,7 @@ import type { HomeAssistant } from "../../../../types";
import type { AlarmPanelCardConfig } from "../../cards/types"; import type { AlarmPanelCardConfig } from "../../cards/types";
import type { LovelaceCardEditor } from "../../types"; import type { LovelaceCardEditor } from "../../types";
import { baseLovelaceCardConfig } from "../structs/base-card-struct"; import { baseLovelaceCardConfig } from "../structs/base-card-struct";
import type { HaFormSchema } from "../../../../components/ha-form/types"; import type { SchemaUnion } from "../../../../components/ha-form/types";
import type { LocalizeFunc } from "../../../../common/translations/localize"; import type { LocalizeFunc } from "../../../../common/translations/localize";
const cardConfigStruct = assign( const cardConfigStruct = assign(
@ -27,7 +27,7 @@ const states = [
"arm_night", "arm_night",
"arm_vacation", "arm_vacation",
"arm_custom_bypass", "arm_custom_bypass",
]; ] as const;
@customElement("hui-alarm-panel-card-editor") @customElement("hui-alarm-panel-card-editor")
export class HuiAlarmPanelCardEditor export class HuiAlarmPanelCardEditor
@ -43,30 +43,32 @@ export class HuiAlarmPanelCardEditor
this._config = config; this._config = config;
} }
private _schema = memoizeOne((localize: LocalizeFunc): HaFormSchema[] => [ private _schema = memoizeOne(
{ (localize: LocalizeFunc) =>
name: "entity", [
required: true, {
selector: { entity: { domain: "alarm_control_panel" } }, name: "entity",
}, required: true,
{ selector: { entity: { domain: "alarm_control_panel" } },
type: "grid", },
name: "", {
schema: [ type: "grid",
{ name: "name", selector: { text: {} } }, name: "",
{ name: "theme", selector: { theme: {} } }, schema: [
], { name: "name", selector: { text: {} } },
}, { name: "theme", selector: { theme: {} } },
],
{ },
type: "multi_select", {
name: "states", type: "multi_select",
options: states.map((s) => [ name: "states",
s, options: states.map((s) => [
localize(`ui.card.alarm_control_panel.${s}`), s,
]) as [string, string][], localize(`ui.card.alarm_control_panel.${s}`),
}, ]) as [string, string][],
]); },
] as const
);
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass || !this._config) { if (!this.hass || !this._config) {
@ -88,30 +90,30 @@ export class HuiAlarmPanelCardEditor
fireEvent(this, "config-changed", { config: ev.detail.value }); fireEvent(this, "config-changed", { config: ev.detail.value });
} }
private _computeLabelCallback = (schema: HaFormSchema) => { private _computeLabelCallback = (
if (schema.name === "entity") { schema: SchemaUnion<ReturnType<typeof this._schema>>
return this.hass!.localize( ) => {
"ui.panel.lovelace.editor.card.generic.entity" switch (schema.name) {
); case "entity":
return this.hass!.localize(
"ui.panel.lovelace.editor.card.generic.entity"
);
case "name":
return this.hass!.localize(
"ui.panel.lovelace.editor.card.generic.name"
);
case "theme":
return `${this.hass!.localize(
"ui.panel.lovelace.editor.card.generic.theme"
)} (${this.hass!.localize(
"ui.panel.lovelace.editor.card.config.optional"
)})`;
default:
// "states"
return this.hass!.localize(
"ui.panel.lovelace.editor.card.alarm-panel.available_states"
);
} }
if (schema.name === "name") {
return this.hass!.localize(`ui.panel.lovelace.editor.card.generic.name`);
}
if (schema.name === "theme") {
return `${this.hass!.localize(
"ui.panel.lovelace.editor.card.generic.theme"
)} (${this.hass!.localize(
"ui.panel.lovelace.editor.card.config.optional"
)})`;
}
return this.hass!.localize(
`ui.panel.lovelace.editor.card.alarm-panel.${
schema.name === "states" ? "available_states" : schema.name
}`
);
}; };
} }

View File

@ -3,7 +3,7 @@ import { customElement, property, state } from "lit/decorators";
import { assert, assign, boolean, object, optional, string } from "superstruct"; import { assert, assign, boolean, object, optional, string } from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-form/ha-form"; import "../../../../components/ha-form/ha-form";
import type { HaFormSchema } from "../../../../components/ha-form/types"; import type { SchemaUnion } from "../../../../components/ha-form/types";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import type { AreaCardConfig } from "../../cards/types"; import type { AreaCardConfig } from "../../cards/types";
import type { LovelaceCardEditor } from "../../types"; import type { LovelaceCardEditor } from "../../types";
@ -19,7 +19,7 @@ const cardConfigStruct = assign(
}) })
); );
const SCHEMA: HaFormSchema[] = [ const SCHEMA = [
{ name: "area", selector: { area: {} } }, { name: "area", selector: { area: {} } },
{ name: "show_camera", required: false, selector: { boolean: {} } }, { name: "show_camera", required: false, selector: { boolean: {} } },
{ {
@ -30,7 +30,7 @@ const SCHEMA: HaFormSchema[] = [
{ name: "theme", required: false, selector: { theme: {} } }, { name: "theme", required: false, selector: { theme: {} } },
], ],
}, },
]; ] as const;
@customElement("hui-area-card-editor") @customElement("hui-area-card-editor")
export class HuiAreaCardEditor export class HuiAreaCardEditor
@ -67,7 +67,7 @@ export class HuiAreaCardEditor
fireEvent(this, "config-changed", { config }); fireEvent(this, "config-changed", { config });
} }
private _computeLabelCallback = (schema: HaFormSchema) => { private _computeLabelCallback = (schema: SchemaUnion<typeof SCHEMA>) => {
switch (schema.name) { switch (schema.name) {
case "theme": case "theme":
return `${this.hass!.localize( return `${this.hass!.localize(

View File

@ -7,7 +7,7 @@ import { fireEvent } from "../../../../common/dom/fire_event";
import { computeDomain } from "../../../../common/entity/compute_domain"; import { computeDomain } from "../../../../common/entity/compute_domain";
import { domainIcon } from "../../../../common/entity/domain_icon"; import { domainIcon } from "../../../../common/entity/domain_icon";
import "../../../../components/ha-form/ha-form"; import "../../../../components/ha-form/ha-form";
import type { HaFormSchema } from "../../../../components/ha-form/types"; import type { SchemaUnion } from "../../../../components/ha-form/types";
import { ActionConfig } from "../../../../data/lovelace"; import { ActionConfig } from "../../../../data/lovelace";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import type { ButtonCardConfig } from "../../cards/types"; import type { ButtonCardConfig } from "../../cards/types";
@ -58,53 +58,50 @@ export class HuiButtonCardEditor
} }
private _schema = memoizeOne( private _schema = memoizeOne(
( (entity?: string, icon?: string, entityState?: HassEntity) =>
entity?: string, [
icon?: string, { name: "entity", selector: { entity: {} } },
entityState?: HassEntity {
): HaFormSchema[] => [ name: "",
{ name: "entity", selector: { entity: {} } }, type: "grid",
{ schema: [
name: "", { name: "name", selector: { text: {} } },
type: "grid", {
schema: [ name: "icon",
{ name: "name", selector: { text: {} } }, selector: {
{ icon: {
name: "icon", placeholder: icon || entityState?.attributes.icon,
selector: { fallbackPath:
icon: { !icon &&
placeholder: icon || entityState?.attributes.icon, !entityState?.attributes.icon &&
fallbackPath: entityState &&
!icon && entity
!entityState?.attributes.icon && ? domainIcon(computeDomain(entity), entityState)
entityState && : undefined,
entity },
? domainIcon(computeDomain(entity), entityState)
: undefined,
}, },
}, },
}, ],
], },
}, {
{ name: "",
name: "", type: "grid",
type: "grid", column_min_width: "100px",
column_min_width: "100px", schema: [
schema: [ { name: "show_name", selector: { boolean: {} } },
{ name: "show_name", selector: { boolean: {} } }, { name: "show_state", selector: { boolean: {} } },
{ name: "show_state", selector: { boolean: {} } }, { name: "show_icon", selector: { boolean: {} } },
{ name: "show_icon", selector: { boolean: {} } }, ],
], },
}, {
{ name: "",
name: "", type: "grid",
type: "grid", schema: [
schema: [ { name: "icon_height", selector: { text: { suffix: "px" } } },
{ name: "icon_height", selector: { text: { suffix: "px" } } }, { name: "theme", selector: { theme: {} } },
{ name: "theme", selector: { theme: {} } }, ],
], },
}, ] as const
]
); );
get _tap_action(): ActionConfig | undefined { get _tap_action(): ActionConfig | undefined {
@ -193,7 +190,9 @@ export class HuiButtonCardEditor
fireEvent(this, "config-changed", { config }); fireEvent(this, "config-changed", { config });
} }
private _computeLabelCallback = (schema: HaFormSchema) => { private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
) => {
if (schema.name === "entity") { if (schema.name === "entity") {
return `${this.hass!.localize( return `${this.hass!.localize(
"ui.panel.lovelace.editor.card.generic.entity" "ui.panel.lovelace.editor.card.generic.entity"

View File

@ -15,7 +15,7 @@ import {
} from "superstruct"; } from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import { LocalizeFunc } from "../../../../common/translations/localize"; import { LocalizeFunc } from "../../../../common/translations/localize";
import type { HaFormSchema } from "../../../../components/ha-form/types"; import type { SchemaUnion } from "../../../../components/ha-form/types";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import type { CalendarCardConfig } from "../../cards/types"; import type { CalendarCardConfig } from "../../cards/types";
import type { LovelaceCardEditor } from "../../types"; import type { LovelaceCardEditor } from "../../types";
@ -31,7 +31,7 @@ const cardConfigStruct = assign(
}) })
); );
const views = ["dayGridMonth", "dayGridDay", "listWeek"]; const views = ["dayGridMonth", "dayGridDay", "listWeek"] as const;
@customElement("hui-calendar-card-editor") @customElement("hui-calendar-card-editor")
export class HuiCalendarCardEditor export class HuiCalendarCardEditor
@ -47,30 +47,33 @@ export class HuiCalendarCardEditor
this._config = config; this._config = config;
} }
private _schema = memoizeOne((localize: LocalizeFunc) => [ private _schema = memoizeOne(
{ (localize: LocalizeFunc) =>
name: "", [
type: "grid",
schema: [
{ name: "title", required: false, selector: { text: {} } },
{ {
name: "initial_view", name: "",
required: false, type: "grid",
selector: { schema: [
select: { { name: "title", required: false, selector: { text: {} } },
options: views.map((view) => [ {
view, name: "initial_view",
localize( required: false,
`ui.panel.lovelace.editor.card.calendar.views.${view}` selector: {
), select: {
]), options: views.map((view) => ({
value: view,
label: localize(
`ui.panel.lovelace.editor.card.calendar.views.${view}`
),
})),
},
},
}, },
}, ],
}, },
], { name: "theme", required: false, selector: { theme: {} } },
}, ] as const
{ name: "theme", required: false, selector: { theme: {} } }, );
]);
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass || !this._config) { if (!this.hass || !this._config) {
@ -116,7 +119,9 @@ export class HuiCalendarCardEditor
fireEvent(this, "config-changed", { config }); fireEvent(this, "config-changed", { config });
} }
private _computeLabelCallback = (schema: HaFormSchema) => { private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
) => {
if (schema.name === "title") { if (schema.name === "title") {
return this.hass!.localize("ui.panel.lovelace.editor.card.generic.title"); return this.hass!.localize("ui.panel.lovelace.editor.card.generic.title");
} }

View File

@ -7,7 +7,7 @@ import type { HassEntity } from "home-assistant-js-websocket/dist/types";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import { computeDomain } from "../../../../common/entity/compute_domain"; import { computeDomain } from "../../../../common/entity/compute_domain";
import { domainIcon } from "../../../../common/entity/domain_icon"; import { domainIcon } from "../../../../common/entity/domain_icon";
import type { HaFormSchema } from "../../../../components/ha-form/types"; import type { SchemaUnion } from "../../../../components/ha-form/types";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import type { EntityCardConfig } from "../../cards/types"; import type { EntityCardConfig } from "../../cards/types";
import { headerFooterConfigStructs } from "../../header-footer/structs"; import { headerFooterConfigStructs } from "../../header-footer/structs";
@ -43,36 +43,37 @@ export class HuiEntityCardEditor
} }
private _schema = memoizeOne( private _schema = memoizeOne(
(entity: string, icon: string, entityState: HassEntity): HaFormSchema[] => [ (entity: string, icon: string, entityState: HassEntity) =>
{ name: "entity", required: true, selector: { entity: {} } }, [
{ { name: "entity", required: true, selector: { entity: {} } },
type: "grid", {
name: "", type: "grid",
schema: [ name: "",
{ name: "name", selector: { text: {} } }, schema: [
{ { name: "name", selector: { text: {} } },
name: "icon", {
selector: { name: "icon",
icon: { selector: {
placeholder: icon || entityState?.attributes.icon, icon: {
fallbackPath: placeholder: icon || entityState?.attributes.icon,
!icon && !entityState?.attributes.icon && entityState fallbackPath:
? domainIcon(computeDomain(entity), entityState) !icon && !entityState?.attributes.icon && entityState
: undefined, ? domainIcon(computeDomain(entity), entityState)
: undefined,
},
}, },
}, },
},
{ {
name: "attribute", name: "attribute",
selector: { attribute: { entity_id: entity } }, selector: { attribute: { entity_id: entity } },
}, },
{ name: "unit", selector: { text: {} } }, { name: "unit", selector: { text: {} } },
{ name: "theme", selector: { theme: {} } }, { name: "theme", selector: { theme: {} } },
{ name: "state_color", selector: { boolean: {} } }, { name: "state_color", selector: { boolean: {} } },
], ],
}, },
] ] as const
); );
protected render(): TemplateResult { protected render(): TemplateResult {
@ -105,7 +106,9 @@ export class HuiEntityCardEditor
fireEvent(this, "config-changed", { config }); fireEvent(this, "config-changed", { config });
} }
private _computeLabelCallback = (schema: HaFormSchema) => { private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
) => {
if (schema.name === "entity") { if (schema.name === "entity") {
return this.hass!.localize( return this.hass!.localize(
"ui.panel.lovelace.editor.card.generic.entity" "ui.panel.lovelace.editor.card.generic.entity"