Use semantic headings in user settings Security (#10774)

* split SettingsSection out of SettingsTab, replace usage

* correct copyright

* use semantic headings in GeneralRoomSettingsTab

* use SettingsTab and SettingsSubsection in room settings

* fix VoipRoomSettingsTab

* use SettingsSection components in space settings

* settingssubsection text component

* use semantic headings in HelpUserSetttings tab

* use ExternalLink components for external links

* test

* strict

* lint

* semantic heading in labs settings

* semantic headings in keyboard settings tab

* semantic heading in preferencesusersettingstab

* tidying

* use new settings components in eventindexpanel

* findByTestId

* prettier

* semantic headings and style refresh for crypto settings

* e2e panel

* test cross signing panel

* strict

* more strict

* tweak

* test eventindexpanel

* strict fixes
This commit is contained in:
Kerry 2023-05-19 10:32:10 +12:00 committed by GitHub
parent 6c262fff6b
commit d9a61c093c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 721 additions and 303 deletions

View file

@ -1,5 +1,5 @@
/*
Copyright 2019 - 2022 The Matrix.org Foundation C.I.C.
Copyright 2019 - 2023 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -41,6 +41,9 @@ import { privateShouldBeEncrypted } from "../../../../../utils/rooms";
import LoginWithQR, { Mode } from "../../../auth/LoginWithQR";
import LoginWithQRSection from "../../devices/LoginWithQRSection";
import type { IServerVersions } from "matrix-js-sdk/src/matrix";
import SettingsTab from "../SettingsTab";
import { SettingsSection } from "../../shared/SettingsSection";
import SettingsSubsection, { SettingsSubsectionText } from "../../shared/SettingsSubsection";
interface IIgnoredUserProps {
userId: string;
@ -245,10 +248,9 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
});
return (
<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{_t("Ignored users")}</span>
<div className="mx_SettingsTab_subsectionText">{userIds}</div>
</div>
<SettingsSubsection heading={_t("Ignored users")}>
<SettingsSubsectionText>{userIds}</SettingsSubsectionText>
</SettingsSubsection>
);
}
@ -260,24 +262,25 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
}
return (
<div className="mx_SettingsTab_section mx_SecurityUserSettingsTab_bulkOptions">
<span className="mx_SettingsTab_subheading">{_t("Bulk options")}</span>
<AccessibleButton
onClick={this.onAcceptAllInvitesClicked}
kind="primary"
disabled={this.state.managingInvites}
>
{_t("Accept all %(invitedRooms)s invites", { invitedRooms: invitedRoomIds.size })}
</AccessibleButton>
<AccessibleButton
onClick={this.onRejectAllInvitesClicked}
kind="danger"
disabled={this.state.managingInvites}
>
{_t("Reject all %(invitedRooms)s invites", { invitedRooms: invitedRoomIds.size })}
</AccessibleButton>
{this.state.managingInvites ? <InlineSpinner /> : <div />}
</div>
<SettingsSubsection heading={_t("Bulk options")}>
<div className="mx_SecurityUserSettingsTab_bulkOptions">
<AccessibleButton
onClick={this.onAcceptAllInvitesClicked}
kind="primary"
disabled={this.state.managingInvites}
>
{_t("Accept all %(invitedRooms)s invites", { invitedRooms: invitedRoomIds.size })}
</AccessibleButton>
<AccessibleButton
onClick={this.onRejectAllInvitesClicked}
kind="danger"
disabled={this.state.managingInvites}
>
{_t("Reject all %(invitedRooms)s invites", { invitedRooms: invitedRoomIds.size })}
</AccessibleButton>
{this.state.managingInvites ? <InlineSpinner /> : <div />}
</div>
</SettingsSubsection>
);
}
@ -291,19 +294,15 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
public render(): React.ReactNode {
const secureBackup = (
<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{_t("Secure Backup")}</span>
<div className="mx_SettingsTab_subsectionText">
<SecureBackupPanel />
</div>
</div>
<SettingsSubsection heading={_t("Secure Backup")}>
<SecureBackupPanel />
</SettingsSubsection>
);
const eventIndex = (
<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{_t("Message search")}</span>
<SettingsSubsection heading={_t("Message search")}>
<EventIndexPanel />
</div>
</SettingsSubsection>
);
// XXX: There's no such panel in the current cross-signing designs, but
@ -311,12 +310,9 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
// in having advanced details here once all flows are implemented, we
// can remove this.
const crossSigning = (
<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{_t("Cross-signing")}</span>
<div className="mx_SettingsTab_subsectionText">
<CrossSigningPanel />
</div>
</div>
<SettingsSubsection heading={_t("Cross-signing")}>
<CrossSigningPanel />
</SettingsSubsection>
);
let warning;
@ -340,28 +336,24 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
});
};
privacySection = (
<React.Fragment>
<div className="mx_SettingsTab_heading">{_t("Privacy")}</div>
<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{_t("Analytics")}</span>
<div className="mx_SettingsTab_subsectionText">
<p>
{_t(
"Share anonymous data to help us identify issues. Nothing personal. " +
"No third parties.",
)}
</p>
<AccessibleButton kind="link" onClick={onClickAnalyticsLearnMore}>
{_t("Learn more")}
</AccessibleButton>
</div>
<SettingsSection heading={_t("Privacy")}>
<SettingsSubsection
heading={_t("Analytics")}
description={_t(
"Share anonymous data to help us identify issues. Nothing personal. No third parties.",
)}
>
<AccessibleButton kind="link" onClick={onClickAnalyticsLearnMore}>
{_t("Learn more")}
</AccessibleButton>
{PosthogAnalytics.instance.isEnabled() && (
<SettingsFlag name="pseudonymousAnalyticsOptIn" level={SettingLevel.ACCOUNT} />
)}
<span className="mx_SettingsTab_subheading">{_t("Sessions")}</span>
</SettingsSubsection>
<SettingsSubsection heading={_t("Sessions")}>
<SettingsFlag name="deviceClientInformationOptIn" level={SettingLevel.ACCOUNT} />
</div>
</React.Fragment>
</SettingsSubsection>
</SettingsSection>
);
}
@ -373,67 +365,60 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
// only show the section if there's something to show
if (ignoreUsersPanel || invitesPanel || e2ePanel) {
advancedSection = (
<>
<div className="mx_SettingsTab_heading">{_t("Advanced")}</div>
<div className="mx_SettingsTab_section">
{ignoreUsersPanel}
{invitesPanel}
{e2ePanel}
</div>
</>
<SettingsSection heading={_t("Advanced")}>
{ignoreUsersPanel}
{invitesPanel}
{e2ePanel}
</SettingsSection>
);
}
}
const useNewSessionManager = SettingsStore.getValue("feature_new_device_manager");
const devicesSection = useNewSessionManager ? null : (
<>
<div className="mx_SettingsTab_heading">{_t("Where you're signed in")}</div>
<div className="mx_SettingsTab_section" data-testid="devices-section">
<span className="mx_SettingsTab_subsectionText">
{_t(
"Manage your signed-in devices below. " +
"A device's name is visible to people you communicate with.",
)}
</span>
<DevicesPanel />
</div>
<SettingsSection heading={_t("Where you're signed in")} data-testid="devices-section">
<SettingsSubsectionText>
{_t(
"Manage your signed-in devices below. " +
"A device's name is visible to people you communicate with.",
)}
</SettingsSubsectionText>
<DevicesPanel />
<LoginWithQRSection
onShowQr={this.onShowQRClicked}
versions={this.state.versions}
capabilities={this.state.capabilities}
/>
</>
</SettingsSection>
);
const client = MatrixClientPeg.get();
if (this.state.showLoginWithQR) {
return (
<div className="mx_SettingsTab mx_SecurityUserSettingsTab">
<SettingsTab>
<LoginWithQR
onFinished={this.onLoginWithQRFinished}
mode={this.state.showLoginWithQR}
client={client}
/>
</div>
</SettingsTab>
);
}
return (
<div className="mx_SettingsTab mx_SecurityUserSettingsTab">
<SettingsTab>
{warning}
{devicesSection}
<div className="mx_SettingsTab_heading">{_t("Encryption")}</div>
<div className="mx_SettingsTab_section">
<SettingsSection heading={_t("Encryption")}>
{secureBackup}
{eventIndex}
{crossSigning}
<CryptographyPanel />
</div>
</SettingsSection>
{privacySection}
{advancedSection}
</div>
</SettingsTab>
);
}
}