From e48110d7c6d246c4f73095e8655a747986faa44a Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 4 Jul 2024 10:46:26 +0100 Subject: [PATCH] Move the account management button (#12663) * Disable profile controls if the HS doesn't allow them to be set Also updates to the js-sdk interface changes in https://github.com/matrix-org/matrix-js-sdk/pull/4246 * Remove unnecessary await * Pass disabled prop to accessiblebutton in avatarsetting * Move the account management button The section it lives in with the server name goes, and the button just lives on its own in the profile section. * Update test * Revert bits of previous PR that are no longer wanted because we squash merge so git can no longer make sense of what changes have been applied. * More squash-merge fails * More more squash merge fails --- .../views/settings/_UserProfileSettings.pcss | 9 +++++ .../views/settings/UserProfileSettings.tsx | 34 ++++++++++++++++++- .../tabs/user/GeneralUserSettingsTab.tsx | 29 +--------------- src/i18n/strings/en_EN.json | 1 - .../tabs/user/GeneralUserSettingsTab-test.tsx | 9 ++--- 5 files changed, 46 insertions(+), 36 deletions(-) diff --git a/res/css/views/settings/_UserProfileSettings.pcss b/res/css/views/settings/_UserProfileSettings.pcss index b1909dde12a..31c1ef628f9 100644 --- a/res/css/views/settings/_UserProfileSettings.pcss +++ b/res/css/views/settings/_UserProfileSettings.pcss @@ -47,6 +47,15 @@ limitations under the License. font-size: 15px; font-weight: 500; } + + .mx_UserProfileSettings_profile_buttons { + margin-top: var(--cpd-space-8x); + margin-bottom: var(--cpd-space-8x); + } + + .mx_UserProfileSettings_accountmanageIcon { + margin-right: var(--cpd-space-2x); + } } @media (max-width: 768px) { diff --git a/src/components/views/settings/UserProfileSettings.tsx b/src/components/views/settings/UserProfileSettings.tsx index af1c098cef3..a5ff4356767 100644 --- a/src/components/views/settings/UserProfileSettings.tsx +++ b/src/components/views/settings/UserProfileSettings.tsx @@ -17,6 +17,7 @@ limitations under the License. import React, { ChangeEvent, useCallback, useEffect, useMemo, useState } from "react"; import { logger } from "matrix-js-sdk/src/logger"; import { EditInPlace, Alert, ErrorMessage } from "@vector-im/compound-web"; +import { Icon as PopOutIcon } from "@vector-im/compound-design-tokens/icons/pop-out.svg"; import { _t } from "../../../languageHandler"; import { OwnProfileStore } from "../../../stores/OwnProfileStore"; @@ -29,6 +30,7 @@ import UserIdentifierCustomisations from "../../../customisations/UserIdentifier import { useId } from "../../../utils/useId"; import CopyableText from "../elements/CopyableText"; import { useMatrixClientContext } from "../../../contexts/MatrixClientContext"; +import AccessibleButton from "../elements/AccessibleButton"; const SpinnerToast: React.FC = ({ children }) => ( <> @@ -55,7 +57,28 @@ const UsernameBox: React.FC = ({ username }) => { ); }; +interface ManageAccountButtonProps { + externalAccountManagementUrl: string; +} + +const ManageAccountButton: React.FC = ({ externalAccountManagementUrl }) => ( + + + {_t("settings|general|oidc_manage_button")} + +); + interface UserProfileSettingsProps { + // The URL to redirect the user to in order to manage their account. + externalAccountManagementUrl?: string; // Whether the homeserver allows the user to set their display name. canSetDisplayName: boolean; // Whether the homeserver allows the user to set their avatar. @@ -65,7 +88,11 @@ interface UserProfileSettingsProps { /** * A group of settings views to allow the user to set their profile information. */ -const UserProfileSettings: React.FC = ({ canSetDisplayName, canSetAvatar }) => { +const UserProfileSettings: React.FC = ({ + externalAccountManagementUrl, + canSetDisplayName, + canSetAvatar, +}) => { const [avatarURL, setAvatarURL] = useState(OwnProfileStore.instance.avatarMxc); const [displayName, setDisplayName] = useState(OwnProfileStore.instance.displayName ?? ""); const [avatarError, setAvatarError] = useState(false); @@ -192,6 +219,11 @@ const UserProfileSettings: React.FC = ({ canSetDisplay )} {userIdentifier && } + {externalAccountManagementUrl && ( +
+ +
+ )} ); }; diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx index ef90077f2d4..46c13430d3f 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx @@ -215,33 +215,6 @@ export default class GeneralUserSettingsTab extends React.Component - - {_t( - "settings|general|external_account_management", - { hostname }, - { code: (sub) => {sub} }, - )} - - - {_t("settings|general|oidc_manage_button")} - - - ); - } return ( <> - {externalAccountManagement} {passwordChangeSection} @@ -324,6 +296,7 @@ export default class GeneralUserSettingsTab extends React.Component diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 21adea64e91..5a532d00789 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2511,7 +2511,6 @@ "error_revoke_msisdn_discovery": "Unable to revoke sharing for phone number", "error_share_email_discovery": "Unable to share email address", "error_share_msisdn_discovery": "Unable to share phone number", - "external_account_management": "Your account details are managed separately at %(hostname)s.", "identity_server_no_token": "No identity access token found", "identity_server_not_set": "Identity server not set", "incorrect_msisdn_verification": "Incorrect verification code", diff --git a/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx b/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx index 2532e98c600..17016e0df20 100644 --- a/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx +++ b/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx @@ -92,13 +92,10 @@ describe("", () => { } as unknown as OidcClientStore; jest.spyOn(stores, "oidcClientStore", "get").mockReturnValue(mockOidcClientStore); - const { getByTestId } = render(getComponent()); + render(getComponent()); - // wait for well-known call to settle - await flushPromises(); - - expect(getByTestId("external-account-management-outer").textContent).toMatch(/.*id\.server\.org/); - expect(getByTestId("external-account-management-link").getAttribute("href")).toMatch(accountManagementLink); + const manageAccountLink = await screen.findByRole("button", { name: "Manage account" }); + expect(manageAccountLink.getAttribute("href")).toMatch(accountManagementLink); }); describe("Manage integrations", () => {