Merge branch 'rc'

This commit is contained in:
Bram Kragten 2025-02-10 19:39:11 +01:00
commit 0ab9098f23
13 changed files with 76 additions and 30 deletions

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "home-assistant-frontend" name = "home-assistant-frontend"
version = "20250205.0" version = "20250210.0"
license = {text = "Apache-2.0"} license = {text = "Apache-2.0"}
description = "The Home Assistant frontend" description = "The Home Assistant frontend"
readme = "README.md" readme = "README.md"

View File

@ -328,6 +328,7 @@ export class HaChartBase extends LitElement {
backgroundColor: "transparent", backgroundColor: "transparent",
textStyle: { textStyle: {
color: style.getPropertyValue("--primary-text-color"), color: style.getPropertyValue("--primary-text-color"),
fontFamily: "Roboto, Noto, sans-serif",
}, },
title: { title: {
textStyle: { textStyle: {

View File

@ -222,14 +222,14 @@ export class StateHistoryChartLine extends LitElement {
minYAxis = ({ min }) => Math.min(min, this.minYAxis!); minYAxis = ({ min }) => Math.min(min, this.minYAxis!);
} }
} else if (this.logarithmicScale) { } 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 (typeof maxYAxis === "number") {
if (this.fitYData) { if (this.fitYData) {
maxYAxis = ({ max }) => Math.max(max, this.maxYAxis!); maxYAxis = ({ max }) => Math.max(max, this.maxYAxis!);
} }
} else if (this.logarithmicScale) { } 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 = { this._chartOptions = {
xAxis: { xAxis: {

View File

@ -237,14 +237,14 @@ export class StatisticsChart extends LitElement {
minYAxis = ({ min }) => Math.min(min, this.minYAxis!); minYAxis = ({ min }) => Math.min(min, this.minYAxis!);
} }
} else if (this.logarithmicScale) { } 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 (typeof maxYAxis === "number") {
if (this.fitYData) { if (this.fitYData) {
maxYAxis = ({ max }) => Math.max(max, this.maxYAxis!); maxYAxis = ({ max }) => Math.max(max, this.maxYAxis!);
} }
} else if (this.logarithmicScale) { } 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(); const endTime = this.endTime ?? new Date();
let startTime = this.startTime; let startTime = this.startTime;
@ -290,7 +290,6 @@ export class StatisticsChart extends LitElement {
align: "left", align: "left",
}, },
position: computeRTL(this.hass) ? "right" : "left", position: computeRTL(this.hass) ? "right" : "left",
// @ts-ignore
scale: true, scale: true,
min: this._clampYAxis(minYAxis), min: this._clampYAxis(minYAxis),
max: this._clampYAxis(maxYAxis), max: this._clampYAxis(maxYAxis),

View File

@ -64,9 +64,13 @@ export class HaNetwork extends LitElement {
> >
</ha-checkbox> </ha-checkbox>
</span> </span>
<span slot="heading" data-for="auto_configure"> Auto Configure </span> <span slot="heading" data-for="auto_configure">
${this.hass.localize(
"ui.panel.config.network.adapter.auto_configure"
)}
</span>
<span slot="description" data-for="auto_configure"> <span slot="description" data-for="auto_configure">
Detected: ${this.hass.localize("ui.panel.config.network.adapter.detected")}:
${format_auto_detected_interfaces(this.networkConfig.adapters)} ${format_auto_detected_interfaces(this.networkConfig.adapters)}
</span> </span>
</ha-settings-row> </ha-settings-row>
@ -85,18 +89,21 @@ export class HaNetwork extends LitElement {
</ha-checkbox> </ha-checkbox>
</span> </span>
<span slot="heading"> <span slot="heading">
Adapter: ${adapter.name} ${this.hass.localize(
"ui.panel.config.network.adapter.adapter"
)}:
${adapter.name}
${adapter.default ${adapter.default
? html`<ha-svg-icon .path=${mdiStar}></ha-svg-icon> ? html`<ha-svg-icon .path=${mdiStar}></ha-svg-icon>
(Default)` (${this.hass.localize("ui.common.default")})`
: ""} : nothing}
</span> </span>
<span slot="description"> <span slot="description">
${format_addresses([...adapter.ipv4, ...adapter.ipv6])} ${format_addresses([...adapter.ipv4, ...adapter.ipv6])}
</span> </span>
</ha-settings-row>` </ha-settings-row>`
) )
: ""} : nothing}
`; `;
} }

View File

