Compare commits

..

14 Commits

Author SHA1 Message Date
Bram Kragten
d98e373f64 Bumped version to 20260128.6 2026-02-04 15:41:09 +01:00
Paul Bottein
649516c9fa Change default icon for blank area if not icon configured (#29394) 2026-02-04 15:40:36 +01:00
Paul Bottein
bbc4fb96b2 Load domain translation when integration page load (#29391) 2026-02-04 15:40:35 +01:00
Paul Bottein
0ae639aeb0 Remove old lovelace overview from pickers (#29390) 2026-02-04 15:40:34 +01:00
karwosts
0e7e41065e Don't shrink ha-dropdown checkboxes (#29387) 2026-02-04 15:40:33 +01:00
Paul Bottein
685843f112 Add translations for new overview dialog (#29382) 2026-02-04 15:40:32 +01:00
Paul Bottein
5e1a99d94a Use area icon for area empty state (#29371) 2026-02-04 15:40:31 +01:00
Bram Kragten
d843349865 Bumped version to 20260128.5 2026-02-03 16:58:01 +01:00
Paul Bottein
ec23164aa9 Improve other devices page in home dashboard (#29370) 2026-02-03 16:57:45 +01:00
Paul Bottein
e74ef11101 Hide edit and delete actions for YAML dashboards in config (#29368)
YAML dashboards are defined in configuration files and cannot be
modified or deleted through the UI. This change ensures the edit
and delete actions are only shown for storage-mode dashboards.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 16:57:43 +01:00
Paul Bottein
a222f6a736 Add missing danger variant in dropdown item (#29359) 2026-02-03 16:57:40 +01:00
Petar Petrov
ef3dd16d45 Move dialog scrim to pseudo-element (#29357) 2026-02-03 16:57:39 +01:00
karwosts
5d4e1d205e Fix missing imports in devtools-statistics (#29355) 2026-02-03 16:57:38 +01:00
Darryn Capes-Davis
1ee5ebbe75 Fix CSS minification issue for ha-card (#29354) 2026-02-03 16:57:37 +01:00
20 changed files with 111 additions and 101 deletions

View File

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

View File

@@ -51,6 +51,7 @@ export class HaCard extends LitElement {
font-weight: var(--ha-font-weight-normal);
}
/* clean-css ignore:start */
:host
::slotted(
.card-content:not(:nth-child(1 of .card-content, .card-header))
@@ -59,6 +60,7 @@ export class HaCard extends LitElement {
padding-top: 0;
margin-top: calc(var(--ha-space-2) * -1);
}
/* clean-css ignore:end */
:host ::slotted(.card-content) {
padding: var(--ha-space-4);

View File

@@ -76,6 +76,18 @@ export class HaDialog extends DialogBase {
var(--divider-color)
);
z-index: var(--dialog-z-index, 8);
--mdc-dialog-box-shadow: var(--dialog-box-shadow, none);
--mdc-typography-headline6-font-weight: var(--ha-font-weight-normal);
--mdc-typography-headline6-font-size: 1.574rem;
}
.mdc-dialog::before {
content: "";
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
pointer-events: none;
-webkit-backdrop-filter: var(
--ha-dialog-scrim-backdrop-filter,
var(--dialog-backdrop-filter, none)
@@ -84,9 +96,6 @@ export class HaDialog extends DialogBase {
--ha-dialog-scrim-backdrop-filter,
var(--dialog-backdrop-filter, none)
);
--mdc-dialog-box-shadow: var(--dialog-box-shadow, none);
--mdc-typography-headline6-font-weight: var(--ha-font-weight-normal);
--mdc-typography-headline6-font-size: 1.574rem;
}
.mdc-dialog .mdc-dialog__scrim {
background-color: var(--mdc-dialog-scrim-color, none);

View File

@@ -37,6 +37,7 @@ export class HaDropdownItem extends DropdownItem {
#check {
visibility: visible;
flex-shrink: 0;
}
#icon ::slotted(*) {

View File

@@ -260,12 +260,7 @@ export class HaNavigationPicker extends LitElement {
const viewConfigs = await Promise.all(
lovelacePanels.map((panel) =>
fetchConfig(
this.hass!.connection,
// path should be null to fetch default lovelace panel
panel.url_path === "lovelace" ? null : panel.url_path,
true
)
fetchConfig(this.hass!.connection, panel.url_path, true)
.then((config) => [panel.id, config] as [string, typeof config])
.catch((_) => [panel.id, undefined] as [string, undefined])
)

View File

@@ -239,9 +239,8 @@ class HaConfigAreaPage extends LitElement {
${this.hass.localize("ui.panel.config.areas.edit_settings")}
</ha-dropdown-item>
<ha-dropdown-item value="delete">
<ha-svg-icon class="warning" slot="icon" .path=${mdiDelete}>
</ha-svg-icon>
<ha-dropdown-item value="delete" variant="danger">
<ha-svg-icon slot="icon" .path=${mdiDelete}> </ha-svg-icon>
${this.hass.localize("ui.panel.config.areas.editor.delete")}
</ha-dropdown-item>
</ha-dropdown>

View File

@@ -224,9 +224,8 @@ export class HaConfigAreasDashboard extends LitElement {
"ui.panel.config.areas.picker.floor.edit_floor"
)}</ha-dropdown-item
>
<ha-dropdown-item value="delete" class="warning"
<ha-dropdown-item value="delete" variant="danger"
><ha-svg-icon
class="warning"
.path=${mdiDelete}
slot="icon"
></ha-svg-icon
@@ -727,9 +726,6 @@ export class HaConfigAreasDashboard extends LitElement {
align-items: center;
overflow-wrap: anywhere;
}
.warning {
color: var(--error-color);
}
`;
}

View File

@@ -123,7 +123,7 @@ class HaConfigBackupDetails extends LitElement {
<ha-svg-icon slot="icon" .path=${mdiDownload}></ha-svg-icon>
${this.hass.localize("ui.common.download")}
</ha-dropdown-item>
<ha-dropdown-item value="delete" class="warning">
<ha-dropdown-item value="delete" variant="danger">
<ha-svg-icon slot="icon" .path=${mdiDelete}></ha-svg-icon>
${this.hass.localize("ui.common.delete")}
</ha-dropdown-item>
@@ -385,12 +385,6 @@ class HaConfigBackupDetails extends LitElement {
--mdc-icon-size: 48px;
color: var(--primary-text-color);
}
.warning {
color: var(--error-color);
}
.warning ha-svg-icon {
color: var(--error-color);
}
ha-button.danger {
--mdc-theme-primary: var(--error-color);
}

View File

@@ -35,6 +35,8 @@ import "../../../../components/ha-dropdown";
import "../../../../components/ha-dropdown-item";
import type { HaMdMenu } from "../../../../components/ha-md-menu";
import "../../../../components/ha-md-menu-item";
import "../../../../components/ha-md-menu";
import "../../../../components/ha-md-divider";
import "../../../../components/search-input-outlined";
import type {
StatisticsMetaData,

View File

@@ -168,6 +168,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
protected willUpdate(changedProperties: PropertyValues): void {
if (changedProperties.has("domain")) {
this.hass.loadBackendTranslation("title", [this.domain]);
this.hass.loadBackendTranslation("config", [this.domain]);
this.hass.loadBackendTranslation("config_subentries", [this.domain]);
this._extraConfigEntries = undefined;
this._fetchManifest();

View File

@@ -80,7 +80,7 @@ export class DialogLovelaceDashboardDetail extends LitElement {
)}
>
<div>
${this._params.dashboard && !this._params.dashboard.id
${this._params.dashboard?.mode === "yaml"
? this.hass.localize(
"ui.panel.config.lovelace.dashboards.cant_edit_yaml"
)
@@ -97,7 +97,7 @@ export class DialogLovelaceDashboardDetail extends LitElement {
</div>
${this._params.urlPath
? html`
${this._params.dashboard?.id
${this._params.dashboard?.mode === "storage"
? html`
<ha-button
slot="secondaryAction"
@@ -123,7 +123,7 @@ export class DialogLovelaceDashboardDetail extends LitElement {
dialogInitialFocus
>
${this._params.urlPath
? this._params.dashboard?.id
? this._params.dashboard?.mode === "storage"
? this.hass.localize(
"ui.panel.config.lovelace.dashboards.detail.update"
)
@@ -232,8 +232,9 @@ export class DialogLovelaceDashboardDetail extends LitElement {
}
private async _updateDashboard() {
if (this._params?.urlPath && !this._params.dashboard?.id) {
if (this._params?.urlPath && this._params.dashboard?.mode === "yaml") {
this.closeDialog();
return;
}
this._submitting = true;
try {

View File

@@ -281,7 +281,8 @@ export class HaConfigLovelaceDashboards extends LitElement {
action: () => this._handleSetAsDefault(dashboard),
disabled: dashboard.default,
},
...(dashboard.type === "user_created"
...(dashboard.type === "user_created" &&
dashboard.mode === "storage"
? [
{
path: mdiPencil,

View File

@@ -47,39 +47,70 @@ export class DialogNewOverview
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title="Welcome to your new overview"
.headerTitle=${this.hass.localize(
"ui.panel.home.new_overview_dialog.title"
)}
prevent-scrim-close
@closed=${this._dialogClosed}
>
<div class="content">
<p>
The overview dashboard has been redesigned to give you a better
experience managing your smart home.
${this.hass.localize(
"ui.panel.home.new_overview_dialog.description"
)}
</p>
<h3>What's new</h3>
<h3>
${this.hass.localize("ui.panel.home.new_overview_dialog.whats_new")}
</h3>
<ul>
<li>
<strong>Automatic organization</strong> - Your devices are now
automatically organized by area and floor.
<strong>
${this.hass.localize(
"ui.panel.home.new_overview_dialog.automatic_organization"
)}
</strong>
-
${this.hass.localize(
"ui.panel.home.new_overview_dialog.automatic_organization_description"
)}
</li>
<li>
<strong>Favorites</strong> - Pin your most used entities to the
top for quick access.
<strong>
${this.hass.localize(
"ui.panel.home.new_overview_dialog.favorites"
)}
</strong>
-
${this.hass.localize(
"ui.panel.home.new_overview_dialog.favorites_description"
)}
</li>
</ul>
<h3>Your existing dashboards</h3>
<h3>
${this.hass.localize(
"ui.panel.home.new_overview_dialog.existing_dashboards"
)}
</h3>
<p>
Your manual dashboards are still available in the sidebar. This new
overview works alongside them. You can also create a new dashboard
using the "Overview (legacy)" template in
<a href="/config/lovelace/dashboards" @click=${this.closeDialog}
>dashboard settings</a
>.
${this.hass.localize(
"ui.panel.home.new_overview_dialog.existing_dashboards_description",
{
dashboard_settings: html`<a
href="/config/lovelace/dashboards"
@click=${this.closeDialog}
>${this.hass.localize(
"ui.panel.home.new_overview_dialog.dashboard_settings"
)}</a
>`,
}
)}
</p>
</div>
<ha-dialog-footer slot="footer">
<ha-button slot="primaryAction" @click=${this.closeDialog}>
OK, understood
${this.hass.localize(
"ui.panel.home.new_overview_dialog.ok_understood"
)}
</ha-button>
</ha-dialog-footer>
</ha-wa-dialog>

View File

@@ -276,12 +276,12 @@ class PanelHome extends LitElement {
<div class="banner-content">
<ha-svg-icon .path=${mdiHomeAssistant}></ha-svg-icon>
<span class="banner-text">
Welcome to the new overview dashboard.
${this.hass.localize("ui.panel.home.banner.welcome_message")}
</span>
</div>
<div class="banner-actions">
<ha-button size="small" appearance="filled" @click=${this._learnMore}>
Learn more
${this.hass.localize("ui.panel.home.banner.learn_more")}
</ha-button>
</div>
</div>

View File

@@ -394,7 +394,6 @@ export class HuiTodoListCard extends LitElement implements LovelaceCard {
"ui.panel.lovelace.cards.todo-list.clear_items"
)}
<ha-svg-icon
class="warning"
slot="icon"
.path=${mdiDeleteSweep}
>

View File

@@ -152,13 +152,9 @@ export class HuiBadgeEditMode extends LitElement {
${this.hass.localize("ui.panel.lovelace.editor.edit_card.cut")}
</ha-dropdown-item>
<wa-divider></wa-divider>
<ha-dropdown-item value="delete" class="warning">
<ha-dropdown-item value="delete" variant="danger">
${this.hass.localize("ui.panel.lovelace.editor.edit_card.delete")}
<ha-svg-icon
class="warning"
slot="icon"
.path=${mdiDelete}
></ha-svg-icon>
<ha-svg-icon slot="icon" .path=${mdiDelete}></ha-svg-icon>
</ha-dropdown-item>
</ha-dropdown>
</div>

View File

@@ -253,11 +253,6 @@ export class HomeAreaViewStrategy extends ReactiveElement {
device_class: "battery",
});
const energyFilter = generateEntityFilter(hass, {
domain: "sensor",
device_class: ["energy", "power"],
});
const primaryFilter = generateEntityFilter(hass, {
entity_category: "none",
});
@@ -269,7 +264,7 @@ export class HomeAreaViewStrategy extends ReactiveElement {
batteryFilter(e)
);
const entities = deviceEntities.entities.filter(
(e) => !batteryFilter(e) && !energyFilter(e) && primaryFilter(e)
(e) => !batteryFilter(e) && primaryFilter(e)
);
if (entities.length === 0) {
@@ -365,7 +360,7 @@ export class HomeAreaViewStrategy extends ReactiveElement {
cards: [
{
type: "empty-state",
icon: "mdi:sofa-outline",
icon: area.icon || "mdi:shape-square-rounded-plus",
icon_color: "primary",
content_only: true,
title: hass.localize(

View File

@@ -14,6 +14,7 @@ import type { HomeAssistant } from "../../../../types";
import { isHelperDomain } from "../../../config/helpers/const";
import type {
EmptyStateCardConfig,
EntitiesCardConfig,
HeadingCardConfig,
} from "../../cards/types";
import { OTHER_DEVICES_FILTERS } from "./helpers/other-devices-filters";
@@ -78,16 +79,6 @@ export class HomeOtherDevicesViewStrategy extends ReactiveElement {
return !isHelperDomain(domain);
});
const batteryFilter = generateEntityFilter(hass, {
domain: "sensor",
device_class: "battery",
});
const energyFilter = generateEntityFilter(hass, {
domain: "sensor",
device_class: ["energy", "power"],
});
const primaryFilter = generateEntityFilter(hass, {
entity_category: "none",
});
@@ -95,12 +86,7 @@ export class HomeOtherDevicesViewStrategy extends ReactiveElement {
for (const deviceEntities of devicesEntities) {
if (deviceEntities.entities.length === 0) continue;
const batteryEntities = deviceEntities.entities.filter((e) =>
batteryFilter(e)
);
const entities = deviceEntities.entities.filter(
(e) => !batteryFilter(e) && !energyFilter(e) && primaryFilter(e)
);
const entities = deviceEntities.entities.filter((e) => primaryFilter(e));
if (entities.length === 0) {
continue;
@@ -129,13 +115,6 @@ export class HomeOtherDevicesViewStrategy extends ReactiveElement {
}
: { action: "none" },
badges: [
...batteryEntities.slice(0, 1).map((e) => ({
entity: e,
type: "entity",
tap_action: {
action: "more-info",
},
})),
...(config.home_panel && device && hass.user?.is_admin
? [
{
@@ -156,13 +135,13 @@ export class HomeOtherDevicesViewStrategy extends ReactiveElement {
: []),
],
} satisfies HeadingCardConfig,
...entities.map((e) => ({
type: "tile",
entity: e,
name: {
type: "entity",
},
})),
{
type: "entities",
entities: entities.map((e) => ({
entity: e,
name: { type: "entity" },
})),
} satisfies EntitiesCardConfig,
],
});
}

View File

@@ -1,4 +1,3 @@
import { mdiViewDashboard } from "@mdi/js";
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
@@ -7,8 +6,8 @@ import "../../components/ha-icon";
import "../../components/ha-list-item";
import "../../components/ha-select";
import "../../components/ha-settings-row";
import "../../components/ha-svg-icon";
import "../../components/ha-spinner";
import "../../components/ha-svg-icon";
import { saveFrontendUserData } from "../../data/frontend";
import type { LovelaceDashboard } from "../../data/lovelace/dashboard";
import { fetchDashboards } from "../../data/lovelace/dashboard";
@@ -55,13 +54,6 @@ class HaPickDashboardRow extends LitElement {
${this.hass.localize("ui.panel.profile.dashboard.system")}
</ha-list-item>
<ha-divider></ha-divider>
<ha-list-item value="lovelace" graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${mdiViewDashboard}
></ha-svg-icon>
${this.hass.localize("ui.panel.profile.dashboard.lovelace")}
</ha-list-item>
${PANEL_DASHBOARDS.map((panel) => {
const panelInfo = this.hass.panels[panel] as
| PanelInfo

View File

@@ -2312,6 +2312,23 @@
"save_failed": "Failed to save home page configuration",
"areas_hint": "You can rearrange your floors and areas in the order that best represents your house on the {areas_page}.",
"areas_page": "areas page"
},
"new_overview_dialog": {
"title": "Welcome to your new overview",
"description": "The overview dashboard has been redesigned to give you a better experience managing your smart home.",
"whats_new": "What's new",
"automatic_organization": "Automatic organization",
"automatic_organization_description": "Your devices are now automatically organized by area and floor.",
"favorites": "Favorites",
"favorites_description": "Pin your most used entities to the top for quick access.",
"existing_dashboards": "Your existing dashboards",
"existing_dashboards_description": "Your manual dashboards are still available in the sidebar. Miss the old format? You can create a new dashboard using the \"Overview (legacy)\" template in {dashboard_settings} and set it as default.",
"dashboard_settings": "dashboard settings",
"ok_understood": "OK, understood"
},
"banner": {
"welcome_message": "Welcome to the new overview dashboard.",
"learn_more": "Learn more"
}
},
"my": {