Skip to content

Commit

Permalink
Use entities-picker in entity selector (home-assistant#11990)
Browse files Browse the repository at this point in the history
  • Loading branch information
balloob authored Mar 9, 2022
1 parent d968fe4 commit 9f1e9b4
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 78 deletions.
102 changes: 100 additions & 2 deletions gallery/src/pages/components/ha-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,98 @@ import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry";
import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor";
import { provideHass } from "../../../../src/fake_data/provide_hass";
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: {
title: string;
Expand Down Expand Up @@ -39,6 +131,7 @@ const SCHEMAS: {
icon: "Icon",
media: "Media",
location: "Location",
entities: "Entities",
},
schema: [
{ name: "addon", selector: { addon: {} } },
Expand Down Expand Up @@ -80,6 +173,10 @@ const SCHEMAS: {
name: "location",
selector: { location: { radius: true, icon: "mdi:home" } },
},
{
name: "entities",
selector: { entity: { multiple: true } },
},
],
},
{
Expand Down Expand Up @@ -320,9 +417,10 @@ class DemoHaForm extends LitElement {
const hass = provideHass(this);
hass.updateTranslations(null, "en");
hass.updateTranslations("config", "en");
hass.addEntities(ENTITIES);
mockEntityRegistry(hass);
mockDeviceRegistry(hass);
mockAreaRegistry(hass);
mockDeviceRegistry(hass, DEVICES);
mockAreaRegistry(hass, AREAS);
mockHassioSupervisor(hass);
}

Expand Down
6 changes: 5 additions & 1 deletion src/components/entity/ha-entities-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class HaEntitiesPickerLight extends LitElement {

@property({ attribute: "pick-entity-label" }) public pickEntityLabel?: string;

@property() public entityFilter?: HaEntityPickerEntityFilterFunc;

protected render(): TemplateResult {
if (!this.hass) {
return html``;
Expand Down Expand Up @@ -94,7 +96,9 @@ class HaEntitiesPickerLight extends LitElement {

private _entityFilter: HaEntityPickerEntityFilterFunc = (
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() {
return this.value || [];
Expand Down
81 changes: 6 additions & 75 deletions src/components/ha-selector/ha-selector-entity.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
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 { 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";
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
import { HomeAssistant } from "../../types";
import "../entity/ha-entity-picker";
import "../entity/ha-entities-picker";

@customElement("ha-selector-entity")
export class HaEntitySelector extends SubscribeMixin(LitElement) {
Expand Down Expand Up @@ -36,33 +35,13 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
></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
${this.label ? html`<label>${this.label}</label>` : ""}
<ha-entities-picker
.hass=${this.hass}
.value=${this.value}
.entityFilter=${this._filterEntities}
.disabled=${this.disabled}
allow-custom-entity
@value-changed=${this._valueChanged}
></ha-entity-picker>
></ha-entities-picker>
`;
}

Expand All @@ -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 => {
if (this.selector.entity?.domain) {
const filterDomain = this.selector.entity.domain;
Expand Down Expand Up @@ -123,43 +91,6 @@ 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 {
Expand Down

0 comments on commit 9f1e9b4

Please sign in to comment.