diff --git a/pyproject.toml b/pyproject.toml index 193a84b4b7..a7effa1919 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20250205.0" +version = "20250210.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md" diff --git a/src/components/chart/ha-chart-base.ts b/src/components/chart/ha-chart-base.ts index 4988ff75c8..81029851a0 100644 --- a/src/components/chart/ha-chart-base.ts +++ b/src/components/chart/ha-chart-base.ts @@ -328,6 +328,7 @@ export class HaChartBase extends LitElement { backgroundColor: "transparent", textStyle: { color: style.getPropertyValue("--primary-text-color"), + fontFamily: "Roboto, Noto, sans-serif", }, title: { textStyle: { diff --git a/src/components/chart/state-history-chart-line.ts b/src/components/chart/state-history-chart-line.ts index d268bd5d7c..76e73a89e7 100644 --- a/src/components/chart/state-history-chart-line.ts +++ b/src/components/chart/state-history-chart-line.ts @@ -222,14 +222,14 @@ export class StateHistoryChartLine extends LitElement { minYAxis = ({ min }) => Math.min(min, this.minYAxis!); } } else if (this.logarithmicScale) { - minYAxis = ({ min }) => (min > 0 ? min * 0.95 : min * 1.05); + minYAxis = ({ min }) => Math.floor(min > 0 ? min * 0.95 : min * 1.05); } if (typeof maxYAxis === "number") { if (this.fitYData) { maxYAxis = ({ max }) => Math.max(max, this.maxYAxis!); } } else if (this.logarithmicScale) { - maxYAxis = ({ max }) => (max > 0 ? max * 1.05 : max * 0.95); + maxYAxis = ({ max }) => Math.ceil(max > 0 ? max * 1.05 : max * 0.95); } this._chartOptions = { xAxis: { diff --git a/src/components/chart/statistics-chart.ts b/src/components/chart/statistics-chart.ts index ac9aabf85e..fd34fa5733 100644 --- a/src/components/chart/statistics-chart.ts +++ b/src/components/chart/statistics-chart.ts @@ -237,14 +237,14 @@ export class StatisticsChart extends LitElement { minYAxis = ({ min }) => Math.min(min, this.minYAxis!); } } else if (this.logarithmicScale) { - minYAxis = ({ min }) => (min > 0 ? min * 0.95 : min * 1.05); + minYAxis = ({ min }) => Math.floor(min > 0 ? min * 0.95 : min * 1.05); } if (typeof maxYAxis === "number") { if (this.fitYData) { maxYAxis = ({ max }) => Math.max(max, this.maxYAxis!); } } else if (this.logarithmicScale) { - maxYAxis = ({ max }) => (max > 0 ? max * 1.05 : max * 0.95); + maxYAxis = ({ max }) => Math.ceil(max > 0 ? max * 1.05 : max * 0.95); } const endTime = this.endTime ?? new Date(); let startTime = this.startTime; @@ -290,7 +290,6 @@ export class StatisticsChart extends LitElement { align: "left", }, position: computeRTL(this.hass) ? "right" : "left", - // @ts-ignore scale: true, min: this._clampYAxis(minYAxis), max: this._clampYAxis(maxYAxis), diff --git a/src/components/ha-network.ts b/src/components/ha-network.ts index 0841010272..f46bf00ced 100644 --- a/src/components/ha-network.ts +++ b/src/components/ha-network.ts @@ -64,9 +64,13 @@ export class HaNetwork extends LitElement { > - Auto Configure + + ${this.hass.localize( + "ui.panel.config.network.adapter.auto_configure" + )} + - Detected: + ${this.hass.localize("ui.panel.config.network.adapter.detected")}: ${format_auto_detected_interfaces(this.networkConfig.adapters)} @@ -85,18 +89,21 @@ export class HaNetwork extends LitElement { - Adapter: ${adapter.name} + ${this.hass.localize( + "ui.panel.config.network.adapter.adapter" + )}: + ${adapter.name} ${adapter.default ? html` - (Default)` - : ""} + (${this.hass.localize("ui.common.default")})` + : nothing} ${format_addresses([...adapter.ipv4, ...adapter.ipv6])} ` ) - : ""} + : nothing} `; } diff --git a/src/panels/config/areas/dialog-area-registry-detail.ts b/src/panels/config/areas/dialog-area-registry-detail.ts index 26f98283b4..98367f9a0c 100644 --- a/src/panels/config/areas/dialog-area-registry-detail.ts +++ b/src/panels/config/areas/dialog-area-registry-detail.ts @@ -329,6 +329,9 @@ class DialogAreaDetail extends LitElement { return [ haStyleDialog, css` + ha-textfield { + display: block; + } ha-aliases-editor, ha-entity-picker, ha-floor-picker, diff --git a/src/panels/lovelace/cards/energy/common/energy-chart-options.ts b/src/panels/lovelace/cards/energy/common/energy-chart-options.ts index 2e576c7c9e..d26d47f96d 100644 --- a/src/panels/lovelace/cards/energy/common/energy-chart-options.ts +++ b/src/panels/lovelace/cards/energy/common/energy-chart-options.ts @@ -72,7 +72,10 @@ export function getCommonOptions( yAxis: { type: "value", name: unit, - nameGap: 5, + nameGap: 2, + nameTextStyle: { + align: "left", + }, axisLabel: { formatter: (value: number) => formatNumber(Math.abs(value), locale), }, @@ -81,10 +84,10 @@ export function getCommonOptions( }, }, grid: { - top: 35, - bottom: 10, - left: 10, - right: 10, + top: 15, + bottom: 0, + left: 1, + right: 1, containLabel: true, }, tooltip: { @@ -222,7 +225,7 @@ export function fillDataGapsAndRoundCaps(datasets: BarSeriesOption[]) { if (x === undefined) { continue; } - if (x !== bucket) { + if (Number(x) !== bucket) { datasets[i].data?.splice(index, 0, { value: [bucket, 0], itemStyle: { diff --git a/src/panels/lovelace/cards/energy/hui-energy-devices-detail-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-devices-detail-graph-card.ts index a1501155b9..42edcdaacc 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-devices-detail-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-devices-detail-graph-card.ts @@ -193,9 +193,10 @@ export class HuiEnergyDevicesDetailGraphCard icon: "circle", }, grid: { + top: 45, bottom: 0, - left: 5, - right: 5, + left: 1, + right: 1, containLabel: true, }, }; @@ -446,9 +447,9 @@ export class HuiEnergyDevicesDetailGraphCard stack: compare ? "devicesCompare" : "devices", }); }); - return sorted_devices.map( - (device) => data.find((d) => (d.id as string).includes(device))! - ); + return sorted_devices + .map((device) => data.find((d) => (d.id as string).includes(device))!) + .filter(Boolean); } static styles = css` diff --git a/src/panels/lovelace/cards/energy/hui-energy-devices-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-devices-graph-card.ts index 3c99584415..fc987b3300 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-devices-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-devices-graph-card.ts @@ -27,6 +27,7 @@ import { hasConfigChanged } from "../../common/has-changed"; import type { ECOption } from "../../../../resources/echarts"; import "../../../../components/ha-card"; import { fireEvent } from "../../../../common/dom/fire_event"; +import { measureTextWidth } from "../../../../util/text"; @customElement("hui-energy-devices-graph-card") export class HuiEnergyDevicesGraphCard @@ -109,8 +110,11 @@ export class HuiEnergyDevicesGraphCard return `${title}${params.marker} ${params.seriesName}: ${value}`; } - private _createOptions = memoizeOne( - (data: BarSeriesOption[]): ECOption => ({ + private _createOptions = memoizeOne((data: BarSeriesOption[]): ECOption => { + const isMobile = window.matchMedia( + "all and (max-width: 450px), all and (max-height: 500px)" + ).matches; + return { xAxis: { type: "value", name: "kWh", @@ -124,6 +128,17 @@ export class HuiEnergyDevicesGraphCard axisLabel: { formatter: this._getDeviceName.bind(this), overflow: "truncate", + fontSize: 12, + margin: 5, + width: Math.min( + isMobile ? 100 : 200, + Math.max( + ...(data[0]?.data?.map( + (d: any) => + measureTextWidth(this._getDeviceName(d.value[1]), 12) + 5 + ) || []) + ) + ), }, }, grid: { @@ -137,8 +152,8 @@ export class HuiEnergyDevicesGraphCard show: true, formatter: this._renderTooltip.bind(this), }, - }) - ); + }; + }); private _getDeviceName(statisticId: string): string { return ( diff --git a/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts index e1ffa869f0..3119e53138 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts @@ -367,6 +367,7 @@ export class HuiEnergySolarGraphCard data.push({ id: "forecast-" + source.stat_energy_from, type: "line", + stack: "forecast", name: this.hass.localize( "ui.panel.lovelace.cards.energy.energy_solar_graph.forecast", { diff --git a/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts index 9836c7f061..18e737696f 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts @@ -300,6 +300,8 @@ export class HuiEnergyUsageGraphCard type: "bar", stack: "usage", data: [], + // @ts-expect-error + order: 0, }); } @@ -315,6 +317,8 @@ export class HuiEnergyUsageGraphCard ) ); + // @ts-expect-error + datasets.sort((a, b) => a.order - b.order); fillDataGapsAndRoundCaps(datasets); this._chartData = datasets; } @@ -482,7 +486,7 @@ export class HuiEnergyUsageGraphCard this._compareStart! ); - Object.entries(combinedData).forEach(([type, sources]) => { + Object.entries(combinedData).forEach(([type, sources], idx) => { Object.entries(sources).forEach(([statId, source]) => { const points: BarSeriesOption["data"] = []; // Process chart data. @@ -513,6 +517,13 @@ export class HuiEnergyUsageGraphCard statId, statisticsMetaData[statId] ), + // @ts-expect-error + order: + type === "used_solar" + ? 1 + : type === "to_battery" + ? Object.keys(combinedData).length + : idx + 2, barMaxWidth: 50, itemStyle: { borderColor: getEnergyColor( diff --git a/src/translations/en.json b/src/translations/en.json index 8271cb33d7..80d7b4f6de 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -6122,7 +6122,12 @@ }, "network_adapter": "Network adapter", "network_adapter_info": "Configure which network adapters integrations will use. Currently this setting only affects multicast traffic. A restart is required for these settings to apply.", - "ip_information": "IP Information" + "ip_information": "IP Information", + "adapter": { + "auto_configure": "Auto configure", + "detected": "Detected", + "adapter": "Adapter" + } }, "storage": { "caption": "Storage", diff --git a/src/util/text.ts b/src/util/text.ts index edd6afdd08..433f7b5fee 100644 --- a/src/util/text.ts +++ b/src/util/text.ts @@ -10,7 +10,7 @@ let textMeasureCanvas: HTMLCanvasElement | undefined; export function measureTextWidth( text: string, fontSize: number, - fontFamily = "sans-serif" + fontFamily = "Roboto, Noto, sans-serif" ): number { if (!textMeasureCanvas) { textMeasureCanvas = document.createElement("canvas");