Add filtering by related entity + fixes (#8801)

This commit is contained in:
Bram Kragten 2021-04-02 20:35:28 +02:00 committed by GitHub
parent 61aaaabcb5
commit c56b4fade3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 62 additions and 6 deletions

View File

@ -84,7 +84,8 @@
"@typescript-eslint/no-unused-vars": 0,
"@typescript-eslint/explicit-function-return-type": 0,
"@typescript-eslint/explicit-module-boundary-types": 0,
"@typescript-eslint/no-shadow": ["error"]
"@typescript-eslint/no-shadow": ["error"],
"lit/attribute-value-entities": 0
},
"plugins": ["disable", "import", "lit", "prettier", "@typescript-eslint"],
"processor": "disable/disable"

View File

@ -99,7 +99,7 @@ export class HaEntityPicker extends LitElement {
@property({ type: Boolean }) private _opened = false;
@query("vaadin-combo-box-light", true) private _comboBox!: HTMLElement;
@query("vaadin-combo-box-light", true) private comboBox!: HTMLElement;
public open() {
this.updateComplete.then(() => {
@ -208,7 +208,7 @@ export class HaEntityPicker extends LitElement {
this.entityFilter,
this.includeDeviceClasses
);
(this._comboBox as any).filteredItems = this._states;
(this.comboBox as any).filteredItems = this._states;
this._initedStates = true;
}
}
@ -296,7 +296,7 @@ export class HaEntityPicker extends LitElement {
private _filterChanged(ev: CustomEvent): void {
const filterString = ev.detail.value.toLowerCase();
(this._comboBox as any).filteredItems = this._states.filter(
(this.comboBox as any).filteredItems = this._states.filter(
(state) =>
state.entity_id.toLowerCase().includes(filterString) ||
computeStateName(state).toLowerCase().includes(filterString)

View File

@ -18,6 +18,9 @@ import type { HomeAssistant } from "../types";
import "./ha-svg-icon";
import "./ha-area-picker";
import "./device/ha-device-picker";
import "./entity/ha-entity-picker";
import { computeStateName } from "../common/entity/compute_state_name";
import { computeDeviceName } from "../data/device_registry";
declare global {
// for fire event
@ -33,6 +36,7 @@ declare global {
interface FilterValue {
area?: string;
device?: string;
entity?: string;
}
@customElement("ha-button-related-filter-menu")
@ -47,6 +51,14 @@ export class HaRelatedFilterButtonMenu extends LitElement {
@property({ attribute: false }) public value?: FilterValue;
/**
* Show no entities of these domains.
* @type {Array}
* @attr exclude-domains
*/
@property({ type: Array, attribute: "exclude-domains" })
public excludeDomains?: string[];
@internalProperty() private _open = false;
protected render(): TemplateResult {
@ -78,6 +90,15 @@ export class HaRelatedFilterButtonMenu extends LitElement {
.value=${this.value?.device}
@value-changed=${this._devicePicked}
></ha-device-picker>
<ha-entity-picker
.label=${this.hass.localize(
"ui.components.related-filter-menu.filter_by_entity"
)}
.hass=${this.hass}
.value=${this.value?.entity}
.excludeDomains=${this.excludeDomains}
@value-changed=${this._entityPicked}
></ha-entity-picker>
</mwc-menu-surface>
`;
}
@ -93,6 +114,25 @@ export class HaRelatedFilterButtonMenu extends LitElement {
this._open = false;
}
private async _entityPicked(ev: CustomEvent) {
const entityId = ev.detail.value;
if (!entityId) {
fireEvent(this, "related-changed", { value: undefined });
return;
}
const filter = this.hass.localize(
"ui.components.related-filter-menu.filtered_by_entity",
"entity_name",
computeStateName((ev.currentTarget as any).comboBox.selectedItem)
);
const items = await findRelated(this.hass, "entity", entityId);
fireEvent(this, "related-changed", {
value: { entity: entityId },
filter,
items,
});
}
private async _devicePicked(ev: CustomEvent) {
const deviceId = ev.detail.value;
if (!deviceId) {
@ -102,7 +142,10 @@ export class HaRelatedFilterButtonMenu extends LitElement {
const filter = this.hass.localize(
"ui.components.related-filter-menu.filtered_by_device",
"device_name",
(ev.currentTarget as any).comboBox.selectedItem.name
computeDeviceName(
(ev.currentTarget as any).comboBox.selectedItem,
this.hass
)
);
const items = await findRelated(this.hass, "device", deviceId);
@ -142,7 +185,8 @@ export class HaRelatedFilterButtonMenu extends LitElement {
position: static;
}
ha-area-picker,
ha-device-picker {
ha-device-picker,
ha-entity-picker {
display: block;
width: 300px;
padding: 4px 16px;

View File

@ -261,6 +261,7 @@ class HaAutomationPicker extends LitElement {
.narrow=${this.narrow}
.hass=${this.hass}
.value=${this._filterValue}
exclude-domains='["automation"]'
@related-changed=${this._relatedFilterChanged}
>
</ha-button-related-filter-menu>

View File

@ -58,6 +58,9 @@ class HaSceneDashboard extends LitElement {
private _scenes = memoizeOne(
(scenes: SceneEntity[], filteredScenes?: string[] | null) => {
if (filteredScenes === null) {
return [];
}
return (filteredScenes
? scenes.filter((scene) => filteredScenes!.includes(scene.entity_id))
: scenes
@ -183,6 +186,7 @@ class HaSceneDashboard extends LitElement {
.narrow=${this.narrow}
.hass=${this.hass}
.value=${this._filterValue}
exclude-domains='["scene"]'
@related-changed=${this._relatedFilterChanged}
>
</ha-button-related-filter-menu>

View File

@ -56,6 +56,9 @@ class HaScriptPicker extends LitElement {
private _scripts = memoizeOne(
(scripts: HassEntity[], filteredScripts?: string[] | null) => {
if (filteredScripts === null) {
return [];
}
return (filteredScripts
? scripts.filter((script) =>
filteredScripts!.includes(script.entity_id)
@ -193,6 +196,7 @@ class HaScriptPicker extends LitElement {
.narrow=${this.narrow}
.hass=${this.hass}
.value=${this._filterValue}
exclude-domains='["script"]'
@related-changed=${this._relatedFilterChanged}
>
</ha-button-related-filter-menu>

View File

@ -399,8 +399,10 @@
}
},
"related-filter-menu": {
"filter_by_entity": "Filter by entity",
"filter_by_device": "Filter by device",
"filter_by_area": "Filter by area",
"filtered_by_entity": "entity: {entity_name}",
"filtered_by_device": "device: {device_name}",
"filtered_by_area": "area: {area_name}"
},