mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Use entities-picker in entity selector (#11990)
This commit is contained in:
parent
d968fe41ee
commit
9f1e9b43fe
@ -12,6 +12,98 @@ import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry";
|
|||||||
import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor";
|
import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor";
|
||||||
import { provideHass } from "../../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../../src/fake_data/provide_hass";
|
||||||
import { HomeAssistant } from "../../../../src/types";
|
import { HomeAssistant } from "../../../../src/types";
|
||||||
|
import { getEntity } from "../../../../src/fake_data/entity";
|
||||||
|
|
||||||
|
const ENTITIES = [
|
||||||
|
getEntity("alarm_control_panel", "alarm", "disarmed", {
|
||||||
|
friendly_name: "Alarm",
|
||||||
|
}),
|
||||||
|
getEntity("media_player", "livingroom", "playing", {
|
||||||
|
friendly_name: "Livingroom",
|
||||||
|
}),
|
||||||
|
getEntity("media_player", "lounge", "idle", {
|
||||||
|
friendly_name: "Lounge",
|
||||||
|
supported_features: 444983,
|
||||||
|
}),
|
||||||
|
getEntity("light", "bedroom", "on", {
|
||||||
|
friendly_name: "Bedroom",
|
||||||
|
}),
|
||||||
|
getEntity("switch", "coffee", "off", {
|
||||||
|
friendly_name: "Coffee",
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
const DEVICES = [
|
||||||
|
{
|
||||||
|
area_id: "bedroom",
|
||||||
|
configuration_url: null,
|
||||||
|
config_entries: ["config_entry_1"],
|
||||||
|
connections: [],
|
||||||
|
disabled_by: null,
|
||||||
|
entry_type: null,
|
||||||
|
id: "device_1",
|
||||||
|
identifiers: [["demo", "volume1"] as [string, string]],
|
||||||
|
manufacturer: null,
|
||||||
|
model: null,
|
||||||
|
name_by_user: null,
|
||||||
|
name: "Dishwasher",
|
||||||
|
sw_version: null,
|
||||||
|
hw_version: null,
|
||||||
|
via_device_id: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
area_id: "backyard",
|
||||||
|
configuration_url: null,
|
||||||
|
config_entries: ["config_entry_2"],
|
||||||
|
connections: [],
|
||||||
|
disabled_by: null,
|
||||||
|
entry_type: null,
|
||||||
|
id: "device_2",
|
||||||
|
identifiers: [["demo", "pwm1"] as [string, string]],
|
||||||
|
manufacturer: null,
|
||||||
|
model: null,
|
||||||
|
name_by_user: null,
|
||||||
|
name: "Lamp",
|
||||||
|
sw_version: null,
|
||||||
|
hw_version: null,
|
||||||
|
via_device_id: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
area_id: null,
|
||||||
|
configuration_url: null,
|
||||||
|
config_entries: ["config_entry_3"],
|
||||||
|
connections: [],
|
||||||
|
disabled_by: null,
|
||||||
|
entry_type: null,
|
||||||
|
id: "device_3",
|
||||||
|
identifiers: [["demo", "pwm1"] as [string, string]],
|
||||||
|
manufacturer: null,
|
||||||
|
model: null,
|
||||||
|
name_by_user: "User name",
|
||||||
|
name: "Technical name",
|
||||||
|
sw_version: null,
|
||||||
|
hw_version: null,
|
||||||
|
via_device_id: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const AREAS = [
|
||||||
|
{
|
||||||
|
area_id: "backyard",
|
||||||
|
name: "Backyard",
|
||||||
|
picture: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
area_id: "bedroom",
|
||||||
|
name: "Bedroom",
|
||||||
|
picture: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
area_id: "livingroom",
|
||||||
|
name: "Livingroom",
|
||||||
|
picture: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const SCHEMAS: {
|
const SCHEMAS: {
|
||||||
title: string;
|
title: string;
|
||||||
@ -39,6 +131,7 @@ const SCHEMAS: {
|
|||||||
icon: "Icon",
|
icon: "Icon",
|
||||||
media: "Media",
|
media: "Media",
|
||||||
location: "Location",
|
location: "Location",
|
||||||
|
entities: "Entities",
|
||||||
},
|
},
|
||||||
schema: [
|
schema: [
|
||||||
{ name: "addon", selector: { addon: {} } },
|
{ name: "addon", selector: { addon: {} } },
|
||||||
@ -80,6 +173,10 @@ const SCHEMAS: {
|
|||||||
name: "location",
|
name: "location",
|
||||||
selector: { location: { radius: true, icon: "mdi:home" } },
|
selector: { location: { radius: true, icon: "mdi:home" } },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "entities",
|
||||||
|
selector: { entity: { multiple: true } },
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -320,9 +417,10 @@ class DemoHaForm extends LitElement {
|
|||||||
const hass = provideHass(this);
|
const hass = provideHass(this);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("config", "en");
|
hass.updateTranslations("config", "en");
|
||||||
|
hass.addEntities(ENTITIES);
|
||||||
mockEntityRegistry(hass);
|
mockEntityRegistry(hass);
|
||||||
mockDeviceRegistry(hass);
|
mockDeviceRegistry(hass, DEVICES);
|
||||||
mockAreaRegistry(hass);
|
mockAreaRegistry(hass, AREAS);
|
||||||
mockHassioSupervisor(hass);
|
mockHassioSupervisor(hass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ class HaEntitiesPickerLight extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: "pick-entity-label" }) public pickEntityLabel?: string;
|
@property({ attribute: "pick-entity-label" }) public pickEntityLabel?: string;
|
||||||
|
|
||||||
|
@property() public entityFilter?: HaEntityPickerEntityFilterFunc;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this.hass) {
|
if (!this.hass) {
|
||||||
return html``;
|
return html``;
|
||||||
@ -94,7 +96,9 @@ class HaEntitiesPickerLight extends LitElement {
|
|||||||
|
|
||||||
private _entityFilter: HaEntityPickerEntityFilterFunc = (
|
private _entityFilter: HaEntityPickerEntityFilterFunc = (
|
||||||
stateObj: HassEntity
|
stateObj: HassEntity
|
||||||
) => !this.value || !this.value.includes(stateObj.entity_id);
|
) =>
|
||||||
|
(!this.value || !this.value.includes(stateObj.entity_id)) &&
|
||||||
|
(!this.entityFilter || this.entityFilter(stateObj));
|
||||||
|
|
||||||
private get _currentEntities() {
|
private get _currentEntities() {
|
||||||
return this.value || [];
|
return this.value || [];
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
import { css, html, LitElement } from "lit";
|
import { html, LitElement } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { repeat } from "lit/directives/repeat";
|
|
||||||
import { fireEvent } from "../../common/dom/fire_event";
|
|
||||||
import { computeStateDomain } from "../../common/entity/compute_state_domain";
|
import { computeStateDomain } from "../../common/entity/compute_state_domain";
|
||||||
import { subscribeEntityRegistry } from "../../data/entity_registry";
|
import { subscribeEntityRegistry } from "../../data/entity_registry";
|
||||||
import { EntitySelector } from "../../data/selector";
|
import { EntitySelector } from "../../data/selector";
|
||||||
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import "../entity/ha-entity-picker";
|
import "../entity/ha-entity-picker";
|
||||||
|
import "../entity/ha-entities-picker";
|
||||||
|
|
||||||
@customElement("ha-selector-entity")
|
@customElement("ha-selector-entity")
|
||||||
export class HaEntitySelector extends SubscribeMixin(LitElement) {
|
export class HaEntitySelector extends SubscribeMixin(LitElement) {
|
||||||
@ -36,33 +35,13 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
|
|||||||
></ha-entity-picker>`;
|
></ha-entity-picker>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For multiple, the value is a list.
|
|
||||||
const value = this._normalizedValue as string[];
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
${this.label ? html`<div>${this.label}</div>` : ""}
|
${this.label ? html`<label>${this.label}</label>` : ""}
|
||||||
${repeat(
|
<ha-entities-picker
|
||||||
value,
|
|
||||||
(val) => val,
|
|
||||||
(entityId, index) => html`
|
|
||||||
<ha-entity-picker
|
|
||||||
.hass=${this.hass}
|
|
||||||
.value=${entityId}
|
|
||||||
.entityFilter=${this._filterEntities}
|
|
||||||
.disabled=${this.disabled}
|
|
||||||
.index=${index}
|
|
||||||
allow-custom-entity
|
|
||||||
@value-changed=${this._valueChanged}
|
|
||||||
></ha-entity-picker>
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
<ha-entity-picker
|
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
|
.value=${this.value}
|
||||||
.entityFilter=${this._filterEntities}
|
.entityFilter=${this._filterEntities}
|
||||||
.disabled=${this.disabled}
|
></ha-entities-picker>
|
||||||
allow-custom-entity
|
|
||||||
@value-changed=${this._valueChanged}
|
|
||||||
></ha-entity-picker>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,17 +60,6 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _normalizedValue() {
|
|
||||||
if (!this.selector.entity.multiple) {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.value) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
return Array.isArray(this.value) ? this.value : [this.value];
|
|
||||||
}
|
|
||||||
|
|
||||||
private _filterEntities = (entity: HassEntity): boolean => {
|
private _filterEntities = (entity: HassEntity): boolean => {
|
||||||
if (this.selector.entity?.domain) {
|
if (this.selector.entity?.domain) {
|
||||||
const filterDomain = this.selector.entity.domain;
|
const filterDomain = this.selector.entity.domain;
|
||||||
@ -123,43 +91,6 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// this method is only used when multiple: true
|
|
||||||
private _valueChanged(ev: any) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
|
|
||||||
// undefined = new value
|
|
||||||
const index = ev.target.index as number | undefined;
|
|
||||||
// undefined = remove
|
|
||||||
const newValue = ev.detail.value as string | undefined;
|
|
||||||
|
|
||||||
let updatedValue: string[] | undefined;
|
|
||||||
|
|
||||||
if (index === undefined) {
|
|
||||||
if (newValue) {
|
|
||||||
updatedValue = [...this._normalizedValue, newValue];
|
|
||||||
}
|
|
||||||
ev.target.value = "";
|
|
||||||
} else if (newValue) {
|
|
||||||
updatedValue = [...this._normalizedValue];
|
|
||||||
updatedValue[index] = newValue;
|
|
||||||
} else {
|
|
||||||
updatedValue = this._normalizedValue.filter((_, i) => i !== index);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updatedValue) {
|
|
||||||
fireEvent(this, "value-changed", {
|
|
||||||
value: updatedValue,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static styles = css`
|
|
||||||
ha-entity-picker + ha-entity-picker {
|
|
||||||
display: block;
|
|
||||||
margin-top: 16px;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user