From 54b328648a44bbeeb89f5ca67130ab8bc5ff711b Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 2 Jan 2025 15:53:57 +0100 Subject: [PATCH 1/8] =?UTF-8?q?Match=20UI=20with=20core=20and=20don't=20al?= =?UTF-8?q?low=20restore=20config=20without=20db=20and=20vice=20=E2=80=A6?= =?UTF-8?q?=20(#23553)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Match UI with core and dont allow restore config without db and vice versa --- .../backup/components/ha-backup-data-picker.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/panels/config/backup/components/ha-backup-data-picker.ts b/src/panels/config/backup/components/ha-backup-data-picker.ts index 57a7bd3e52..4b5cfa86df 100644 --- a/src/panels/config/backup/components/ha-backup-data-picker.ts +++ b/src/panels/config/backup/components/ha-backup-data-picker.ts @@ -86,12 +86,6 @@ export class HaBackupDataPicker extends LitElement { version: data.homeassistant_version, }); } - if (data.database_included) { - items.push({ - label: "History", - id: "database", - }); - } items.push( ...data.folders.map((folder) => ({ label: this._localizeFolder(folder), @@ -145,9 +139,6 @@ export class HaBackupDataPicker extends LitElement { if (value.homeassistant_included) { homeassistant.push("config"); } - if (value.database_included) { - homeassistant.push("database"); - } const folders = value.folders; homeassistant.push(...folders); @@ -164,7 +155,9 @@ export class HaBackupDataPicker extends LitElement { (selectedItems: SelectedItems, data: BackupData): BackupData => ({ homeassistant_version: data.homeassistant_version, homeassistant_included: selectedItems.homeassistant.includes("config"), - database_included: selectedItems.homeassistant.includes("database"), + database_included: + data.database_included && + selectedItems.homeassistant.includes("config"), addons: data.addons.filter((addon) => selectedItems.addons.includes(addon.slug) ), From 8c52bc3ffbdfd24d401f903bc27809b062dd8837 Mon Sep 17 00:00:00 2001 From: Petar Petrov Date: Tue, 14 Jan 2025 12:24:52 +0200 Subject: [PATCH 2/8] Fix more-info chart rendering (#23619) * Fix more-info chart rendering * lint fix * remove animation-container & _chartHeight * don't change height on resize * handle default height in ha-chart-base * fix chart height in energy panel * lint * lint --- src/components/chart/ha-chart-base.ts | 210 +++++++----------- .../chart/state-history-chart-line.ts | 9 +- .../chart/state-history-chart-timeline.ts | 9 +- src/components/chart/state-history-charts.ts | 21 +- src/components/chart/statistics-chart.ts | 14 +- src/dialogs/more-info/ha-more-info-dialog.ts | 12 +- .../ha-more-info-history-and-logbook.ts | 11 +- src/dialogs/more-info/ha-more-info-history.ts | 15 +- src/dialogs/more-info/ha-more-info-info.ts | 11 +- 9 files changed, 91 insertions(+), 221 deletions(-) diff --git a/src/components/chart/ha-chart-base.ts b/src/components/chart/ha-chart-base.ts index 92c660dcfe..1321a7da21 100644 --- a/src/components/chart/ha-chart-base.ts +++ b/src/components/chart/ha-chart-base.ts @@ -4,6 +4,7 @@ import type { ChartData, ChartOptions, TooltipModel, + UpdateMode, } from "chart.js"; import type { CSSResultGroup, PropertyValues } from "lit"; import { css, html, nothing, LitElement } from "lit"; @@ -20,12 +21,6 @@ import "../ha-icon-button"; export const MIN_TIME_BETWEEN_UPDATES = 60 * 5 * 1000; -export interface ChartResizeOptions { - aspectRatio?: number; - height?: number; - width?: number; -} - interface Tooltip extends Omit, "tooltipPosition" | "hasValue" | "getProps"> { top: string; @@ -61,8 +56,6 @@ export class HaChartBase extends LitElement { @property({ attribute: "external-hidden", type: Boolean }) public externalHidden = false; - @state() private _chartHeight?: number; - @state() private _legendHeight?: number; @state() private _tooltip?: Tooltip; @@ -96,36 +89,10 @@ export class HaChartBase extends LitElement { } } - public updateChart = ( - mode: - | "resize" - | "reset" - | "none" - | "hide" - | "show" - | "default" - | "active" - | undefined - ): void => { + public updateChart = (mode?: UpdateMode): void => { this.chart?.update(mode); }; - public resize = (options?: ChartResizeOptions): void => { - if (options?.aspectRatio && !options.height) { - options.height = Math.round( - (options.width ?? this.clientWidth) / options.aspectRatio - ); - } else if (options?.aspectRatio && !options.width) { - options.width = Math.round( - (options.height ?? this.clientHeight) * options.aspectRatio - ); - } - this.chart?.resize( - options?.width ?? this.clientWidth, - options?.height ?? this.clientHeight - ); - }; - protected firstUpdated() { this._setupChart(); this.data.datasets.forEach((dataset, index) => { @@ -267,96 +234,84 @@ export class HaChartBase extends LitElement { ` : ""}
-
+
- -
-
- ${isMac - ? this.hass.localize( - "ui.components.history_charts.zoom_hint_mac" - ) - : this.hass.localize("ui.components.history_charts.zoom_hint")} -
+
+ ${isMac + ? this.hass.localize("ui.components.history_charts.zoom_hint_mac") + : this.hass.localize("ui.components.history_charts.zoom_hint")}
- ${this._isZoomed && this.chartType !== "timeline" - ? html`` - : nothing} - ${this._tooltip - ? html`
-
${this._tooltip.title}
- ${this._tooltip.beforeBody - ? html`
- ${this._tooltip.beforeBody} -
` - : ""} -
-
    - ${this._tooltip.body.map( - (item, i) => - html`
  • -
    - ${item.lines.join("\n")} -
  • ` - )} -
-
- ${this._tooltip.footer.length - ? html`` - : ""} -
` - : ""}
+ ${this._isZoomed && this.chartType !== "timeline" + ? html`` + : nothing} + ${this._tooltip + ? html`
+
${this._tooltip.title}
+ ${this._tooltip.beforeBody + ? html`
+ ${this._tooltip.beforeBody} +
` + : ""} +
+
    + ${this._tooltip.body.map( + (item, i) => + html`
  • +
    + ${item.lines.join("\n")} +
  • ` + )} +
+
+ ${this._tooltip.footer.length + ? html`` + : ""} +
` + : ""}
`; } @@ -471,11 +426,11 @@ export class HaChartBase extends LitElement { ...(this.plugins || []), { id: "resizeHook", - resize: (chart) => { - const change = chart.height - (this._chartHeight ?? 0); - if (!this._chartHeight || change > 12 || change < -12) { - // hysteresis to prevent infinite render loops - this._chartHeight = chart.height; + resize: (chart: Chart) => { + if (!this.height) { + // lock the height + // this removes empty space below the chart + this.height = chart.height; } }, legend: { @@ -486,6 +441,10 @@ export class HaChartBase extends LitElement { ]; } + private _getDefaultHeight() { + return this.clientWidth / 2; + } + private _handleChartScroll(ev: MouseEvent) { const modifier = isMac ? "metaKey" : "ctrlKey"; this._tooltip = undefined; @@ -573,11 +532,6 @@ export class HaChartBase extends LitElement { display: block; position: relative; } - .animation-container { - overflow: hidden; - height: 0; - transition: height 300ms cubic-bezier(0.4, 0, 0.2, 1); - } .chart-container { position: relative; } diff --git a/src/components/chart/state-history-chart-line.ts b/src/components/chart/state-history-chart-line.ts index e2113b7478..887952f3b3 100644 --- a/src/components/chart/state-history-chart-line.ts +++ b/src/components/chart/state-history-chart-line.ts @@ -1,7 +1,7 @@ import type { ChartData, ChartDataset, ChartOptions } from "chart.js"; import type { PropertyValues } from "lit"; import { html, LitElement } from "lit"; -import { property, query, state } from "lit/decorators"; +import { property, state } from "lit/decorators"; import { getGraphColorByIndex } from "../../common/color/colors"; import { fireEvent } from "../../common/dom/fire_event"; import { computeRTL } from "../../common/util/compute_rtl"; @@ -12,7 +12,6 @@ import { } from "../../common/number/format_number"; import type { LineChartEntity, LineChartState } from "../../data/history"; import type { HomeAssistant } from "../../types"; -import type { ChartResizeOptions, HaChartBase } from "./ha-chart-base"; import { MIN_TIME_BETWEEN_UPDATES } from "./ha-chart-base"; import { clickIsTouch } from "./click_is_touch"; @@ -67,12 +66,6 @@ export class StateHistoryChartLine extends LitElement { private _chartTime: Date = new Date(); - @query("ha-chart-base") private _chart?: HaChartBase; - - public resize = (options?: ChartResizeOptions): void => { - this._chart?.resize(options); - }; - protected render() { return html` { - this._chart?.resize(options); - }; - protected render() { return html` { - this._charts?.forEach( - (chart: StateHistoryChartLine | StateHistoryChartTimeline) => - chart.resize(options) - ); - }; - protected render() { if (!isComponentLoaded(this.hass, "history")) { return html`
diff --git a/src/components/chart/statistics-chart.ts b/src/components/chart/statistics-chart.ts index 2873df4d60..ff0dd5d0fe 100644 --- a/src/components/chart/statistics-chart.ts +++ b/src/components/chart/statistics-chart.ts @@ -6,7 +6,7 @@ import type { } from "chart.js"; import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit"; import { css, html, LitElement } from "lit"; -import { customElement, property, state, query } from "lit/decorators"; +import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { getGraphColorByIndex } from "../../common/color/colors"; import { isComponentLoaded } from "../../common/config/is_component_loaded"; @@ -30,11 +30,7 @@ import { } from "../../data/recorder"; import type { HomeAssistant } from "../../types"; import "./ha-chart-base"; -import type { - ChartResizeOptions, - ChartDatasetExtra, - HaChartBase, -} from "./ha-chart-base"; +import type { ChartDatasetExtra } from "./ha-chart-base"; import { clickIsTouch } from "./click_is_touch"; export const supportedStatTypeMap: Record = { @@ -98,14 +94,8 @@ export class StatisticsChart extends LitElement { @state() private _hiddenStats = new Set(); - @query("ha-chart-base") private _chart?: HaChartBase; - private _computedStyle?: CSSStyleDeclaration; - public resize = (options?: ChartResizeOptions): void => { - this._chart?.resize(options); - }; - protected shouldUpdate(changedProps: PropertyValues): boolean { return changedProps.size > 1 || !changedProps.has("hass"); } diff --git a/src/dialogs/more-info/ha-more-info-dialog.ts b/src/dialogs/more-info/ha-more-info-dialog.ts index 51d14f1cce..37ea6841f9 100644 --- a/src/dialogs/more-info/ha-more-info-dialog.ts +++ b/src/dialogs/more-info/ha-more-info-dialog.ts @@ -12,7 +12,7 @@ import { import type { HassEntity } from "home-assistant-js-websocket"; import type { PropertyValues } from "lit"; import { LitElement, css, html, nothing } from "lit"; -import { customElement, property, query, state } from "lit/decorators"; +import { customElement, property, state } from "lit/decorators"; import { cache } from "lit/directives/cache"; import { dynamicElement } from "../../common/dom/dynamic-element-directive"; import { fireEvent } from "../../common/dom/fire_event"; @@ -47,9 +47,7 @@ import { } from "./const"; import "./controls/more-info-default"; import "./ha-more-info-history-and-logbook"; -import type { MoreInfoHistoryAndLogbook } from "./ha-more-info-history-and-logbook"; import "./ha-more-info-info"; -import type { MoreInfoInfo } from "./ha-more-info-info"; import "./ha-more-info-settings"; import "./more-info-content"; @@ -98,9 +96,6 @@ export class MoreInfoDialog extends LitElement { @state() private _infoEditMode = false; - @query("ha-more-info-info, ha-more-info-history-and-logbook") - private _history?: MoreInfoInfo | MoreInfoHistoryAndLogbook; - public showDialog(params: MoreInfoDialogParams) { this._entityId = params.entityId; if (!this._entityId) { @@ -283,7 +278,6 @@ export class MoreInfoDialog extends LitElement { ; - @query("statistics-chart, state-history-charts") private _chart?: - | StateHistoryCharts - | StatisticsChart; - - public resize = (options?: ChartResizeOptions): void => { - if (this._chart) { - this._chart.resize(options); - } - }; - protected render() { if (!this.entityId) { return nothing; diff --git a/src/dialogs/more-info/ha-more-info-info.ts b/src/dialogs/more-info/ha-more-info-info.ts index efee44afbd..be4a09e4a0 100644 --- a/src/dialogs/more-info/ha-more-info-info.ts +++ b/src/dialogs/more-info/ha-more-info-info.ts @@ -1,8 +1,7 @@ import type { HassEntity } from "home-assistant-js-websocket"; import { css, html, LitElement, nothing } from "lit"; -import { customElement, property, query } from "lit/decorators"; +import { customElement, property } from "lit/decorators"; import { computeDomain } from "../../common/entity/compute_domain"; -import type { ChartResizeOptions } from "../../components/chart/ha-chart-base"; import type { ExtEntityRegistryEntry } from "../../data/entity_registry"; import type { HomeAssistant } from "../../types"; import { @@ -14,7 +13,6 @@ import { DOMAINS_WITH_MORE_INFO, } from "./const"; import "./ha-more-info-history"; -import type { MoreInfoHistory } from "./ha-more-info-history"; import "./ha-more-info-logbook"; import "./more-info-content"; @@ -28,13 +26,6 @@ export class MoreInfoInfo extends LitElement { @property({ attribute: false }) public editMode?: boolean; - @query("ha-more-info-history") - private _history?: MoreInfoHistory; - - public resize(options?: ChartResizeOptions) { - this._history?.resize(options); - } - protected render() { const entityId = this.entityId; const stateObj = this.hass.states[entityId] as HassEntity | undefined; From bf471eb8c377fcacce748ad0d3925d9cfbd185b0 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Sun, 12 Jan 2025 08:24:35 +0100 Subject: [PATCH 3/8] Minor fixes for backup translations (#23691) --- .../config/backup/components/config/ha-backup-config-data.ts | 2 +- src/panels/config/backup/dialogs/dialog-upload-backup.ts | 4 +++- src/translations/en.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/panels/config/backup/components/config/ha-backup-config-data.ts b/src/panels/config/backup/components/config/ha-backup-config-data.ts index 7d48cb6906..23786dc258 100644 --- a/src/panels/config/backup/components/config/ha-backup-config-data.ts +++ b/src/panels/config/backup/components/config/ha-backup-config-data.ts @@ -209,7 +209,7 @@ class HaBackupConfigData extends LitElement { ${this.hass.localize( - "ui.panel.config.backup.data.history_description" + "ui.panel.config.backup.data.media_description" )}
- Cancel + ${this.hass.localize("ui.common.cancel")} ${this.hass.localize( "ui.panel.config.backup.dialogs.upload.action" diff --git a/src/translations/en.json b/src/translations/en.json index 6c7587e163..d0742548db 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2605,7 +2605,7 @@ "protected_not_encrypted": "Not encrypted" }, "restore": { - "title": "Selected what to restore", + "title": "Select what to restore", "action": "Restore" }, "locations": { From b28e7d2f06f35f540e110416f79cf23eb3eff86d Mon Sep 17 00:00:00 2001 From: Petar Petrov Date: Tue, 14 Jan 2025 10:25:01 +0200 Subject: [PATCH 4/8] Fix navigation from stacked dialogs with the same name (#23698) * Fix navigation from stacked dialogs * lint fix * Keep only 1 instance per dialog tag in the stack --- src/dialogs/make-dialog-manager.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/dialogs/make-dialog-manager.ts b/src/dialogs/make-dialog-manager.ts index 6a780e0189..1c0f954a14 100644 --- a/src/dialogs/make-dialog-manager.ts +++ b/src/dialogs/make-dialog-manager.ts @@ -104,6 +104,12 @@ export const showDialog = async ( addHistory ); } + const dialogIndex = OPEN_DIALOG_STACK.findIndex( + (state) => state.dialogTag === dialogTag + ); + if (dialogIndex !== -1) { + OPEN_DIALOG_STACK.splice(dialogIndex, 1); + } OPEN_DIALOG_STACK.push({ element, root, @@ -173,8 +179,10 @@ export const closeLastDialog = async () => { export const closeAllDialogs = async () => { for (let i = OPEN_DIALOG_STACK.length - 1; i >= 0; i--) { - // eslint-disable-next-line no-await-in-loop - const closed = await closeDialog(OPEN_DIALOG_STACK[i].dialogTag); + const closed = + !OPEN_DIALOG_STACK[i] || + // eslint-disable-next-line no-await-in-loop + (await closeDialog(OPEN_DIALOG_STACK[i].dialogTag)); if (!closed) { return false; } From 6b471ba6e77f4d5976b97101dcbfc211577941c6 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 14 Jan 2025 11:28:32 +0100 Subject: [PATCH 5/8] Fix background on cast devices (#23731) --- cast/src/html/receiver.html.template | 1 - src/panels/lovelace/views/hui-view-background.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cast/src/html/receiver.html.template b/cast/src/html/receiver.html.template index d326ce55ff..0cb9154fc9 100644 --- a/cast/src/html/receiver.html.template +++ b/cast/src/html/receiver.html.template @@ -7,7 +7,6 @@ <%= renderTemplate("../../../src/html/_style_base.html.template") %> diff --git a/src/panels/lovelace/views/hui-view-background.ts b/src/panels/lovelace/views/hui-view-background.ts index 5a065d2650..06b7439298 100644 --- a/src/panels/lovelace/views/hui-view-background.ts +++ b/src/panels/lovelace/views/hui-view-background.ts @@ -55,7 +55,7 @@ export class HUIViewBackground extends LitElement { const alignment = background.alignment ?? "center"; const size = background.size ?? "cover"; const repeat = background.repeat ?? "no-repeat"; - return `${alignment} / ${size} ${repeat} url('${background.image}')`; + return `${alignment} / ${size} ${repeat} url('${this.hass.hassUrl(background.image)}')`; } if (typeof background === "string") { return background; From ac98672cb7caeedfcc11a6fc23268576d458d2c5 Mon Sep 17 00:00:00 2001 From: Wendelin <12148533+wendevlin@users.noreply.github.com> Date: Tue, 14 Jan 2025 15:41:43 +0100 Subject: [PATCH 6/8] Fix background (#23736) --- cast/src/receiver/layout/hc-lovelace.ts | 3 ++- src/panels/lovelace/hui-root.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cast/src/receiver/layout/hc-lovelace.ts b/cast/src/receiver/layout/hc-lovelace.ts index 0cf3d5121d..b84b052484 100644 --- a/cast/src/receiver/layout/hc-lovelace.ts +++ b/cast/src/receiver/layout/hc-lovelace.ts @@ -59,7 +59,8 @@ class HcLovelace extends LitElement { return html` - + + - + +
`; From c6f0c62fd6be3e4a1f5670f144f5b813a1b0a0e0 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 16 Jan 2025 12:46:10 +0100 Subject: [PATCH 7/8] Prevent race in dialog box (#23758) Co-authored-by: Petar Petrov Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com> --- src/dialogs/generic/dialog-box.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/dialogs/generic/dialog-box.ts b/src/dialogs/generic/dialog-box.ts index 212c181c27..c24d6d11ea 100644 --- a/src/dialogs/generic/dialog-box.ts +++ b/src/dialogs/generic/dialog-box.ts @@ -27,7 +27,14 @@ class DialogBox extends LitElement { @query("ha-md-dialog") private _dialog?: HaMdDialog; + private _closePromise?: Promise; + + private _closeResolve?: () => void; + public async showDialog(params: DialogBoxParams): Promise { + if (this._closePromise) { + await this._closePromise; + } this._params = params; } @@ -132,21 +139,24 @@ class DialogBox extends LitElement { private _dismiss(): void { this._closeState = "canceled"; - this._closeDialog(); this._cancel(); + this._closeDialog(); } private _confirm(): void { this._closeState = "confirmed"; - this._closeDialog(); if (this._params!.confirm) { this._params!.confirm(this._textField?.value); } + this._closeDialog(); } private _closeDialog() { fireEvent(this, "dialog-closed", { dialog: this.localName }); this._dialog?.close(); + this._closePromise = new Promise((resolve) => { + this._closeResolve = resolve; + }); } private _dialogClosed() { @@ -156,6 +166,8 @@ class DialogBox extends LitElement { } this._closeState = undefined; this._params = undefined; + this._closeResolve?.(); + this._closeResolve = undefined; } static get styles(): CSSResultGroup { From bf1b0ac949d4cb5f46b3d15244620efc12dad7e3 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Thu, 23 Jan 2025 14:17:53 +0100 Subject: [PATCH 8/8] Bumped version to 20250109.1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 01d6a21fe9..4a7e60bbf1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20250109.0" +version = "20250109.1" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md"