Merge branch 'rc'

This commit is contained in:
Bram Kragten 2025-07-04 13:53:23 +02:00
commit fe946eb75b
6 changed files with 140 additions and 104 deletions

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
version = "20250702.0"
version = "20250702.1"
license = "Apache-2.0"
license-files = ["LICENSE*"]
description = "The Home Assistant frontend"

View File

@ -390,6 +390,7 @@ export class HaChartBase extends LitElement {
type: "inside",
orient: "horizontal",
filterMode: "none",
xAxisIndex: 0,
moveOnMouseMove: !this._isTouchDevice || this._isZoomed,
preventDefaultMouseMove: !this._isTouchDevice || this._isZoomed,
zoomLock: !this._isTouchDevice && !this._modifierPressed,

View File

@ -24,6 +24,10 @@ const MANUAL_SCHEMA = [
{ name: "media_content_type", required: false, selector: { text: {} } },
] as const;
const INCLUDE_DOMAINS = ["media_player"];
const EMPTY_FORM = {};
@customElement("ha-selector-media")
export class HaMediaSelector extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -84,7 +88,7 @@ export class HaMediaSelector extends LitElement {
(stateObj &&
supportsFeature(stateObj, MediaPlayerEntityFeature.BROWSE_MEDIA));
const hasAccept = this.selector.media?.accept?.length;
const hasAccept = this.selector?.media?.accept?.length;
return html`
${hasAccept
@ -100,7 +104,7 @@ export class HaMediaSelector extends LitElement {
.disabled=${this.disabled}
.helper=${this.helper}
.required=${this.required}
include-domains='["media_player"]'
.includeDomains=${INCLUDE_DOMAINS}
allow-custom-entity
@value-changed=${this._entityChanged}
></ha-entity-picker>
@ -114,7 +118,7 @@ export class HaMediaSelector extends LitElement {
</ha-alert>
<ha-form
.hass=${this.hass}
.data=${this.value}
.data=${this.value || EMPTY_FORM}
.schema=${MANUAL_SCHEMA}
.computeLabel=${this._computeLabelCallback}
></ha-form>
@ -122,21 +126,19 @@ export class HaMediaSelector extends LitElement {
: html`
<ha-card
outlined
tabindex="0"
role="button"
aria-label=${!this.value?.media_content_id
? this.hass.localize("ui.components.selectors.media.pick_media")
: this.value.metadata?.title || this.value.media_content_id}
@click=${this._pickMedia}
@keydown=${this._handleKeyDown}
class=${this.disabled || (!this.value?.entity_id && !hasAccept)
? "disabled"
: ""}
>
<div
class="thumbnail ${classMap({
portrait:
!!this.value?.metadata?.media_class &&
MediaClassBrowserSettings[
this.value.metadata.children_media_class ||
this.value.metadata.media_class
].thumbnail_ratio === "portrait",
})}"
>
<div class="content-container">
<div class="thumbnail">
${this.value?.metadata?.thumbnail
? html`
<div
@ -180,6 +182,7 @@ export class HaMediaSelector extends LitElement {
)
: this.value.metadata?.title || this.value.media_content_id}
</div>
</div>
</ha-card>
`}
`;
@ -229,6 +232,13 @@ export class HaMediaSelector extends LitElement {
});
}
private _handleKeyDown(ev: KeyboardEvent) {
if (ev.key === "Enter" || ev.key === " ") {
ev.preventDefault();
this._pickMedia();
}
}
static styles = css`
ha-entity-picker {
display: block;
@ -243,41 +253,52 @@ export class HaMediaSelector extends LitElement {
}
ha-card {
position: relative;
width: 200px;
width: 100%;
box-sizing: border-box;
cursor: pointer;
transition: background-color 180ms ease-in-out;
min-height: 56px;
}
ha-card:hover:not(.disabled),
ha-card:focus:not(.disabled) {
background-color: var(--state-icon-hover-color, rgba(0, 0, 0, 0.04));
}
ha-card:focus {
outline: none;
}
ha-card.disabled {
pointer-events: none;
color: var(--disabled-text-color);
}
.content-container {
display: flex;
align-items: center;
padding: 8px;
gap: 12px;
}
ha-card .thumbnail {
width: 100%;
width: 40px;
height: 40px;
flex-shrink: 0;
position: relative;
box-sizing: border-box;
transition: padding-bottom 0.1s ease-out;
padding-bottom: 100%;
}
ha-card .thumbnail.portrait {
padding-bottom: 150%;
border-radius: 8px;
overflow: hidden;
}
ha-card .image {
border-radius: 3px 3px 0 0;
border-radius: 8px;
}
.folder {
--mdc-icon-size: calc(var(--media-browse-item-size, 175px) * 0.4);
--mdc-icon-size: 24px;
}
.title {
font-size: var(--ha-font-size-l);
padding-top: 16px;
font-size: var(--ha-font-size-m);
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 16px;
padding-left: 16px;
padding-right: 4px;
padding-inline-start: 16px;
padding-inline-end: 4px;
white-space: nowrap;
line-height: 1.4;
flex: 1;
min-width: 0;
}
.image {
position: absolute;
@ -290,13 +311,15 @@ export class HaMediaSelector extends LitElement {
background-position: center;
}
.centered-image {
margin: 0 8px;
margin: 4px;
background-size: contain;
}
.icon-holder {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
`;
}

View File

@ -2,12 +2,19 @@ import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../../../common/dom/fire_event";
import "../../../../../components/ha-selector/ha-selector-media";
import "../../../../../components/ha-selector/ha-selector";
import type { PlayMediaAction } from "../../../../../data/script";
import type { MediaSelectorValue } from "../../../../../data/selector";
import type {
MediaSelectorValue,
Selector,
} from "../../../../../data/selector";
import type { HomeAssistant } from "../../../../../types";
import type { ActionElement } from "../ha-automation-action-row";
const MEDIA_SELECTOR_SCHEMA: Selector = {
media: {},
};
@customElement("ha-automation-action-play_media")
export class HaPlayMediaAction extends LitElement implements ActionElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -38,12 +45,13 @@ export class HaPlayMediaAction extends LitElement implements ActionElement {
protected render() {
return html`
<ha-selector-media
<ha-selector
.selector=${MEDIA_SELECTOR_SCHEMA}
.hass=${this.hass}
.disabled=${this.disabled}
.value=${this._getSelectorValue(this.action)}
@value-changed=${this._valueChanged}
></ha-selector-media>
></ha-selector>
`;
}

View File

@ -243,11 +243,11 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
);
let itemsToShow = this._config?.forecast_slots ?? 5;
if (this._sizeController.value.width === "very-very-narrow") {
if (this._sizeController.value?.width === "very-very-narrow") {
itemsToShow = Math.min(3, itemsToShow);
} else if (this._sizeController.value.width === "very-narrow") {
} else if (this._sizeController.value?.width === "very-narrow") {
itemsToShow = Math.min(5, itemsToShow);
} else if (this._sizeController.value.width === "narrow") {
} else if (this._sizeController.value?.width === "narrow") {
itemsToShow = Math.min(7, itemsToShow);
}
@ -266,8 +266,12 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
return html`
<ha-card
class=${classMap({
[this._sizeController.value.height]: true,
[this._sizeController.value.width]: true,
[this._sizeController.value?.height]: Boolean(
this._sizeController.value
),
[this._sizeController.value?.width]: Boolean(
this._sizeController.value
),
})}
@action=${this._handleAction}
.actionHandler=${actionHandler({

View File

@ -5890,7 +5890,7 @@
"not_ready": "{count} not ready",
"nvm_backup": {
"title": "Backup and restore",
"description": "Back up or restore your Z-Wave controller's non-volatile memory (NVM). The NVM contains your network information including paired devices. It's recommended to create a backup before making any major changes to your Z-Wave network.",
"description": "Back up or restore your Z-Wave adapter's non-volatile memory (NVM). The NVM contains your network information including paired devices. It's recommended to create a backup before making any major changes to your Z-Wave network.",
"download_backup": "Download backup",
"restore_backup": "Restore from backup",
"backup_failed": "Failed to download backup",
@ -5898,21 +5898,21 @@
"restore_failed": "Failed to restore backup",
"creating": "Creating backup",
"restoring": "Restoring backup",
"migrate": "Migrate controller"
"migrate": "Migrate adapter"
},
"statistics": {
"title": "Controller statistics",
"title": "Adapter statistics",
"messages_tx": {
"label": "Messages TX",
"tooltip": "Number of messages successfully sent to the controller"
"tooltip": "Number of messages successfully sent to the adapter"
},
"messages_rx": {
"label": "Messages RX",
"tooltip": "Number of messages successfully received by the controller"
"tooltip": "Number of messages successfully received by the adapter"
},
"messages_dropped_tx": {
"label": "Dropped messages TX",
"tooltip": "Number of messages from the controller that were dropped by the host"
"tooltip": "Number of messages from the adapter that were dropped by the host"
},
"messages_dropped_rx": {
"label": "Dropped messages RX",
@ -5920,23 +5920,23 @@
},
"nak": {
"label": "NAK",
"tooltip": "Number of messages that the controller did not accept"
"tooltip": "Number of messages that the adapter did not accept"
},
"can": {
"label": "CAN",
"tooltip": "Number of collisions while sending a message to the controller"
"tooltip": "Number of collisions while sending a message to the adapter"
},
"timeout_ack": {
"label": "Timeout ACK",
"tooltip": "Number of transmission attempts where an ACK was missing from the controller"
"tooltip": "Number of transmission attempts where an ACK was missing from the adapter"
},
"timeout_response": {
"label": "Timeout response",
"tooltip": "Number of transmission attempts where the controller response did not come in time"
"tooltip": "Number of transmission attempts where the adapter response did not come in time"
},
"timeout_callback": {
"label": "Timeout callback",
"tooltip": "Number of transmission attempts where the controller callback did not come in time"
"tooltip": "Number of transmission attempts where the adapter callback did not come in time"
}
}
},
@ -5959,18 +5959,18 @@
},
"hard_reset_controller": {
"NotStarted": {
"title": "Reset controller to factory settings",
"body": "If you decide to move forward, you will reset your controller to factory settings. As a result, the controller will forget all devices it is paired with and all Z-Wave devices for this network will be removed from Home Assistant. If there are any devices still paired with the controller when it is reset, they will have to go through the exclusion process before they can be re-paired. Would you like to continue?"
"title": "Reset adapter to factory settings",
"body": "If you decide to move forward, you will reset your adapter to factory settings. As a result, the adapter will forget all devices it is paired with and all Z-Wave devices for this network will be removed from Home Assistant. If there are any devices still paired with the adapter when it is reset, they will have to go through the exclusion process before they can be re-paired. Would you like to continue?"
},
"InProgress": {
"title": "Resetting controller",
"body": "Your controller is being reset and restarted. Wait until the process is complete before closing this dialog"
"title": "Resetting adapter",
"body": "Your adapter is being reset and restarted. Wait until the process is complete before closing this dialog"
},
"Done": {
"title": "Controller reset complete",
"body": "Your controller has been reset to factory settings and has been restarted! You can now close this dialog."
"title": "Adapter reset complete",
"body": "Your adapter has been reset to factory settings and has been restarted! You can now close this dialog."
},
"confirmation": "This action cannot be undone unless you have an NVM backup from your controller."
"confirmation": "This action cannot be undone unless you have a backup from your adapter."
},
"node_statistics": {
"title": "Device statistics",
@ -6035,7 +6035,7 @@
},
"rssi": {
"label": "RSSI",
"tooltip": "The RSSI of the ACK frame received by the controller"
"tooltip": "The RSSI of the ACK frame received by the adapter"
},
"route_failed_between": {
"label": "Route failed between",
@ -6254,7 +6254,7 @@
},
"rebuild_node_routes": {
"title": "Rebuild routes for a Z-Wave device",
"introduction": "Tell {device} to update its routes back to the controller. This can help with communication issues if you have recently moved the device or your controller.",
"introduction": "Assign new routes between {device} and the adapter. This can help with communication issues if you have recently moved the device or your adapter.",
"traffic_warning": "The route rebuilding process generates a large amount of traffic on the Z-Wave network. This may cause devices to respond slowly (or not at all) while the rebuilding is in progress.",
"start_rebuilding_routes": "Rebuild Routes for Device",
"rebuilding_routes_failed": "{device} routes could not be rebuild.",
@ -6266,7 +6266,7 @@
"update_firmware": {
"title": "Update device firmware",
"warning": "WARNING: Firmware updates can brick your device if you do not correctly follow the manufacturer's guidance. The Home Assistant and Z-Wave JS teams do not take any responsibility for any damages to your device as a result of the firmware update and will not be able to help you if you brick your device. Would you still like to continue?",
"warning_controller": "WARNING: Firmware updates can brick your controller if you do not use the right firmware files, or if you attempt to stop the firmware update before it completes. The Home Assistant and Z-Wave JS teams do not take any responsibility for any damages to your controller as a result of the firmware update and will not be able to help you if you brick your controller. Would you still like to continue?",
"warning_controller": "WARNING: Firmware updates can brick your adapter if you do not use the right firmware files, or if you attempt to stop the firmware update before it completes. The Home Assistant and Z-Wave JS teams do not take any responsibility for any damages to your adapter as a result of the firmware update and will not be able to help you if you brick your adapter. Would you still like to continue?",
"introduction": "Select the firmware file you would like to use to update {device}.",
"introduction_controller": "Select the firmware file you would like to use to update {device}. Note that once you start a firmware update, you MUST wait for the update to complete.",
"firmware_target_intro": "Select the firmware target (0 for the Z-Wave chip, ≥1 for other chips if they exist) for this update.",
@ -6287,7 +6287,7 @@
"error": "Unable to update firmware on {device}: {message}.",
"try_again": "To attempt the firmware update again, select the new firmware file you would like to use.",
"done": "The firmware update is complete! If you want to attempt another firmware update on this device, please wait until it gets re-interviewed.",
"done_controller": "The firmware update is complete! Your controller is being restarted and your network will temporarily be unavailable.",
"done_controller": "The firmware update is complete! Your adapter is being restarted and your network will temporarily be unavailable.",
"Error_Timeout": "Timed out",
"Error_Checksum": "Checksum error",
"Error_TransmissionFailed": "Transmission failed",