From a0f3e4f7857e9e6513c757b362ec37dc1eb7de9a Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Mon, 2 Dec 2024 16:41:41 +0100 Subject: [PATCH] Add a label filter (#23081) * Label filter * adjust height * ci * Update src/components/ha-filter-labels.ts --------- Co-authored-by: Petar Petrov --- src/components/ha-filter-labels.ts | 46 ++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/components/ha-filter-labels.ts b/src/components/ha-filter-labels.ts index 6f5e8f5f3b..a199b308e5 100644 --- a/src/components/ha-filter-labels.ts +++ b/src/components/ha-filter-labels.ts @@ -1,6 +1,7 @@ import "@material/mwc-list/mwc-list"; import type { SelectedDetail } from "@material/mwc-list"; import "@material/mwc-menu/mwc-menu-surface"; +import memoizeOne from "memoize-one"; import { mdiCog, mdiFilterVariantRemove } from "@mdi/js"; import type { UnsubscribeFunc } from "home-assistant-js-websocket"; import type { CSSResultGroup } from "lit"; @@ -21,6 +22,8 @@ import "./ha-icon"; import "./ha-label"; import "./ha-icon-button"; import "./ha-list-item"; +import "./search-input-outlined"; +import { stringCompare } from "../common/string/compare"; @customElement("ha-filter-labels") export class HaFilterLabels extends SubscribeMixin(LitElement) { @@ -36,6 +39,8 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) { @state() private _shouldRender = false; + @state() private _filter?: string; + protected hassSubscribe(): (UnsubscribeFunc | Promise)[] { return [ subscribeLabelRegistry(this.hass.connection, (labels) => { @@ -44,6 +49,25 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) { ]; } + private _filteredLabels = memoizeOne( + // `_value` used to recalculate the memoization when the selection changes + (labels: LabelRegistryEntry[], filter: string | undefined, _value) => + labels + .filter( + (label) => + !filter || + label.name.toLowerCase().includes(filter) || + label.label_id.toLowerCase().includes(filter) + ) + .sort((a, b) => + stringCompare( + a.name || a.label_id, + b.name || b.label_id, + this.hass.locale.language + ) + ) + ); + protected render() { return html` ${this._shouldRender - ? html` + ? html` + ${repeat( - this._labels, + this._filteredLabels(this._labels, this._filter, this.value), (label) => label.label_id, (label) => { const color = label.color @@ -93,8 +122,7 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) { `; } )} - - ` + ` : nothing} ${this.expanded @@ -115,7 +143,7 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) { setTimeout(() => { if (!this.expanded) return; this.renderRoot.querySelector("mwc-list")!.style.height = - `${this.clientHeight - (49 + 48)}px`; + `${this.clientHeight - (49 + 48 + 32)}px`; }, 300); } } @@ -132,6 +160,10 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) { this.expanded = ev.detail.expanded; } + private _handleSearchChange(ev: CustomEvent) { + this._filter = ev.detail.value.toLowerCase(); + } + private async _labelSelected(ev: CustomEvent>>) { if (!ev.detail.index.size) { fireEvent(this, "data-table-filter-changed", { @@ -218,6 +250,10 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) { right: 0; left: 0; } + search-input-outlined { + display: block; + padding: 0 8px; + } `, ]; }