mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 19:56:42 +00:00
Save sidebar in user data (#25555)
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com> Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
9f5f100e98
commit
208e863327
@ -14,7 +14,6 @@ import {
|
||||
mdiTooltipAccount,
|
||||
mdiViewDashboard,
|
||||
} from "@mdi/js";
|
||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import type { CSSResultGroup, PropertyValues } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import {
|
||||
@ -30,6 +29,7 @@ import { fireEvent } from "../common/dom/fire_event";
|
||||
import { toggleAttribute } from "../common/dom/toggle_attribute";
|
||||
import { stringCompare } from "../common/string/compare";
|
||||
import { throttle } from "../common/util/throttle";
|
||||
import { subscribeFrontendUserData } from "../data/frontend";
|
||||
import type { ActionHandlerDetail } from "../data/lovelace/action_handler";
|
||||
import type { PersistentNotification } from "../data/persistent_notification";
|
||||
import { subscribeNotifications } from "../data/persistent_notification";
|
||||
@ -41,11 +41,13 @@ import { SubscribeMixin } from "../mixins/subscribe-mixin";
|
||||
import { actionHandler } from "../panels/lovelace/common/directives/action-handler-directive";
|
||||
import { haStyleScrollbar } from "../resources/styles";
|
||||
import type { HomeAssistant, PanelInfo, Route } from "../types";
|
||||
import "./ha-fade-in";
|
||||
import "./ha-icon";
|
||||
import "./ha-icon-button";
|
||||
import "./ha-md-list";
|
||||
import "./ha-md-list-item";
|
||||
import type { HaMdListItem } from "./ha-md-list-item";
|
||||
import "./ha-spinner";
|
||||
import "./ha-svg-icon";
|
||||
import "./user/ha-user-badge";
|
||||
|
||||
@ -187,38 +189,57 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
||||
@property({ attribute: "always-expand", type: Boolean })
|
||||
public alwaysExpand = false;
|
||||
|
||||
@property({ attribute: false })
|
||||
public panelOrder!: string[];
|
||||
|
||||
@property({ attribute: false })
|
||||
public hiddenPanels!: string[];
|
||||
|
||||
@state() private _notifications?: PersistentNotification[];
|
||||
|
||||
@state() private _updatesCount = 0;
|
||||
|
||||
@state() private _issuesCount = 0;
|
||||
|
||||
@state() private _panelOrder?: string[];
|
||||
|
||||
@state() private _hiddenPanels?: string[];
|
||||
|
||||
private _mouseLeaveTimeout?: number;
|
||||
|
||||
private _tooltipHideTimeout?: number;
|
||||
|
||||
private _recentKeydownActiveUntil = 0;
|
||||
|
||||
private _unsubPersistentNotifications: UnsubscribeFunc | undefined;
|
||||
|
||||
@query(".tooltip") private _tooltip!: HTMLDivElement;
|
||||
|
||||
public hassSubscribe(): UnsubscribeFunc[] {
|
||||
return this.hass.user?.is_admin
|
||||
? [
|
||||
subscribeRepairsIssueRegistry(this.hass.connection!, (repairs) => {
|
||||
this._issuesCount = repairs.issues.filter(
|
||||
(issue) => !issue.ignored
|
||||
).length;
|
||||
}),
|
||||
]
|
||||
: [];
|
||||
public hassSubscribe() {
|
||||
return [
|
||||
subscribeFrontendUserData(
|
||||
this.hass.connection,
|
||||
"sidebar",
|
||||
({ value }) => {
|
||||
this._panelOrder = value?.panelOrder;
|
||||
this._hiddenPanels = value?.hiddenPanels;
|
||||
|
||||
// fallback to old localStorage values
|
||||
if (!this._panelOrder) {
|
||||
const storedOrder = localStorage.getItem("sidebarPanelOrder");
|
||||
this._panelOrder = storedOrder ? JSON.parse(storedOrder) : [];
|
||||
}
|
||||
if (!this._hiddenPanels) {
|
||||
const storedHidden = localStorage.getItem("sidebarHiddenPanels");
|
||||
this._hiddenPanels = storedHidden ? JSON.parse(storedHidden) : [];
|
||||
}
|
||||
}
|
||||
),
|
||||
subscribeNotifications(this.hass.connection, (notifications) => {
|
||||
this._notifications = notifications;
|
||||
}),
|
||||
...(this.hass.user?.is_admin
|
||||
? [
|
||||
subscribeRepairsIssueRegistry(this.hass.connection!, (repairs) => {
|
||||
this._issuesCount = repairs.issues.filter(
|
||||
(issue) => !issue.ignored
|
||||
).length;
|
||||
}),
|
||||
]
|
||||
: []),
|
||||
];
|
||||
}
|
||||
|
||||
protected render() {
|
||||
@ -254,8 +275,8 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
||||
changedProps.has("_updatesCount") ||
|
||||
changedProps.has("_issuesCount") ||
|
||||
changedProps.has("_notifications") ||
|
||||
changedProps.has("hiddenPanels") ||
|
||||
changedProps.has("panelOrder")
|
||||
changedProps.has("_hiddenPanels") ||
|
||||
changedProps.has("_panelOrder")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@ -279,23 +300,6 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
||||
);
|
||||
}
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues) {
|
||||
super.firstUpdated(changedProps);
|
||||
this._subscribePersistentNotifications();
|
||||
}
|
||||
|
||||
private _subscribePersistentNotifications(): void {
|
||||
if (this._unsubPersistentNotifications) {
|
||||
this._unsubPersistentNotifications();
|
||||
}
|
||||
this._unsubPersistentNotifications = subscribeNotifications(
|
||||
this.hass.connection,
|
||||
(notifications) => {
|
||||
this._notifications = notifications;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected updated(changedProps) {
|
||||
super.updated(changedProps);
|
||||
if (changedProps.has("alwaysExpand")) {
|
||||
@ -307,14 +311,6 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
||||
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
|
||||
if (
|
||||
this.hass &&
|
||||
oldHass?.connected === false &&
|
||||
this.hass.connected === true
|
||||
) {
|
||||
this._subscribePersistentNotifications();
|
||||
}
|
||||
|
||||
this._calculateCounts();
|
||||
|
||||
if (!SUPPORT_SCROLL_IF_NEEDED) {
|
||||
@ -369,11 +365,19 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
|
||||
private _renderAllPanels(selectedPanel: string) {
|
||||
if (!this._panelOrder || !this._hiddenPanels) {
|
||||
return html`
|
||||
<ha-fade-in .delay=${500}
|
||||
><ha-spinner size="large"></ha-spinner
|
||||
></ha-fade-in>
|
||||
`;
|
||||
}
|
||||
|
||||
const [beforeSpacer, afterSpacer] = computePanels(
|
||||
this.hass.panels,
|
||||
this.hass.defaultPanel,
|
||||
this.panelOrder,
|
||||
this.hiddenPanels,
|
||||
this._panelOrder,
|
||||
this._hiddenPanels,
|
||||
this.hass.locale
|
||||
);
|
||||
|
||||
@ -559,18 +563,9 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
showEditSidebarDialog(this, {
|
||||
saveCallback: this._saveSidebar,
|
||||
});
|
||||
showEditSidebarDialog(this);
|
||||
}
|
||||
|
||||
private _saveSidebar = (order: string[], hidden: string[]) => {
|
||||
fireEvent(this, "hass-edit-sidebar", {
|
||||
order,
|
||||
hidden,
|
||||
});
|
||||
};
|
||||
|
||||
private _itemMouseEnter(ev: MouseEvent) {
|
||||
// On keypresses on the listbox, we're going to ignore mouse enter events
|
||||
// for 100ms so that we ignore it when pressing down arrow scrolls the
|
||||
@ -730,13 +725,22 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
ha-fade-in,
|
||||
ha-md-list {
|
||||
padding: 4px 0;
|
||||
box-sizing: border-box;
|
||||
height: calc(100% - var(--header-height) - 132px);
|
||||
height: calc(
|
||||
100% - var(--header-height) - 132px - var(--safe-area-inset-bottom)
|
||||
);
|
||||
}
|
||||
|
||||
ha-fade-in {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
ha-md-list {
|
||||
padding: 4px 0;
|
||||
box-sizing: border-box;
|
||||
overflow-x: hidden;
|
||||
background: none;
|
||||
margin-left: var(--safe-area-inset-left);
|
||||
|
@ -5,9 +5,15 @@ export interface CoreFrontendUserData {
|
||||
showEntityIdPicker?: boolean;
|
||||
}
|
||||
|
||||
export interface SidebarFrontendUserData {
|
||||
panelOrder: string[];
|
||||
hiddenPanels: string[];
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface FrontendUserData {
|
||||
core: CoreFrontendUserData;
|
||||
sidebar: SidebarFrontendUserData;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,5 @@
|
||||
import type { HomeAssistant } from "../types";
|
||||
import {
|
||||
fetchFrontendUserData,
|
||||
saveFrontendUserData,
|
||||
subscribeFrontendUserData,
|
||||
} from "./frontend";
|
||||
import { saveFrontendUserData, subscribeFrontendUserData } from "./frontend";
|
||||
|
||||
export enum NumberFormat {
|
||||
language = "language",
|
||||
@ -78,9 +74,6 @@ export type TranslationCategory =
|
||||
| "selector"
|
||||
| "services";
|
||||
|
||||
export const fetchTranslationPreferences = (hass: HomeAssistant) =>
|
||||
fetchFrontendUserData(hass.connection, "language");
|
||||
|
||||
export const subscribeTranslationPreferences = (
|
||||
hass: HomeAssistant,
|
||||
callback: (data: { value: FrontendLocaleData | null }) => void
|
||||
|
@ -1,18 +1,25 @@
|
||||
import "@material/mwc-linear-progress/mwc-linear-progress";
|
||||
import { mdiClose } from "@mdi/js";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { css, html, LitElement, nothing, type TemplateResult } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import "../../components/ha-alert";
|
||||
import "../../components/ha-dialog-header";
|
||||
import "../../components/ha-fade-in";
|
||||
import "../../components/ha-icon-button";
|
||||
import "../../components/ha-items-display-editor";
|
||||
import type { DisplayValue } from "../../components/ha-items-display-editor";
|
||||
import "../../components/ha-md-dialog";
|
||||
import type { HaMdDialog } from "../../components/ha-md-dialog";
|
||||
import { computePanels, PANEL_ICONS } from "../../components/ha-sidebar";
|
||||
import "../../components/ha-spinner";
|
||||
import {
|
||||
fetchFrontendUserData,
|
||||
saveFrontendUserData,
|
||||
} from "../../data/frontend";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import type { EditSidebarDialogParams } from "./show-dialog-edit-sidebar";
|
||||
import { showConfirmationDialog } from "../generic/show-dialog-box";
|
||||
|
||||
@customElement("dialog-edit-sidebar")
|
||||
class DialogEditSidebar extends LitElement {
|
||||
@ -22,21 +29,43 @@ class DialogEditSidebar extends LitElement {
|
||||
|
||||
@query("ha-md-dialog") private _dialog?: HaMdDialog;
|
||||
|
||||
@state() private _order: string[] = [];
|
||||
@state() private _order?: string[];
|
||||
|
||||
@state() private _hidden: string[] = [];
|
||||
@state() private _hidden?: string[];
|
||||
|
||||
private _saveCallback?: (order: string[], hidden: string[]) => void;
|
||||
@state() private _error?: string;
|
||||
|
||||
public async showDialog(params: EditSidebarDialogParams): Promise<void> {
|
||||
/**
|
||||
* If user has old localStorage values, show a confirmation dialog
|
||||
*/
|
||||
@state() private _migrateToUserData = false;
|
||||
|
||||
public async showDialog(): Promise<void> {
|
||||
this._open = true;
|
||||
|
||||
const storedOrder = localStorage.getItem("sidebarPanelOrder");
|
||||
const storedHidden = localStorage.getItem("sidebarHiddenPanels");
|
||||
this._getData();
|
||||
}
|
||||
|
||||
this._order = storedOrder ? JSON.parse(storedOrder) : this._order;
|
||||
this._hidden = storedHidden ? JSON.parse(storedHidden) : this._hidden;
|
||||
this._saveCallback = params.saveCallback;
|
||||
private async _getData() {
|
||||
try {
|
||||
const data = await fetchFrontendUserData(this.hass.connection, "sidebar");
|
||||
this._order = data?.panelOrder;
|
||||
this._hidden = data?.hiddenPanels;
|
||||
|
||||
// fallback to old localStorage values
|
||||
if (!this._order) {
|
||||
const storedOrder = localStorage.getItem("sidebarPanelOrder");
|
||||
this._migrateToUserData = !!storedOrder;
|
||||
this._order = storedOrder ? JSON.parse(storedOrder) : [];
|
||||
}
|
||||
if (!this._hidden) {
|
||||
const storedHidden = localStorage.getItem("sidebarHiddenPanels");
|
||||
this._migrateToUserData = this._migrateToUserData || !!storedHidden;
|
||||
this._hidden = storedHidden ? JSON.parse(storedHidden) : [];
|
||||
}
|
||||
} catch (err: any) {
|
||||
this._error = err.message || err;
|
||||
}
|
||||
}
|
||||
|
||||
private _dialogClosed(): void {
|
||||
@ -52,12 +81,16 @@ class DialogEditSidebar extends LitElement {
|
||||
panels ? Object.values(panels) : []
|
||||
);
|
||||
|
||||
protected render() {
|
||||
if (!this._open) {
|
||||
return nothing;
|
||||
private _renderContent(): TemplateResult {
|
||||
if (!this._order || !this._hidden) {
|
||||
return html`<ha-fade-in .delay=${500}
|
||||
><ha-spinner size="large"></ha-spinner
|
||||
></ha-fade-in>`;
|
||||
}
|
||||
|
||||
const dialogTitle = this.hass.localize("ui.sidebar.edit_sidebar");
|
||||
if (this._error) {
|
||||
return html`<ha-alert alert-type="error">${this._error}</ha-alert>`;
|
||||
}
|
||||
|
||||
const panels = this._panels(this.hass.panels);
|
||||
|
||||
@ -71,7 +104,7 @@ class DialogEditSidebar extends LitElement {
|
||||
|
||||
const items = [
|
||||
...beforeSpacer,
|
||||
...panels.filter((panel) => this._hidden.includes(panel.url_path)),
|
||||
...panels.filter((panel) => this._hidden!.includes(panel.url_path)),
|
||||
...afterSpacer.filter((panel) => panel.url_path !== "config"),
|
||||
].map((panel) => ({
|
||||
value: panel.url_path,
|
||||
@ -89,6 +122,26 @@ class DialogEditSidebar extends LitElement {
|
||||
disableSorting: panel.url_path === "developer-tools",
|
||||
}));
|
||||
|
||||
return html`<ha-items-display-editor
|
||||
.hass=${this.hass}
|
||||
.value=${{
|
||||
order: this._order,
|
||||
hidden: this._hidden,
|
||||
}}
|
||||
.items=${items}
|
||||
@value-changed=${this._changed}
|
||||
dont-sort-visible
|
||||
>
|
||||
</ha-items-display-editor>`;
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this._open) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const dialogTitle = this.hass.localize("ui.sidebar.edit_sidebar");
|
||||
|
||||
return html`
|
||||
<ha-md-dialog open @closed=${this._dialogClosed}>
|
||||
<ha-dialog-header slot="headline">
|
||||
@ -98,26 +151,22 @@ class DialogEditSidebar extends LitElement {
|
||||
.path=${mdiClose}
|
||||
@click=${this.closeDialog}
|
||||
></ha-icon-button>
|
||||
<span slot="title" .title=${dialogTitle}> ${dialogTitle} </span>
|
||||
<span slot="title" .title=${dialogTitle}>${dialogTitle}</span>
|
||||
${!this._migrateToUserData
|
||||
? html`<span slot="subtitle"
|
||||
>${this.hass.localize("ui.sidebar.edit_subtitle")}</span
|
||||
>`
|
||||
: nothing}
|
||||
</ha-dialog-header>
|
||||
<div slot="content" class="content">
|
||||
<ha-items-display-editor
|
||||
.hass=${this.hass}
|
||||
.value=${{
|
||||
order: this._order,
|
||||
hidden: this._hidden,
|
||||
}}
|
||||
.items=${items}
|
||||
@value-changed=${this._changed}
|
||||
dont-sort-visible
|
||||
>
|
||||
</ha-items-display-editor>
|
||||
</div>
|
||||
<div slot="content" class="content">${this._renderContent()}</div>
|
||||
<div slot="actions">
|
||||
<ha-button @click=${this.closeDialog}>
|
||||
${this.hass.localize("ui.common.cancel")}
|
||||
</ha-button>
|
||||
<ha-button @click=${this._save}>
|
||||
<ha-button
|
||||
.disabled=${!this._order || !this._hidden}
|
||||
@click=${this._save}
|
||||
>
|
||||
${this.hass.localize("ui.common.save")}
|
||||
</ha-button>
|
||||
</div>
|
||||
@ -131,8 +180,27 @@ class DialogEditSidebar extends LitElement {
|
||||
this._hidden = [...hidden];
|
||||
}
|
||||
|
||||
private _save(): void {
|
||||
this._saveCallback?.(this._order ?? [], this._hidden ?? []);
|
||||
private async _save() {
|
||||
if (this._migrateToUserData) {
|
||||
const confirmation = await showConfirmationDialog(this, {
|
||||
destructive: true,
|
||||
text: this.hass.localize("ui.sidebar.migrate_to_user_data"),
|
||||
});
|
||||
if (!confirmation) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await saveFrontendUserData(this.hass.connection, "sidebar", {
|
||||
panelOrder: this._order!,
|
||||
hiddenPanels: this._hidden!,
|
||||
});
|
||||
} catch (err: any) {
|
||||
this._error = err.message || err;
|
||||
return;
|
||||
}
|
||||
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
@ -149,6 +217,12 @@ class DialogEditSidebar extends LitElement {
|
||||
min-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
ha-fade-in {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,11 @@
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
|
||||
export interface EditSidebarDialogParams {
|
||||
saveCallback: (order: string[], hidden: string[]) => void;
|
||||
}
|
||||
|
||||
export const loadEditSidebarDialog = () => import("./dialog-edit-sidebar");
|
||||
|
||||
export const showEditSidebarDialog = (
|
||||
element: HTMLElement,
|
||||
dialogParams: EditSidebarDialogParams
|
||||
): void => {
|
||||
export const showEditSidebarDialog = (element: HTMLElement): void => {
|
||||
fireEvent(element, "show-dialog", {
|
||||
dialogTag: "dialog-edit-sidebar",
|
||||
dialogImport: loadEditSidebarDialog,
|
||||
dialogParams,
|
||||
dialogParams: {},
|
||||
});
|
||||
};
|
||||
|
@ -5,31 +5,23 @@ import type { HASSDomEvent } from "../common/dom/fire_event";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { listenMediaQuery } from "../common/dom/media_query";
|
||||
import { toggleAttribute } from "../common/dom/toggle_attribute";
|
||||
import { computeRTLDirection } from "../common/util/compute_rtl";
|
||||
import "../components/ha-drawer";
|
||||
import { showNotificationDrawer } from "../dialogs/notifications/show-notification-drawer";
|
||||
import type { HomeAssistant, Route } from "../types";
|
||||
import "./partial-panel-resolver";
|
||||
import { computeRTLDirection } from "../common/util/compute_rtl";
|
||||
import { storage } from "../common/decorators/storage";
|
||||
|
||||
declare global {
|
||||
// for fire event
|
||||
interface HASSDomEvents {
|
||||
"hass-toggle-menu": undefined | { open?: boolean };
|
||||
"hass-edit-sidebar": EditSideBarEvent;
|
||||
"hass-show-notifications": undefined;
|
||||
}
|
||||
interface HTMLElementEventMap {
|
||||
"hass-edit-sidebar": HASSDomEvent<EditSideBarEvent>;
|
||||
"hass-toggle-menu": HASSDomEvent<HASSDomEvents["hass-toggle-menu"]>;
|
||||
}
|
||||
}
|
||||
|
||||
interface EditSideBarEvent {
|
||||
order: string[];
|
||||
hidden: string[];
|
||||
}
|
||||
|
||||
@customElement("home-assistant-main")
|
||||
export class HomeAssistantMain extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
@ -44,22 +36,6 @@ export class HomeAssistantMain extends LitElement {
|
||||
|
||||
@state() private _drawerOpen = false;
|
||||
|
||||
@state()
|
||||
@storage({
|
||||
key: "sidebarPanelOrder",
|
||||
state: true,
|
||||
subscribe: true,
|
||||
})
|
||||
private _panelOrder: string[] = [];
|
||||
|
||||
@state()
|
||||
@storage({
|
||||
key: "sidebarHiddenPanels",
|
||||
state: true,
|
||||
subscribe: true,
|
||||
})
|
||||
private _hiddenPanels: string[] = [];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
listenMediaQuery("(max-width: 870px)", (matches) => {
|
||||
@ -81,8 +57,6 @@ export class HomeAssistantMain extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.narrow=${sidebarNarrow}
|
||||
.route=${this.route}
|
||||
.panelOrder=${this._panelOrder}
|
||||
.hiddenPanels=${this._hiddenPanels}
|
||||
.alwaysExpand=${sidebarNarrow || this.hass.dockedSidebar === "docked"}
|
||||
></ha-sidebar>
|
||||
<partial-panel-resolver
|
||||
@ -106,14 +80,6 @@ export class HomeAssistantMain extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
this.addEventListener(
|
||||
"hass-edit-sidebar",
|
||||
(ev: HASSDomEvent<EditSideBarEvent>) => {
|
||||
this._panelOrder = ev.detail.order;
|
||||
this._hiddenPanels = ev.detail.hidden;
|
||||
}
|
||||
);
|
||||
|
||||
this.addEventListener("hass-toggle-menu", (ev) => {
|
||||
if (this._sidebarEditMode) {
|
||||
return;
|
||||
|
@ -150,6 +150,23 @@ class HaProfileSectionGeneral extends LitElement {
|
||||
.narrow=${this.narrow}
|
||||
.hass=${this.hass}
|
||||
></ha-pick-first-weekday-row>
|
||||
<ha-settings-row .narrow=${this.narrow}>
|
||||
<span slot="heading">
|
||||
${this.hass.localize(
|
||||
"ui.panel.profile.customize_sidebar.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="description">
|
||||
${this.hass.localize(
|
||||
"ui.panel.profile.customize_sidebar.description"
|
||||
)}
|
||||
</span>
|
||||
<mwc-button @click=${this._customizeSidebar}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.profile.customize_sidebar.button"
|
||||
)}
|
||||
</mwc-button>
|
||||
</ha-settings-row>
|
||||
${this.hass.user!.is_admin
|
||||
? html`
|
||||
<ha-advanced-mode-row
|
||||
@ -187,23 +204,6 @@ class HaProfileSectionGeneral extends LitElement {
|
||||
.narrow=${this.narrow}
|
||||
.hass=${this.hass}
|
||||
></ha-pick-dashboard-row>
|
||||
<ha-settings-row .narrow=${this.narrow}>
|
||||
<span slot="heading">
|
||||
${this.hass.localize(
|
||||
"ui.panel.profile.customize_sidebar.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="description">
|
||||
${this.hass.localize(
|
||||
"ui.panel.profile.customize_sidebar.description"
|
||||
)}
|
||||
</span>
|
||||
<mwc-button @click=${this._customizeSidebar}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.profile.customize_sidebar.button"
|
||||
)}
|
||||
</mwc-button>
|
||||
</ha-settings-row>
|
||||
${this.hass.dockedSidebar !== "auto" || !this.narrow
|
||||
? html`
|
||||
<ha-force-narrow-row
|
||||
@ -248,18 +248,9 @@ class HaProfileSectionGeneral extends LitElement {
|
||||
}
|
||||
|
||||
private _customizeSidebar() {
|
||||
showEditSidebarDialog(this, {
|
||||
saveCallback: this._saveSidebar,
|
||||
});
|
||||
showEditSidebarDialog(this);
|
||||
}
|
||||
|
||||
private _saveSidebar = (order: string[], hidden: string[]) => {
|
||||
fireEvent(this, "hass-edit-sidebar", {
|
||||
order,
|
||||
hidden,
|
||||
});
|
||||
};
|
||||
|
||||
private _handleLogOut() {
|
||||
showConfirmationDialog(this, {
|
||||
title: this.hass.localize("ui.panel.profile.logout_title"),
|
||||
|
@ -2019,7 +2019,9 @@
|
||||
"sidebar": {
|
||||
"external_app_configuration": "App settings",
|
||||
"sidebar_toggle": "Sidebar toggle",
|
||||
"edit_sidebar": "Edit sidebar"
|
||||
"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 into. To create a sidebar per device, you should use a different user for that device."
|
||||
},
|
||||
"panel": {
|
||||
"my": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user