mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Add customize mode option to card features with modes (#20670)
* Add customize mode options to card features with modes * Better type * Fix water heater and humidifier * Clean schema
This commit is contained in:
parent
334c245b65
commit
7120ad99b9
@ -2,6 +2,6 @@ export const filterModes = (
|
||||
supportedModes: string[] | undefined,
|
||||
selectedModes: string[] | undefined
|
||||
): string[] =>
|
||||
(selectedModes || []).length
|
||||
? selectedModes!.filter((mode) => (supportedModes || []).includes(mode))
|
||||
selectedModes
|
||||
? selectedModes.filter((mode) => (supportedModes || []).includes(mode))
|
||||
: supportedModes || [];
|
||||
|
@ -45,7 +45,6 @@ class HuiClimateFanModesCardFeature
|
||||
return {
|
||||
type: "climate-fan-modes",
|
||||
style: "dropdown",
|
||||
fan_modes: [],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,8 @@ import {
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types";
|
||||
import { ClimateHvacModesCardFeatureConfig } from "./types";
|
||||
import { filterModes } from "./common/filter-modes";
|
||||
import { ClimateHvacModesCardFeatureConfig } from "./types";
|
||||
|
||||
export const supportsClimateHvacModesCardFeature = (stateObj: HassEntity) => {
|
||||
const domain = computeDomain(stateObj.entity_id);
|
||||
@ -46,7 +46,6 @@ class HuiClimateHvacModesCardFeature
|
||||
static getStubConfig(): ClimateHvacModesCardFeatureConfig {
|
||||
return {
|
||||
type: "climate-hvac-modes",
|
||||
hvac_modes: [],
|
||||
};
|
||||
}
|
||||
|
||||
@ -120,10 +119,12 @@ class HuiClimateHvacModesCardFeature
|
||||
|
||||
const color = stateColorCss(this.stateObj);
|
||||
|
||||
const ordererHvacModes = (this.stateObj.attributes.hvac_modes || [])
|
||||
.concat()
|
||||
.sort(compareClimateHvacModes);
|
||||
|
||||
const options = filterModes(
|
||||
[...(this.stateObj?.attributes.hvac_modes || [])].sort(
|
||||
compareClimateHvacModes
|
||||
),
|
||||
ordererHvacModes,
|
||||
this._config.hvac_modes
|
||||
).map<ControlSelectOption>((mode) => ({
|
||||
value: mode,
|
||||
|
@ -45,7 +45,6 @@ class HuiClimatePresetModesCardFeature
|
||||
return {
|
||||
type: "climate-preset-modes",
|
||||
style: "dropdown",
|
||||
preset_modes: [],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,6 @@ class HuiClimateSwingModesCardFeature
|
||||
return {
|
||||
type: "climate-swing-modes",
|
||||
style: "dropdown",
|
||||
swing_modes: [],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,6 @@ class HuiFanPresetModesCardFeature
|
||||
return {
|
||||
type: "fan-preset-modes",
|
||||
style: "dropdown",
|
||||
preset_modes: [],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,6 @@ class HuiHumidifierModesCardFeature
|
||||
return {
|
||||
type: "humidifier-modes",
|
||||
style: "dropdown",
|
||||
modes: [],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,6 @@ class HuiWaterHeaterOperationModeCardFeature
|
||||
static getStubConfig(): WaterHeaterOperationModesCardFeatureConfig {
|
||||
return {
|
||||
type: "water-heater-operation-modes",
|
||||
operation_modes: [],
|
||||
};
|
||||
}
|
||||
|
||||
@ -105,10 +104,12 @@ class HuiWaterHeaterOperationModeCardFeature
|
||||
|
||||
const color = stateColorCss(this.stateObj);
|
||||
|
||||
const orderedModes = (this.stateObj.attributes.operation_list || [])
|
||||
.concat()
|
||||
.sort(compareWaterHeaterOperationMode);
|
||||
|
||||
const options = filterModes(
|
||||
[...(this.stateObj?.attributes.operation_list || [])].sort(
|
||||
compareWaterHeaterOperationMode
|
||||
),
|
||||
orderedModes,
|
||||
this._config.operation_modes
|
||||
).map<ControlSelectOption>((mode) => ({
|
||||
value: mode,
|
||||
|
@ -17,6 +17,10 @@ import {
|
||||
} from "../../card-features/types";
|
||||
import type { LovelaceCardFeatureEditor } from "../../types";
|
||||
|
||||
type ClimateFanModesCardFeatureData = ClimateFanModesCardFeatureConfig & {
|
||||
customize_modes: boolean;
|
||||
};
|
||||
|
||||
@customElement("hui-climate-fan-modes-card-feature-editor")
|
||||
export class HuiClimateFanModesCardFeatureEditor
|
||||
extends LitElement
|
||||
@ -36,7 +40,8 @@ export class HuiClimateFanModesCardFeatureEditor
|
||||
(
|
||||
localize: LocalizeFunc,
|
||||
formatEntityAttributeValue: FormatEntityAttributeValueFunc,
|
||||
stateObj?: HassEntity
|
||||
stateObj: HassEntity | undefined,
|
||||
customizeModes: boolean
|
||||
) =>
|
||||
[
|
||||
{
|
||||
@ -55,20 +60,33 @@ export class HuiClimateFanModesCardFeatureEditor
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "fan_modes",
|
||||
name: "customize_modes",
|
||||
selector: {
|
||||
select: {
|
||||
multiple: true,
|
||||
reorder: true,
|
||||
mode: "list",
|
||||
options:
|
||||
stateObj?.attributes.fan_modes?.map((mode) => ({
|
||||
value: mode,
|
||||
label: formatEntityAttributeValue(stateObj, "fan_mode", mode),
|
||||
})) || [],
|
||||
},
|
||||
boolean: {},
|
||||
},
|
||||
},
|
||||
...(customizeModes
|
||||
? ([
|
||||
{
|
||||
name: "fan_modes",
|
||||
selector: {
|
||||
select: {
|
||||
multiple: true,
|
||||
reorder: true,
|
||||
options:
|
||||
stateObj?.attributes.fan_modes?.map((mode) => ({
|
||||
value: mode,
|
||||
label: formatEntityAttributeValue(
|
||||
stateObj,
|
||||
"fan_mode",
|
||||
mode
|
||||
),
|
||||
})) || [],
|
||||
},
|
||||
},
|
||||
},
|
||||
] as const satisfies readonly HaFormSchema[])
|
||||
: []),
|
||||
] as const satisfies readonly HaFormSchema[]
|
||||
);
|
||||
|
||||
@ -81,16 +99,17 @@ export class HuiClimateFanModesCardFeatureEditor
|
||||
? this.hass.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
const data: ClimateFanModesCardFeatureConfig = {
|
||||
const data: ClimateFanModesCardFeatureData = {
|
||||
style: "dropdown",
|
||||
fan_modes: [],
|
||||
...this._config,
|
||||
customize_modes: this._config.fan_modes !== undefined,
|
||||
};
|
||||
|
||||
const schema = this._schema(
|
||||
this.hass.localize,
|
||||
this.hass.formatEntityAttributeValue,
|
||||
stateObj
|
||||
stateObj,
|
||||
data.customize_modes
|
||||
);
|
||||
|
||||
return html`
|
||||
@ -105,7 +124,21 @@ export class HuiClimateFanModesCardFeatureEditor
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
fireEvent(this, "config-changed", { config: ev.detail.value });
|
||||
const { customize_modes, ...config } = ev.detail
|
||||
.value as ClimateFanModesCardFeatureData;
|
||||
|
||||
const stateObj = this.context?.entity_id
|
||||
? this.hass!.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
if (customize_modes && !config.fan_modes) {
|
||||
config.fan_modes = stateObj?.attributes.fan_modes || [];
|
||||
}
|
||||
if (!customize_modes && config.fan_modes) {
|
||||
delete config.fan_modes;
|
||||
}
|
||||
|
||||
fireEvent(this, "config-changed", { config: config });
|
||||
}
|
||||
|
||||
private _computeLabelCallback = (
|
||||
@ -114,6 +147,7 @@ export class HuiClimateFanModesCardFeatureEditor
|
||||
switch (schema.name) {
|
||||
case "style":
|
||||
case "fan_modes":
|
||||
case "customize_modes":
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.features.types.climate-fan-modes.${schema.name}`
|
||||
);
|
||||
|
@ -6,8 +6,11 @@ import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import type { FormatEntityStateFunc } from "../../../../common/translations/entity-state";
|
||||
import type { LocalizeFunc } from "../../../../common/translations/localize";
|
||||
import "../../../../components/ha-form/ha-form";
|
||||
import type { SchemaUnion } from "../../../../components/ha-form/types";
|
||||
import { HVAC_MODES } from "../../../../data/climate";
|
||||
import type {
|
||||
HaFormSchema,
|
||||
SchemaUnion,
|
||||
} from "../../../../components/ha-form/types";
|
||||
import { compareClimateHvacModes } from "../../../../data/climate";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import {
|
||||
ClimateHvacModesCardFeatureConfig,
|
||||
@ -15,6 +18,10 @@ import {
|
||||
} from "../../card-features/types";
|
||||
import type { LovelaceCardFeatureEditor } from "../../types";
|
||||
|
||||
type ClimateHvacModesCardFeatureData = ClimateHvacModesCardFeatureConfig & {
|
||||
customize_modes: boolean;
|
||||
};
|
||||
|
||||
@customElement("hui-climate-hvac-modes-card-feature-editor")
|
||||
export class HuiClimateHvacModesCardFeatureEditor
|
||||
extends LitElement
|
||||
@ -34,7 +41,8 @@ export class HuiClimateHvacModesCardFeatureEditor
|
||||
(
|
||||
localize: LocalizeFunc,
|
||||
formatEntityState: FormatEntityStateFunc,
|
||||
stateObj?: HassEntity
|
||||
stateObj: HassEntity | undefined,
|
||||
customizeModes: boolean
|
||||
) =>
|
||||
[
|
||||
{
|
||||
@ -53,22 +61,34 @@ export class HuiClimateHvacModesCardFeatureEditor
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "hvac_modes",
|
||||
name: "customize_modes",
|
||||
selector: {
|
||||
select: {
|
||||
multiple: true,
|
||||
reorder: true,
|
||||
mode: "list",
|
||||
options: HVAC_MODES.filter((mode) =>
|
||||
stateObj?.attributes.hvac_modes?.includes(mode)
|
||||
).map((mode) => ({
|
||||
value: mode,
|
||||
label: stateObj ? formatEntityState(stateObj, mode) : mode,
|
||||
})),
|
||||
},
|
||||
boolean: {},
|
||||
},
|
||||
},
|
||||
] as const
|
||||
...(customizeModes
|
||||
? ([
|
||||
{
|
||||
name: "hvac_modes",
|
||||
selector: {
|
||||
select: {
|
||||
reorder: true,
|
||||
multiple: true,
|
||||
options: (stateObj?.attributes.hvac_modes || [])
|
||||
.concat()
|
||||
.sort(compareClimateHvacModes)
|
||||
.map((mode) => ({
|
||||
value: mode,
|
||||
label: stateObj
|
||||
? formatEntityState(stateObj, mode)
|
||||
: mode,
|
||||
})),
|
||||
},
|
||||
},
|
||||
},
|
||||
] as const satisfies readonly HaFormSchema[])
|
||||
: []),
|
||||
] as const satisfies readonly HaFormSchema[]
|
||||
);
|
||||
|
||||
protected render() {
|
||||
@ -80,16 +100,17 @@ export class HuiClimateHvacModesCardFeatureEditor
|
||||
? this.hass.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
const data: ClimateHvacModesCardFeatureConfig = {
|
||||
const data: ClimateHvacModesCardFeatureData = {
|
||||
style: "icons",
|
||||
hvac_modes: [],
|
||||
...this._config,
|
||||
customize_modes: this._config.hvac_modes !== undefined,
|
||||
};
|
||||
|
||||
const schema = this._schema(
|
||||
this.hass.localize,
|
||||
this.hass.formatEntityState,
|
||||
stateObj
|
||||
stateObj,
|
||||
data.customize_modes
|
||||
);
|
||||
|
||||
return html`
|
||||
@ -104,7 +125,24 @@ export class HuiClimateHvacModesCardFeatureEditor
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
fireEvent(this, "config-changed", { config: ev.detail.value });
|
||||
const { customize_modes, ...config } = ev.detail
|
||||
.value as ClimateHvacModesCardFeatureData;
|
||||
|
||||
const stateObj = this.context?.entity_id
|
||||
? this.hass!.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
if (customize_modes && !config.hvac_modes) {
|
||||
const ordererHvacModes = (stateObj?.attributes.hvac_modes || [])
|
||||
.concat()
|
||||
.sort(compareClimateHvacModes);
|
||||
config.hvac_modes = ordererHvacModes;
|
||||
}
|
||||
if (!customize_modes && config.hvac_modes) {
|
||||
delete config.hvac_modes;
|
||||
}
|
||||
|
||||
fireEvent(this, "config-changed", { config: config });
|
||||
}
|
||||
|
||||
private _computeLabelCallback = (
|
||||
@ -113,6 +151,7 @@ export class HuiClimateHvacModesCardFeatureEditor
|
||||
switch (schema.name) {
|
||||
case "hvac_modes":
|
||||
case "style":
|
||||
case "customize_modes":
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.features.types.climate-hvac-modes.${schema.name}`
|
||||
);
|
||||
|
@ -17,6 +17,10 @@ import {
|
||||
} from "../../card-features/types";
|
||||
import type { LovelaceCardFeatureEditor } from "../../types";
|
||||
|
||||
type ClimatePresetModesCardFeatureData = ClimatePresetModesCardFeatureConfig & {
|
||||
customize_modes: boolean;
|
||||
};
|
||||
|
||||
@customElement("hui-climate-preset-modes-card-feature-editor")
|
||||
export class HuiClimatePresetModesCardFeatureEditor
|
||||
extends LitElement
|
||||
@ -36,7 +40,8 @@ export class HuiClimatePresetModesCardFeatureEditor
|
||||
(
|
||||
localize: LocalizeFunc,
|
||||
formatEntityAttributeValue: FormatEntityAttributeValueFunc,
|
||||
stateObj?: HassEntity
|
||||
stateObj: HassEntity | undefined,
|
||||
customizeModes: boolean
|
||||
) =>
|
||||
[
|
||||
{
|
||||
@ -55,24 +60,33 @@ export class HuiClimatePresetModesCardFeatureEditor
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "preset_modes",
|
||||
name: "customize_modes",
|
||||
selector: {
|
||||
select: {
|
||||
multiple: true,
|
||||
reorder: true,
|
||||
mode: "list",
|
||||
options:
|
||||
stateObj?.attributes.preset_modes?.map((mode) => ({
|
||||
value: mode,
|
||||
label: formatEntityAttributeValue(
|
||||
stateObj,
|
||||
"preset_mode",
|
||||
mode
|
||||
),
|
||||
})) || [],
|
||||
},
|
||||
boolean: {},
|
||||
},
|
||||
},
|
||||
...(customizeModes
|
||||
? ([
|
||||
{
|
||||
name: "preset_modes",
|
||||
selector: {
|
||||
select: {
|
||||
reorder: true,
|
||||
multiple: true,
|
||||
options:
|
||||
stateObj?.attributes.preset_modes?.map((mode) => ({
|
||||
value: mode,
|
||||
label: formatEntityAttributeValue(
|
||||
stateObj,
|
||||
"preset_mode",
|
||||
mode
|
||||
),
|
||||
})) || [],
|
||||
},
|
||||
},
|
||||
},
|
||||
] as const satisfies readonly HaFormSchema[])
|
||||
: []),
|
||||
] as const satisfies readonly HaFormSchema[]
|
||||
);
|
||||
|
||||
@ -85,16 +99,17 @@ export class HuiClimatePresetModesCardFeatureEditor
|
||||
? this.hass.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
const data: ClimatePresetModesCardFeatureConfig = {
|
||||
const data: ClimatePresetModesCardFeatureData = {
|
||||
style: "dropdown",
|
||||
preset_modes: [],
|
||||
...this._config,
|
||||
customize_modes: this._config.preset_modes !== undefined,
|
||||
};
|
||||
|
||||
const schema = this._schema(
|
||||
this.hass.localize,
|
||||
this.hass.formatEntityAttributeValue,
|
||||
stateObj
|
||||
stateObj,
|
||||
data.customize_modes
|
||||
);
|
||||
|
||||
return html`
|
||||
@ -109,7 +124,21 @@ export class HuiClimatePresetModesCardFeatureEditor
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
fireEvent(this, "config-changed", { config: ev.detail.value });
|
||||
const { customize_modes, ...config } = ev.detail
|
||||
.value as ClimatePresetModesCardFeatureData;
|
||||
|
||||
const stateObj = this.context?.entity_id
|
||||
? this.hass!.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
if (customize_modes && !config.preset_modes) {
|
||||
config.preset_modes = stateObj?.attributes.preset_modes || [];
|
||||
}
|
||||
if (!customize_modes && config.preset_modes) {
|
||||
delete config.preset_modes;
|
||||
}
|
||||
|
||||
fireEvent(this, "config-changed", { config: config });
|
||||
}
|
||||
|
||||
private _computeLabelCallback = (
|
||||
@ -118,6 +147,7 @@ export class HuiClimatePresetModesCardFeatureEditor
|
||||
switch (schema.name) {
|
||||
case "style":
|
||||
case "preset_modes":
|
||||
case "customize_modes":
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.features.types.climate-preset-modes.${schema.name}`
|
||||
);
|
||||
|
@ -17,6 +17,10 @@ import {
|
||||
} from "../../card-features/types";
|
||||
import type { LovelaceCardFeatureEditor } from "../../types";
|
||||
|
||||
type ClimateSwingModesCardFeatureData = ClimateSwingModesCardFeatureConfig & {
|
||||
customize_modes: boolean;
|
||||
};
|
||||
|
||||
@customElement("hui-climate-swing-modes-card-feature-editor")
|
||||
export class HuiClimateSwingModesCardFeatureEditor
|
||||
extends LitElement
|
||||
@ -36,7 +40,8 @@ export class HuiClimateSwingModesCardFeatureEditor
|
||||
(
|
||||
localize: LocalizeFunc,
|
||||
formatEntityAttributeValue: FormatEntityAttributeValueFunc,
|
||||
stateObj?: HassEntity
|
||||
stateObj: HassEntity | undefined,
|
||||
customizeModes: boolean
|
||||
) =>
|
||||
[
|
||||
{
|
||||
@ -55,24 +60,33 @@ export class HuiClimateSwingModesCardFeatureEditor
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "swing_modes",
|
||||
name: "customize_modes",
|
||||
selector: {
|
||||
select: {
|
||||
multiple: true,
|
||||
reorder: true,
|
||||
mode: "list",
|
||||
options:
|
||||
stateObj?.attributes.swing_modes?.map((mode) => ({
|
||||
value: mode,
|
||||
label: formatEntityAttributeValue(
|
||||
stateObj,
|
||||
"swing_mode",
|
||||
mode
|
||||
),
|
||||
})) || [],
|
||||
},
|
||||
boolean: {},
|
||||
},
|
||||
},
|
||||
...(customizeModes
|
||||
? ([
|
||||
{
|
||||
name: "swing_modes",
|
||||
selector: {
|
||||
select: {
|
||||
reorder: true,
|
||||
multiple: true,
|
||||
options:
|
||||
stateObj?.attributes.swing_modes?.map((mode) => ({
|
||||
value: mode,
|
||||
label: formatEntityAttributeValue(
|
||||
stateObj,
|
||||
"swing_mode",
|
||||
mode
|
||||
),
|
||||
})) || [],
|
||||
},
|
||||
},
|
||||
},
|
||||
] as const satisfies readonly HaFormSchema[])
|
||||
: []),
|
||||
] as const satisfies readonly HaFormSchema[]
|
||||
);
|
||||
|
||||
@ -85,16 +99,17 @@ export class HuiClimateSwingModesCardFeatureEditor
|
||||
? this.hass.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
const data: ClimateSwingModesCardFeatureConfig = {
|
||||
const data: ClimateSwingModesCardFeatureData = {
|
||||
style: "dropdown",
|
||||
swing_modes: [],
|
||||
...this._config,
|
||||
customize_modes: this._config.swing_modes !== undefined,
|
||||
};
|
||||
|
||||
const schema = this._schema(
|
||||
this.hass.localize,
|
||||
this.hass.formatEntityAttributeValue,
|
||||
stateObj
|
||||
stateObj,
|
||||
data.customize_modes
|
||||
);
|
||||
|
||||
return html`
|
||||
@ -109,7 +124,21 @@ export class HuiClimateSwingModesCardFeatureEditor
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
fireEvent(this, "config-changed", { config: ev.detail.value });
|
||||
const { customize_modes, ...config } = ev.detail
|
||||
.value as ClimateSwingModesCardFeatureData;
|
||||
|
||||
const stateObj = this.context?.entity_id
|
||||
? this.hass!.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
if (customize_modes && !config.swing_modes) {
|
||||
config.swing_modes = stateObj?.attributes.swing_modes || [];
|
||||
}
|
||||
if (!customize_modes && config.swing_modes) {
|
||||
delete config.swing_modes;
|
||||
}
|
||||
|
||||
fireEvent(this, "config-changed", { config: config });
|
||||
}
|
||||
|
||||
private _computeLabelCallback = (
|
||||
@ -118,6 +147,7 @@ export class HuiClimateSwingModesCardFeatureEditor
|
||||
switch (schema.name) {
|
||||
case "style":
|
||||
case "swing_modes":
|
||||
case "customize_modes":
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.features.types.climate-swing-modes.${schema.name}`
|
||||
);
|
||||
|
@ -17,6 +17,10 @@ import {
|
||||
} from "../../card-features/types";
|
||||
import type { LovelaceCardFeatureEditor } from "../../types";
|
||||
|
||||
type FanPresetModesCardFeatureData = FanPresetModesCardFeatureConfig & {
|
||||
customize_modes: boolean;
|
||||
};
|
||||
|
||||
@customElement("hui-fan-preset-modes-card-feature-editor")
|
||||
export class HuiFanPresetModesCardFeatureEditor
|
||||
extends LitElement
|
||||
@ -36,7 +40,8 @@ export class HuiFanPresetModesCardFeatureEditor
|
||||
(
|
||||
localize: LocalizeFunc,
|
||||
formatEntityAttributeValue: FormatEntityAttributeValueFunc,
|
||||
stateObj?: HassEntity
|
||||
stateObj: HassEntity | undefined,
|
||||
customizeModes: boolean
|
||||
) =>
|
||||
[
|
||||
{
|
||||
@ -55,24 +60,33 @@ export class HuiFanPresetModesCardFeatureEditor
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "preset_modes",
|
||||
name: "customize_modes",
|
||||
selector: {
|
||||
select: {
|
||||
multiple: true,
|
||||
reorder: true,
|
||||
mode: "list",
|
||||
options:
|
||||
stateObj?.attributes.preset_modes?.map((mode) => ({
|
||||
value: mode,
|
||||
label: formatEntityAttributeValue(
|
||||
stateObj,
|
||||
"preset_mode",
|
||||
mode
|
||||
),
|
||||
})) || [],
|
||||
},
|
||||
boolean: {},
|
||||
},
|
||||
},
|
||||
...(customizeModes
|
||||
? ([
|
||||
{
|
||||
name: "preset_modes",
|
||||
selector: {
|
||||
select: {
|
||||
reorder: true,
|
||||
multiple: true,
|
||||
options:
|
||||
stateObj?.attributes.preset_modes?.map((mode) => ({
|
||||
value: mode,
|
||||
label: formatEntityAttributeValue(
|
||||
stateObj,
|
||||
"preset_mode",
|
||||
mode
|
||||
),
|
||||
})) || [],
|
||||
},
|
||||
},
|
||||
},
|
||||
] as const satisfies readonly HaFormSchema[])
|
||||
: []),
|
||||
] as const satisfies readonly HaFormSchema[]
|
||||
);
|
||||
|
||||
@ -85,16 +99,17 @@ export class HuiFanPresetModesCardFeatureEditor
|
||||
? this.hass.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
const data: FanPresetModesCardFeatureConfig = {
|
||||
const data: FanPresetModesCardFeatureData = {
|
||||
style: "dropdown",
|
||||
preset_modes: [],
|
||||
...this._config,
|
||||
customize_modes: this._config.preset_modes !== undefined,
|
||||
};
|
||||
|
||||
const schema = this._schema(
|
||||
this.hass.localize,
|
||||
this.hass.formatEntityAttributeValue,
|
||||
stateObj
|
||||
stateObj,
|
||||
data.customize_modes
|
||||
);
|
||||
|
||||
return html`
|
||||
@ -109,7 +124,21 @@ export class HuiFanPresetModesCardFeatureEditor
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
fireEvent(this, "config-changed", { config: ev.detail.value });
|
||||
const { customize_modes, ...config } = ev.detail
|
||||
.value as FanPresetModesCardFeatureData;
|
||||
|
||||
const stateObj = this.context?.entity_id
|
||||
? this.hass!.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
if (customize_modes && !config.preset_modes) {
|
||||
config.preset_modes = stateObj?.attributes.preset_modes || [];
|
||||
}
|
||||
if (!customize_modes && config.preset_modes) {
|
||||
delete config.preset_modes;
|
||||
}
|
||||
|
||||
fireEvent(this, "config-changed", { config: config });
|
||||
}
|
||||
|
||||
private _computeLabelCallback = (
|
||||
@ -118,6 +147,7 @@ export class HuiFanPresetModesCardFeatureEditor
|
||||
switch (schema.name) {
|
||||
case "style":
|
||||
case "preset_modes":
|
||||
case "customize_modes":
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.features.types.fan-preset-modes.${schema.name}`
|
||||
);
|
||||
|
@ -17,6 +17,10 @@ import {
|
||||
} from "../../card-features/types";
|
||||
import type { LovelaceCardFeatureEditor } from "../../types";
|
||||
|
||||
type HumidifierModesCardFeatureData = HumidifierModesCardFeatureConfig & {
|
||||
customize_modes: boolean;
|
||||
};
|
||||
|
||||
@customElement("hui-humidifier-modes-card-feature-editor")
|
||||
export class HuiHumidifierModesCardFeatureEditor
|
||||
extends LitElement
|
||||
@ -36,7 +40,8 @@ export class HuiHumidifierModesCardFeatureEditor
|
||||
(
|
||||
localize: LocalizeFunc,
|
||||
formatEntityAttributeValue: FormatEntityAttributeValueFunc,
|
||||
stateObj?: HassEntity
|
||||
stateObj: HassEntity | undefined,
|
||||
customizeModes: boolean
|
||||
) =>
|
||||
[
|
||||
{
|
||||
@ -55,20 +60,33 @@ export class HuiHumidifierModesCardFeatureEditor
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "modes",
|
||||
name: "customize_modes",
|
||||
selector: {
|
||||
select: {
|
||||
multiple: true,
|
||||
reorder: true,
|
||||
mode: "list",
|
||||
options:
|
||||
stateObj?.attributes.available_modes?.map((mode) => ({
|
||||
value: mode,
|
||||
label: formatEntityAttributeValue(stateObj, "mode", mode),
|
||||
})) || [],
|
||||
},
|
||||
boolean: {},
|
||||
},
|
||||
},
|
||||
...(customizeModes
|
||||
? ([
|
||||
{
|
||||
name: "modes",
|
||||
selector: {
|
||||
select: {
|
||||
reorder: true,
|
||||
multiple: true,
|
||||
options:
|
||||
stateObj?.attributes.available_modes?.map((mode) => ({
|
||||
value: mode,
|
||||
label: formatEntityAttributeValue(
|
||||
stateObj,
|
||||
"mode",
|
||||
mode
|
||||
),
|
||||
})) || [],
|
||||
},
|
||||
},
|
||||
},
|
||||
] as const satisfies readonly HaFormSchema[])
|
||||
: []),
|
||||
] as const satisfies readonly HaFormSchema[]
|
||||
);
|
||||
|
||||
@ -81,16 +99,17 @@ export class HuiHumidifierModesCardFeatureEditor
|
||||
? this.hass.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
const data: HumidifierModesCardFeatureConfig = {
|
||||
const data: HumidifierModesCardFeatureData = {
|
||||
style: "dropdown",
|
||||
modes: [],
|
||||
...this._config,
|
||||
customize_modes: this._config.modes !== undefined,
|
||||
};
|
||||
|
||||
const schema = this._schema(
|
||||
this.hass.localize,
|
||||
this.hass.formatEntityAttributeValue,
|
||||
stateObj
|
||||
stateObj,
|
||||
data.customize_modes
|
||||
);
|
||||
|
||||
return html`
|
||||
@ -105,7 +124,21 @@ export class HuiHumidifierModesCardFeatureEditor
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
fireEvent(this, "config-changed", { config: ev.detail.value });
|
||||
const { customize_modes, ...config } = ev.detail
|
||||
.value as HumidifierModesCardFeatureData;
|
||||
|
||||
const stateObj = this.context?.entity_id
|
||||
? this.hass!.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
if (customize_modes && !config.modes) {
|
||||
config.modes = stateObj?.attributes.available_modes || [];
|
||||
}
|
||||
if (!customize_modes && config.modes) {
|
||||
delete config.modes;
|
||||
}
|
||||
|
||||
fireEvent(this, "config-changed", { config: config });
|
||||
}
|
||||
|
||||
private _computeLabelCallback = (
|
||||
@ -114,6 +147,7 @@ export class HuiHumidifierModesCardFeatureEditor
|
||||
switch (schema.name) {
|
||||
case "style":
|
||||
case "modes":
|
||||
case "customize_modes":
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.features.types.humidifier-modes.${schema.name}`
|
||||
);
|
||||
|
@ -5,14 +5,22 @@ import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import type { FormatEntityStateFunc } from "../../../../common/translations/entity-state";
|
||||
import "../../../../components/ha-form/ha-form";
|
||||
import type { SchemaUnion } from "../../../../components/ha-form/types";
|
||||
import type {
|
||||
HaFormSchema,
|
||||
SchemaUnion,
|
||||
} from "../../../../components/ha-form/types";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import {
|
||||
WaterHeaterOperationModesCardFeatureConfig,
|
||||
LovelaceCardFeatureContext,
|
||||
} from "../../card-features/types";
|
||||
import type { LovelaceCardFeatureEditor } from "../../types";
|
||||
import { OPERATION_MODES } from "../../../../data/water_heater";
|
||||
import { compareWaterHeaterOperationMode } from "../../../../data/water_heater";
|
||||
|
||||
type WaterHeaterOperationModesCardFeatureData =
|
||||
WaterHeaterOperationModesCardFeatureConfig & {
|
||||
customize_modes: boolean;
|
||||
};
|
||||
|
||||
@customElement("hui-water-heater-operation-modes-card-feature-editor")
|
||||
export class HuiWaterHeaterOperationModesCardFeatureEditor
|
||||
@ -30,25 +38,41 @@ export class HuiWaterHeaterOperationModesCardFeatureEditor
|
||||
}
|
||||
|
||||
private _schema = memoizeOne(
|
||||
(formatEntityState: FormatEntityStateFunc, stateObj?: HassEntity) =>
|
||||
(
|
||||
formatEntityState: FormatEntityStateFunc,
|
||||
stateObj: HassEntity | undefined,
|
||||
customizeModes: boolean
|
||||
) =>
|
||||
[
|
||||
{
|
||||
name: "operation_modes",
|
||||
name: "customize_modes",
|
||||
selector: {
|
||||
select: {
|
||||
multiple: true,
|
||||
reorder: true,
|
||||
mode: "list",
|
||||
options: OPERATION_MODES.filter((mode) =>
|
||||
stateObj?.attributes.operation_list?.includes(mode)
|
||||
).map((mode) => ({
|
||||
value: mode,
|
||||
label: stateObj ? formatEntityState(stateObj, mode) : mode,
|
||||
})),
|
||||
},
|
||||
boolean: {},
|
||||
},
|
||||
},
|
||||
] as const
|
||||
...(customizeModes
|
||||
? ([
|
||||
{
|
||||
name: "operation_modes",
|
||||
selector: {
|
||||
select: {
|
||||
reorder: true,
|
||||
multiple: true,
|
||||
options: (stateObj?.attributes.operation_list || [])
|
||||
.concat()
|
||||
.sort(compareWaterHeaterOperationMode)
|
||||
.map((mode) => ({
|
||||
value: mode,
|
||||
label: stateObj
|
||||
? formatEntityState(stateObj, mode)
|
||||
: mode,
|
||||
})),
|
||||
},
|
||||
},
|
||||
},
|
||||
] as const satisfies readonly HaFormSchema[])
|
||||
: []),
|
||||
] as const satisfies readonly HaFormSchema[]
|
||||
);
|
||||
|
||||
protected render() {
|
||||
@ -60,12 +84,21 @@ export class HuiWaterHeaterOperationModesCardFeatureEditor
|
||||
? this.hass.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
const schema = this._schema(this.hass.formatEntityState, stateObj);
|
||||
const data: WaterHeaterOperationModesCardFeatureData = {
|
||||
...this._config,
|
||||
customize_modes: this._config.operation_modes !== undefined,
|
||||
};
|
||||
|
||||
const schema = this._schema(
|
||||
this.hass.formatEntityState,
|
||||
stateObj,
|
||||
data.customize_modes
|
||||
);
|
||||
|
||||
return html`
|
||||
<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._config}
|
||||
.data=${data}
|
||||
.schema=${schema}
|
||||
.computeLabel=${this._computeLabelCallback}
|
||||
@value-changed=${this._valueChanged}
|
||||
@ -74,7 +107,23 @@ export class HuiWaterHeaterOperationModesCardFeatureEditor
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
fireEvent(this, "config-changed", { config: ev.detail.value });
|
||||
const { customize_modes, ...config } = ev.detail
|
||||
.value as WaterHeaterOperationModesCardFeatureData;
|
||||
|
||||
const stateObj = this.context?.entity_id
|
||||
? this.hass!.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
if (customize_modes && !config.operation_modes) {
|
||||
config.operation_modes = (stateObj?.attributes.operation_list || [])
|
||||
.concat()
|
||||
.sort(compareWaterHeaterOperationMode);
|
||||
}
|
||||
if (!customize_modes && config.operation_modes) {
|
||||
delete config.operation_modes;
|
||||
}
|
||||
|
||||
fireEvent(this, "config-changed", { config: config });
|
||||
}
|
||||
|
||||
private _computeLabelCallback = (
|
||||
@ -82,13 +131,12 @@ export class HuiWaterHeaterOperationModesCardFeatureEditor
|
||||
) => {
|
||||
switch (schema.name) {
|
||||
case "operation_modes":
|
||||
case "customize_modes":
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.features.types.water-heater-modes.${schema.name}`
|
||||
`ui.panel.lovelace.editor.features.types.water-heater-operation-modes.${schema.name}`
|
||||
);
|
||||
default:
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.card.generic.${schema.name}`
|
||||
);
|
||||
return "";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -5996,16 +5996,18 @@
|
||||
"dropdown": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::dropdown%]",
|
||||
"icons": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::icons%]"
|
||||
},
|
||||
"customize_modes": "Customize fan modes",
|
||||
"fan_modes": "Fan modes"
|
||||
},
|
||||
"climate-swing-modes": {
|
||||
"label": "Climate swing modes",
|
||||
"swing_modes": "Swing modes",
|
||||
"style": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style%]",
|
||||
"style_list": {
|
||||
"dropdown": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::dropdown%]",
|
||||
"icons": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::icons%]"
|
||||
},
|
||||
"swing_modes": "Swing modes"
|
||||
"customize_modes": "Customize swing modes"
|
||||
},
|
||||
"climate-hvac-modes": {
|
||||
"label": "Climate HVAC modes",
|
||||
@ -6014,7 +6016,8 @@
|
||||
"style_list": {
|
||||
"dropdown": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::dropdown%]",
|
||||
"icons": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::icons%]"
|
||||
}
|
||||
},
|
||||
"customize_modes": "Customize HVAC modes"
|
||||
},
|
||||
"climate-preset-modes": {
|
||||
"label": "Climate preset modes",
|
||||
@ -6023,6 +6026,7 @@
|
||||
"dropdown": "Dropdown",
|
||||
"icons": "Icons"
|
||||
},
|
||||
"customize_modes": "Customize preset modes",
|
||||
"preset_modes": "Preset modes"
|
||||
},
|
||||
"fan-preset-modes": {
|
||||
@ -6032,6 +6036,7 @@
|
||||
"dropdown": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::dropdown%]",
|
||||
"icons": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::icons%]"
|
||||
},
|
||||
"customize_modes": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::customize_modes%]",
|
||||
"preset_modes": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::preset_modes%]"
|
||||
},
|
||||
"humidifier-toggle": {
|
||||
@ -6044,6 +6049,7 @@
|
||||
"dropdown": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::dropdown%]",
|
||||
"icons": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::icons%]"
|
||||
},
|
||||
"customize_modes": "Customize modes",
|
||||
"modes": "Modes"
|
||||
},
|
||||
"select-options": {
|
||||
@ -6065,7 +6071,8 @@
|
||||
},
|
||||
"water-heater-operation-modes": {
|
||||
"label": "Water heater operation modes",
|
||||
"operation_modes": "Operation modes"
|
||||
"operation_modes": "Operation modes",
|
||||
"customize_modes": "Customize operation modes"
|
||||
},
|
||||
"lawn-mower-commands": {
|
||||
"label": "Lawn mower commands",
|
||||
|
Loading…
x
Reference in New Issue
Block a user