From 33c7e0fa2d5e432b71496a44ad979d106b98e52d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 2 Apr 2024 10:55:22 -0400 Subject: [PATCH 01/10] Hide conversation entities from default dashboard (#20327) --- src/panels/lovelace/common/generate-lovelace-config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/panels/lovelace/common/generate-lovelace-config.ts b/src/panels/lovelace/common/generate-lovelace-config.ts index 8af49cabdc..819001bb53 100644 --- a/src/panels/lovelace/common/generate-lovelace-config.ts +++ b/src/panels/lovelace/common/generate-lovelace-config.ts @@ -35,6 +35,7 @@ import { ButtonsHeaderFooterConfig } from "../header-footer/types"; const HIDE_DOMAIN = new Set([ "automation", "configurator", + "conversation", "device_tracker", "geo_location", "persistent_notification", From 56d328b4db1e74c08faae3803ea9841c464b490b Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 2 Apr 2024 18:33:30 +0200 Subject: [PATCH 02/10] Fix error in console when taking control of the strategy (#20329) --- .../dialogs/dialog-dashboard-strategy-editor.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/panels/lovelace/editor/dashboard-strategy-editor/dialogs/dialog-dashboard-strategy-editor.ts b/src/panels/lovelace/editor/dashboard-strategy-editor/dialogs/dialog-dashboard-strategy-editor.ts index 0a826b11b0..f2b2320283 100644 --- a/src/panels/lovelace/editor/dashboard-strategy-editor/dialogs/dialog-dashboard-strategy-editor.ts +++ b/src/panels/lovelace/editor/dashboard-strategy-editor/dialogs/dialog-dashboard-strategy-editor.ts @@ -172,12 +172,14 @@ class DialogDashboardStrategyEditor extends LitElement { `; } - private _takeControl() { + private _takeControl(ev) { + ev.stopPropagation(); this._params!.takeControl(); this.closeDialog(); } - private _showRawConfigEditor() { + private _showRawConfigEditor(ev) { + ev.stopPropagation(); this._params!.showRawConfigEditor(); this.closeDialog(); } From ed1a69071bb13c388560f7be3891d9289096405d Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 2 Apr 2024 19:05:01 +0200 Subject: [PATCH 03/10] Replace add label by manage labels in filters (#20330) --- src/components/ha-filter-labels.ts | 17 +++++++---------- src/translations/en.json | 1 + 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/components/ha-filter-labels.ts b/src/components/ha-filter-labels.ts index 43c3c10098..c28b3fabe1 100644 --- a/src/components/ha-filter-labels.ts +++ b/src/components/ha-filter-labels.ts @@ -1,19 +1,18 @@ import { SelectedDetail } from "@material/mwc-list"; import "@material/mwc-menu/mwc-menu-surface"; -import { mdiPlus } from "@mdi/js"; +import { mdiCog } from "@mdi/js"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { CSSResultGroup, LitElement, css, html, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { repeat } from "lit/directives/repeat"; import { computeCssColor } from "../common/color/compute-color"; import { fireEvent } from "../common/dom/fire_event"; +import { navigate } from "../common/navigate"; import { LabelRegistryEntry, - createLabelRegistryEntry, subscribeLabelRegistry, } from "../data/label_registry"; import { SubscribeMixin } from "../mixins/subscribe-mixin"; -import { showLabelDetailDialog } from "../panels/config/labels/show-dialog-label-detail"; import { haStyleScrollbar } from "../resources/styles"; import type { HomeAssistant } from "../types"; import "./ha-check-list-item"; @@ -95,11 +94,11 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) { ${this.expanded ? html` - - ${this.hass.localize("ui.panel.config.labels.add_label")} + + ${this.hass.localize("ui.panel.config.labels.manage_labels")} ` : nothing} `; @@ -115,10 +114,8 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) { } } - private _addLabel() { - showLabelDetailDialog(this, { - createEntry: (values) => createLabelRegistryEntry(this.hass, values), - }); + private _manageLabels() { + navigate("/config/labels"); } private _expandedWillChange(ev) { diff --git a/src/translations/en.json b/src/translations/en.json index 2f0ed5d46c..f41492dce9 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1962,6 +1962,7 @@ "color": "Color" }, "add_label": "Add label", + "manage_labels": "Manage labels", "no_labels": "You don't have any labels", "introduction": "Labels can help you organize your areas, devices and entities. They can be used to filter in the UI, or use them as a target in automations.", "introduction2": "Go to the area, device or entity you want to add a label to, and click on the edit button to assign labels to them.", From 9bef5c2af99ed4951980089eb2d86edd4821e3fc Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 2 Apr 2024 19:42:54 +0200 Subject: [PATCH 04/10] Add clear button to search field (#20332) --- src/components/search-input-outlined.ts | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/components/search-input-outlined.ts b/src/components/search-input-outlined.ts index f949323cac..5e40df35c9 100644 --- a/src/components/search-input-outlined.ts +++ b/src/components/search-input-outlined.ts @@ -1,5 +1,12 @@ -import { mdiMagnify } from "@mdi/js"; -import { CSSResultGroup, LitElement, TemplateResult, css, html } from "lit"; +import { mdiClose, mdiMagnify } from "@mdi/js"; +import { + CSSResultGroup, + LitElement, + TemplateResult, + css, + html, + nothing, +} from "lit"; import { customElement, property, query } from "lit/decorators"; import { fireEvent } from "../common/dom/fire_event"; import { HomeAssistant } from "../types"; @@ -54,6 +61,15 @@ class SearchInputOutlined extends LitElement { .path=${mdiMagnify} > + ${this.filter + ? html` + ` + : nothing} `; } @@ -66,12 +82,17 @@ class SearchInputOutlined extends LitElement { this._filterChanged(e.target.value); } + private async _clearSearch() { + this._filterChanged(""); + } + static get styles(): CSSResultGroup { return css` :host { display: inline-flex; /* For iOS */ z-index: 0; + --mdc-icon-button-size: 24px; } ha-outlined-text-field { display: block; From 41fdf31e34c5ba31bc68cb059f4901c17befd448 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 2 Apr 2024 20:39:39 +0200 Subject: [PATCH 05/10] Check for entity state and entity string in conditional card (#20331) Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com> --- .../lovelace/common/validate-condition.ts | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/panels/lovelace/common/validate-condition.ts b/src/panels/lovelace/common/validate-condition.ts index 00294ff9fe..908d5719dd 100644 --- a/src/panels/lovelace/common/validate-condition.ts +++ b/src/panels/lovelace/common/validate-condition.ts @@ -58,18 +58,12 @@ export interface AndCondition extends BaseCondition { function getValueFromEntityId( hass: HomeAssistant, - value: string | string[] -): string | string[] { - if ( - typeof value === "string" && - isValidEntityId(value) && - hass.states[value] - ) { - value = hass.states[value]?.state; - } else if (Array.isArray(value)) { - value = value.map((v) => getValueFromEntityId(hass, v) as string); + value: string +): string | undefined { + if (isValidEntityId(value) && hass.states[value]) { + return hass.states[value]?.state; } - return value; + return undefined; } function checkStateCondition( @@ -83,8 +77,17 @@ function checkStateCondition( let value = condition.state ?? condition.state_not; // Handle entity_id, UI should be updated for conditionnal card (filters does not have UI for now) - if (Array.isArray(value) || typeof value === "string") { - value = getValueFromEntityId(hass, value); + if (Array.isArray(value)) { + const entityValues = value + .map((v) => getValueFromEntityId(hass, v)) + .filter((v): v is string => v !== undefined); + value = [...value, ...entityValues]; + } else if (typeof value === "string") { + const entityValue = getValueFromEntityId(hass, value); + value = [value]; + if (entityValue) { + value.push(entityValue); + } } return condition.state != null @@ -103,10 +106,10 @@ function checkStateNumericCondition( // Handle entity_id, UI should be updated for conditionnal card (filters does not have UI for now) if (typeof above === "string") { - above = getValueFromEntityId(hass, above) as string; + above = getValueFromEntityId(hass, above) ?? above; } if (typeof below === "string") { - below = getValueFromEntityId(hass, below) as string; + below = getValueFromEntityId(hass, below) ?? below; } const numericState = Number(state); From 5b86b1277f4c9d9cb9465b8007d806923dc242fc Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 2 Apr 2024 21:41:56 +0200 Subject: [PATCH 06/10] Add edit button to areas in area dashboard + color add floor fab (#20339) --- .../config/areas/ha-config-areas-dashboard.ts | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/panels/config/areas/ha-config-areas-dashboard.ts b/src/panels/config/areas/ha-config-areas-dashboard.ts index 875e13367b..12584b4f22 100644 --- a/src/panels/config/areas/ha-config-areas-dashboard.ts +++ b/src/panels/config/areas/ha-config-areas-dashboard.ts @@ -271,7 +271,14 @@ export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) { ? html`` : ""} -

${area.name}

+
+ ${area.name} + +
${formatListWithAnds( @@ -305,6 +312,16 @@ export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) { loadAreaRegistryDetailDialog(); } + private _openAreaDetails(ev) { + ev.preventDefault(); + const area = ev.currentTarget.area; + showAreaRegistryDetailDialog(this, { + entry: area, + updateEntry: async (values) => + updateAreaRegistryEntry(this.hass!, area.area_id, values), + }); + } + private async _areaMoved(ev) { const areasAndFloors = this._processAreas( this.hass.areas, @@ -469,8 +486,10 @@ export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) { min-height: 16px; color: var(--secondary-text-color); } - .floor { - --primary-color: var(--secondary-text-color); + .card-header { + display: flex; + justify-content: space-between; + align-items: center; } .warning { color: var(--error-color); From 1e2c1d1464c76f7bbcd637ad4201f36f68aca6a5 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 2 Apr 2024 21:46:21 +0200 Subject: [PATCH 07/10] Add search to device and entity filters (#20341) --- src/components/ha-filter-devices.ts | 87 +++++++++++++++++++--------- src/components/ha-filter-entities.ts | 67 +++++++++++++++------ 2 files changed, 108 insertions(+), 46 deletions(-) diff --git a/src/components/ha-filter-devices.ts b/src/components/ha-filter-devices.ts index 4b9f2bebc4..de5f5d9c78 100644 --- a/src/components/ha-filter-devices.ts +++ b/src/components/ha-filter-devices.ts @@ -13,10 +13,11 @@ import { stringCompare } from "../common/string/compare"; import { computeDeviceName } from "../data/device_registry"; import { findRelated, RelatedResult } from "../data/search"; import { haStyleScrollbar } from "../resources/styles"; -import type { HomeAssistant } from "../types"; -import "./ha-expansion-panel"; -import "./ha-check-list-item"; import { loadVirtualizer } from "../resources/virtualizer"; +import type { HomeAssistant } from "../types"; +import "./ha-check-list-item"; +import "./ha-expansion-panel"; +import "./search-input-outlined"; @customElement("ha-filter-devices") export class HaFilterDevices extends LitElement { @@ -32,6 +33,8 @@ export class HaFilterDevices extends LitElement { @state() private _shouldRender = false; + @state() private _filter?: string; + public willUpdate(properties: PropertyValues) { super.willUpdate(properties); @@ -55,15 +58,25 @@ export class HaFilterDevices extends LitElement { : nothing}
${this._shouldRender - ? html` - - - ` + + + + + ` : nothing} `; @@ -72,12 +85,14 @@ export class HaFilterDevices extends LitElement { private _keyFunction = (device) => device?.id; private _renderItem = (device) => - html` - ${computeDeviceName(device, this.hass)} - `; + !device + ? nothing + : html` + ${computeDeviceName(device, this.hass)} + `; private _handleItemClick(ev) { const listItem = ev.target.closest("ha-check-list-item"); @@ -99,7 +114,7 @@ export class HaFilterDevices extends LitElement { setTimeout(() => { if (!this.expanded) return; this.renderRoot.querySelector("mwc-list")!.style.height = - `${this.clientHeight - 49}px`; + `${this.clientHeight - 49 - 32}px`; // 32px is the height of the search input }, 300); } } @@ -112,16 +127,28 @@ export class HaFilterDevices extends LitElement { this.expanded = ev.detail.expanded; } - private _devices = memoizeOne((devices: HomeAssistant["devices"], _value) => { - const values = Object.values(devices); - return values.sort((a, b) => - stringCompare( - a.name_by_user || a.name || "", - b.name_by_user || b.name || "", - this.hass.locale.language - ) - ); - }); + private _handleSearchChange(ev: CustomEvent) { + this._filter = ev.detail.value.toLowerCase(); + } + + private _devices = memoizeOne( + (devices: HomeAssistant["devices"], filter: string, _value) => { + const values = Object.values(devices); + return values + .filter( + (device) => + !filter || + computeDeviceName(device, this.hass).toLowerCase().includes(filter) + ) + .sort((a, b) => + stringCompare( + computeDeviceName(a, this.hass), + computeDeviceName(b, this.hass), + this.hass.locale.language + ) + ); + } + ); private async _findRelated() { const relatedPromises: Promise[] = []; @@ -197,6 +224,10 @@ export class HaFilterDevices extends LitElement { ha-check-list-item { width: 100%; } + search-input-outlined { + display: block; + padding: 0 8px; + } `, ]; } diff --git a/src/components/ha-filter-entities.ts b/src/components/ha-filter-entities.ts index 2cffd99456..15d9b2f391 100644 --- a/src/components/ha-filter-entities.ts +++ b/src/components/ha-filter-entities.ts @@ -14,10 +14,11 @@ import { computeStateName } from "../common/entity/compute_state_name"; import { stringCompare } from "../common/string/compare"; import { findRelated, RelatedResult } from "../data/search"; import { haStyleScrollbar } from "../resources/styles"; -import type { HomeAssistant } from "../types"; -import "./ha-state-icon"; -import "./ha-check-list-item"; import { loadVirtualizer } from "../resources/virtualizer"; +import type { HomeAssistant } from "../types"; +import "./ha-check-list-item"; +import "./ha-state-icon"; +import "./search-input-outlined"; @customElement("ha-filter-entities") export class HaFilterEntities extends LitElement { @@ -33,6 +34,8 @@ export class HaFilterEntities extends LitElement { @state() private _shouldRender = false; + @state() private _filter?: string; + public willUpdate(properties: PropertyValues) { super.willUpdate(properties); @@ -57,11 +60,18 @@ export class HaFilterEntities extends LitElement {
${this._shouldRender ? html` + + { if (!this.expanded) return; this.renderRoot.querySelector("mwc-list")!.style.height = - `${this.clientHeight - 49}px`; + `${this.clientHeight - 49 - 32}px`; // 32px is the height of the search input }, 300); } } @@ -89,18 +99,20 @@ export class HaFilterEntities extends LitElement { private _keyFunction = (entity) => entity?.entity_id; private _renderItem = (entity) => - html` - - ${computeStateName(entity)} - `; + !entity + ? nothing + : html` + + ${computeStateName(entity)} + `; private _handleItemClick(ev) { const listItem = ev.target.closest("ha-check-list-item"); @@ -125,12 +137,27 @@ export class HaFilterEntities extends LitElement { this.expanded = ev.detail.expanded; } + private _handleSearchChange(ev: CustomEvent) { + this._filter = ev.detail.value.toLowerCase(); + } + private _entities = memoizeOne( - (states: HomeAssistant["states"], type: this["type"], _value) => { + ( + states: HomeAssistant["states"], + type: this["type"], + filter: string, + _value + ) => { const values = Object.values(states); return values .filter( - (entityState) => !type || computeStateDomain(entityState) !== type + (entityState) => + (!type || computeStateDomain(entityState) !== type) && + (!filter || + entityState.entity_id.toLowerCase().includes(filter) || + entityState.attributes.friendly_name + ?.toLowerCase() + .includes(filter)) ) .sort((a, b) => stringCompare( @@ -216,6 +243,10 @@ export class HaFilterEntities extends LitElement { --mdc-list-item-graphic-margin: 16px; width: 100%; } + search-input-outlined { + display: block; + padding: 0 8px; + } `, ]; } From 59b66219cb3bf86f5db702edff88b7a8f7ef6b78 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 2 Apr 2024 22:05:03 +0200 Subject: [PATCH 08/10] Add clear filter button to individual filters (#20343) --- src/components/ha-filter-blueprints.ts | 26 +++++++++++++--- src/components/ha-filter-categories.ts | 20 +++++++++++- src/components/ha-filter-devices.ts | 20 +++++++++++- src/components/ha-filter-entities.ts | 20 +++++++++++- src/components/ha-filter-floor-areas.ts | 25 ++++++++++++--- src/components/ha-filter-integrations.ts | 20 +++++++++++- src/components/ha-filter-labels.ts | 21 +++++++++++-- src/components/ha-filter-states.ts | 22 +++++++++++-- src/layouts/hass-tabs-subpage-data-table.ts | 34 ++++++++++++--------- 9 files changed, 177 insertions(+), 31 deletions(-) diff --git a/src/components/ha-filter-blueprints.ts b/src/components/ha-filter-blueprints.ts index c20dc197bf..2b48e27e54 100644 --- a/src/components/ha-filter-blueprints.ts +++ b/src/components/ha-filter-blueprints.ts @@ -1,12 +1,13 @@ import { SelectedDetail } from "@material/mwc-list"; import "@material/mwc-menu/mwc-menu-surface"; +import { mdiFilterVariantRemove } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../common/dom/fire_event"; -import { findRelated, RelatedResult } from "../data/search"; -import type { HomeAssistant } from "../types"; -import { haStyleScrollbar } from "../resources/styles"; import { Blueprints, fetchBlueprints } from "../data/blueprint"; +import { findRelated, RelatedResult } from "../data/search"; +import { haStyleScrollbar } from "../resources/styles"; +import type { HomeAssistant } from "../types"; @customElement("ha-filter-blueprints") export class HaFilterBlueprints extends LitElement { @@ -35,7 +36,11 @@ export class HaFilterBlueprints extends LitElement {
${this.hass.localize("ui.panel.config.blueprint.caption")} ${this.value?.length - ? html`
${this.value?.length}
` + ? html`
${this.value?.length}
+ ` : nothing}
${this._blueprints && this._shouldRender @@ -128,6 +133,15 @@ export class HaFilterBlueprints extends LitElement { }); } + private _clearFilter(ev) { + ev.preventDefault(); + this.value = undefined; + fireEvent(this, "data-table-filter-changed", { + value: undefined, + items: undefined, + }); + } + static get styles(): CSSResultGroup { return [ haStyleScrollbar, @@ -147,6 +161,10 @@ export class HaFilterBlueprints extends LitElement { display: flex; align-items: center; } + .header ha-icon-button { + margin-inline-start: auto; + margin-inline-end: 8px; + } .badge { display: inline-block; margin-left: 8px; diff --git a/src/components/ha-filter-categories.ts b/src/components/ha-filter-categories.ts index fdaa8d481a..40dac92a85 100644 --- a/src/components/ha-filter-categories.ts +++ b/src/components/ha-filter-categories.ts @@ -2,6 +2,7 @@ import { ActionDetail, SelectedDetail } from "@material/mwc-list"; import { mdiDelete, mdiDotsVertical, + mdiFilterVariantRemove, mdiPencil, mdiPlus, mdiTag, @@ -68,7 +69,11 @@ export class HaFilterCategories extends SubscribeMixin(LitElement) {
${this.hass.localize("ui.panel.config.category.caption")} ${this.value?.length - ? html`
${this.value?.length}
` + ? html`
${this.value?.length}
+ ` : nothing}
${this._shouldRender @@ -254,6 +259,15 @@ export class HaFilterCategories extends SubscribeMixin(LitElement) { }); } + private _clearFilter(ev) { + ev.preventDefault(); + this.value = undefined; + fireEvent(this, "data-table-filter-changed", { + value: undefined, + items: undefined, + }); + } + static get styles(): CSSResultGroup { return [ haStyleScrollbar, @@ -274,6 +288,10 @@ export class HaFilterCategories extends SubscribeMixin(LitElement) { display: flex; align-items: center; } + .header ha-icon-button { + margin-inline-start: auto; + margin-inline-end: 8px; + } .badge { display: inline-block; margin-left: 8px; diff --git a/src/components/ha-filter-devices.ts b/src/components/ha-filter-devices.ts index de5f5d9c78..97f17f9c83 100644 --- a/src/components/ha-filter-devices.ts +++ b/src/components/ha-filter-devices.ts @@ -1,3 +1,4 @@ +import { mdiFilterVariantRemove } from "@mdi/js"; import { css, CSSResultGroup, @@ -54,7 +55,11 @@ export class HaFilterDevices extends LitElement {
${this.hass.localize("ui.panel.config.devices.caption")} ${this.value?.length - ? html`
${this.value?.length}
` + ? html`
${this.value?.length}
+ ` : nothing}
${this._shouldRender @@ -185,6 +190,15 @@ export class HaFilterDevices extends LitElement { }); } + private _clearFilter(ev) { + ev.preventDefault(); + this.value = undefined; + fireEvent(this, "data-table-filter-changed", { + value: undefined, + items: undefined, + }); + } + static get styles(): CSSResultGroup { return [ haStyleScrollbar, @@ -205,6 +219,10 @@ export class HaFilterDevices extends LitElement { display: flex; align-items: center; } + .header ha-icon-button { + margin-inline-start: auto; + margin-inline-end: 8px; + } .badge { display: inline-block; margin-left: 8px; diff --git a/src/components/ha-filter-entities.ts b/src/components/ha-filter-entities.ts index 15d9b2f391..585d35a527 100644 --- a/src/components/ha-filter-entities.ts +++ b/src/components/ha-filter-entities.ts @@ -1,3 +1,4 @@ +import { mdiFilterVariantRemove } from "@mdi/js"; import { css, CSSResultGroup, @@ -55,7 +56,11 @@ export class HaFilterEntities extends LitElement {
${this.hass.localize("ui.panel.config.entities.caption")} ${this.value?.length - ? html`
${this.value?.length}
` + ? html`
${this.value?.length}
+ ` : nothing}
${this._shouldRender @@ -204,6 +209,15 @@ export class HaFilterEntities extends LitElement { }); } + private _clearFilter(ev) { + ev.preventDefault(); + this.value = undefined; + fireEvent(this, "data-table-filter-changed", { + value: undefined, + items: undefined, + }); + } + static get styles(): CSSResultGroup { return [ haStyleScrollbar, @@ -223,6 +237,10 @@ export class HaFilterEntities extends LitElement { display: flex; align-items: center; } + .header ha-icon-button { + margin-inline-start: auto; + margin-inline-end: 8px; + } .badge { display: inline-block; margin-left: 8px; diff --git a/src/components/ha-filter-floor-areas.ts b/src/components/ha-filter-floor-areas.ts index 6960621fb3..ba983b7349 100644 --- a/src/components/ha-filter-floor-areas.ts +++ b/src/components/ha-filter-floor-areas.ts @@ -1,5 +1,5 @@ import "@material/mwc-menu/mwc-menu-surface"; -import { mdiTextureBox } from "@mdi/js"; +import { mdiFilterVariantRemove, mdiTextureBox } from "@mdi/js"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -53,9 +53,13 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) { ${this.hass.localize("ui.panel.config.areas.caption")} ${this.value?.areas?.length || this.value?.floors?.length ? html`
- ${(this.value?.areas?.length || 0) + - (this.value?.floors?.length || 0)} -
` + ${(this.value?.areas?.length || 0) + + (this.value?.floors?.length || 0)} + + ` : nothing} ${this._shouldRender @@ -238,6 +242,15 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) { }); } + private _clearFilter(ev) { + ev.preventDefault(); + this.value = undefined; + fireEvent(this, "data-table-filter-changed", { + value: undefined, + items: undefined, + }); + } + static get styles(): CSSResultGroup { return [ haStyleScrollbar, @@ -257,6 +270,10 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) { display: flex; align-items: center; } + .header ha-icon-button { + margin-inline-start: auto; + margin-inline-end: 8px; + } .badge { display: inline-block; margin-left: 8px; diff --git a/src/components/ha-filter-integrations.ts b/src/components/ha-filter-integrations.ts index 5f8b1224b5..2f8b6f3cf0 100644 --- a/src/components/ha-filter-integrations.ts +++ b/src/components/ha-filter-integrations.ts @@ -1,4 +1,5 @@ import { SelectedDetail } from "@material/mwc-list"; +import { mdiFilterVariantRemove } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { repeat } from "lit/directives/repeat"; @@ -38,7 +39,11 @@ export class HaFilterIntegrations extends LitElement {
${this.hass.localize("ui.panel.config.integrations.caption")} ${this.value?.length - ? html`
${this.value?.length}
` + ? html`
${this.value?.length}
+ ` : nothing}
${this._manifests && this._shouldRender @@ -142,6 +147,15 @@ export class HaFilterIntegrations extends LitElement { }); } + private _clearFilter(ev) { + ev.preventDefault(); + this.value = undefined; + fireEvent(this, "data-table-filter-changed", { + value: undefined, + items: undefined, + }); + } + static get styles(): CSSResultGroup { return [ haStyleScrollbar, @@ -161,6 +175,10 @@ export class HaFilterIntegrations extends LitElement { display: flex; align-items: center; } + .header ha-icon-button { + margin-inline-start: auto; + margin-inline-end: 8px; + } .badge { display: inline-block; margin-left: 8px; diff --git a/src/components/ha-filter-labels.ts b/src/components/ha-filter-labels.ts index c28b3fabe1..eef52f52de 100644 --- a/src/components/ha-filter-labels.ts +++ b/src/components/ha-filter-labels.ts @@ -1,6 +1,6 @@ import { SelectedDetail } from "@material/mwc-list"; import "@material/mwc-menu/mwc-menu-surface"; -import { mdiCog } from "@mdi/js"; +import { mdiCog, mdiFilterVariantRemove } from "@mdi/js"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { CSSResultGroup, LitElement, css, html, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -53,7 +53,11 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) {
${this.hass.localize("ui.panel.config.labels.caption")} ${this.value?.length - ? html`
${this.value?.length}
` + ? html`
${this.value?.length}
+ ` : nothing}
${this._shouldRender @@ -150,6 +154,15 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) { }); } + private _clearFilter(ev) { + ev.preventDefault(); + this.value = undefined; + fireEvent(this, "data-table-filter-changed", { + value: undefined, + items: undefined, + }); + } + static get styles(): CSSResultGroup { return [ haStyleScrollbar, @@ -170,6 +183,10 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) { display: flex; align-items: center; } + .header ha-icon-button { + margin-inline-start: auto; + margin-inline-end: 8px; + } .badge { display: inline-block; margin-left: 8px; diff --git a/src/components/ha-filter-states.ts b/src/components/ha-filter-states.ts index 71451460b0..b3eb0fc1da 100644 --- a/src/components/ha-filter-states.ts +++ b/src/components/ha-filter-states.ts @@ -1,11 +1,12 @@ import { SelectedDetail } from "@material/mwc-list"; +import { mdiFilterVariantRemove } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../common/dom/fire_event"; import { haStyleScrollbar } from "../resources/styles"; import type { HomeAssistant } from "../types"; -import "./ha-expansion-panel"; import "./ha-check-list-item"; +import "./ha-expansion-panel"; import "./ha-icon"; @customElement("ha-filter-states") @@ -43,7 +44,11 @@ export class HaFilterStates extends LitElement {
${this.label} ${this.value?.length - ? html`
${this.value?.length}
` + ? html`
${this.value?.length}
+ ` : nothing}
${this._shouldRender @@ -118,6 +123,15 @@ export class HaFilterStates extends LitElement { }); } + private _clearFilter(ev) { + ev.preventDefault(); + this.value = undefined; + fireEvent(this, "data-table-filter-changed", { + value: undefined, + items: undefined, + }); + } + static get styles(): CSSResultGroup { return [ haStyleScrollbar, @@ -137,6 +151,10 @@ export class HaFilterStates extends LitElement { display: flex; align-items: center; } + .header ha-icon-button { + margin-inline-start: auto; + margin-inline-end: 8px; + } .badge { display: inline-block; margin-left: 8px; diff --git a/src/layouts/hass-tabs-subpage-data-table.ts b/src/layouts/hass-tabs-subpage-data-table.ts index 53a60e37e3..57036a9ab4 100644 --- a/src/layouts/hass-tabs-subpage-data-table.ts +++ b/src/layouts/hass-tabs-subpage-data-table.ts @@ -368,14 +368,16 @@ export class HaTabsSubpageDataTable extends LitElement { "ui.components.subpage-data-table.filters" )} - + ${this.filters + ? html`` + : nothing}
- + ${this.filters + ? html`` + : nothing}
From ed7c9c33b93f25f0a7ab0eb473dc708bab781f27 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 2 Apr 2024 22:31:37 +0200 Subject: [PATCH 09/10] Add my link support for labels (#20345) --- src/panels/my/ha-panel-my.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/panels/my/ha-panel-my.ts b/src/panels/my/ha-panel-my.ts index 100eeddf59..e5a5e2c327 100644 --- a/src/panels/my/ha-panel-my.ts +++ b/src/panels/my/ha-panel-my.ts @@ -116,6 +116,9 @@ export const getMyRedirects = (hasSupervisor: boolean): Redirects => ({ entities: { redirect: "/config/entities", }, + labels: { + redirect: "/config/labels", + }, energy: { component: "energy", redirect: "/energy", From 17ad3a87f3314c46672f0756a5acf7a9c405cfae Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 2 Apr 2024 23:31:14 +0200 Subject: [PATCH 10/10] Bumped version to 20240402.2 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f19e51af4f..c78a2c67f1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20240402.1" +version = "20240402.2" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md"