Prevent duplicate entities from being chosen in the target picker (#14882)

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
fixes undefined
This commit is contained in:
karwosts 2022-12-28 05:24:32 -08:00 committed by GitHub
parent 6a15216104
commit 1198f983aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 6 deletions

View File

@ -84,6 +84,14 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
@property({ type: Array, attribute: "include-device-classes" }) @property({ type: Array, attribute: "include-device-classes" })
public includeDeviceClasses?: string[]; public includeDeviceClasses?: string[];
/**
* List of devices to be excluded.
* @type {Array}
* @attr exclude-devices
*/
@property({ type: Array, attribute: "exclude-devices" })
public excludeDevices?: string[];
@property() public deviceFilter?: HaDevicePickerDeviceFilterFunc; @property() public deviceFilter?: HaDevicePickerDeviceFilterFunc;
@property({ type: Boolean }) public disabled?: boolean; @property({ type: Boolean }) public disabled?: boolean;
@ -104,7 +112,8 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
includeDomains: this["includeDomains"], includeDomains: this["includeDomains"],
excludeDomains: this["excludeDomains"], excludeDomains: this["excludeDomains"],
includeDeviceClasses: this["includeDeviceClasses"], includeDeviceClasses: this["includeDeviceClasses"],
deviceFilter: this["deviceFilter"] deviceFilter: this["deviceFilter"],
excludeDevices: this["excludeDevices"]
): Device[] => { ): Device[] => {
if (!devices.length) { if (!devices.length) {
return [ return [
@ -164,6 +173,12 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
}); });
} }
if (excludeDevices) {
inputDevices = inputDevices.filter(
(device) => !excludeDevices!.includes(device.id)
);
}
if (includeDeviceClasses) { if (includeDeviceClasses) {
inputDevices = inputDevices.filter((device) => { inputDevices = inputDevices.filter((device) => {
const devEntities = deviceEntityLookup[device.id]; const devEntities = deviceEntityLookup[device.id];
@ -258,7 +273,8 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
this.includeDomains, this.includeDomains,
this.excludeDomains, this.excludeDomains,
this.includeDeviceClasses, this.includeDeviceClasses,
this.deviceFilter this.deviceFilter,
this.excludeDevices
); );
} }
} }

View File

@ -73,6 +73,14 @@ export class HaAreaPicker extends LitElement {
@property({ type: Array, attribute: "include-device-classes" }) @property({ type: Array, attribute: "include-device-classes" })
public includeDeviceClasses?: string[]; public includeDeviceClasses?: string[];
/**
* List of areas to be excluded.
* @type {Array}
* @attr exclude-areas
*/
@property({ type: Array, attribute: "exclude-areas" })
public excludeAreas?: string[];
@property() public deviceFilter?: HaDevicePickerDeviceFilterFunc; @property() public deviceFilter?: HaDevicePickerDeviceFilterFunc;
@property() public entityFilter?: (entity: EntityRegistryEntry) => boolean; @property() public entityFilter?: (entity: EntityRegistryEntry) => boolean;
@ -109,7 +117,8 @@ export class HaAreaPicker extends LitElement {
includeDeviceClasses: this["includeDeviceClasses"], includeDeviceClasses: this["includeDeviceClasses"],
deviceFilter: this["deviceFilter"], deviceFilter: this["deviceFilter"],
entityFilter: this["entityFilter"], entityFilter: this["entityFilter"],
noAdd: this["noAdd"] noAdd: this["noAdd"],
excludeAreas: this["excludeAreas"]
): AreaRegistryEntry[] => { ): AreaRegistryEntry[] => {
if (!areas.length) { if (!areas.length) {
return [ return [
@ -235,6 +244,12 @@ export class HaAreaPicker extends LitElement {
outputAreas = areas.filter((area) => areaIds!.includes(area.area_id)); outputAreas = areas.filter((area) => areaIds!.includes(area.area_id));
} }
if (excludeAreas) {
outputAreas = outputAreas.filter(
(area) => !excludeAreas!.includes(area.area_id)
);
}
if (!outputAreas.length) { if (!outputAreas.length) {
outputAreas = [ outputAreas = [
{ {
@ -264,7 +279,7 @@ export class HaAreaPicker extends LitElement {
(this._init && changedProps.has("_opened") && this._opened) (this._init && changedProps.has("_opened") && this._opened)
) { ) {
this._init = true; this._init = true;
(this.comboBox as any).items = this._getAreas( const areas = this._getAreas(
Object.values(this.hass.areas), Object.values(this.hass.areas),
Object.values(this.hass.devices), Object.values(this.hass.devices),
Object.values(this.hass.entities), Object.values(this.hass.entities),
@ -273,8 +288,11 @@ export class HaAreaPicker extends LitElement {
this.includeDeviceClasses, this.includeDeviceClasses,
this.deviceFilter, this.deviceFilter,
this.entityFilter, this.entityFilter,
this.noAdd this.noAdd,
this.excludeAreas
); );
(this.comboBox as any).items = areas;
(this.comboBox as any).filteredItems = areas;
} }
} }
@ -384,7 +402,8 @@ export class HaAreaPicker extends LitElement {
this.includeDeviceClasses, this.includeDeviceClasses,
this.deviceFilter, this.deviceFilter,
this.entityFilter, this.entityFilter,
this.noAdd this.noAdd,
this.excludeAreas
); );
await this.updateComplete; await this.updateComplete;
await this.comboBox.updateComplete; await this.comboBox.updateComplete;

View File

@ -345,6 +345,7 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
.entityFilter=${this.entityRegFilter} .entityFilter=${this.entityRegFilter}
.includeDeviceClasses=${this.includeDeviceClasses} .includeDeviceClasses=${this.includeDeviceClasses}
.includeDomains=${this.includeDomains} .includeDomains=${this.includeDomains}
.excludeAreas=${ensureArray(this.value?.area_id)}
@value-changed=${this._targetPicked} @value-changed=${this._targetPicked}
></ha-area-picker> ></ha-area-picker>
`; `;
@ -360,6 +361,7 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
.deviceFilter=${this.deviceFilter} .deviceFilter=${this.deviceFilter}
.includeDeviceClasses=${this.includeDeviceClasses} .includeDeviceClasses=${this.includeDeviceClasses}
.includeDomains=${this.includeDomains} .includeDomains=${this.includeDomains}
.excludeDevices=${ensureArray(this.value?.device_id)}
@value-changed=${this._targetPicked} @value-changed=${this._targetPicked}
></ha-device-picker> ></ha-device-picker>
`; `;
@ -375,6 +377,7 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
.entityFilter=${this.entityFilter} .entityFilter=${this.entityFilter}
.includeDeviceClasses=${this.includeDeviceClasses} .includeDeviceClasses=${this.includeDeviceClasses}
.includeDomains=${this.includeDomains} .includeDomains=${this.includeDomains}
.excludeEntities=${ensureArray(this.value?.entity_id)}
@value-changed=${this._targetPicked} @value-changed=${this._targetPicked}
allow-custom-entity allow-custom-entity
></ha-entity-picker> ></ha-entity-picker>
@ -392,6 +395,13 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
const target = ev.currentTarget; const target = ev.currentTarget;
target.value = ""; target.value = "";
this._addMode = undefined; this._addMode = undefined;
if (
this.value &&
this.value[target.type] &&
ensureArray(this.value[target.type]).includes(value)
) {
return;
}
fireEvent(this, "value-changed", { fireEvent(this, "value-changed", {
value: this.value value: this.value
? { ? {