Merge 365db51526
into 634e1dbde8
commit
43a8b1d5c2
|
@ -44,7 +44,7 @@ const createPanelNavigationItem = (hass: HomeAssistant, panel: PanelInfo) => ({
|
|||
path: `/${panel.url_path}`,
|
||||
icon: panel.icon ?? "mdi:view-dashboard",
|
||||
title:
|
||||
panel.url_path === hass.defaultPanel
|
||||
panel.url_path === hass.sidebar.defaultPanel
|
||||
? hass.localize("panel.states")
|
||||
: hass.localize(`panel.${panel.title}`) ||
|
||||
panel.title ||
|
||||
|
|
|
@ -50,6 +50,7 @@ import type { HaMdListItem } from "./ha-md-list-item";
|
|||
import "./ha-spinner";
|
||||
import "./ha-svg-icon";
|
||||
import "./user/ha-user-badge";
|
||||
import { DEFAULT_PANEL } from "../data/panel";
|
||||
|
||||
const SHOW_AFTER_SPACER = ["config", "developer-tools"];
|
||||
|
||||
|
@ -140,9 +141,9 @@ const defaultPanelSorter = (
|
|||
export const computePanels = memoizeOne(
|
||||
(
|
||||
panels: HomeAssistant["panels"],
|
||||
defaultPanel: HomeAssistant["defaultPanel"],
|
||||
panelsOrder: string[],
|
||||
hiddenPanels: string[],
|
||||
defaultPanel: HomeAssistant["sidebar"]["defaultPanel"],
|
||||
panelsOrder: HomeAssistant["sidebar"]["panelOrder"],
|
||||
hiddenPanels: HomeAssistant["sidebar"]["hiddenPanels"],
|
||||
locale: HomeAssistant["locale"]
|
||||
): [PanelInfo[], PanelInfo[]] => {
|
||||
if (!panels) {
|
||||
|
@ -195,10 +196,6 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
|||
|
||||
@state() private _issuesCount = 0;
|
||||
|
||||
@state() private _panelOrder?: string[];
|
||||
|
||||
@state() private _hiddenPanels?: string[];
|
||||
|
||||
private _mouseLeaveTimeout?: number;
|
||||
|
||||
private _tooltipHideTimeout?: number;
|
||||
|
@ -213,18 +210,32 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
|||
this.hass.connection,
|
||||
"sidebar",
|
||||
({ value }) => {
|
||||
this._panelOrder = value?.panelOrder;
|
||||
this._hiddenPanels = value?.hiddenPanels;
|
||||
let panelOrder = value?.panelOrder;
|
||||
let hiddenPanels = value?.hiddenPanels;
|
||||
let defaultPanel = value?.defaultPanel;
|
||||
|
||||
// fallback to old localStorage values
|
||||
if (!this._panelOrder) {
|
||||
if (!panelOrder) {
|
||||
const storedOrder = localStorage.getItem("sidebarPanelOrder");
|
||||
this._panelOrder = storedOrder ? JSON.parse(storedOrder) : [];
|
||||
panelOrder = storedOrder ? JSON.parse(storedOrder) : [];
|
||||
}
|
||||
if (!this._hiddenPanels) {
|
||||
if (!hiddenPanels) {
|
||||
const storedHidden = localStorage.getItem("sidebarHiddenPanels");
|
||||
this._hiddenPanels = storedHidden ? JSON.parse(storedHidden) : [];
|
||||
hiddenPanels = storedHidden ? JSON.parse(storedHidden) : [];
|
||||
}
|
||||
if (!defaultPanel) {
|
||||
const storedDefault = localStorage.getItem("defaultPanel");
|
||||
defaultPanel = storedDefault
|
||||
? JSON.parse(storedDefault)
|
||||
: DEFAULT_PANEL;
|
||||
}
|
||||
|
||||
fireEvent(this, "hass-set-sidebar-data", {
|
||||
...value,
|
||||
defaultPanel: defaultPanel as string,
|
||||
panelOrder: panelOrder as string[],
|
||||
hiddenPanels: hiddenPanels as string[],
|
||||
});
|
||||
}
|
||||
),
|
||||
subscribeNotifications(this.hass.connection, (notifications) => {
|
||||
|
@ -275,8 +286,8 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
|||
changedProps.has("_updatesCount") ||
|
||||
changedProps.has("_issuesCount") ||
|
||||
changedProps.has("_notifications") ||
|
||||
changedProps.has("_hiddenPanels") ||
|
||||
changedProps.has("_panelOrder")
|
||||
(changedProps.has("hass") &&
|
||||
changedProps.get("hass")?.sidebar !== this.hass.sidebar)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
@ -295,7 +306,7 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
|||
hass.localize !== oldHass.localize ||
|
||||
hass.locale !== oldHass.locale ||
|
||||
hass.states !== oldHass.states ||
|
||||
hass.defaultPanel !== oldHass.defaultPanel ||
|
||||
hass.sidebar !== oldHass.sidebar ||
|
||||
hass.connected !== oldHass.connected
|
||||
);
|
||||
}
|
||||
|
@ -365,7 +376,7 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
|||
}
|
||||
|
||||
private _renderAllPanels(selectedPanel: string) {
|
||||
if (!this._panelOrder || !this._hiddenPanels) {
|
||||
if (!this.hass.sidebar.panelOrder || !this.hass.sidebar.hiddenPanels) {
|
||||
return html`
|
||||
<ha-fade-in .delay=${500}
|
||||
><ha-spinner size="small"></ha-spinner
|
||||
|
@ -375,9 +386,9 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
|||
|
||||
const [beforeSpacer, afterSpacer] = computePanels(
|
||||
this.hass.panels,
|
||||
this.hass.defaultPanel,
|
||||
this._panelOrder,
|
||||
this._hiddenPanels,
|
||||
this.hass.sidebar.defaultPanel,
|
||||
this.hass.sidebar.panelOrder,
|
||||
this.hass.sidebar.hiddenPanels,
|
||||
this.hass.locale
|
||||
);
|
||||
|
||||
|
@ -402,11 +413,11 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
|||
return panels.map((panel) =>
|
||||
this._renderPanel(
|
||||
panel.url_path,
|
||||
panel.url_path === this.hass.defaultPanel
|
||||
panel.url_path === this.hass.sidebar.defaultPanel
|
||||
? panel.title || this.hass.localize("panel.states")
|
||||
: this.hass.localize(`panel.${panel.title}`) || panel.title,
|
||||
panel.icon,
|
||||
panel.url_path === this.hass.defaultPanel && !panel.icon
|
||||
panel.url_path === this.hass.sidebar.defaultPanel && !panel.icon
|
||||
? PANEL_ICONS.lovelace
|
||||
: panel.url_path in PANEL_ICONS
|
||||
? PANEL_ICONS[panel.url_path]
|
||||
|
|
|
@ -8,6 +8,7 @@ export interface CoreFrontendUserData {
|
|||
export interface SidebarFrontendUserData {
|
||||
panelOrder: string[];
|
||||
hiddenPanels: string[];
|
||||
defaultPanel?: string;
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import type { HomeAssistant, PanelInfo } from "../types";
|
||||
|
||||
/** Panel to show when no panel is picked. */
|
||||
|
@ -10,16 +9,9 @@ export const getStorageDefaultPanelUrlPath = (): string => {
|
|||
return defaultPanel ? JSON.parse(defaultPanel) : DEFAULT_PANEL;
|
||||
};
|
||||
|
||||
export const setDefaultPanel = (
|
||||
element: HTMLElement,
|
||||
urlPath: string
|
||||
): void => {
|
||||
fireEvent(element, "hass-default-panel", { defaultPanel: urlPath });
|
||||
};
|
||||
|
||||
export const getDefaultPanel = (hass: HomeAssistant): PanelInfo =>
|
||||
hass.panels[hass.defaultPanel]
|
||||
? hass.panels[hass.defaultPanel]
|
||||
hass.panels[hass.sidebar.defaultPanel]
|
||||
? hass.panels[hass.sidebar.defaultPanel]
|
||||
: hass.panels[DEFAULT_PANEL];
|
||||
|
||||
export const getPanelNameTranslationKey = (panel: PanelInfo) => {
|
||||
|
|
|
@ -96,7 +96,7 @@ class DialogEditSidebar extends LitElement {
|
|||
|
||||
const [beforeSpacer, afterSpacer] = computePanels(
|
||||
this.hass.panels,
|
||||
this.hass.defaultPanel,
|
||||
this.hass.sidebar.defaultPanel,
|
||||
this._order,
|
||||
this._hidden,
|
||||
this.hass.locale
|
||||
|
@ -109,12 +109,12 @@ class DialogEditSidebar extends LitElement {
|
|||
].map((panel) => ({
|
||||
value: panel.url_path,
|
||||
label:
|
||||
panel.url_path === this.hass.defaultPanel
|
||||
panel.url_path === this.hass.sidebar.defaultPanel
|
||||
? panel.title || this.hass.localize("panel.states")
|
||||
: this.hass.localize(`panel.${panel.title}`) || panel.title || "?",
|
||||
icon: panel.icon || undefined,
|
||||
iconPath:
|
||||
panel.url_path === this.hass.defaultPanel && !panel.icon
|
||||
panel.url_path === this.hass.sidebar.defaultPanel && !panel.icon
|
||||
? PANEL_ICONS.lovelace
|
||||
: panel.url_path in PANEL_ICONS
|
||||
? PANEL_ICONS[panel.url_path]
|
||||
|
@ -195,6 +195,7 @@ class DialogEditSidebar extends LitElement {
|
|||
await saveFrontendUserData(this.hass.connection, "sidebar", {
|
||||
panelOrder: this._order!,
|
||||
hiddenPanels: this._hidden!,
|
||||
defaultPanel: this.hass.sidebar.defaultPanel,
|
||||
});
|
||||
} catch (err: any) {
|
||||
this._error = err.message || err;
|
||||
|
|
|
@ -13,10 +13,11 @@ import type {
|
|||
LovelaceDashboardCreateParams,
|
||||
LovelaceDashboardMutableParams,
|
||||
} from "../../../../data/lovelace/dashboard";
|
||||
import { DEFAULT_PANEL, setDefaultPanel } from "../../../../data/panel";
|
||||
import { DEFAULT_PANEL } from "../../../../data/panel";
|
||||
import { haStyleDialog } from "../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { LovelaceDashboardDetailsDialogParams } from "./show-dialog-lovelace-dashboard-detail";
|
||||
import { saveFrontendUserData } from "../../../../data/frontend";
|
||||
|
||||
@customElement("dialog-lovelace-dashboard-detail")
|
||||
export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
|
@ -59,7 +60,7 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
|||
if (!this._params || !this._data) {
|
||||
return nothing;
|
||||
}
|
||||
const defaultPanelUrlPath = this.hass.defaultPanel;
|
||||
const defaultPanelUrlPath = this.hass.sidebar.defaultPanel;
|
||||
const titleInvalid = !this._data.title || !this._data.title.trim();
|
||||
|
||||
return html`
|
||||
|
@ -249,15 +250,17 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
|||
};
|
||||
}
|
||||
|
||||
private _toggleDefault() {
|
||||
private async _toggleDefault() {
|
||||
const urlPath = this._params?.urlPath;
|
||||
if (!urlPath) {
|
||||
return;
|
||||
}
|
||||
setDefaultPanel(
|
||||
this,
|
||||
urlPath === this.hass.defaultPanel ? DEFAULT_PANEL : urlPath
|
||||
);
|
||||
await saveFrontendUserData(this.hass!.connection, "sidebar", {
|
||||
panelOrder: this.hass!.sidebar.panelOrder,
|
||||
hiddenPanels: this.hass!.sidebar.hiddenPanels,
|
||||
defaultPanel:
|
||||
urlPath === this.hass.sidebar.defaultPanel ? DEFAULT_PANEL : urlPath,
|
||||
});
|
||||
}
|
||||
|
||||
private async _updateDashboard() {
|
||||
|
|
|
@ -255,7 +255,7 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||
const defaultMode = (
|
||||
this.hass.panels?.lovelace?.config as LovelacePanelConfig
|
||||
).mode;
|
||||
const defaultUrlPath = this.hass.defaultPanel;
|
||||
const defaultUrlPath = this.hass.sidebar.defaultPanel;
|
||||
const isDefault = defaultUrlPath === "lovelace";
|
||||
const result: DataTableItem[] = [
|
||||
{
|
||||
|
|
|
@ -139,7 +139,7 @@ export class HuiDialogSelectDashboard extends LitElement {
|
|||
...(this._params!.dashboards || (await fetchDashboards(this.hass))),
|
||||
];
|
||||
|
||||
const currentPath = this._fromUrlPath || this.hass.defaultPanel;
|
||||
const currentPath = this._fromUrlPath || this.hass.sidebar.defaultPanel;
|
||||
for (const dashboard of this._dashboards!) {
|
||||
if (dashboard.url_path !== currentPath) {
|
||||
this._toUrlPath = dashboard.url_path;
|
||||
|
|
|
@ -77,7 +77,7 @@ export class HuiDialogSelectView extends LitElement {
|
|||
"ui.panel.lovelace.editor.select_view.dashboard_label"
|
||||
)}
|
||||
.disabled=${!this._dashboards.length}
|
||||
.value=${this._urlPath || this.hass.defaultPanel}
|
||||
.value=${this._urlPath || this.hass.sidebar.defaultPanel}
|
||||
@selected=${this._dashboardChanged}
|
||||
@closed=${stopPropagation}
|
||||
fixedMenuPosition
|
||||
|
|
|
@ -6,8 +6,8 @@ import "../../components/ha-select";
|
|||
import "../../components/ha-settings-row";
|
||||
import type { LovelaceDashboard } from "../../data/lovelace/dashboard";
|
||||
import { fetchDashboards } from "../../data/lovelace/dashboard";
|
||||
import { setDefaultPanel } from "../../data/panel";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { saveFrontendUserData } from "../../data/frontend";
|
||||
|
||||
@customElement("ha-pick-dashboard-row")
|
||||
class HaPickDashboardRow extends LitElement {
|
||||
|
@ -37,7 +37,7 @@ class HaPickDashboardRow extends LitElement {
|
|||
"ui.panel.profile.dashboard.dropdown_label"
|
||||
)}
|
||||
.disabled=${!this._dashboards?.length}
|
||||
.value=${this.hass.defaultPanel}
|
||||
.value=${this.hass.sidebar.defaultPanel}
|
||||
@selected=${this._dashboardChanged}
|
||||
naturalMenuWidth
|
||||
>
|
||||
|
@ -71,12 +71,16 @@ class HaPickDashboardRow extends LitElement {
|
|||
this._dashboards = await fetchDashboards(this.hass);
|
||||
}
|
||||
|
||||
private _dashboardChanged(ev) {
|
||||
private async _dashboardChanged(ev) {
|
||||
const urlPath = ev.target.value;
|
||||
if (!urlPath || urlPath === this.hass.defaultPanel) {
|
||||
if (!urlPath || urlPath === this.hass.sidebar.defaultPanel) {
|
||||
return;
|
||||
}
|
||||
setDefaultPanel(this, urlPath);
|
||||
await saveFrontendUserData(this.hass!.connection, "sidebar", {
|
||||
panelOrder: this.hass!.sidebar.panelOrder,
|
||||
hiddenPanels: this.hass!.sidebar.hiddenPanels,
|
||||
defaultPanel: urlPath,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -167,6 +167,10 @@ class HaProfileSectionGeneral extends LitElement {
|
|||
)}
|
||||
</mwc-button>
|
||||
</ha-settings-row>
|
||||
<ha-pick-dashboard-row
|
||||
.narrow=${this.narrow}
|
||||
.hass=${this.hass}
|
||||
></ha-pick-dashboard-row>
|
||||
${this.hass.user!.is_admin
|
||||
? html`
|
||||
<ha-advanced-mode-row
|
||||
|
@ -200,10 +204,6 @@ class HaProfileSectionGeneral extends LitElement {
|
|||
.narrow=${this.narrow}
|
||||
.hass=${this.hass}
|
||||
></ha-pick-theme-row>
|
||||
<ha-pick-dashboard-row
|
||||
.narrow=${this.narrow}
|
||||
.hass=${this.hass}
|
||||
></ha-pick-dashboard-row>
|
||||
${this.hass.dockedSidebar !== "auto" || !this.narrow
|
||||
? html`
|
||||
<ha-force-narrow-row
|
||||
|
|
|
@ -59,7 +59,11 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
|||
services: null as any,
|
||||
user: null as any,
|
||||
panelUrl: (this as any)._panelUrl,
|
||||
defaultPanel: DEFAULT_PANEL,
|
||||
sidebar: {
|
||||
defaultPanel: DEFAULT_PANEL,
|
||||
hiddenPanels: [],
|
||||
panelOrder: [],
|
||||
},
|
||||
language,
|
||||
selectedLanguage: null,
|
||||
locale: {
|
||||
|
|
|
@ -7,20 +7,16 @@ interface DockSidebarParams {
|
|||
dock: HomeAssistant["dockedSidebar"];
|
||||
}
|
||||
|
||||
interface DefaultPanelParams {
|
||||
defaultPanel: HomeAssistant["defaultPanel"];
|
||||
}
|
||||
|
||||
declare global {
|
||||
// for fire event
|
||||
interface HASSDomEvents {
|
||||
"hass-dock-sidebar": DockSidebarParams;
|
||||
"hass-default-panel": DefaultPanelParams;
|
||||
"hass-set-sidebar-data": HomeAssistant["sidebar"];
|
||||
}
|
||||
// for add event listener
|
||||
interface HTMLElementEventMap {
|
||||
"hass-dock-sidebar": HASSDomEvent<DockSidebarParams>;
|
||||
"hass-default-panel": HASSDomEvent<DefaultPanelParams>;
|
||||
"hass-set-sidebar-data": HASSDomEvent<HomeAssistant["sidebar"]>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,8 +28,10 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
|
|||
this._updateHass({ dockedSidebar: ev.detail.dock });
|
||||
storeState(this.hass!);
|
||||
});
|
||||
this.addEventListener("hass-default-panel", (ev) => {
|
||||
this._updateHass({ defaultPanel: ev.detail.defaultPanel });
|
||||
this.addEventListener("hass-set-sidebar-data", async (ev) => {
|
||||
this._updateHass({
|
||||
sidebar: ev.detail,
|
||||
});
|
||||
storeState(this.hass!);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -243,7 +243,11 @@ export interface HomeAssistant {
|
|||
vibrate: boolean;
|
||||
debugConnection: boolean;
|
||||
dockedSidebar: "docked" | "always_hidden" | "auto";
|
||||
defaultPanel: string;
|
||||
sidebar: {
|
||||
defaultPanel: string;
|
||||
panelOrder: string[];
|
||||
hiddenPanels: string[];
|
||||
};
|
||||
moreInfoEntityId: string | null;
|
||||
user?: CurrentUser;
|
||||
userData?: CoreFrontendUserData | null;
|
||||
|
|
|
@ -8,7 +8,7 @@ const STORED_STATE = [
|
|||
"debugConnection",
|
||||
"suspendWhenHidden",
|
||||
"enableShortcuts",
|
||||
"defaultPanel",
|
||||
"sidebar",
|
||||
];
|
||||
|
||||
export function storeState(hass: HomeAssistant) {
|
||||
|
|
Loading…
Reference in New Issue