mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-13 12:26:35 +00:00
Add filtering by related entity + fixes (#8801)
This commit is contained in:
parent
61aaaabcb5
commit
c56b4fade3
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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}"
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user