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
This commit is contained in:
parent
1fbc97296c
commit
e48110d7c6
5 changed files with 46 additions and 36 deletions
|
@ -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) {
|
||||
|
|
|
@ -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<UsernameBoxProps> = ({ username }) => {
|
|||
);
|
||||
};
|
||||
|
||||
interface ManageAccountButtonProps {
|
||||
externalAccountManagementUrl: string;
|
||||
}
|
||||
|
||||
const ManageAccountButton: React.FC<ManageAccountButtonProps> = ({ externalAccountManagementUrl }) => (
|
||||
<AccessibleButton
|
||||
onClick={null}
|
||||
element="a"
|
||||
kind="primary"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
href={externalAccountManagementUrl}
|
||||
data-testid="external-account-management-link"
|
||||
>
|
||||
<PopOutIcon className="mx_UserProfileSettings_accountmanageIcon" width="24" height="24" />
|
||||
{_t("settings|general|oidc_manage_button")}
|
||||
</AccessibleButton>
|
||||
);
|
||||
|
||||
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<UserProfileSettingsProps> = ({ canSetDisplayName, canSetAvatar }) => {
|
||||
const UserProfileSettings: React.FC<UserProfileSettingsProps> = ({
|
||||
externalAccountManagementUrl,
|
||||
canSetDisplayName,
|
||||
canSetAvatar,
|
||||
}) => {
|
||||
const [avatarURL, setAvatarURL] = useState(OwnProfileStore.instance.avatarMxc);
|
||||
const [displayName, setDisplayName] = useState(OwnProfileStore.instance.displayName ?? "");
|
||||
const [avatarError, setAvatarError] = useState<boolean>(false);
|
||||
|
@ -192,6 +219,11 @@ const UserProfileSettings: React.FC<UserProfileSettingsProps> = ({ canSetDisplay
|
|||
</Alert>
|
||||
)}
|
||||
{userIdentifier && <UsernameBox username={userIdentifier} />}
|
||||
{externalAccountManagementUrl && (
|
||||
<div className="mx_UserProfileSettings_profile_buttons">
|
||||
<ManageAccountButton externalAccountManagementUrl={externalAccountManagementUrl} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -215,33 +215,6 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
|
|||
);
|
||||
}
|
||||
|
||||
let externalAccountManagement: JSX.Element | undefined;
|
||||
if (this.state.externalAccountManagementUrl) {
|
||||
const { hostname } = new URL(this.state.externalAccountManagementUrl);
|
||||
|
||||
externalAccountManagement = (
|
||||
<>
|
||||
<SettingsSubsectionText data-testid="external-account-management-outer">
|
||||
{_t(
|
||||
"settings|general|external_account_management",
|
||||
{ hostname },
|
||||
{ code: (sub) => <code>{sub}</code> },
|
||||
)}
|
||||
</SettingsSubsectionText>
|
||||
<AccessibleButton
|
||||
onClick={null}
|
||||
element="a"
|
||||
kind="primary"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
href={this.state.externalAccountManagementUrl}
|
||||
data-testid="external-account-management-link"
|
||||
>
|
||||
{_t("settings|general|oidc_manage_button")}
|
||||
</AccessibleButton>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<SettingsSubsection
|
||||
|
@ -249,7 +222,6 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
|
|||
stretchContent
|
||||
data-testid="accountSection"
|
||||
>
|
||||
{externalAccountManagement}
|
||||
{passwordChangeSection}
|
||||
</SettingsSubsection>
|
||||
</>
|
||||
|
@ -324,6 +296,7 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
|
|||
<SettingsTab data-testid="mx_GeneralUserSettingsTab">
|
||||
<SettingsSection>
|
||||
<UserProfileSettings
|
||||
externalAccountManagementUrl={this.state.externalAccountManagementUrl}
|
||||
canSetDisplayName={this.state.canSetDisplayName}
|
||||
canSetAvatar={this.state.canSetAvatar}
|
||||
/>
|
||||
|
|
|
@ -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 <code>%(hostname)s</code>.",
|
||||
"identity_server_no_token": "No identity access token found",
|
||||
"identity_server_not_set": "Identity server not set",
|
||||
"incorrect_msisdn_verification": "Incorrect verification code",
|
||||
|
|
|
@ -92,13 +92,10 @@ describe("<GeneralUserSettingsTab />", () => {
|
|||
} 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", () => {
|
||||
|
|
Loading…
Reference in a new issue