From bccc3512ff4804f93288dfcd53da99e991aaa377 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 20 Dec 2024 17:58:26 +0100 Subject: [PATCH] Add filter pane --- src/components/ha-filter-states.ts | 23 +++-- .../config/backup/ha-config-backup-backups.ts | 86 +++++++++++++++---- 2 files changed, 88 insertions(+), 21 deletions(-) diff --git a/src/components/ha-filter-states.ts b/src/components/ha-filter-states.ts index cb454ba7ab1d..8667e17df40e 100644 --- a/src/components/ha-filter-states.ts +++ b/src/components/ha-filter-states.ts @@ -1,9 +1,9 @@ import "@material/mwc-list/mwc-list"; -import type { SelectedDetail } from "@material/mwc-list"; +import type { List, SelectedDetail } from "@material/mwc-list"; import { mdiFilterVariantRemove } from "@mdi/js"; import type { CSSResultGroup } from "lit"; import { css, html, LitElement, nothing } from "lit"; -import { customElement, property, state } from "lit/decorators"; +import { customElement, property, query, state } from "lit/decorators"; import { fireEvent } from "../common/dom/fire_event"; import { haStyleScrollbar } from "../resources/styles"; import type { HomeAssistant } from "../types"; @@ -32,6 +32,8 @@ export class HaFilterStates extends LitElement { @state() private _shouldRender = false; + @query("mwc-list") private _list!: List; + protected render() { if (!this.states) { return nothing; @@ -84,12 +86,21 @@ export class HaFilterStates extends LitElement { `; } - protected updated(changed) { + protected willUpdate(changed) { if (changed.has("expanded") && this.expanded) { - setTimeout(() => { + this._shouldRender = true; + } + } + + protected updated(changed) { + if ((changed.has("expanded") || changed.has("states")) && this.expanded) { + setTimeout(async () => { if (!this.expanded) return; - this.renderRoot.querySelector("mwc-list")!.style.height = - `${this.clientHeight - 49}px`; + const list = this._list; + if (!list) { + return; + } + list.style.height = `${this.clientHeight - 49}px`; }, 300); } } diff --git a/src/panels/config/backup/ha-config-backup-backups.ts b/src/panels/config/backup/ha-config-backup-backups.ts index 6314f440d602..8face7b6c042 100644 --- a/src/panels/config/backup/ha-config-backup-backups.ts +++ b/src/panels/config/backup/ha-config-backup-backups.ts @@ -28,6 +28,7 @@ import type { import "../../../components/ha-button"; import "../../../components/ha-button-menu"; import "../../../components/ha-fab"; +import "../../../components/ha-filter-states"; import "../../../components/ha-icon"; import "../../../components/ha-icon-next"; import "../../../components/ha-icon-overflow-menu"; @@ -46,6 +47,7 @@ import { } from "../../../data/backup"; import type { ManagerStateEvent } from "../../../data/backup_manager"; import type { CloudStatus } from "../../../data/cloud"; +import type { DataTableFiltersValues } from "../../../data/data_table_filters"; import { extractApiErrorMessage } from "../../../data/hassio/common"; import { showAlertDialog, @@ -89,6 +91,14 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) { @state() private _selected: string[] = []; + @storage({ + storage: "sessionStorage", + key: "backups-table-filters", + state: true, + subscribe: false, + }) + private _filters: DataTableFiltersValues = {}; + @storage({ key: "backups-table-grouping", state: false, subscribe: false }) private _activeGrouping?: string = "formatted_type"; @@ -99,8 +109,6 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) { }) private _activeCollapsed: string[] = []; - @state() private _searchParams = new URLSearchParams(window.location.search); - @query("hass-tabs-subpage-data-table", true) private _dataTable!: HaTabsSubpageDataTable; @@ -108,7 +116,7 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) { super.connectedCallback(); window.addEventListener("location-changed", this._locationChanged); window.addEventListener("popstate", this._popState); - this._searchParams = new URLSearchParams(window.location.search); + this._setFiltersFromUrl(); } disconnectedCallback(): void { @@ -118,15 +126,11 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) { } private _locationChanged = () => { - if (window.location.search.substring(1) !== this._searchParams.toString()) { - this._searchParams = new URLSearchParams(window.location.search); - } + this._setFiltersFromUrl(); }; private _popState = () => { - if (window.location.search.substring(1) !== this._searchParams.toString()) { - this._searchParams = new URLSearchParams(window.location.search); - } + this._setFiltersFromUrl(); }; private _columns = memoizeOne( @@ -258,14 +262,18 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) { } private _data = memoizeOne( - (backups: BackupContent[], searchParams: URLSearchParams): BackupRow[] => { - const type = searchParams.get("type")?.toLowerCase(); + ( + backups: BackupContent[], + filters: DataTableFiltersValues + ): BackupRow[] => { + const typeFilter = filters["ha-filter-states"] as string[] | undefined; let filteredBackups = backups; - if (type) { + if (typeFilter?.length) { filteredBackups = filteredBackups.filter( (backup) => - backup.with_automatic_settings === (type === "automatic") || - (backup.with_automatic_settings === null && type === "manual") + (backup.with_automatic_settings && + typeFilter.includes("automatic")) || + (!backup.with_automatic_settings && typeFilter.includes("manual")) ); } return filteredBackups.map((backup) => ({ @@ -295,6 +303,15 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) { back-path="/config/backup/overview" clickable id="backup_id" + has-filters + .filters=${Object.values(this._filters).filter((filter) => + Array.isArray(filter) + ? filter.length + : filter && + Object.values(filter).some((val) => + Array.isArray(val) ? val.length : val + ) + ).length} selectable .selected=${this._selected.length} .initialGroupColumn=${this._activeGrouping} @@ -306,7 +323,7 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) { .route=${this.route} @row-click=${this._showBackupDetails} .columns=${this._columns(this.hass.localize)} - .data=${this._data(this.backups, this._searchParams)} + .data=${this._data(this.backups, this._filters)} .noDataText=${this.hass.localize("ui.panel.config.backup.no_backups")} .searchLabel=${this.hass.localize( "ui.panel.config.backup.picker.search" @@ -362,6 +379,16 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) { ` : nothing} + ${!this._needsOnboarding ? html` [ + { + value: "automatic", + label: "Automatic", + }, + { + value: "manual", + label: "Manual", + }, + ]); + + private _filterChanged(ev) { + const type = ev.target.localName; + this._filters = { ...this._filters, [type]: ev.detail.value }; + } + + private _setFiltersFromUrl() { + const searchParams = new URLSearchParams(window.location.search); + const type = searchParams.get("type"); + + if (!type) { + return; + } + + this._filters = { + "ha-filter-states": [type], + }; + } + private get _needsOnboarding() { return !this.config?.create_backup.password; }