@ -329,6 +329,9 @@ class DialogAreaDetail extends LitElement {
return [ return [
haStyleDialog, haStyleDialog,
css` css`
ha-textfield {
display: block;
}
ha-aliases-editor, ha-aliases-editor,
ha-entity-picker, ha-entity-picker,
ha-floor-picker, ha-floor-picker,

View File

@ -72,7 +72,10 @@ export function getCommonOptions(
yAxis: { yAxis: {
type: "value", type: "value",
name: unit, name: unit,
nameGap: 5, nameGap: 2,
nameTextStyle: {
align: "left",
},
axisLabel: { axisLabel: {
formatter: (value: number) => formatNumber(Math.abs(value), locale), formatter: (value: number) => formatNumber(Math.abs(value), locale),
}, },
@ -81,10 +84,10 @@ export function getCommonOptions(
}, },
}, },
grid: { grid: {
top: 35, top: 15,
bottom: 10, bottom: 0,
left: 10, left: 1,
right: 10, right: 1,
containLabel: true, containLabel: true,
}, },
tooltip: { tooltip: {
@ -222,7 +225,7 @@ export function fillDataGapsAndRoundCaps(datasets: BarSeriesOption[]) {
if (x === undefined) { if (x === undefined) {
continue; continue;
} }
if (x !== bucket) { if (Number(x) !== bucket) {
datasets[i].data?.splice(index, 0, { datasets[i].data?.splice(index, 0, {
value: [bucket, 0], value: [bucket, 0],
itemStyle: { itemStyle: {

View File

@ -193,9 +193,10 @@ export class HuiEnergyDevicesDetailGraphCard
icon: "circle", icon: "circle",
}, },
grid: { grid: {
top: 45,
bottom: 0, bottom: 0,
left: 5, left: 1,
right: 5, right: 1,
containLabel: true, containLabel: true,
}, },
}; };
@ -446,9 +447,9 @@ export class HuiEnergyDevicesDetailGraphCard
stack: compare ? "devicesCompare" : "devices", stack: compare ? "devicesCompare" : "devices",
}); });
}); });
return sorted_devices.map( return sorted_devices
(device) => data.find((d) => (d.id as string).includes(device))! .map((device) => data.find((d) => (d.id as string).includes(device))!)
); .filter(Boolean);
} }
static styles = css` static styles = css`

View File

@ -27,6 +27,7 @@ import { hasConfigChanged } from "../../common/has-changed";
import type { ECOption } from "../../../../resources/echarts"; import type { ECOption } from "../../../../resources/echarts";
import "../../../../components/ha-card"; import "../../../../components/ha-card";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import { measureTextWidth } from "../../../../util/text";
@customElement("hui-energy-devices-graph-card") @customElement("hui-energy-devices-graph-card")
export class HuiEnergyDevicesGraphCard export class HuiEnergyDevicesGraphCard
@ -109,8 +110,11 @@ export class HuiEnergyDevicesGraphCard
return `${title}${params.marker} ${params.seriesName}: ${value}`; return `${title}${params.marker} ${params.seriesName}: ${value}`;
} }
private _createOptions = memoizeOne( private _createOptions = memoizeOne((data: BarSeriesOption[]): ECOption => {
(data: BarSeriesOption[]): ECOption => ({ const isMobile = window.matchMedia(
"all and (max-width: 450px), all and (max-height: 500px)"
).matches;
return {
xAxis: { xAxis: {
type: "value", type: "value",
name: "kWh", name: "kWh",
@ -124,6 +128,17 @@ export class HuiEnergyDevicesGraphCard
axisLabel: { axisLabel: {
formatter: this._getDeviceName.bind(this), formatter: this._getDeviceName.bind(this),
overflow: "truncate", 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: { grid: {
@ -137,8 +152,8 @@ export class HuiEnergyDevicesGraphCard
show: true, show: true,
formatter: this._renderTooltip.bind(this), formatter: this._renderTooltip.bind(this),
}, },
}) };
); });
private _getDeviceName(statisticId: string): string { private _getDeviceName(statisticId: string): string {
return ( return (

View File

@ -367,6 +367,7 @@ export class HuiEnergySolarGraphCard
data.push({ data.push({
id: "forecast-" + source.stat_energy_from, id: "forecast-" + source.stat_energy_from,
type: "line", type: "line",
stack: "forecast",
name: this.hass.localize( name: this.hass.localize(
"ui.panel.lovelace.cards.energy.energy_solar_graph.forecast", "ui.panel.lovelace.cards.energy.energy_solar_graph.forecast",
{ {

View File

@ -300,6 +300,8 @@ export class HuiEnergyUsageGraphCard
type: "bar", type: "bar",
stack: "usage", stack: "usage",
data: [], 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); fillDataGapsAndRoundCaps(datasets);
this._chartData = datasets; this._chartData = datasets;
} }
@ -482,7 +486,7 @@ export class HuiEnergyUsageGraphCard
this._compareStart! this._compareStart!
); );
Object.entries(combinedData).forEach(([type, sources]) => { Object.entries(combinedData).forEach(([type, sources], idx) => {
Object.entries(sources).forEach(([statId, source]) => { Object.entries(sources).forEach(([statId, source]) => {
const points: BarSeriesOption["data"] = []; const points: BarSeriesOption["data"] = [];
// Process chart data. // Process chart data.
@ -513,6 +517,13 @@ export class HuiEnergyUsageGraphCard
statId, statId,
statisticsMetaData[statId] statisticsMetaData[statId]
), ),
// @ts-expect-error
order:
type === "used_solar"
? 1
: type === "to_battery"
? Object.keys(combinedData).length
: idx + 2,
barMaxWidth: 50, barMaxWidth: 50,
itemStyle: { itemStyle: {
borderColor: getEnergyColor( borderColor: getEnergyColor(

View File

@ -6122,7 +6122,12 @@
}, },
"network_adapter": "Network adapter", "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.", "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": { "storage": {
"caption": "Storage", "caption": "Storage",

View File

@ -10,7 +10,7 @@ let textMeasureCanvas: HTMLCanvasElement | undefined;
export function measureTextWidth( export function measureTextWidth(
text: string, text: string,
fontSize: number, fontSize: number,
fontFamily = "sans-serif" fontFamily = "Roboto, Noto, sans-serif"
): number { ): number {
if (!textMeasureCanvas) { if (!textMeasureCanvas) {
textMeasureCanvas = document.createElement("canvas"); textMeasureCanvas = document.createElement("canvas");