diff --git a/src/panels/profile/ha-panel-profile.ts b/src/panels/profile/ha-panel-profile.ts index 0c4c121aaf..b755872cb2 100644 --- a/src/panels/profile/ha-panel-profile.ts +++ b/src/panels/profile/ha-panel-profile.ts @@ -1,286 +1,45 @@ -import "@material/mwc-button"; -import { UnsubscribeFunc } from "home-assistant-js-websocket"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property, state } from "lit/decorators"; -import { fireEvent } from "../../common/dom/fire_event"; -import "../../components/ha-card"; -import "../../components/ha-menu-button"; -import "../../components/ha-top-app-bar-fixed"; -import { isExternal } from "../../data/external"; -import { - CoreFrontendUserData, - getOptimisticFrontendUserDataCollection, -} from "../../data/frontend"; -import { RefreshToken } from "../../data/refresh_token"; -import { showConfirmationDialog } from "../../dialogs/generic/show-dialog-box"; -import { haStyle } from "../../resources/styles"; +import { customElement, property } from "lit/decorators"; + import { HomeAssistant } from "../../types"; -import "./ha-advanced-mode-row"; -import "./ha-change-password-card"; -import "./ha-enable-shortcuts-row"; -import "./ha-force-narrow-row"; -import "./ha-long-lived-access-tokens-card"; -import "./ha-mfa-modules-card"; -import "./ha-pick-dashboard-row"; -import "./ha-pick-first-weekday-row"; -import "./ha-pick-language-row"; -import "./ha-pick-number-format-row"; -import "./ha-pick-theme-row"; -import "./ha-pick-time-format-row"; -import "./ha-pick-date-format-row"; -import "./ha-pick-time-zone-row"; -import "./ha-push-notifications-row"; -import "./ha-refresh-tokens-card"; -import "./ha-set-suspend-row"; -import "./ha-set-vibrate-row"; +import { HassRouterPage, RouterOptions } from "../../layouts/hass-router-page"; +import { PageNavigation } from "../../layouts/hass-tabs-subpage"; +import { SubscribeMixin } from "../../mixins/subscribe-mixin"; + +export const profileSections: PageNavigation[] = [ + { + path: "/profile/general", + translationKey: "ui.panel.profile.tabs.general", + }, + { + path: "/profile/security", + translationKey: "ui.panel.profile.tabs.security", + }, +]; @customElement("ha-panel-profile") -class HaPanelProfile extends LitElement { +class HaPanelProfile extends SubscribeMixin(HassRouterPage) { @property({ attribute: false }) public hass!: HomeAssistant; @property({ type: Boolean }) public narrow = false; - @state() private _refreshTokens?: RefreshToken[]; + protected routerOptions: RouterOptions = { + defaultPage: "general", + routes: { + general: { + tag: "ha-profile-section-general", + load: () => import("./ha-profile-section-general"), + }, + security: { + tag: "ha-profile-section-security", + load: () => import("./ha-profile-section-security"), + }, + }, + }; - @state() private _coreUserData?: CoreFrontendUserData | null; - - private _unsubCoreData?: UnsubscribeFunc; - - public connectedCallback() { - super.connectedCallback(); - this._refreshRefreshTokens(); - this._unsubCoreData = getOptimisticFrontendUserDataCollection( - this.hass.connection, - "core" - ).subscribe((coreUserData) => { - this._coreUserData = coreUserData; - }); - } - - public disconnectedCallback() { - super.disconnectedCallback(); - if (this._unsubCoreData) { - this._unsubCoreData(); - this._unsubCoreData = undefined; - } - } - - protected render(): TemplateResult { - return html` - - -
${this.hass.localize("panel.profile")}
-
- -
- ${this.hass.localize("ui.panel.profile.current_user", { - fullName: this.hass.user!.name, - })} - ${this.hass.user!.is_owner - ? this.hass.localize("ui.panel.profile.is_owner") - : ""} -
-
- - ${this.hass.localize("ui.panel.profile.logout")} - -
-
- -
- ${this.hass.localize("ui.panel.profile.user_settings_detail")} -
- - - - - - - ${this.hass.user!.is_admin - ? html` - - ` - : ""} -
- -
- ${this.hass.localize("ui.panel.profile.client_settings_detail")} -
- - - - - ${this.hass.localize( - "ui.panel.profile.customize_sidebar.header" - )} - - - ${this.hass.localize( - "ui.panel.profile.customize_sidebar.description" - )} - - - ${this.hass.localize( - "ui.panel.profile.customize_sidebar.button" - )} - - - ${this.hass.dockedSidebar !== "auto" || !this.narrow - ? html` - - ` - : ""} - ${"vibrate" in navigator - ? html` - - ` - : ""} - ${!isExternal - ? html` - - ` - : ""} - - -
- - ${this.hass.user!.credentials.some( - (cred) => cred.auth_provider_type === "homeassistant" - ) - ? html` - - ` - : ""} - - - - - - -
-
- `; - } - - private _customizeSidebar() { - fireEvent(this, "hass-edit-sidebar", { editMode: true }); - } - - private async _refreshRefreshTokens() { - this._refreshTokens = await this.hass.callWS({ - type: "auth/refresh_tokens", - }); - } - - private _handleLogOut() { - showConfirmationDialog(this, { - title: this.hass.localize("ui.panel.profile.logout_title"), - text: this.hass.localize("ui.panel.profile.logout_text"), - confirmText: this.hass.localize("ui.panel.profile.logout"), - confirm: () => fireEvent(this, "hass-logout"), - }); - } - - static get styles(): CSSResultGroup { - return [ - haStyle, - css` - :host { - -ms-user-select: initial; - -webkit-user-select: initial; - -moz-user-select: initial; - } - - .content { - display: block; - max-width: 600px; - margin: 0 auto; - padding-bottom: env(safe-area-inset-bottom); - } - - .content > * { - display: block; - margin: 24px 0; - } - - .promo-advanced { - text-align: center; - color: var(--secondary-text-color); - } - `, - ]; + protected updatePageEl(el) { + el.route = this.routeTail; + el.hass = this.hass; + el.narrow = this.narrow; } } declare global { diff --git a/src/panels/profile/ha-profile-section-general.ts b/src/panels/profile/ha-profile-section-general.ts new file mode 100644 index 0000000000..054e96eb2d --- /dev/null +++ b/src/panels/profile/ha-profile-section-general.ts @@ -0,0 +1,262 @@ +import "@material/mwc-button"; +import { UnsubscribeFunc } from "home-assistant-js-websocket"; +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { fireEvent } from "../../common/dom/fire_event"; +import "../../components/ha-card"; +import "../../layouts/hass-tabs-subpage"; +import { profileSections } from "./ha-panel-profile"; +import { isExternal } from "../../data/external"; +import { + CoreFrontendUserData, + getOptimisticFrontendUserDataCollection, +} from "../../data/frontend"; +import { showConfirmationDialog } from "../../dialogs/generic/show-dialog-box"; +import { haStyle } from "../../resources/styles"; +import { HomeAssistant, Route } from "../../types"; +import "./ha-advanced-mode-row"; +import "./ha-enable-shortcuts-row"; +import "./ha-force-narrow-row"; +import "./ha-pick-dashboard-row"; +import "./ha-pick-first-weekday-row"; +import "./ha-pick-language-row"; +import "./ha-pick-number-format-row"; +import "./ha-pick-theme-row"; +import "./ha-pick-time-format-row"; +import "./ha-pick-date-format-row"; +import "./ha-pick-time-zone-row"; +import "./ha-push-notifications-row"; +import "./ha-set-suspend-row"; +import "./ha-set-vibrate-row"; + +@customElement("ha-profile-section-general") +class HaProfileSectionGeneral extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ type: Boolean }) public narrow = false; + + @state() private _coreUserData?: CoreFrontendUserData | null; + + @property({ attribute: false }) public route!: Route; + + private _unsubCoreData?: UnsubscribeFunc; + + private getCoreData() { + this._unsubCoreData = getOptimisticFrontendUserDataCollection( + this.hass.connection, + "core" + ).subscribe((coreUserData) => { + this._coreUserData = coreUserData; + }); + } + + public connectedCallback() { + super.connectedCallback(); + if (this.hass) { + this.getCoreData(); + } + } + + public firstUpdated() { + if (!this._unsubCoreData) { + this.getCoreData(); + } + } + + public disconnectedCallback() { + super.disconnectedCallback(); + if (this._unsubCoreData) { + this._unsubCoreData(); + this._unsubCoreData = undefined; + } + } + + protected render(): TemplateResult { + return html` + +
${this.hass.localize("panel.profile")}
+
+ +
+ ${this.hass.localize("ui.panel.profile.current_user", { + fullName: this.hass.user!.name, + })} + ${this.hass.user!.is_owner + ? this.hass.localize("ui.panel.profile.is_owner") + : ""} +
+
+ + ${this.hass.localize("ui.panel.profile.logout")} + +
+
+ +
+ ${this.hass.localize("ui.panel.profile.user_settings_detail")} +
+ + + + + + + ${this.hass.user!.is_admin + ? html` + + ` + : ""} +
+ +
+ ${this.hass.localize("ui.panel.profile.client_settings_detail")} +
+ + + + + ${this.hass.localize( + "ui.panel.profile.customize_sidebar.header" + )} + + + ${this.hass.localize( + "ui.panel.profile.customize_sidebar.description" + )} + + + ${this.hass.localize( + "ui.panel.profile.customize_sidebar.button" + )} + + + ${this.hass.dockedSidebar !== "auto" || !this.narrow + ? html` + + ` + : ""} + ${"vibrate" in navigator + ? html` + + ` + : ""} + ${!isExternal + ? html` + + ` + : ""} + + +
+
+
+ `; + } + + private _customizeSidebar() { + fireEvent(this, "hass-edit-sidebar", { editMode: true }); + } + + private _handleLogOut() { + showConfirmationDialog(this, { + title: this.hass.localize("ui.panel.profile.logout_title"), + text: this.hass.localize("ui.panel.profile.logout_text"), + confirmText: this.hass.localize("ui.panel.profile.logout"), + confirm: () => fireEvent(this, "hass-logout"), + }); + } + + static get styles(): CSSResultGroup { + return [ + haStyle, + css` + :host { + -ms-user-select: initial; + -webkit-user-select: initial; + -moz-user-select: initial; + } + + .content { + display: block; + max-width: 600px; + margin: 0 auto; + padding-bottom: env(safe-area-inset-bottom); + } + + .content > * { + display: block; + margin: 24px 0; + } + + .promo-advanced { + text-align: center; + color: var(--secondary-text-color); + } + `, + ]; + } +} +declare global { + interface HTMLElementTagNameMap { + "ha-profile-section-general": HaProfileSectionGeneral; + } +} diff --git a/src/panels/profile/ha-profile-section-security.ts b/src/panels/profile/ha-profile-section-security.ts new file mode 100644 index 0000000000..793cb497bd --- /dev/null +++ b/src/panels/profile/ha-profile-section-security.ts @@ -0,0 +1,119 @@ +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import "../../layouts/hass-tabs-subpage"; +import { profileSections } from "./ha-panel-profile"; +import { RefreshToken } from "../../data/refresh_token"; +import { haStyle } from "../../resources/styles"; +import { HomeAssistant, Route } from "../../types"; +import "./ha-change-password-card"; +import "./ha-long-lived-access-tokens-card"; +import "./ha-mfa-modules-card"; +import "./ha-refresh-tokens-card"; + +@customElement("ha-profile-section-security") +class HaProfileSectionSecurity extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ type: Boolean }) public narrow = false; + + @state() private _refreshTokens?: RefreshToken[]; + + @property({ attribute: false }) public route!: Route; + + public connectedCallback() { + super.connectedCallback(); + this._refreshRefreshTokens(); + } + + public firstUpdated() { + if (!this._refreshTokens) { + this._refreshRefreshTokens(); + } + } + + protected render(): TemplateResult { + return html` + +
${this.hass.localize("panel.profile")}
+
+ ${this.hass.user!.credentials.some( + (cred) => cred.auth_provider_type === "homeassistant" + ) + ? html` + + ` + : ""} + + + + + +
+
+ `; + } + + private async _refreshRefreshTokens() { + if (!this.hass) { + return; + } + this._refreshTokens = await this.hass.callWS({ + type: "auth/refresh_tokens", + }); + } + + static get styles(): CSSResultGroup { + return [ + haStyle, + css` + :host { + -ms-user-select: initial; + -webkit-user-select: initial; + -moz-user-select: initial; + } + + .content { + display: block; + max-width: 600px; + margin: 0 auto; + padding-bottom: env(safe-area-inset-bottom); + } + + .content > * { + display: block; + margin: 24px 0; + } + + .promo-advanced { + text-align: center; + color: var(--secondary-text-color); + } + `, + ]; + } +} +declare global { + interface HTMLElementTagNameMap { + "ha-profile-section-security": HaProfileSectionSecurity; + } +} diff --git a/src/translations/en.json b/src/translations/en.json index 03bf3a621e..0576924ef5 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5903,6 +5903,10 @@ "edit_zones": "Edit zones" }, "profile": { + "tabs": { + "general": "General", + "security": "Security" + }, "current_user": "You are currently logged in as {fullName}.", "is_owner": "You are an owner.", "user_settings_header": "User settings",