Allow selecting multiple entities (#11986)

This commit is contained in:
Paulus Schoutsen 2022-03-08 10:09:45 -08:00 committed by GitHub
parent 68e7ce1883
commit fc6b594a27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 97 additions and 9 deletions

View File

@ -175,6 +175,12 @@ const SCHEMAS: {
},
},
},
{
name: "Multiples",
input: {
entity: { name: "Entity", selector: { entity: { multiple: true } } },
},
},
];
@customElement("demo-components-ha-selector")

View File

@ -1,6 +1,8 @@
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
import { html, LitElement } from "lit";
import { css, html, LitElement } from "lit";
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 { subscribeEntityRegistry } from "../../data/entity_registry";
import { EntitySelector } from "../../data/selector";
@ -23,14 +25,45 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
@property({ type: Boolean }) public disabled = false;
protected render() {
return html`<ha-entity-picker
.hass=${this.hass}
.value=${this.value}
.label=${this.label}
.entityFilter=${this._filterEntities}
.disabled=${this.disabled}
allow-custom-entity
></ha-entity-picker>`;
if (!this.selector.entity.multiple) {
return html`<ha-entity-picker
.hass=${this.hass}
.value=${this.value}
.label=${this.label}
.entityFilter=${this._filterEntities}
.disabled=${this.disabled}
allow-custom-entity
></ha-entity-picker>`;
}
// For multiple, the value is a list.
const value = this._normalizedValue as string[];
return html`
${this.label ? html`<div>${this.label}</div>` : ""}
${repeat(
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}
.entityFilter=${this._filterEntities}
.disabled=${this.disabled}
allow-custom-entity
@value-changed=${this._valueChanged}
></ha-entity-picker>
`;
}
public hassSubscribe(): UnsubscribeFunc[] {
@ -48,6 +81,17 @@ 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 => {
if (this.selector.entity?.domain) {
const filterDomain = this.selector.entity.domain;
@ -79,6 +123,43 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
}
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 {

View File

@ -23,6 +23,7 @@ export interface EntitySelector {
integration?: string;
domain?: string | string[];
device_class?: string;
multiple?: boolean;
};
}