((panel) => ({
value: panel.url_path,
label:
- panel.url_path === defaultPanel
- ? panel.title || this.hass.localize("panel.states")
- : this.hass.localize(`panel.${panel.title}`) || panel.title || "?",
- icon: panel.icon || undefined,
- iconPath:
- panel.url_path === defaultPanel && !panel.icon
- ? PANEL_ICONS.lovelace
- : panel.url_path in PANEL_ICONS
- ? PANEL_ICONS[panel.url_path]
- : undefined,
- disableSorting: panel.url_path === "developer-tools",
+ (getPanelTitle(this.hass, panel) || panel.url_path) +
+ `${defaultPanel === panel.url_path ? " (default)" : ""}`,
+ icon: getPanelIcon(panel),
+ iconPath: getPanelIconPath(panel),
+ disableSorting: SHOW_AFTER_SPACER_PANELS.includes(panel.url_path),
+ disableHiding: panel.url_path === defaultPanel,
}));
- return html`
- `;
+ return html`
+
+
+ `;
}
protected render() {
@@ -171,6 +188,22 @@ class DialogEditSidebar extends LitElement {
>${this.hass.localize("ui.sidebar.edit_subtitle")}`
: nothing}
+
+
+
+
+ ${this.hass.localize("ui.sidebar.reset_to_defaults")}
+
+
${this._renderContent()}
@@ -194,6 +227,26 @@ class DialogEditSidebar extends LitElement {
this._hidden = [...hidden];
}
+ private _resetToDefaults = async () => {
+ const confirmation = await showConfirmationDialog(this, {
+ text: this.hass.localize("ui.sidebar.reset_confirmation"),
+ confirmText: this.hass.localize("ui.common.reset"),
+ });
+
+ if (!confirmation) {
+ return;
+ }
+
+ this._order = [];
+ this._hidden = [];
+ try {
+ await saveFrontendUserData(this.hass.connection, "sidebar", {});
+ } catch (err: any) {
+ this._error = err.message || err;
+ }
+ this.closeDialog();
+ };
+
private async _save() {
if (this._migrateToUserData) {
const confirmation = await showConfirmationDialog(this, {
diff --git a/src/panels/config/lovelace/dashboards/dialog-lovelace-dashboard-detail.ts b/src/panels/config/lovelace/dashboards/dialog-lovelace-dashboard-detail.ts
index a113f06b47b0..01ce8be93756 100644
--- a/src/panels/config/lovelace/dashboards/dialog-lovelace-dashboard-detail.ts
+++ b/src/panels/config/lovelace/dashboards/dialog-lovelace-dashboard-detail.ts
@@ -8,16 +8,13 @@ import "../../../../components/ha-button";
import { createCloseHeading } from "../../../../components/ha-dialog";
import "../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../components/ha-form/types";
-import { saveFrontendSystemData } from "../../../../data/frontend";
import type {
LovelaceDashboard,
LovelaceDashboardCreateParams,
LovelaceDashboardMutableParams,
} from "../../../../data/lovelace/dashboard";
-import { DEFAULT_PANEL } from "../../../../data/panel";
import { haStyleDialog } from "../../../../resources/styles";
import type { HomeAssistant } from "../../../../types";
-import { showConfirmationDialog } from "../../../lovelace/custom-card-helpers";
import type { LovelaceDashboardDetailsDialogParams } from "./show-dialog-lovelace-dashboard-detail";
@customElement("dialog-lovelace-dashboard-detail")
@@ -61,9 +58,9 @@ export class DialogLovelaceDashboardDetail extends LitElement {
if (!this._params || !this._data) {
return nothing;
}
- const defaultPanelUrlPath =
- this.hass.systemData?.default_panel || DEFAULT_PANEL;
+
const titleInvalid = !this._data.title || !this._data.title.trim();
+ const isLovelaceDashboard = this._params.urlPath === "lovelace";
return html`
`
- : ""}
-
- ${this._params.urlPath === defaultPanelUrlPath
- ? this.hass.localize(
- "ui.panel.config.lovelace.dashboards.detail.remove_default"
- )
- : this.hass.localize(
- "ui.panel.config.lovelace.dashboards.detail.set_default"
- )}
-
+ : nothing}
`
- : ""}
+ : nothing}
& {
default: boolean;
filename: string;
+ localized_type: string;
type: string;
};
@@ -112,7 +126,7 @@ export class HaConfigLovelaceDashboards extends LitElement {
state: false,
subscribe: false,
})
- private _activeGrouping?: string = "type";
+ private _activeGrouping?: string = "localized_type";
@storage({
key: "lovelace-dashboards-table-collapsed",
@@ -167,7 +181,7 @@ export class HaConfigLovelaceDashboards extends LitElement {
this._handleSetAsDefault(dashboard),
+ disabled: dashboard.default,
+ },
+ ...(dashboard.type === "user_created"
? [
{
path: mdiPencil,
@@ -262,10 +284,6 @@ export class HaConfigLovelaceDashboards extends LitElement {
),
action: () => this._handleEdit(dashboard),
},
- ]
- : []),
- ...(this._canDelete(dashboard.url_path)
- ? [
{
label: this.hass.localize(
"ui.panel.config.lovelace.dashboards.picker.delete"
@@ -288,92 +306,43 @@ export class HaConfigLovelaceDashboards extends LitElement {
private _getItems = memoize(
(dashboards: LovelaceDashboard[], defaultUrlPath: string | null) => {
- const defaultMode = (
- this.hass.panels?.lovelace?.config as LovelacePanelConfig
- ).mode;
+ const mode = (this.hass.panels?.lovelace?.config as LovelacePanelConfig)
+ .mode;
const isDefault = defaultUrlPath === "lovelace";
const result: DataTableItem[] = [
{
icon: "mdi:view-dashboard",
title: this.hass.localize("panel.states"),
default: isDefault,
- show_in_sidebar: isDefault,
+ show_in_sidebar: true,
require_admin: false,
url_path: "lovelace",
- mode: defaultMode,
- filename: defaultMode === "yaml" ? "ui-lovelace.yaml" : "",
- type: this._localizeType("built_in"),
+ mode: mode,
+ filename: mode === "yaml" ? "ui-lovelace.yaml" : "",
+ type: "built_in",
+ localized_type: this._localizeType("built_in"),
},
];
- if (isComponentLoaded(this.hass, "energy")) {
- result.push({
- icon: "mdi:lightning-bolt",
- title: this.hass.localize(`ui.panel.config.dashboard.energy.main`),
- show_in_sidebar: true,
- mode: "storage",
- url_path: "energy",
- filename: "",
- default: false,
- require_admin: false,
- type: this._localizeType("built_in"),
- });
- }
-
- if (this.hass.panels.light) {
- result.push({
- icon: this.hass.panels.light.icon || "mdi:lamps",
- title: this.hass.localize("panel.light"),
- show_in_sidebar: true,
- mode: "storage",
- url_path: "light",
- filename: "",
- default: false,
- require_admin: false,
- type: this._localizeType("built_in"),
- });
- }
- if (this.hass.panels.security) {
- result.push({
- icon: this.hass.panels.security.icon || "mdi:security",
- title: this.hass.localize("panel.security"),
- show_in_sidebar: true,
- mode: "storage",
- url_path: "security",
- filename: "",
- default: false,
- require_admin: false,
- type: this._localizeType("built_in"),
- });
- }
-
- if (this.hass.panels.climate) {
- result.push({
- icon: this.hass.panels.climate.icon || "mdi:home-thermometer",
- title: this.hass.localize("panel.climate"),
- show_in_sidebar: true,
- mode: "storage",
- url_path: "climate",
- filename: "",
- default: false,
- require_admin: false,
- type: this._localizeType("built_in"),
- });
- }
-
- if (this.hass.panels.home) {
- result.push({
- icon: this.hass.panels.home.icon || "mdi:home",
- title: this.hass.localize("panel.home"),
+ PANEL_DASHBOARDS.forEach((panel) => {
+ const panelInfo = this.hass.panels[panel];
+ if (!panel) {
+ return;
+ }
+ const item: DataTableItem = {
+ icon: getPanelIcon(panelInfo),
+ title: getPanelTitle(this.hass, panelInfo) || panelInfo.url_path,
show_in_sidebar: true,
mode: "storage",
- url_path: "home",
+ url_path: panelInfo.url_path,
filename: "",
- default: false,
+ default: defaultUrlPath === panelInfo.url_path,
require_admin: false,
- type: this._localizeType("built_in"),
- });
- }
+ type: "built_in",
+ localized_type: this._localizeType("built_in"),
+ };
+ result.push(item);
+ });
result.push(
...dashboards
@@ -386,7 +355,8 @@ export class HaConfigLovelaceDashboards extends LitElement {
filename: "",
...dashboard,
default: defaultUrlPath === dashboard.url_path,
- type: this._localizeType("user_created"),
+ type: "user_created",
+ localized_type: this._localizeType("user_created"),
}) satisfies DataTableItem
)
);
@@ -486,20 +456,32 @@ export class HaConfigLovelaceDashboards extends LitElement {
this._openDetailDialog(dashboard, urlPath);
}
- private _canDelete(urlPath: string) {
- return ![
- "lovelace",
- "energy",
- "light",
- "security",
- "climate",
- "home",
- ].includes(urlPath);
- }
+ private _handleSetAsDefault = async (item: DataTableItem) => {
+ if (item.default) {
+ return;
+ }
- private _canEdit(urlPath: string) {
- return !["light", "security", "climate", "home"].includes(urlPath);
- }
+ const confirm = await showConfirmationDialog(this, {
+ title: this.hass.localize(
+ "ui.panel.config.lovelace.dashboards.detail.set_default_confirm_title"
+ ),
+ text: this.hass.localize(
+ "ui.panel.config.lovelace.dashboards.detail.set_default_confirm_text"
+ ),
+ confirmText: this.hass.localize("ui.common.ok"),
+ dismissText: this.hass.localize("ui.common.cancel"),
+ destructive: false,
+ });
+
+ if (!confirm) {
+ return;
+ }
+
+ await saveFrontendSystemData(this.hass.connection, "core", {
+ ...this.hass.systemData,
+ default_panel: item.url_path,
+ });
+ };
private _handleDelete = async (item: DataTableItem) => {
const dashboard = this._dashboards.find(
@@ -581,10 +563,6 @@ export class HaConfigLovelaceDashboards extends LitElement {
private async _deleteDashboard(
dashboard: LovelaceDashboard
): Promise {
- if (!this._canDelete(dashboard.url_path)) {
- return false;
- }
-
const confirm = await showConfirmationDialog(this, {
title: this.hass!.localize(
"ui.panel.config.lovelace.dashboards.confirm_delete_title",
diff --git a/src/panels/profile/ha-pick-dashboard-row.ts b/src/panels/profile/ha-pick-dashboard-row.ts
index bb4163cf736e..4df5e24e38b8 100644
--- a/src/panels/profile/ha-pick-dashboard-row.ts
+++ b/src/panels/profile/ha-pick-dashboard-row.ts
@@ -1,13 +1,16 @@
import type { PropertyValues, TemplateResult } from "lit";
-import { html, LitElement } from "lit";
+import { html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
+import "../../components/ha-divider";
import "../../components/ha-list-item";
import "../../components/ha-select";
import "../../components/ha-settings-row";
+import { saveFrontendUserData } from "../../data/frontend";
import type { LovelaceDashboard } from "../../data/lovelace/dashboard";
import { fetchDashboards } from "../../data/lovelace/dashboard";
-import type { HomeAssistant } from "../../types";
-import { saveFrontendUserData } from "../../data/frontend";
+import { getPanelTitle } from "../../data/panel";
+import type { HomeAssistant, PanelInfo } from "../../types";
+import { PANEL_DASHBOARDS } from "../config/lovelace/dashboards/ha-config-lovelace-dashboards";
const USE_SYSTEM_VALUE = "___use_system___";
@@ -47,12 +50,24 @@ class HaPickDashboardRow extends LitElement {
${this.hass.localize("ui.panel.profile.dashboard.system")}
+
${this.hass.localize("ui.panel.profile.dashboard.lovelace")}
-
- ${this.hass.localize("ui.panel.profile.dashboard.home")}
-
+ ${PANEL_DASHBOARDS.map((panel) => {
+ const panelInfo = this.hass.panels[panel] as
+ | PanelInfo
+ | undefined;
+ if (!panelInfo) {
+ return nothing;
+ }
+ return html`
+
+ ${getPanelTitle(this.hass, panelInfo)}
+
+ `;
+ })}
+
${this._dashboards.map((dashboard) => {
if (!this.hass.user!.is_admin && dashboard.require_admin) {
return "";
diff --git a/src/translations/en.json b/src/translations/en.json
index 5e96e900c591..e43531522a98 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2217,7 +2217,9 @@
"sidebar_toggle": "Sidebar toggle",
"edit_sidebar": "Edit sidebar",
"edit_subtitle": "Synced on all devices",
- "migrate_to_user_data": "This will change the sidebar on all the devices you are logged in to. To create a sidebar per device, you should use a different user for that device."
+ "migrate_to_user_data": "This will change the sidebar on all the devices you are logged in to. To create a sidebar per device, you should use a different user for that device.",
+ "reset_to_defaults": "Reset to defaults",
+ "reset_confirmation": "Are you sure you want to reset the sidebar to its default configuration? This will restore the original order and visibility of all panels."
},
"panel": {
"home": {
@@ -3508,6 +3510,7 @@
"edit": "Edit",
"delete": "Delete",
"add_dashboard": "Add dashboard",
+ "set_as_default": "Set as default",
"type": {
"user_created": "User created",
"built_in": "Built-in"
@@ -3516,7 +3519,7 @@
"confirm_delete_title": "Delete {dashboard_title}?",
"confirm_delete_text": "This dashboard will be permanently deleted.",
"cant_edit_yaml": "Dashboards created in YAML cannot be edited from the UI. Change them in configuration.yaml.",
- "cant_edit_default": "The default dashboard, Overview, cannot be edited from the UI. You can hide it by setting another dashboard as default.",
+ "cant_edit_lovelace": "The Overview dashboard title and icon cannot be changed. You can create a new dashboard to get more customization options.",
"detail": {
"edit_dashboard": "Edit dashboard",
"new_dashboard": "Add new dashboard",
@@ -3533,9 +3536,7 @@
"set_default": "Set as default",
"remove_default": "Remove as default",
"set_default_confirm_title": "Set as default dashboard?",
- "set_default_confirm_text": "This will replace the current default dashboard. Users can still override their default dashboard in their profile settings.",
- "remove_default_confirm_title": "Remove default dashboard?",
- "remove_default_confirm_text": "The default dashboard will be changed to Overview for every user. Users can still override their default dashboard in their profile settings."
+ "set_default_confirm_text": "This dashboard will be shown to all users when opening Home Assistant. Each user can change this in their profile."
}
},
"resources": {