Use semantic headings in user settings - integrations and account deletion (#10837)
* allow testids in settings sections * use semantic headings in LabsUserSettingsTab * put back margin var * use SettingsTab wrapper * use semantic headings for deactivate acc section * use semantic heading in manage integratios * i18n * explicit cast to boolean * Update src/components/views/settings/shared/SettingsSubsection.tsx Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * test manage integration settings * test deactivate account section display * remove debug * fix cypress test --------- Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
parent
c3687489dd
commit
8cd84b0e7b
7 changed files with 232 additions and 54 deletions
|
@ -43,7 +43,7 @@ describe("General user settings tab", () => {
|
||||||
// Exclude userId from snapshots
|
// Exclude userId from snapshots
|
||||||
const percyCSS = ".mx_ProfileSettings_profile_controls_userId { visibility: hidden !important; }";
|
const percyCSS = ".mx_ProfileSettings_profile_controls_userId { visibility: hidden !important; }";
|
||||||
|
|
||||||
cy.get(".mx_SettingsTab.mx_GeneralUserSettingsTab").percySnapshotElement("User settings tab - General", {
|
cy.findByTestId("mx_GeneralUserSettingsTab").percySnapshotElement("User settings tab - General", {
|
||||||
percyCSS,
|
percyCSS,
|
||||||
// Emulate TabbedView's actual min and max widths
|
// Emulate TabbedView's actual min and max widths
|
||||||
// 580: '.mx_UserSettingsDialog .mx_TabbedView' min-width
|
// 580: '.mx_UserSettingsDialog .mx_TabbedView' min-width
|
||||||
|
@ -51,7 +51,7 @@ describe("General user settings tab", () => {
|
||||||
widths: [580, 796],
|
widths: [580, 796],
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get(".mx_SettingsTab.mx_GeneralUserSettingsTab").within(() => {
|
cy.findByTestId("mx_GeneralUserSettingsTab").within(() => {
|
||||||
// Assert that the top heading is rendered
|
// Assert that the top heading is rendered
|
||||||
cy.findByTestId("general").should("have.text", "General").should("be.visible");
|
cy.findByTestId("general").should("have.text", "General").should("be.visible");
|
||||||
|
|
||||||
|
@ -156,16 +156,10 @@ describe("General user settings tab", () => {
|
||||||
// Make sure integration manager's toggle switch is enabled
|
// Make sure integration manager's toggle switch is enabled
|
||||||
cy.get(".mx_ToggleSwitch_enabled").should("be.visible");
|
cy.get(".mx_ToggleSwitch_enabled").should("be.visible");
|
||||||
|
|
||||||
// Assert space between "Manage integrations" and the integration server address is set to 4px;
|
cy.get(".mx_SetIntegrationManager_heading_manager").should(
|
||||||
cy.get(".mx_SetIntegrationManager_heading_manager").should("have.css", "column-gap", "4px");
|
"have.text",
|
||||||
|
"Manage integrations(scalar.vector.im)",
|
||||||
cy.get(".mx_SetIntegrationManager_heading_manager").within(() => {
|
);
|
||||||
cy.get(".mx_SettingsTab_heading").should("have.text", "Manage integrations");
|
|
||||||
|
|
||||||
// Assert the headings' inline end margin values are set to zero in favor of the column-gap declaration
|
|
||||||
cy.get(".mx_SettingsTab_heading").should("have.css", "margin-inline-end", "0px");
|
|
||||||
cy.get(".mx_SettingsTab_subheading").should("have.css", "margin-inline-end", "0px");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert the account deactivation button is displayed
|
// Assert the account deactivation button is displayed
|
||||||
|
@ -178,7 +172,7 @@ describe("General user settings tab", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should support adding and removing a profile picture", () => {
|
it("should support adding and removing a profile picture", () => {
|
||||||
cy.get(".mx_SettingsTab.mx_GeneralUserSettingsTab .mx_ProfileSettings").within(() => {
|
cy.get(".mx_SettingsTab .mx_ProfileSettings").within(() => {
|
||||||
// Upload a picture
|
// Upload a picture
|
||||||
cy.get(".mx_ProfileSettings_avatarUpload").selectFile("cypress/fixtures/riot.png", { force: true });
|
cy.get(".mx_ProfileSettings_avatarUpload").selectFile("cypress/fixtures/riot.png", { force: true });
|
||||||
|
|
||||||
|
@ -225,7 +219,7 @@ describe("General user settings tab", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should support changing a display name", () => {
|
it("should support changing a display name", () => {
|
||||||
cy.get(".mx_SettingsTab.mx_GeneralUserSettingsTab .mx_ProfileSettings").within(() => {
|
cy.get(".mx_SettingsTab .mx_ProfileSettings").within(() => {
|
||||||
// Change the diaplay name to USER_NAME_NEW
|
// Change the diaplay name to USER_NAME_NEW
|
||||||
cy.findByRole("textbox", { name: "Display Name" }).type(`{selectAll}{del}${USER_NAME_NEW}{enter}`);
|
cy.findByRole("textbox", { name: "Display Name" }).type(`{selectAll}{del}${USER_NAME_NEW}{enter}`);
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,20 +17,12 @@ limitations under the License.
|
||||||
.mx_SetIntegrationManager {
|
.mx_SetIntegrationManager {
|
||||||
.mx_SettingsFlag {
|
.mx_SettingsFlag {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: var(--SettingsTab_heading_nth_child-margin-top);
|
|
||||||
|
|
||||||
.mx_SetIntegrationManager_heading_manager {
|
.mx_SetIntegrationManager_heading_manager {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
column-gap: $spacing-4;
|
column-gap: $spacing-4;
|
||||||
|
|
||||||
.mx_SettingsTab_heading,
|
|
||||||
.mx_SettingsTab_subheading {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-inline-end: 0; /* Cancel the default right (inline-end) margin */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_ToggleSwitch {
|
.mx_ToggleSwitch {
|
||||||
|
|
|
@ -23,6 +23,8 @@ import { IntegrationManagerInstance } from "../../../integrations/IntegrationMan
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import { SettingLevel } from "../../../settings/SettingLevel";
|
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||||
import ToggleSwitch from "../elements/ToggleSwitch";
|
import ToggleSwitch from "../elements/ToggleSwitch";
|
||||||
|
import Heading from "../typography/Heading";
|
||||||
|
import { SettingsSubsectionText } from "./shared/SettingsSubsection";
|
||||||
|
|
||||||
interface IProps {}
|
interface IProps {}
|
||||||
|
|
||||||
|
@ -70,11 +72,15 @@ export default class SetIntegrationManager extends React.Component<IProps, IStat
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<label className="mx_SetIntegrationManager" htmlFor="toggle_integration">
|
<label
|
||||||
|
className="mx_SetIntegrationManager"
|
||||||
|
data-testid="mx_SetIntegrationManager"
|
||||||
|
htmlFor="toggle_integration"
|
||||||
|
>
|
||||||
<div className="mx_SettingsFlag">
|
<div className="mx_SettingsFlag">
|
||||||
<div className="mx_SetIntegrationManager_heading_manager">
|
<div className="mx_SetIntegrationManager_heading_manager">
|
||||||
<span className="mx_SettingsTab_heading">{_t("Manage integrations")}</span>
|
<Heading size="h2">{_t("Manage integrations")}</Heading>
|
||||||
<span className="mx_SettingsTab_subheading">{managerName}</span>
|
<Heading size="h3">{managerName}</Heading>
|
||||||
</div>
|
</div>
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
id="toggle_integration"
|
id="toggle_integration"
|
||||||
|
@ -83,13 +89,13 @@ export default class SetIntegrationManager extends React.Component<IProps, IStat
|
||||||
onChange={this.onProvisioningToggled}
|
onChange={this.onProvisioningToggled}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_SettingsTab_subsectionText">{bodyText}</div>
|
<SettingsSubsectionText>{bodyText}</SettingsSubsectionText>
|
||||||
<div className="mx_SettingsTab_subsectionText">
|
<SettingsSubsectionText>
|
||||||
{_t(
|
{_t(
|
||||||
"Integration managers receive configuration data, and can modify widgets, " +
|
"Integration managers receive configuration data, and can modify widgets, " +
|
||||||
"send room invites, and set power levels on your behalf.",
|
"send room invites, and set power levels on your behalf.",
|
||||||
)}
|
)}
|
||||||
</div>
|
</SettingsSubsectionText>
|
||||||
</label>
|
</label>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,9 @@ import SetIdServer from "../../SetIdServer";
|
||||||
import SetIntegrationManager from "../../SetIntegrationManager";
|
import SetIntegrationManager from "../../SetIntegrationManager";
|
||||||
import ToggleSwitch from "../../../elements/ToggleSwitch";
|
import ToggleSwitch from "../../../elements/ToggleSwitch";
|
||||||
import { IS_MAC } from "../../../../../Keyboard";
|
import { IS_MAC } from "../../../../../Keyboard";
|
||||||
|
import SettingsTab from "../SettingsTab";
|
||||||
|
import { SettingsSection } from "../../shared/SettingsSection";
|
||||||
|
import SettingsSubsection from "../../shared/SettingsSubsection";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
closeSettingsFn: () => void;
|
closeSettingsFn: () => void;
|
||||||
|
@ -492,27 +495,24 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
|
||||||
private renderManagementSection(): JSX.Element {
|
private renderManagementSection(): JSX.Element {
|
||||||
// TODO: Improve warning text for account deactivation
|
// TODO: Improve warning text for account deactivation
|
||||||
return (
|
return (
|
||||||
<div className="mx_SettingsTab_section" data-testid="account-management-section">
|
<SettingsSection heading={_t("Deactivate account")}>
|
||||||
<span className="mx_SettingsTab_subheading">{_t("Account management")}</span>
|
<SettingsSubsection
|
||||||
<span className="mx_SettingsTab_subsectionText">
|
heading={_t("Account management")}
|
||||||
{_t("Deactivating your account is a permanent action — be careful!")}
|
data-testid="account-management-section"
|
||||||
</span>
|
description={_t("Deactivating your account is a permanent action — be careful!")}
|
||||||
<AccessibleButton onClick={this.onDeactivateClicked} kind="danger">
|
>
|
||||||
{_t("Deactivate Account")}
|
<AccessibleButton onClick={this.onDeactivateClicked} kind="danger">
|
||||||
</AccessibleButton>
|
{_t("Deactivate Account")}
|
||||||
</div>
|
</AccessibleButton>
|
||||||
|
</SettingsSubsection>
|
||||||
|
</SettingsSection>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderIntegrationManagerSection(): ReactNode {
|
private renderIntegrationManagerSection(): ReactNode {
|
||||||
if (!SettingsStore.getValue(UIFeature.Widgets)) return null;
|
if (!SettingsStore.getValue(UIFeature.Widgets)) return null;
|
||||||
|
|
||||||
return (
|
return <SetIntegrationManager />;
|
||||||
<div className="mx_SettingsTab_section">
|
|
||||||
{/* has its own heading as it includes the current integration manager */}
|
|
||||||
<SetIntegrationManager />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
|
@ -531,12 +531,7 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
|
||||||
|
|
||||||
let accountManagementSection: JSX.Element | undefined;
|
let accountManagementSection: JSX.Element | undefined;
|
||||||
if (SettingsStore.getValue(UIFeature.Deactivate)) {
|
if (SettingsStore.getValue(UIFeature.Deactivate)) {
|
||||||
accountManagementSection = (
|
accountManagementSection = this.renderManagementSection();
|
||||||
<>
|
|
||||||
<div className="mx_SettingsTab_heading">{_t("Deactivate account")}</div>
|
|
||||||
{this.renderManagementSection()}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let discoverySection;
|
let discoverySection;
|
||||||
|
@ -552,7 +547,7 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_SettingsTab mx_GeneralUserSettingsTab">
|
<SettingsTab data-testid="mx_GeneralUserSettingsTab">
|
||||||
<div className="mx_SettingsTab_heading" data-testid="general">
|
<div className="mx_SettingsTab_heading" data-testid="general">
|
||||||
{_t("General")}
|
{_t("General")}
|
||||||
</div>
|
</div>
|
||||||
|
@ -561,9 +556,9 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
|
||||||
{this.renderLanguageSection()}
|
{this.renderLanguageSection()}
|
||||||
{supportsMultiLanguageSpellCheck ? this.renderSpellCheckSection() : null}
|
{supportsMultiLanguageSpellCheck ? this.renderSpellCheckSection() : null}
|
||||||
{discoverySection}
|
{discoverySection}
|
||||||
{this.renderIntegrationManagerSection() /* Has its own title */}
|
{this.renderIntegrationManagerSection()}
|
||||||
{accountManagementSection}
|
{accountManagementSection}
|
||||||
</div>
|
</SettingsTab>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1568,10 +1568,10 @@
|
||||||
"Language and region": "Language and region",
|
"Language and region": "Language and region",
|
||||||
"Spell check": "Spell check",
|
"Spell check": "Spell check",
|
||||||
"Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.",
|
"Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.",
|
||||||
|
"Deactivate account": "Deactivate account",
|
||||||
"Account management": "Account management",
|
"Account management": "Account management",
|
||||||
"Deactivating your account is a permanent action — be careful!": "Deactivating your account is a permanent action — be careful!",
|
"Deactivating your account is a permanent action — be careful!": "Deactivating your account is a permanent action — be careful!",
|
||||||
"Deactivate Account": "Deactivate Account",
|
"Deactivate Account": "Deactivate Account",
|
||||||
"Deactivate account": "Deactivate account",
|
|
||||||
"Discovery": "Discovery",
|
"Discovery": "Discovery",
|
||||||
"%(brand)s version:": "%(brand)s version:",
|
"%(brand)s version:": "%(brand)s version:",
|
||||||
"Olm version:": "Olm version:",
|
"Olm version:": "Olm version:",
|
||||||
|
|
|
@ -10,9 +10,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { render } from "@testing-library/react";
|
|
||||||
|
import { fireEvent, render, screen, within } from "@testing-library/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { M_AUTHENTICATION } from "matrix-js-sdk/src/matrix";
|
import { M_AUTHENTICATION } from "matrix-js-sdk/src/matrix";
|
||||||
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
|
||||||
import GeneralUserSettingsTab from "../../../../../../src/components/views/settings/tabs/user/GeneralUserSettingsTab";
|
import GeneralUserSettingsTab from "../../../../../../src/components/views/settings/tabs/user/GeneralUserSettingsTab";
|
||||||
import MatrixClientContext from "../../../../../../src/contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../../../../src/contexts/MatrixClientContext";
|
||||||
|
@ -24,6 +26,8 @@ import {
|
||||||
mockPlatformPeg,
|
mockPlatformPeg,
|
||||||
flushPromises,
|
flushPromises,
|
||||||
} from "../../../../../test-utils";
|
} from "../../../../../test-utils";
|
||||||
|
import { UIFeature } from "../../../../../../src/settings/UIFeature";
|
||||||
|
import { SettingLevel } from "../../../../../../src/settings/SettingLevel";
|
||||||
|
|
||||||
describe("<GeneralUserSettingsTab />", () => {
|
describe("<GeneralUserSettingsTab />", () => {
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
|
@ -49,6 +53,8 @@ describe("<GeneralUserSettingsTab />", () => {
|
||||||
mockPlatformPeg();
|
mockPlatformPeg();
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
clientWellKnownSpy.mockReturnValue({});
|
clientWellKnownSpy.mockReturnValue({});
|
||||||
|
jest.spyOn(SettingsStore, "getValue").mockRestore();
|
||||||
|
jest.spyOn(logger, "error").mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not show account management link when not available", () => {
|
it("does not show account management link when not available", () => {
|
||||||
|
@ -74,4 +80,83 @@ describe("<GeneralUserSettingsTab />", () => {
|
||||||
expect(getByTestId("external-account-management-outer").textContent).toMatch(/.*id\.server\.org/);
|
expect(getByTestId("external-account-management-outer").textContent).toMatch(/.*id\.server\.org/);
|
||||||
expect(getByTestId("external-account-management-link").getAttribute("href")).toMatch(accountManagementLink);
|
expect(getByTestId("external-account-management-link").getAttribute("href")).toMatch(accountManagementLink);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Manage integrations", () => {
|
||||||
|
it("should not render manage integrations section when widgets feature is disabled", () => {
|
||||||
|
jest.spyOn(SettingsStore, "getValue").mockImplementation(
|
||||||
|
(settingName) => settingName !== UIFeature.Widgets,
|
||||||
|
);
|
||||||
|
render(getComponent());
|
||||||
|
|
||||||
|
expect(screen.queryByTestId("mx_SetIntegrationManager")).not.toBeInTheDocument();
|
||||||
|
expect(SettingsStore.getValue).toHaveBeenCalledWith(UIFeature.Widgets);
|
||||||
|
});
|
||||||
|
it("should render manage integrations sections", () => {
|
||||||
|
jest.spyOn(SettingsStore, "getValue").mockImplementation(
|
||||||
|
(settingName) => settingName === UIFeature.Widgets,
|
||||||
|
);
|
||||||
|
|
||||||
|
render(getComponent());
|
||||||
|
|
||||||
|
expect(screen.getByTestId("mx_SetIntegrationManager")).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
it("should update integrations provisioning on toggle", () => {
|
||||||
|
jest.spyOn(SettingsStore, "getValue").mockImplementation(
|
||||||
|
(settingName) => settingName === UIFeature.Widgets,
|
||||||
|
);
|
||||||
|
jest.spyOn(SettingsStore, "setValue").mockResolvedValue(undefined);
|
||||||
|
|
||||||
|
render(getComponent());
|
||||||
|
|
||||||
|
const integrationSection = screen.getByTestId("mx_SetIntegrationManager");
|
||||||
|
fireEvent.click(within(integrationSection).getByRole("switch"));
|
||||||
|
|
||||||
|
expect(SettingsStore.setValue).toHaveBeenCalledWith(
|
||||||
|
"integrationProvisioning",
|
||||||
|
null,
|
||||||
|
SettingLevel.ACCOUNT,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
expect(within(integrationSection).getByRole("switch")).toBeChecked();
|
||||||
|
});
|
||||||
|
it("handles error when updating setting fails", async () => {
|
||||||
|
jest.spyOn(SettingsStore, "getValue").mockImplementation(
|
||||||
|
(settingName) => settingName === UIFeature.Widgets,
|
||||||
|
);
|
||||||
|
jest.spyOn(logger, "error").mockImplementation(() => {});
|
||||||
|
|
||||||
|
jest.spyOn(SettingsStore, "setValue").mockRejectedValue("oups");
|
||||||
|
|
||||||
|
render(getComponent());
|
||||||
|
|
||||||
|
const integrationSection = screen.getByTestId("mx_SetIntegrationManager");
|
||||||
|
fireEvent.click(within(integrationSection).getByRole("switch"));
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
expect(logger.error).toHaveBeenCalledWith("Error changing integration manager provisioning");
|
||||||
|
expect(logger.error).toHaveBeenCalledWith("oups");
|
||||||
|
expect(within(integrationSection).getByRole("switch")).not.toBeChecked();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("deactive account", () => {
|
||||||
|
it("should not render section when account deactivation feature is disabled", () => {
|
||||||
|
jest.spyOn(SettingsStore, "getValue").mockImplementation(
|
||||||
|
(settingName) => settingName !== UIFeature.Deactivate,
|
||||||
|
);
|
||||||
|
render(getComponent());
|
||||||
|
|
||||||
|
expect(screen.queryByText("Deactivate account")).not.toBeInTheDocument();
|
||||||
|
expect(SettingsStore.getValue).toHaveBeenCalledWith(UIFeature.Deactivate);
|
||||||
|
});
|
||||||
|
it("should render section when account deactivation feature is enabled", () => {
|
||||||
|
jest.spyOn(SettingsStore, "getValue").mockImplementation(
|
||||||
|
(settingName) => settingName === UIFeature.Deactivate,
|
||||||
|
);
|
||||||
|
render(getComponent());
|
||||||
|
|
||||||
|
expect(screen.getByText("Deactivate account").parentElement!).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`<GeneralUserSettingsTab /> Manage integrations should render manage integrations sections 1`] = `
|
||||||
|
<label
|
||||||
|
class="mx_SetIntegrationManager"
|
||||||
|
data-testid="mx_SetIntegrationManager"
|
||||||
|
for="toggle_integration"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsFlag"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="mx_SetIntegrationManager_heading_manager"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
class="mx_Heading_h2"
|
||||||
|
>
|
||||||
|
Manage integrations
|
||||||
|
</h2>
|
||||||
|
<h3
|
||||||
|
class="mx_Heading_h3"
|
||||||
|
>
|
||||||
|
(scalar.vector.im)
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
aria-checked="false"
|
||||||
|
aria-disabled="false"
|
||||||
|
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_enabled"
|
||||||
|
id="toggle_integration"
|
||||||
|
role="switch"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="mx_ToggleSwitch_ball"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsection_text"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Use an integration manager
|
||||||
|
<b>
|
||||||
|
(scalar.vector.im)
|
||||||
|
</b>
|
||||||
|
to manage bots, widgets, and sticker packs.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsection_text"
|
||||||
|
>
|
||||||
|
Integration managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`<GeneralUserSettingsTab /> deactive account should render section when account deactivation feature is enabled 1`] = `
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSection"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
class="mx_Heading_h2"
|
||||||
|
>
|
||||||
|
Deactivate account
|
||||||
|
</h2>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSection_subSections"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsection"
|
||||||
|
data-testid="account-management-section"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsectionHeading"
|
||||||
|
>
|
||||||
|
<h3
|
||||||
|
class="mx_Heading_h3 mx_SettingsSubsectionHeading_heading"
|
||||||
|
>
|
||||||
|
Account management
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsection_description"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsection_text"
|
||||||
|
>
|
||||||
|
Deactivating your account is a permanent action — be careful!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsection_content"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_danger"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
Deactivate Account
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
Loading…
Reference in a new issue