From 5d6fcaf6bb692008eb084c8c4c7e7fe80589e785 Mon Sep 17 00:00:00 2001 From: Brynley McDonald Date: Thu, 6 Feb 2025 22:59:58 +1300 Subject: [PATCH 1/7] Add Mastodon and Bluesky to help tip (#24099) Add Mastodon and Bluesky to socials tip --- src/panels/config/dashboard/ha-config-dashboard.ts | 12 ++++++++++++ src/translations/en.json | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/panels/config/dashboard/ha-config-dashboard.ts b/src/panels/config/dashboard/ha-config-dashboard.ts index 335d84a7ac..726434b6de 100644 --- a/src/panels/config/dashboard/ha-config-dashboard.ts +++ b/src/panels/config/dashboard/ha-config-dashboard.ts @@ -66,6 +66,18 @@ const randomTip = (hass: HomeAssistant, narrow: boolean) => { rel="noreferrer" >${hass.localize("ui.panel.config.tips.join_x")}`, + mastodon: html`${hass.localize("ui.panel.config.tips.join_mastodon")}`, + bluesky: html`${hass.localize("ui.panel.config.tips.join_bluesky")}`, discord: html` Date: Mon, 10 Feb 2025 15:53:05 +0100 Subject: [PATCH 2/7] Fix section border radius (#24159) --- src/panels/lovelace/sections/hui-grid-section.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/panels/lovelace/sections/hui-grid-section.ts b/src/panels/lovelace/sections/hui-grid-section.ts index f50a5dc7b4..059fe80852 100644 --- a/src/panels/lovelace/sections/hui-grid-section.ts +++ b/src/panels/lovelace/sections/hui-grid-section.ts @@ -240,6 +240,7 @@ export class GridSection extends LitElement implements LovelaceSectionElement { .container.edit-mode { padding: 8px; border-radius: var(--ha-card-border-radius, 12px); + border-start-end-radius: 0; border: 2px dashed var(--divider-color); min-height: var(--row-height); } From d9559b7f07010650726935cb63bb8eb2f044e0b4 Mon Sep 17 00:00:00 2001 From: Petar Petrov Date: Fri, 14 Feb 2025 13:46:55 +0200 Subject: [PATCH 3/7] Optimize chart performance (#24215) * Stop listening to chart scroll events to improve performance * only set visualmap when needed * Reduce statistics detail for long periods * reduce calls to `setOption` * tweak zoom modifier code * always replace series * revert statistics detail change --- src/components/chart/ha-chart-base.ts | 64 ++++++------------ .../chart/state-history-chart-line.ts | 67 ++++++++++--------- 2 files changed, 57 insertions(+), 74 deletions(-) diff --git a/src/components/chart/ha-chart-base.ts b/src/components/chart/ha-chart-base.ts index 81029851a0..78902bc018 100644 --- a/src/components/chart/ha-chart-base.ts +++ b/src/components/chart/ha-chart-base.ts @@ -6,6 +6,7 @@ import type { DataZoomComponentOption } from "echarts/components"; import type { EChartsType } from "echarts/core"; import type { ECElementEvent, + SetOptionOpts, XAXisOption, YAXisOption, } from "echarts/types/dist/shared"; @@ -83,19 +84,19 @@ export class HaChartBase extends LitElement { this._listeners.push( listenMediaQuery("(prefers-reduced-motion)", (matches) => { - this._reducedMotion = matches; - this.chart?.setOption({ animation: !this._reducedMotion }); + if (this._reducedMotion !== matches) { + this._reducedMotion = matches; + this.chart?.setOption({ animation: !this._reducedMotion }); + } }) ); // Add keyboard event listeners const handleKeyDown = (ev: KeyboardEvent) => { - if ((isMac && ev.metaKey) || (!isMac && ev.ctrlKey)) { + if ((isMac && ev.key === "Meta") || (!isMac && ev.key === "Control")) { this._modifierPressed = true; if (!this.options?.dataZoom) { - this.chart?.setOption({ - dataZoom: this._getDataZoomConfig(), - }); + this.chart?.setOption({ dataZoom: this._getDataZoomConfig() }); } } }; @@ -104,9 +105,7 @@ export class HaChartBase extends LitElement { if ((isMac && ev.key === "Meta") || (!isMac && ev.key === "Control")) { this._modifierPressed = false; if (!this.options?.dataZoom) { - this.chart?.setOption({ - dataZoom: this._getDataZoomConfig(), - }); + this.chart?.setOption({ dataZoom: this._getDataZoomConfig() }); } } }; @@ -124,27 +123,26 @@ export class HaChartBase extends LitElement { } public willUpdate(changedProps: PropertyValues): void { - super.willUpdate(changedProps); - - if (!this.hasUpdated || !this.chart) { + if (!this.chart) { return; } if (changedProps.has("_themes")) { this._setupChart(); return; } + let chartOptions: ECOption = {}; + const chartUpdateParams: SetOptionOpts = { lazyUpdate: true }; if (changedProps.has("data")) { - this.chart.setOption( - { series: this.data }, - { lazyUpdate: true, replaceMerge: ["series"] } - ); + chartOptions.series = this.data; + chartUpdateParams.replaceMerge = ["series"]; } - if (changedProps.has("options") || changedProps.has("_isZoomed")) { - this.chart.setOption(this._createOptions(), { - lazyUpdate: true, - // if we replace the whole object, it will reset the dataZoom - replaceMerge: ["grid"], - }); + if (changedProps.has("options")) { + chartOptions = { ...chartOptions, ...this._createOptions() }; + } else if (this._isTouchDevice && changedProps.has("_isZoomed")) { + chartOptions.dataZoom = this._getDataZoomConfig(); + } + if (Object.keys(chartOptions).length > 0) { + this.chart.setOption(chartOptions, chartUpdateParams); } } @@ -158,7 +156,6 @@ export class HaChartBase extends LitElement { style=${styleMap({ height: this.height ?? `${this._getDefaultHeight()}px`, })} - @wheel=${this._handleWheel} >
${this._isZoomed @@ -240,8 +237,8 @@ export class HaChartBase extends LitElement { type: "inside", orient: "horizontal", filterMode: "none", - moveOnMouseMove: this._isZoomed, - preventDefaultMouseMove: this._isZoomed, + moveOnMouseMove: !this._isTouchDevice || this._isZoomed, + preventDefaultMouseMove: !this._isTouchDevice || this._isZoomed, zoomLock: !this._isTouchDevice && !this._modifierPressed, }; } @@ -514,23 +511,6 @@ export class HaChartBase extends LitElement { private _handleZoomReset() { this.chart?.dispatchAction({ type: "dataZoom", start: 0, end: 100 }); - this._modifierPressed = false; - } - - private _handleWheel(e: WheelEvent) { - // if the window is not focused, we don't receive the keydown events but scroll still works - if (!this.options?.dataZoom) { - const modifierPressed = (isMac && e.metaKey) || (!isMac && e.ctrlKey); - if (modifierPressed) { - e.preventDefault(); - } - if (modifierPressed !== this._modifierPressed) { - this._modifierPressed = modifierPressed; - this.chart?.setOption({ - dataZoom: this._getDataZoomConfig(), - }); - } - } } static styles = css` diff --git a/src/components/chart/state-history-chart-line.ts b/src/components/chart/state-history-chart-line.ts index 76e73a89e7..f7e60f7804 100644 --- a/src/components/chart/state-history-chart-line.ts +++ b/src/components/chart/state-history-chart-line.ts @@ -75,6 +75,8 @@ export class StateHistoryChartLine extends LitElement { @state() private _yWidth = 25; + @state() private _visualMap?: VisualMapComponentOption[]; + private _chartTime: Date = new Date(); protected render() { @@ -92,7 +94,7 @@ export class StateHistoryChartLine extends LitElement { `; } - private _renderTooltip(params: any) { + private _renderTooltip = (params: any) => { const time = params[0].axisValue; const title = formatDateTimeWithSeconds( @@ -115,7 +117,7 @@ export class StateHistoryChartLine extends LitElement { return; } // If the datapoint is not found, we need to find the last datapoint before the current time - let lastData; + let lastData: any; const data = dataset.data || []; for (let i = data.length - 1; i >= 0; i--) { const point = data[i]; @@ -175,7 +177,7 @@ export class StateHistoryChartLine extends LitElement { }) .join("
") ); - } + }; private _datasetHidden(ev: CustomEvent) { this._hiddenStats.add(ev.detail.name); @@ -208,8 +210,8 @@ export class StateHistoryChartLine extends LitElement { changedProps.has("minYAxis") || changedProps.has("maxYAxis") || changedProps.has("fitYData") || - changedProps.has("_chartData") || changedProps.has("paddingYAxis") || + changedProps.has("_visualMap") || changedProps.has("_yWidth") ) { const rtl = computeRTL(this.hass); @@ -280,37 +282,11 @@ export class StateHistoryChartLine extends LitElement { right: rtl ? Math.max(this.paddingYAxis, this._yWidth) : 1, bottom: 30, }, - visualMap: this._chartData - .map((_, seriesIndex) => { - const dataIndex = this._datasetToDataIndex[seriesIndex]; - const data = this.data[dataIndex]; - if (!data.statistics || data.statistics.length === 0) { - return false; - } - // render stat data with a slightly transparent line - const firstStateTS = - data.states[0]?.last_changed ?? this.endTime.getTime(); - return { - show: false, - seriesIndex, - dimension: 0, - pieces: [ - { - max: firstStateTS - 0.01, - colorAlpha: 0.5, - }, - { - min: firstStateTS, - colorAlpha: 1, - }, - ], - }; - }) - .filter(Boolean) as VisualMapComponentOption[], + visualMap: this._visualMap, tooltip: { trigger: "axis", appendTo: document.body, - formatter: this._renderTooltip.bind(this), + formatter: this._renderTooltip, }, }; } @@ -725,6 +701,33 @@ export class StateHistoryChartLine extends LitElement { this._chartData = datasets; this._entityIds = entityIds; this._datasetToDataIndex = datasetToDataIndex; + const visualMap: VisualMapComponentOption[] = []; + this._chartData.forEach((_, seriesIndex) => { + const dataIndex = this._datasetToDataIndex[seriesIndex]; + const data = this.data[dataIndex]; + if (!data.statistics || data.statistics.length === 0) { + return; + } + // render stat data with a slightly transparent line + const firstStateTS = + data.states[0]?.last_changed ?? this.endTime.getTime(); + visualMap.push({ + show: false, + seriesIndex, + dimension: 0, + pieces: [ + { + max: firstStateTS - 0.01, + colorAlpha: 0.5, + }, + { + min: firstStateTS, + colorAlpha: 1, + }, + ], + }); + }); + this._visualMap = visualMap.length > 0 ? visualMap : undefined; } private _clampYAxis(value?: number | ((values: any) => number)) { From 37ee2bf308c9c76cf7aec8e7e18cb5a0da9edbe8 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 13 Feb 2025 08:47:03 -0500 Subject: [PATCH 4/7] Fix config flow URLs linking to device (#24223) --- src/panels/config/integrations/ha-config-flow-card.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/config/integrations/ha-config-flow-card.ts b/src/panels/config/integrations/ha-config-flow-card.ts index 54291d238a..4538dc3914 100644 --- a/src/panels/config/integrations/ha-config-flow-card.ts +++ b/src/panels/config/integrations/ha-config-flow-card.ts @@ -70,7 +70,7 @@ export class HaConfigFlowCard extends LitElement { ? html`
Date: Fri, 14 Feb 2025 13:53:48 +0200 Subject: [PATCH 5/7] Fix endTime of statistics-chart (#24233) --- src/components/chart/statistics-chart.ts | 5 +++-- src/panels/lovelace/cards/hui-statistics-graph-card.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/chart/statistics-chart.ts b/src/components/chart/statistics-chart.ts index fd34fa5733..7954d76010 100644 --- a/src/components/chart/statistics-chart.ts +++ b/src/components/chart/statistics-chart.ts @@ -273,11 +273,13 @@ export class StatisticsChart extends LitElement { this._chartOptions = { xAxis: [ { + id: "xAxis", type: "time", min: startTime, - max: endTime, + max: this.endTime, }, { + id: "hiddenAxis", type: "time", show: false, }, @@ -368,7 +370,6 @@ export class StatisticsChart extends LitElement { if (endTime > new Date()) { endTime = new Date(); } - this.endTime = endTime; let unit: string | undefined | null; diff --git a/src/panels/lovelace/cards/hui-statistics-graph-card.ts b/src/panels/lovelace/cards/hui-statistics-graph-card.ts index 3754725c9d..a8402a8010 100644 --- a/src/panels/lovelace/cards/hui-statistics-graph-card.ts +++ b/src/panels/lovelace/cards/hui-statistics-graph-card.ts @@ -327,7 +327,7 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard { ); const endDate = this._energyEnd; try { - let unitClass; + let unitClass: string | undefined | null; if (this._config!.unit && this._metadata) { const metadata = Object.values(this._metadata).find( (metaData) => From 64274d7355bc45aef51860c9a1357d0c37e78d26 Mon Sep 17 00:00:00 2001 From: Petar Petrov Date: Fri, 14 Feb 2025 14:32:09 +0200 Subject: [PATCH 6/7] Fix inclusion dialog in ZwaveJS panel (#24234) --- .../zwave_js/zwave_js-config-dashboard.ts | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts index 96b91b41f2..2ddef810e7 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts @@ -76,6 +76,8 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) { @state() private _statistics?: ZWaveJSControllerStatisticsUpdatedMessage; + private _dialogOpen = false; + protected async firstUpdated() { if (this.hass) { await this._fetchData(); @@ -104,11 +106,17 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) { } ), subscribeS2Inclusion(this.hass, this.configEntryId, (message) => { - showZWaveJSAddNodeDialog(this, { - entry_id: this.configEntryId, - dsk: message.dsk, - onStop: () => setTimeout(() => this._fetchData(), 100), - }); + if (!this._dialogOpen) { + showZWaveJSAddNodeDialog(this, { + entry_id: this.configEntryId, + dsk: message.dsk, + onStop: () => { + setTimeout(() => this._fetchData(), 100); + this._dialogOpen = false; + }, + }); + this._dialogOpen = true; + } }), ]; } @@ -570,11 +578,17 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) { } private async _addNodeClicked() { - showZWaveJSAddNodeDialog(this, { - entry_id: this.configEntryId!, - // refresh the data after the dialog is closed. add a small delay for the inclusion state to update - onStop: () => setTimeout(() => this._fetchData(), 100), - }); + if (!this._dialogOpen) { + showZWaveJSAddNodeDialog(this, { + entry_id: this.configEntryId!, + // refresh the data after the dialog is closed. add a small delay for the inclusion state to update + onStop: () => { + setTimeout(() => this._fetchData(), 100); + this._dialogOpen = false; + }, + }); + this._dialogOpen = true; + } } private async _removeNodeClicked() { From 8dbc203130db1683b423cebe28d3aca1be6e2e0a Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 14 Feb 2025 13:33:35 +0100 Subject: [PATCH 7/7] Bumped version to 20250214.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a7effa1919..fc74110b4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20250210.0" +version = "20250214.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md"