mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-25 05:47:20 +00:00
Add default dashboard selection to profile page (#5360)
* Add default dashboard selection to profile page * Comments * Console.bye
This commit is contained in:
parent
263138a388
commit
8a6bd04543
@ -32,7 +32,7 @@ import { classMap } from "lit-html/directives/class-map";
|
||||
import { PaperIconItemElement } from "@polymer/paper-item/paper-icon-item";
|
||||
import { computeRTL } from "../common/util/compute_rtl";
|
||||
import { compare } from "../common/string/compare";
|
||||
import { getDefaultPanelUrlPath, getDefaultPanel } from "../data/panel";
|
||||
import { getDefaultPanel } from "../data/panel";
|
||||
|
||||
const SHOW_AFTER_SPACER = ["config", "developer-tools", "hassio"];
|
||||
|
||||
@ -87,10 +87,8 @@ const computePanels = (hass: HomeAssistant): [PanelInfo[], PanelInfo[]] => {
|
||||
const beforeSpacer: PanelInfo[] = [];
|
||||
const afterSpacer: PanelInfo[] = [];
|
||||
|
||||
const defaultPage = getDefaultPanelUrlPath();
|
||||
|
||||
Object.values(panels).forEach((panel) => {
|
||||
if (!panel.title || panel.url_path === defaultPage) {
|
||||
if (!panel.title || panel.url_path === hass.defaultPanel) {
|
||||
return;
|
||||
}
|
||||
(SHOW_AFTER_SPACER.includes(panel.url_path)
|
||||
@ -143,7 +141,7 @@ class HaSidebar extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
const defaultPanel = getDefaultPanel(hass.panels);
|
||||
const defaultPanel = getDefaultPanel(hass);
|
||||
|
||||
return html`
|
||||
<div class="menu">
|
||||
@ -297,7 +295,8 @@ class HaSidebar extends LitElement {
|
||||
hass.panelUrl !== oldHass.panelUrl ||
|
||||
hass.user !== oldHass.user ||
|
||||
hass.localize !== oldHass.localize ||
|
||||
hass.states !== oldHass.states
|
||||
hass.states !== oldHass.states ||
|
||||
hass.defaultPanel !== oldHass.defaultPanel
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,20 @@
|
||||
import { HomeAssistant, PanelInfo } from "../types";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
|
||||
/** Panel to show when no panel is picked. */
|
||||
const DEFAULT_PANEL = "lovelace";
|
||||
export const DEFAULT_PANEL = "lovelace";
|
||||
|
||||
export const getDefaultPanelUrlPath = () =>
|
||||
localStorage.defaultPage || DEFAULT_PANEL;
|
||||
export const getStorageDefaultPanelUrlPath = () =>
|
||||
localStorage.defaultPanel
|
||||
? JSON.parse(localStorage.defaultPanel)
|
||||
: DEFAULT_PANEL;
|
||||
|
||||
export const getDefaultPanel = (panels: HomeAssistant["panels"]) =>
|
||||
panels[localStorage.defaultPage] || panels[DEFAULT_PANEL];
|
||||
export const setDefaultPanel = (element: HTMLElement, urlPath: string) => {
|
||||
fireEvent(element, "hass-default-panel", { defaultPanel: urlPath });
|
||||
};
|
||||
|
||||
export const getDefaultPanel = (hass: HomeAssistant) =>
|
||||
hass.panels[hass.defaultPanel];
|
||||
|
||||
export const getPanelTitle = (hass: HomeAssistant): string | undefined => {
|
||||
if (!hass.panels) {
|
||||
|
@ -11,6 +11,7 @@ import { HomeAssistant } from "../types";
|
||||
import { HassEntities } from "home-assistant-js-websocket";
|
||||
import { getLocalLanguage } from "../util/hass-translation";
|
||||
import { translationMetadata } from "../resources/translations-metadata";
|
||||
import { DEFAULT_PANEL } from "../data/panel";
|
||||
|
||||
const ensureArray = <T>(val: T | T[]): T[] =>
|
||||
Array.isArray(val) ? val : [val];
|
||||
@ -172,6 +173,7 @@ export const provideHass = (
|
||||
name: "Demo User",
|
||||
},
|
||||
panelUrl: "lovelace",
|
||||
defaultPanel: DEFAULT_PANEL,
|
||||
|
||||
language: localLanguage,
|
||||
selectedLanguage: localLanguage,
|
||||
|
@ -10,7 +10,7 @@ import { registerServiceWorker } from "../util/register-service-worker";
|
||||
import { Route, HomeAssistant } from "../types";
|
||||
import { navigate } from "../common/navigate";
|
||||
import { HassElement } from "../state/hass-element";
|
||||
import { getDefaultPanelUrlPath } from "../data/panel";
|
||||
import { getStorageDefaultPanelUrlPath } from "../data/panel";
|
||||
|
||||
export class HomeAssistantAppEl extends HassElement {
|
||||
@property() private _route?: Route;
|
||||
@ -86,7 +86,7 @@ export class HomeAssistantAppEl extends HassElement {
|
||||
this._route === undefined &&
|
||||
(route.path === "" || route.path === "/")
|
||||
) {
|
||||
navigate(window, `/${getDefaultPanelUrlPath()}`, true);
|
||||
navigate(window, getStorageDefaultPanelUrlPath(), true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ import { PolymerChangedEvent } from "../../../../polymer-types";
|
||||
import { HaSwitch } from "../../../../components/ha-switch";
|
||||
import { createCloseHeading } from "../../../../components/ha-dialog";
|
||||
import { haStyleDialog } from "../../../../resources/styles";
|
||||
import { setDefaultPanel, DEFAULT_PANEL } from "../../../../data/panel";
|
||||
|
||||
@customElement("dialog-lovelace-dashboard-detail")
|
||||
export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
@ -57,6 +58,7 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
if (!this._params) {
|
||||
return html``;
|
||||
}
|
||||
const defaultPanelUrlPath = this.hass.defaultPanel;
|
||||
const urlInvalid =
|
||||
this._params.urlPath !== "lovelace" &&
|
||||
!/^[a-zA-Z0-9_-]+-[a-zA-Z0-9_-]+$/.test(this._urlPath);
|
||||
@ -169,12 +171,9 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
slot="secondaryAction"
|
||||
@click=${this._toggleDefault}
|
||||
.disabled=${this._params.urlPath === "lovelace" &&
|
||||
(!localStorage.defaultPage ||
|
||||
localStorage.defaultPage === "lovelace")}
|
||||
defaultPanelUrlPath === "lovelace"}
|
||||
>
|
||||
${this._params.urlPath === localStorage.defaultPage ||
|
||||
(this._params.urlPath === "lovelace" &&
|
||||
!localStorage.defaultPage)
|
||||
${this._params.urlPath === defaultPanelUrlPath
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.detail.remove_default"
|
||||
)
|
||||
@ -244,12 +243,10 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
if (!urlPath) {
|
||||
return;
|
||||
}
|
||||
if (urlPath === localStorage.defaultPage) {
|
||||
delete localStorage.defaultPage;
|
||||
} else {
|
||||
localStorage.defaultPage = urlPath;
|
||||
}
|
||||
location.reload();
|
||||
setDefaultPanel(
|
||||
this,
|
||||
urlPath === this.hass.defaultPanel ? DEFAULT_PANEL : urlPath
|
||||
);
|
||||
}
|
||||
|
||||
private async _updateDashboard() {
|
||||
|
@ -184,8 +184,8 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
||||
private _getItems = memoize((dashboards: LovelaceDashboard[]) => {
|
||||
const defaultMode = (this.hass.panels?.lovelace
|
||||
?.config as LovelacePanelConfig).mode;
|
||||
const isDefault =
|
||||
!localStorage.defaultPage || localStorage.defaultPage === "lovelace";
|
||||
const defaultUrlPath = this.hass.defaultPanel;
|
||||
const isDefault = defaultUrlPath === "lovelace";
|
||||
return [
|
||||
{
|
||||
icon: "hass:view-dashboard",
|
||||
@ -201,7 +201,7 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
||||
return {
|
||||
filename: "",
|
||||
...dashboard,
|
||||
default: localStorage.defaultPage === dashboard.url_path,
|
||||
default: defaultUrlPath === dashboard.url_path,
|
||||
};
|
||||
}),
|
||||
];
|
||||
|
@ -20,6 +20,7 @@ import "./ha-long-lived-access-tokens-card";
|
||||
import "./ha-advanced-mode-row";
|
||||
import "./ha-pick-language-row";
|
||||
import "./ha-pick-theme-row";
|
||||
import "./ha-pick-dashboard-row";
|
||||
import "./ha-push-notifications-row";
|
||||
import "./ha-force-narrow-row";
|
||||
import "./ha-set-vibrate-row";
|
||||
@ -98,6 +99,10 @@ class HaPanelProfile 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
|
||||
|
86
src/panels/profile/ha-pick-dashboard-row.ts
Normal file
86
src/panels/profile/ha-pick-dashboard-row.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import {
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
html,
|
||||
property,
|
||||
customElement,
|
||||
PropertyValues,
|
||||
} from "lit-element";
|
||||
|
||||
import "./ha-settings-row";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-listbox/paper-listbox";
|
||||
import "../../components/ha-paper-dropdown-menu";
|
||||
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { LovelaceDashboard, fetchDashboards } from "../../data/lovelace";
|
||||
import { setDefaultPanel } from "../../data/panel";
|
||||
|
||||
@customElement("ha-pick-dashboard-row")
|
||||
class HaPickDashboardRow extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public narrow!: boolean;
|
||||
@property() private _dashboards: LovelaceDashboard[] = [];
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues) {
|
||||
super.firstUpdated(changedProps);
|
||||
this._getDashboards();
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<ha-settings-row .narrow=${this.narrow}>
|
||||
<span slot="heading">
|
||||
${this.hass.localize("ui.panel.profile.dashboard.header")}
|
||||
</span>
|
||||
<span slot="description">
|
||||
${this.hass.localize("ui.panel.profile.dashboard.description")}
|
||||
</span>
|
||||
<ha-paper-dropdown-menu
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.profile.dashboard.dropdown_label"
|
||||
)}
|
||||
dynamic-align
|
||||
.disabled=${!this._dashboards.length}
|
||||
>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
.selected=${this.hass.defaultPanel}
|
||||
@iron-select=${this._dashboardChanged}
|
||||
attr-for-selected="url-path"
|
||||
>
|
||||
<paper-item url-path="lovelace">default</paper-item>
|
||||
${this._dashboards.map((dashboard) => {
|
||||
if (!this.hass.user!.is_admin && dashboard.require_admin) {
|
||||
return "";
|
||||
}
|
||||
return html`
|
||||
<paper-item url-path=${dashboard.url_path}
|
||||
>${dashboard.title}</paper-item
|
||||
>
|
||||
`;
|
||||
})}
|
||||
</paper-listbox>
|
||||
</ha-paper-dropdown-menu>
|
||||
</ha-settings-row>
|
||||
`;
|
||||
}
|
||||
|
||||
private async _getDashboards() {
|
||||
this._dashboards = await fetchDashboards(this.hass);
|
||||
}
|
||||
|
||||
private _dashboardChanged(ev: CustomEvent) {
|
||||
const urlPath = ev.detail.item.getAttribute("url-path");
|
||||
if (!urlPath || urlPath === this.hass.defaultPanel) {
|
||||
return;
|
||||
}
|
||||
setDefaultPanel(this, urlPath);
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-pick-dashboard-row": HaPickDashboardRow;
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ import { Constructor, ServiceCallResponse } from "../types";
|
||||
import { HassBaseEl } from "./hass-base-mixin";
|
||||
import { broadcastConnectionStatus } from "../data/connection-status";
|
||||
import { subscribeFrontendUserData } from "../data/frontend";
|
||||
import { DEFAULT_PANEL } from "../data/panel";
|
||||
|
||||
export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
||||
superClass: T
|
||||
@ -38,7 +39,7 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
||||
services: null as any,
|
||||
user: null as any,
|
||||
panelUrl: (this as any)._panelUrl,
|
||||
|
||||
defaultPanel: DEFAULT_PANEL,
|
||||
language: getLocalLanguage(),
|
||||
selectedLanguage: null,
|
||||
resources: null as any,
|
||||
|
@ -7,15 +7,25 @@ interface DockSidebarParams {
|
||||
dock: HomeAssistant["dockedSidebar"];
|
||||
}
|
||||
|
||||
interface DefaultPanelParams {
|
||||
defaultPanel: HomeAssistant["defaultPanel"];
|
||||
}
|
||||
|
||||
declare global {
|
||||
// for fire event
|
||||
interface HASSDomEvents {
|
||||
"hass-dock-sidebar": DockSidebarParams;
|
||||
}
|
||||
interface HASSDomEvents {
|
||||
"hass-default-panel": DefaultPanelParams;
|
||||
}
|
||||
// for add event listener
|
||||
interface HTMLElementEventMap {
|
||||
"hass-dock-sidebar": HASSDomEvent<DockSidebarParams>;
|
||||
}
|
||||
interface HTMLElementEventMap {
|
||||
"hass-default-panel": HASSDomEvent<DefaultPanelParams>;
|
||||
}
|
||||
}
|
||||
|
||||
export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
|
||||
@ -26,5 +36,9 @@ 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 });
|
||||
storeState(this.hass!);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -2209,6 +2209,11 @@
|
||||
"link_promo": "Learn about themes",
|
||||
"dropdown_label": "Theme"
|
||||
},
|
||||
"dashboard": {
|
||||
"header": "Dashboard",
|
||||
"description": "Pick a default dashboard for this device.",
|
||||
"dropdown_label": "Dashboard"
|
||||
},
|
||||
"change_password": {
|
||||
"header": "Change Password",
|
||||
"current_password": "Current Password",
|
||||
|
@ -154,6 +154,7 @@ export interface HomeAssistant {
|
||||
|
||||
vibrate: boolean;
|
||||
dockedSidebar: "docked" | "always_hidden" | "auto";
|
||||
defaultPanel: string;
|
||||
moreInfoEntityId: string | null;
|
||||
user?: CurrentUser;
|
||||
userData?: CoreFrontendUserData | null;
|
||||
|
@ -5,6 +5,7 @@ const STORED_STATE = [
|
||||
"selectedTheme",
|
||||
"selectedLanguage",
|
||||
"vibrate",
|
||||
"defaultPanel",
|
||||
];
|
||||
const STORAGE = window.localStorage || {};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user