Allow null selector (#14212)

This commit is contained in:
Paul Bottein 2022-10-27 19:17:42 +02:00 committed by GitHub
parent a56b2e3270
commit 2ab5da6d84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 121 additions and 106 deletions

View File

@ -39,11 +39,11 @@ export const computeInitialHaFormData = (
const selector: Selector = field.selector; const selector: Selector = field.selector;
if ("device" in selector) { if ("device" in selector) {
data[field.name] = selector.device.multiple ? [] : ""; data[field.name] = selector.device?.multiple ? [] : "";
} else if ("entity" in selector) { } else if ("entity" in selector) {
data[field.name] = selector.entity.multiple ? [] : ""; data[field.name] = selector.entity?.multiple ? [] : "";
} else if ("area" in selector) { } else if ("area" in selector) {
data[field.name] = selector.area.multiple ? [] : ""; data[field.name] = selector.area?.multiple ? [] : "";
} else if ("boolean" in selector) { } else if ("boolean" in selector) {
data[field.name] = false; data[field.name] = false;
} else if ( } else if (
@ -56,9 +56,9 @@ export const computeInitialHaFormData = (
) { ) {
data[field.name] = ""; data[field.name] = "";
} else if ("number" in selector) { } else if ("number" in selector) {
data[field.name] = selector.number.min ?? 0; data[field.name] = selector.number?.min ?? 0;
} else if ("select" in selector) { } else if ("select" in selector) {
if (selector.select.options.length) { if (selector.select?.options.length) {
data[field.name] = selector.select.options[0][0]; data[field.name] = selector.select.options[0][0];
} }
} else if ("duration" in selector) { } else if ("duration" in selector) {
@ -75,7 +75,7 @@ export const computeInitialHaFormData = (
} else if ("color_rgb" in selector) { } else if ("color_rgb" in selector) {
data[field.name] = [0, 0, 0]; data[field.name] = [0, 0, 0];
} else if ("color_temp" in selector) { } else if ("color_temp" in selector) {
data[field.name] = selector.color_temp.min_mireds ?? 153; data[field.name] = selector.color_temp?.min_mireds ?? 153;
} else if ( } else if (
"action" in selector || "action" in selector ||
"media" in selector || "media" in selector ||

View File

@ -55,8 +55,8 @@ export class HaAreaSelector extends SubscribeMixin(LitElement) {
protected updated(changedProperties: PropertyValues): void { protected updated(changedProperties: PropertyValues): void {
if ( if (
changedProperties.has("selector") && changedProperties.has("selector") &&
(this.selector.area.device?.integration || (this.selector.area?.device?.integration ||
this.selector.area.entity?.integration) && this.selector.area?.entity?.integration) &&
!this._entitySources !this._entitySources
) { ) {
fetchEntitySourcesWithCache(this.hass).then((sources) => { fetchEntitySourcesWithCache(this.hass).then((sources) => {
@ -67,14 +67,14 @@ export class HaAreaSelector extends SubscribeMixin(LitElement) {
protected render(): TemplateResult { protected render(): TemplateResult {
if ( if (
(this.selector.area.device?.integration || (this.selector.area?.device?.integration ||
this.selector.area.entity?.integration) && this.selector.area?.entity?.integration) &&
!this._entitySources !this._entitySources
) { ) {
return html``; return html``;
} }
if (!this.selector.area.multiple) { if (!this.selector.area?.multiple) {
return html` return html`
<ha-area-picker <ha-area-picker
.hass=${this.hass} .hass=${this.hass}
@ -106,7 +106,7 @@ export class HaAreaSelector extends SubscribeMixin(LitElement) {
} }
private _filterEntities = (entity: HassEntity): boolean => { private _filterEntities = (entity: HassEntity): boolean => {
if (!this.selector.area.entity) { if (!this.selector.area?.entity) {
return true; return true;
} }
@ -118,7 +118,7 @@ export class HaAreaSelector extends SubscribeMixin(LitElement) {
}; };
private _filterDevices = (device: DeviceRegistryEntry): boolean => { private _filterDevices = (device: DeviceRegistryEntry): boolean => {
if (!this.selector.area.device) { if (!this.selector.area?.device) {
return true; return true;
} }

View File

@ -30,9 +30,9 @@ export class HaSelectorAttribute extends SubscribeMixin(LitElement) {
return html` return html`
<ha-entity-attribute-picker <ha-entity-attribute-picker
.hass=${this.hass} .hass=${this.hass}
.entityId=${this.selector.attribute.entity_id || .entityId=${this.selector.attribute?.entity_id ||
this.context?.filter_entity} this.context?.filter_entity}
.hideAttributes=${this.selector.attribute.hide_attributes} .hideAttributes=${this.selector.attribute?.hide_attributes}
.value=${this.value} .value=${this.value}
.label=${this.label} .label=${this.label}
.helper=${this.helper} .helper=${this.helper}
@ -49,7 +49,7 @@ export class HaSelectorAttribute extends SubscribeMixin(LitElement) {
// No need to filter value if no value // No need to filter value if no value
!this.value || !this.value ||
// Only adjust value if we used the context // Only adjust value if we used the context
this.selector.attribute.entity_id || this.selector.attribute?.entity_id ||
// Only check if context has changed // Only check if context has changed
!changedProps.has("context") !changedProps.has("context")
) { ) {

View File

@ -28,7 +28,7 @@ export class HaConfigEntrySelector extends LitElement {
.helper=${this.helper} .helper=${this.helper}
.disabled=${this.disabled} .disabled=${this.disabled}
.required=${this.required} .required=${this.required}
.integration=${this.selector.config_entry.integration} .integration=${this.selector.config_entry?.integration}
allow-custom-entity allow-custom-entity
></ha-config-entry-picker>`; ></ha-config-entry-picker>`;
} }

View File

@ -53,7 +53,7 @@ export class HaDeviceSelector extends SubscribeMixin(LitElement) {
super.updated(changedProperties); super.updated(changedProperties);
if ( if (
changedProperties.has("selector") && changedProperties.has("selector") &&
this.selector.device.integration && this.selector.device?.integration &&
!this._entitySources !this._entitySources
) { ) {
fetchEntitySourcesWithCache(this.hass).then((sources) => { fetchEntitySourcesWithCache(this.hass).then((sources) => {
@ -63,11 +63,11 @@ export class HaDeviceSelector extends SubscribeMixin(LitElement) {
} }
protected render() { protected render() {
if (this.selector.device.integration && !this._entitySources) { if (this.selector.device?.integration && !this._entitySources) {
return html``; return html``;
} }
if (!this.selector.device.multiple) { if (!this.selector.device?.multiple) {
return html` return html`
<ha-device-picker <ha-device-picker
.hass=${this.hass} .hass=${this.hass}
@ -75,10 +75,10 @@ export class HaDeviceSelector extends SubscribeMixin(LitElement) {
.label=${this.label} .label=${this.label}
.helper=${this.helper} .helper=${this.helper}
.deviceFilter=${this._filterDevices} .deviceFilter=${this._filterDevices}
.includeDeviceClasses=${this.selector.device.entity?.device_class .includeDeviceClasses=${this.selector.device?.entity?.device_class
? [this.selector.device.entity.device_class] ? [this.selector.device.entity.device_class]
: undefined} : undefined}
.includeDomains=${this.selector.device.entity?.domain .includeDomains=${this.selector.device?.entity?.domain
? [this.selector.device.entity.domain] ? [this.selector.device.entity.domain]
: undefined} : undefined}
.disabled=${this.disabled} .disabled=${this.disabled}
@ -113,6 +113,9 @@ export class HaDeviceSelector extends SubscribeMixin(LitElement) {
? this._deviceIntegrationLookup(this._entitySources, this._entities) ? this._deviceIntegrationLookup(this._entitySources, this._entities)
: undefined; : undefined;
if (!this.selector.device) {
return true;
}
return filterSelectorDevices( return filterSelectorDevices(
this.selector.device, this.selector.device,
device, device,

View File

@ -28,7 +28,7 @@ export class HaTimeDuration extends LitElement {
.data=${this.value} .data=${this.value}
.disabled=${this.disabled} .disabled=${this.disabled}
.required=${this.required} .required=${this.required}
?enableDay=${this.selector.duration.enable_day} ?enableDay=${this.selector.duration?.enable_day}
></ha-duration-input> ></ha-duration-input>
`; `;
} }

View File

@ -30,14 +30,14 @@ export class HaEntitySelector extends LitElement {
@property({ type: Boolean }) public required = true; @property({ type: Boolean }) public required = true;
protected render() { protected render() {
if (!this.selector.entity.multiple) { if (!this.selector.entity?.multiple) {
return html`<ha-entity-picker return html`<ha-entity-picker
.hass=${this.hass} .hass=${this.hass}
.value=${this.value} .value=${this.value}
.label=${this.label} .label=${this.label}
.helper=${this.helper} .helper=${this.helper}
.includeEntities=${this.selector.entity.include_entities} .includeEntities=${this.selector.entity?.include_entities}
.excludeEntities=${this.selector.entity.exclude_entities} .excludeEntities=${this.selector.entity?.exclude_entities}
.entityFilter=${this._filterEntities} .entityFilter=${this._filterEntities}
.disabled=${this.disabled} .disabled=${this.disabled}
.required=${this.required} .required=${this.required}
@ -64,7 +64,7 @@ export class HaEntitySelector extends LitElement {
super.updated(changedProps); super.updated(changedProps);
if ( if (
changedProps.has("selector") && changedProps.has("selector") &&
this.selector.entity.integration && this.selector.entity?.integration &&
!this._entitySources !this._entitySources
) { ) {
fetchEntitySourcesWithCache(this.hass).then((sources) => { fetchEntitySourcesWithCache(this.hass).then((sources) => {
@ -73,8 +73,16 @@ export class HaEntitySelector extends LitElement {
} }
} }
private _filterEntities = (entity: HassEntity): boolean => private _filterEntities = (entity: HassEntity): boolean => {
filterSelectorEntities(this.selector.entity, entity, this._entitySources); if (!this.selector?.entity) {
return true;
}
return filterSelectorEntities(
this.selector.entity,
entity,
this._entitySources
);
};
} }
declare global { declare global {

View File

@ -32,7 +32,7 @@ export class HaFileSelector extends LitElement {
return html` return html`
<ha-file-upload <ha-file-upload
.hass=${this.hass} .hass=${this.hass}
.accept=${this.selector.file.accept} .accept=${this.selector.file?.accept}
.icon=${mdiFile} .icon=${mdiFile}
.label=${this.label} .label=${this.label}
.required=${this.required} .required=${this.required}

View File

@ -30,8 +30,8 @@ export class HaIconSelector extends LitElement {
.required=${this.required} .required=${this.required}
.disabled=${this.disabled} .disabled=${this.disabled}
.helper=${this.helper} .helper=${this.helper}
.fallbackPath=${this.selector.icon.fallbackPath} .fallbackPath=${this.selector.icon?.fallbackPath}
.placeholder=${this.selector.icon.placeholder} .placeholder=${this.selector.icon?.placeholder}
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
></ha-icon-picker> ></ha-icon-picker>
`; `;

View File

@ -43,7 +43,7 @@ export class HaLocationSelector extends LitElement {
value?: LocationSelectorValue value?: LocationSelectorValue
): MarkerLocation[] => { ): MarkerLocation[] => {
const computedStyles = getComputedStyle(this); const computedStyles = getComputedStyle(this);
const zoneRadiusColor = selector.location.radius const zoneRadiusColor = selector.location?.radius
? computedStyles.getPropertyValue("--zone-radius-color") || ? computedStyles.getPropertyValue("--zone-radius-color") ||
computedStyles.getPropertyValue("--accent-color") computedStyles.getPropertyValue("--accent-color")
: undefined; : undefined;
@ -52,10 +52,10 @@ export class HaLocationSelector extends LitElement {
id: "location", id: "location",
latitude: value?.latitude || this.hass.config.latitude, latitude: value?.latitude || this.hass.config.latitude,
longitude: value?.longitude || this.hass.config.longitude, longitude: value?.longitude || this.hass.config.longitude,
radius: selector.location.radius ? value?.radius || 1000 : undefined, radius: selector.location?.radius ? value?.radius || 1000 : undefined,
radius_color: zoneRadiusColor, radius_color: zoneRadiusColor,
icon: icon:
selector.location.icon || selector.location.radius selector.location?.icon || selector.location?.radius
? "mdi:map-marker-radius" ? "mdi:map-marker-radius"
: "mdi:map-marker", : "mdi:map-marker",
location_editable: true, location_editable: true,

View File

@ -27,7 +27,7 @@ export class HaNumberSelector extends LitElement {
@property({ type: Boolean }) public disabled = false; @property({ type: Boolean }) public disabled = false;
protected render() { protected render() {
const isBox = this.selector.number.mode === "box"; const isBox = this.selector.number?.mode === "box";
return html` return html`
<div class="input"> <div class="input">
@ -37,10 +37,10 @@ export class HaNumberSelector extends LitElement {
? html`${this.label}${this.required ? " *" : ""}` ? html`${this.label}${this.required ? " *" : ""}`
: ""} : ""}
<ha-slider <ha-slider
.min=${this.selector.number.min} .min=${this.selector.number?.min}
.max=${this.selector.number.max} .max=${this.selector.number?.max}
.value=${this._value} .value=${this._value}
.step=${this.selector.number.step ?? 1} .step=${this.selector.number?.step ?? 1}
.disabled=${this.disabled} .disabled=${this.disabled}
.required=${this.required} .required=${this.required}
pin pin
@ -51,24 +51,26 @@ export class HaNumberSelector extends LitElement {
` `
: ""} : ""}
<ha-textfield <ha-textfield
.inputMode=${(this.selector.number.step || 1) % 1 !== 0 .inputMode=${(this.selector.number?.step || 1) % 1 !== 0
? "decimal" ? "decimal"
: "numeric"} : "numeric"}
.label=${this.selector.number.mode !== "box" ? undefined : this.label} .label=${this.selector.number?.mode !== "box"
? undefined
: this.label}
.placeholder=${this.placeholder} .placeholder=${this.placeholder}
class=${classMap({ single: this.selector.number.mode === "box" })} class=${classMap({ single: this.selector.number?.mode === "box" })}
.min=${this.selector.number.min} .min=${this.selector.number?.min}
.max=${this.selector.number.max} .max=${this.selector.number?.max}
.value=${this.value ?? ""} .value=${this.value ?? ""}
.step=${this.selector.number.step ?? 1} .step=${this.selector.number?.step ?? 1}
helperPersistent helperPersistent
.helper=${isBox ? this.helper : undefined} .helper=${isBox ? this.helper : undefined}
.disabled=${this.disabled} .disabled=${this.disabled}
.required=${this.required} .required=${this.required}
.suffix=${this.selector.number.unit_of_measurement} .suffix=${this.selector.number?.unit_of_measurement}
type="number" type="number"
autoValidate autoValidate
?no-spinner=${this.selector.number.mode !== "box"} ?no-spinner=${this.selector.number?.mode !== "box"}
@input=${this._handleInputChange} @input=${this._handleInputChange}
> >
</ha-textfield> </ha-textfield>
@ -80,7 +82,7 @@ export class HaNumberSelector extends LitElement {
} }
private get _value() { private get _value() {
return this.value ?? (this.selector.number.min || 0); return this.value ?? (this.selector.number?.min || 0);
} }
private _handleInputChange(ev) { private _handleInputChange(ev) {
@ -88,7 +90,7 @@ export class HaNumberSelector extends LitElement {
const value = const value =
ev.target.value === "" || isNaN(ev.target.value) ev.target.value === "" || isNaN(ev.target.value)
? this.required ? this.required
? this.selector.number.min || 0 ? this.selector.number?.min || 0
: undefined : undefined
: Number(ev.target.value); : Number(ev.target.value);
if (this.value === value) { if (this.value === value) {

View File

@ -9,6 +9,7 @@ import type { HomeAssistant } from "../../types";
import "../ha-checkbox"; import "../ha-checkbox";
import "../ha-chip"; import "../ha-chip";
import "../ha-chip-set"; import "../ha-chip-set";
import "../ha-combo-box";
import type { HaComboBox } from "../ha-combo-box"; import type { HaComboBox } from "../ha-combo-box";
import "../ha-formfield"; import "../ha-formfield";
import "../ha-radio"; import "../ha-radio";
@ -36,12 +37,13 @@ export class HaSelectSelector extends LitElement {
private _filter = ""; private _filter = "";
protected render() { protected render() {
const options = this.selector.select.options.map((option) => const options =
typeof option === "object" ? option : { value: option, label: option } this.selector.select?.options.map((option) =>
); typeof option === "object" ? option : { value: option, label: option }
) || [];
if (!this.selector.select.custom_value && this._mode === "list") { if (!this.selector.select?.custom_value && this._mode === "list") {
if (!this.selector.select.multiple) { if (!this.selector.select?.multiple) {
return html` return html`
<div> <div>
${this.label} ${this.label}
@ -82,7 +84,7 @@ export class HaSelectSelector extends LitElement {
`; `;
} }
if (this.selector.select.multiple) { if (this.selector.select?.multiple) {
const value = const value =
!this.value || this.value === "" ? [] : (this.value as string[]); !this.value || this.value === "" ? [] : (this.value as string[]);
@ -123,7 +125,7 @@ export class HaSelectSelector extends LitElement {
`; `;
} }
if (this.selector.select.custom_value) { if (this.selector.select?.custom_value) {
if ( if (
this.value !== undefined && this.value !== undefined &&
!options.find((option) => option.value === this.value) !options.find((option) => option.value === this.value)
@ -178,8 +180,8 @@ export class HaSelectSelector extends LitElement {
private get _mode(): "list" | "dropdown" { private get _mode(): "list" | "dropdown" {
return ( return (
this.selector.select.mode || this.selector.select?.mode ||
(this.selector.select.options.length < 6 ? "list" : "dropdown") ((this.selector.select?.options?.length || 0) < 6 ? "list" : "dropdown")
); );
} }
@ -243,7 +245,7 @@ export class HaSelectSelector extends LitElement {
return; return;
} }
if (!this.selector.select.multiple) { if (!this.selector.select?.multiple) {
fireEvent(this, "value-changed", { fireEvent(this, "value-changed", {
value: newValue, value: newValue,
}); });
@ -271,14 +273,14 @@ export class HaSelectSelector extends LitElement {
this._filter = ev?.detail.value || ""; this._filter = ev?.detail.value || "";
const filteredItems = this.comboBox.items?.filter((item) => { const filteredItems = this.comboBox.items?.filter((item) => {
if (this.selector.select.multiple && this.value?.includes(item.value)) { if (this.selector.select?.multiple && this.value?.includes(item.value)) {
return false; return false;
} }
const label = item.label || item.value; const label = item.label || item.value;
return label.toLowerCase().includes(this._filter?.toLowerCase()); return label.toLowerCase().includes(this._filter?.toLowerCase());
}); });
if (this._filter && this.selector.select.custom_value) { if (this._filter && this.selector.select?.custom_value) {
filteredItems?.unshift({ label: this._filter, value: this._filter }); filteredItems?.unshift({ label: this._filter, value: this._filter });
} }

View File

@ -30,9 +30,9 @@ export class HaSelectorState extends SubscribeMixin(LitElement) {
return html` return html`
<ha-entity-state-picker <ha-entity-state-picker
.hass=${this.hass} .hass=${this.hass}
.entityId=${this.selector.state.entity_id || .entityId=${this.selector.state?.entity_id ||
this.context?.filter_entity} this.context?.filter_entity}
.attribute=${this.selector.state.attribute || .attribute=${this.selector.state?.attribute ||
this.context?.filter_attribute} this.context?.filter_attribute}
.value=${this.value} .value=${this.value}
.label=${this.label} .label=${this.label}

View File

@ -64,8 +64,8 @@ export class HaTargetSelector extends SubscribeMixin(LitElement) {
super.updated(changedProperties); super.updated(changedProperties);
if ( if (
changedProperties.has("selector") && changedProperties.has("selector") &&
(this.selector.target.device?.integration || (this.selector.target?.device?.integration ||
this.selector.target.entity?.integration) && this.selector.target?.entity?.integration) &&
!this._entitySources !this._entitySources
) { ) {
fetchEntitySourcesWithCache(this.hass).then((sources) => { fetchEntitySourcesWithCache(this.hass).then((sources) => {
@ -76,8 +76,8 @@ export class HaTargetSelector extends SubscribeMixin(LitElement) {
protected render(): TemplateResult { protected render(): TemplateResult {
if ( if (
(this.selector.target.device?.integration || (this.selector.target?.device?.integration ||
this.selector.target.entity?.integration) && this.selector.target?.entity?.integration) &&
!this._entitySources !this._entitySources
) { ) {
return html``; return html``;
@ -94,7 +94,7 @@ export class HaTargetSelector extends SubscribeMixin(LitElement) {
} }
private _filterEntities = (entity: HassEntity): boolean => { private _filterEntities = (entity: HassEntity): boolean => {
if (!this.selector.target.entity) { if (!this.selector.target?.entity) {
return true; return true;
} }
@ -106,7 +106,7 @@ export class HaTargetSelector extends SubscribeMixin(LitElement) {
}; };
private _filterDevices = (device: DeviceRegistryEntry): boolean => { private _filterDevices = (device: DeviceRegistryEntry): boolean => {
if (!this.selector.target.device) { if (!this.selector.target?.device) {
return true; return true;
} }

View File

@ -39,7 +39,7 @@ export class HaTextSelector extends LitElement {
.disabled=${this.disabled} .disabled=${this.disabled}
@input=${this._handleChange} @input=${this._handleChange}
autocapitalize="none" autocapitalize="none"
.autocomplete=${this.selector.text.autocomplete} .autocomplete=${this.selector.text?.autocomplete}
spellcheck="false" spellcheck="false"
.required=${this.required} .required=${this.required}
autogrow autogrow
@ -59,7 +59,7 @@ export class HaTextSelector extends LitElement {
html`<div style="width: 24px"></div>` html`<div style="width: 24px"></div>`
: this.selector.text?.suffix} : this.selector.text?.suffix}
.required=${this.required} .required=${this.required}
.autocomplete=${this.selector.text.autocomplete} .autocomplete=${this.selector.text?.autocomplete}
></ha-textfield> ></ha-textfield>
${this.selector.text?.type === "password" ${this.selector.text?.type === "password"
? html`<ha-icon-button ? html`<ha-icon-button

View File

@ -24,7 +24,7 @@ export class HaSelectorUiAction extends LitElement {
.label=${this.label} .label=${this.label}
.hass=${this.hass} .hass=${this.hass}
.config=${this.value} .config=${this.value}
.actions=${this.selector["ui-action"].actions} .actions=${this.selector["ui-action"]?.actions}
.tooltipText=${this.helper} .tooltipText=${this.helper}
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
></hui-action-editor> ></hui-action-editor>

View File

@ -36,26 +36,26 @@ export type Selector =
export interface ActionSelector { export interface ActionSelector {
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
action: {}; action: {} | null;
} }
export interface AddonSelector { export interface AddonSelector {
addon: { addon: {
name?: string; name?: string;
slug?: string; slug?: string;
}; } | null;
} }
export interface SelectorDevice { export interface SelectorDevice {
integration?: DeviceSelector["device"]["integration"]; integration?: NonNullable<DeviceSelector["device"]>["integration"];
manufacturer?: DeviceSelector["device"]["manufacturer"]; manufacturer?: NonNullable<DeviceSelector["device"]>["manufacturer"];
model?: DeviceSelector["device"]["model"]; model?: NonNullable<DeviceSelector["device"]>["model"];
} }
export interface SelectorEntity { export interface SelectorEntity {
integration?: EntitySelector["entity"]["integration"]; integration?: NonNullable<EntitySelector["entity"]>["integration"];
domain?: EntitySelector["entity"]["domain"]; domain?: NonNullable<EntitySelector["entity"]>["domain"];
device_class?: EntitySelector["entity"]["device_class"]; device_class?: NonNullable<EntitySelector["entity"]>["device_class"];
} }
export interface AreaSelector { export interface AreaSelector {
@ -63,47 +63,47 @@ export interface AreaSelector {
entity?: SelectorEntity; entity?: SelectorEntity;
device?: SelectorDevice; device?: SelectorDevice;
multiple?: boolean; multiple?: boolean;
}; } | null;
} }
export interface AttributeSelector { export interface AttributeSelector {
attribute: { attribute: {
entity_id?: string; entity_id?: string;
hide_attributes?: readonly string[]; hide_attributes?: readonly string[];
}; } | null;
} }
export interface BooleanSelector { export interface BooleanSelector {
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
boolean: {}; boolean: {} | null;
} }
export interface ColorRGBSelector { export interface ColorRGBSelector {
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
color_rgb: {}; color_rgb: {} | null;
} }
export interface ColorTempSelector { export interface ColorTempSelector {
color_temp: { color_temp: {
min_mireds?: number; min_mireds?: number;
max_mireds?: number; max_mireds?: number;
}; } | null;
} }
export interface ConfigEntrySelector { export interface ConfigEntrySelector {
config_entry: { config_entry: {
integration?: string; integration?: string;
}; } | null;
} }
export interface DateSelector { export interface DateSelector {
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
date: {}; date: {} | null;
} }
export interface DateTimeSelector { export interface DateTimeSelector {
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
datetime: {}; datetime: {} | null;
} }
export interface DeviceSelector { export interface DeviceSelector {
@ -113,13 +113,13 @@ export interface DeviceSelector {
model?: string; model?: string;
entity?: SelectorEntity; entity?: SelectorEntity;
multiple?: boolean; multiple?: boolean;
}; } | null;
} }
export interface DurationSelector { export interface DurationSelector {
duration: { duration: {
enable_day?: boolean; enable_day?: boolean;
}; } | null;
} }
export interface EntitySelector { export interface EntitySelector {
@ -130,24 +130,24 @@ export interface EntitySelector {
multiple?: boolean; multiple?: boolean;
include_entities?: string[]; include_entities?: string[];
exclude_entities?: string[]; exclude_entities?: string[];
}; } | null;
} }
export interface FileSelector { export interface FileSelector {
file: { file: {
accept: string; accept: string;
}; } | null;
} }
export interface IconSelector { export interface IconSelector {
icon: { icon: {
placeholder?: string; placeholder?: string;
fallbackPath?: string; fallbackPath?: string;
}; } | null;
} }
export interface LocationSelector { export interface LocationSelector {
location: { radius?: boolean; icon?: string }; location: { radius?: boolean; icon?: string } | null;
} }
export interface LocationSelectorValue { export interface LocationSelectorValue {
@ -158,7 +158,7 @@ export interface LocationSelectorValue {
export interface MediaSelector { export interface MediaSelector {
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
media: {}; media: {} | null;
} }
export interface MediaSelectorValue { export interface MediaSelectorValue {
@ -176,7 +176,7 @@ export interface MediaSelectorValue {
export interface NavigationSelector { export interface NavigationSelector {
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
navigation: {}; navigation: {} | null;
} }
export interface NumberSelector { export interface NumberSelector {
@ -186,12 +186,12 @@ export interface NumberSelector {
step?: number; step?: number;
mode?: "box" | "slider"; mode?: "box" | "slider";
unit_of_measurement?: string; unit_of_measurement?: string;
}; } | null;
} }
export interface ObjectSelector { export interface ObjectSelector {
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
object: {}; object: {} | null;
} }
export interface SelectOption { export interface SelectOption {
@ -206,14 +206,14 @@ export interface SelectSelector {
custom_value?: boolean; custom_value?: boolean;
mode?: "list" | "dropdown"; mode?: "list" | "dropdown";
options: readonly string[] | readonly SelectOption[]; options: readonly string[] | readonly SelectOption[];
}; } | null;
} }
export interface StateSelector { export interface StateSelector {
state: { state: {
entity_id?: string; entity_id?: string;
attribute?: string; attribute?: string;
}; } | null;
} }
export interface StringSelector { export interface StringSelector {
@ -235,34 +235,34 @@ export interface StringSelector {
| "color"; | "color";
suffix?: string; suffix?: string;
autocomplete?: string; autocomplete?: string;
}; } | null;
} }
export interface TargetSelector { export interface TargetSelector {
target: { target: {
entity?: SelectorEntity; entity?: SelectorEntity;
device?: SelectorDevice; device?: SelectorDevice;
}; } | null;
} }
export interface TemplateSelector { export interface TemplateSelector {
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
template: {}; template: {} | null;
} }
export interface ThemeSelector { export interface ThemeSelector {
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
theme: {}; theme: {} | null;
} }
export interface TimeSelector { export interface TimeSelector {
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
time: {}; time: {} | null;
} }
export interface UiActionSelector { export interface UiActionSelector {
"ui-action": { "ui-action": {
actions?: UiAction[]; actions?: UiAction[];
}; } | null;
} }
export const filterSelectorDevices = ( export const filterSelectorDevices = (