From b2fc4a2fdb0383630f70b975f634967bd3451b9a Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Tue, 11 Oct 2022 16:27:46 +0200 Subject: [PATCH] use kebab context menu in current device section --- src/components/structures/ContextMenu.tsx | 7 +++ .../settings/devices/CurrentDeviceSection.tsx | 50 ++++++++++++++++++- .../settings/tabs/user/SessionManagerTab.tsx | 5 ++ src/i18n/strings/en_EN.json | 3 +- .../CurrentDeviceSection-test.tsx.snap | 35 +++++++++++++ .../shared/SettingsSubsectionHeading-test.tsx | 39 +++++++++++++++ .../SettingsSubsectionHeading-test.tsx.snap | 38 ++++++++++++++ .../SessionManagerTab-test.tsx.snap | 22 ++++++++ 8 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 test/components/views/settings/shared/SettingsSubsectionHeading-test.tsx create mode 100644 test/components/views/settings/shared/__snapshots__/SettingsSubsectionHeading-test.tsx.snap diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index c3f7d1c4347a..9a13d6242484 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -92,6 +92,9 @@ export interface IProps extends IPosition { // within an existing FocusLock e.g inside a modal. focusLock?: boolean; + // call onFinished on any interaction with the menu + closeOnInteraction?: boolean; + // Function to be called on menu close onFinished(); // on resize callback @@ -186,6 +189,10 @@ export default class ContextMenu extends React.PureComponent { private onClick = (ev: React.MouseEvent) => { // Don't allow clicks to escape the context menu wrapper ev.stopPropagation(); + + if (this.props.closeOnInteraction) { + this.props.onFinished?.(); + } }; // We now only handle closing the ContextMenu in this keyDown handler. diff --git a/src/components/views/settings/devices/CurrentDeviceSection.tsx b/src/components/views/settings/devices/CurrentDeviceSection.tsx index fc58617d3135..1ba64a30f3c3 100644 --- a/src/components/views/settings/devices/CurrentDeviceSection.tsx +++ b/src/components/views/settings/devices/CurrentDeviceSection.tsx @@ -14,17 +14,20 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { LocalNotificationSettings } from 'matrix-js-sdk/src/@types/local_notifications'; import React, { useState } from 'react'; +import { LocalNotificationSettings } from 'matrix-js-sdk/src/@types/local_notifications'; import { _t } from '../../../../languageHandler'; import Spinner from '../../elements/Spinner'; import SettingsSubsection from '../shared/SettingsSubsection'; +import SettingsSubsectionHeading from '../shared/SettingsSubsectionHeading'; import DeviceDetails from './DeviceDetails'; import DeviceExpandDetailsButton from './DeviceExpandDetailsButton'; import DeviceTile from './DeviceTile'; import { DeviceVerificationStatusCard } from './DeviceVerificationStatusCard'; import { ExtendedDevice } from './types'; +import { KebabContextMenu } from '../../context_menus/KebabContextMenu'; +import { IconizedContextMenuOption } from '../../context_menus/IconizedContextMenu'; interface Props { device?: ExtendedDevice; @@ -34,9 +37,47 @@ interface Props { setPushNotifications?: (deviceId: string, enabled: boolean) => Promise | undefined; onVerifyCurrentDevice: () => void; onSignOutCurrentDevice: () => void; + signOutAllOtherSessions?: () => void; saveDeviceName: (deviceName: string) => Promise; } +type CurrentDeviceSectionHeadingProps = + Pick + & { disabled?: boolean }; + +const CurrentDeviceSectionHeading: React.FC = ({ + onSignOutCurrentDevice, + signOutAllOtherSessions, + disabled, +}) => { + const menuOptions = [ + , + ...(signOutAllOtherSessions + ? [ + , + ] + : [] + ), + ]; + return + + ; +}; + const CurrentDeviceSection: React.FC = ({ device, isLoading, @@ -45,13 +86,18 @@ const CurrentDeviceSection: React.FC = ({ setPushNotifications, onVerifyCurrentDevice, onSignOutCurrentDevice, + signOutAllOtherSessions, saveDeviceName, }) => { const [isExpanded, setIsExpanded] = useState(false); return } > { /* only show big spinner on first load */ } { isLoading && !device && } diff --git a/src/components/views/settings/tabs/user/SessionManagerTab.tsx b/src/components/views/settings/tabs/user/SessionManagerTab.tsx index 2c94d5a5c2fd..d1fbb6ce5c10 100644 --- a/src/components/views/settings/tabs/user/SessionManagerTab.tsx +++ b/src/components/views/settings/tabs/user/SessionManagerTab.tsx @@ -171,6 +171,10 @@ const SessionManagerTab: React.FC = () => { setSelectedDeviceIds([]); }, [filter, setSelectedDeviceIds]); + const signOutAllOtherSessions = shouldShowOtherSessions ? () => { + onSignOutOtherDevices(Object.keys(otherDevices)); + }: undefined; + return { saveDeviceName={(deviceName) => saveDeviceName(currentDeviceId, deviceName)} onVerifyCurrentDevice={onVerifyCurrentDevice} onSignOutCurrentDevice={onSignOutCurrentDevice} + signOutAllOtherSessions={signOutAllOtherSessions} /> { shouldShowOtherSessions && diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 5bd66ec9a31e..be300bcaf8c1 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1717,6 +1717,8 @@ "Please enter verification code sent via text.": "Please enter verification code sent via text.", "Verification code": "Verification code", "Discovery options will appear once you have added a phone number above.": "Discovery options will appear once you have added a phone number above.", + "Sign out": "Sign out", + "Sign out all other sessions": "Sign out all other sessions", "Current session": "Current session", "Confirm logging out these devices by using Single Sign On to prove your identity.|other": "Confirm logging out these devices by using Single Sign On to prove your identity.", "Confirm logging out these devices by using Single Sign On to prove your identity.|one": "Confirm logging out this device by using Single Sign On to prove your identity.", @@ -1773,7 +1775,6 @@ "Not ready for secure messaging": "Not ready for secure messaging", "Inactive": "Inactive", "Inactive for %(inactiveAgeDays)s days or longer": "Inactive for %(inactiveAgeDays)s days or longer", - "Sign out": "Sign out", "Filter devices": "Filter devices", "Show": "Show", "%(selectedDeviceCount)s sessions selected": "%(selectedDeviceCount)s sessions selected", diff --git a/test/components/views/settings/devices/__snapshots__/CurrentDeviceSection-test.tsx.snap b/test/components/views/settings/devices/__snapshots__/CurrentDeviceSection-test.tsx.snap index 58356001f5b6..630df03a179f 100644 --- a/test/components/views/settings/devices/__snapshots__/CurrentDeviceSection-test.tsx.snap +++ b/test/components/views/settings/devices/__snapshots__/CurrentDeviceSection-test.tsx.snap @@ -128,6 +128,19 @@ exports[` handles when device is falsy 1`] = ` > Current session +
renders device and correct security card when > Current session +
renders device and correct security card when > Current session +
', () => { + const defaultProps = { + heading: 'test', + }; + const getComponent = (props = {}) => + render(); + + it('renders without children', () => { + const { container } = getComponent(); + expect({ container }).toMatchSnapshot(); + }); + + it('renders with children', () => { + const children = test; + const { container } = getComponent({ children }); + expect({ container }).toMatchSnapshot(); + }); +}); diff --git a/test/components/views/settings/shared/__snapshots__/SettingsSubsectionHeading-test.tsx.snap b/test/components/views/settings/shared/__snapshots__/SettingsSubsectionHeading-test.tsx.snap new file mode 100644 index 000000000000..f23700790b05 --- /dev/null +++ b/test/components/views/settings/shared/__snapshots__/SettingsSubsectionHeading-test.tsx.snap @@ -0,0 +1,38 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` renders with children 1`] = ` +Object { + "container":
+
+

+ test +

+ + test + +
+
, +} +`; + +exports[` renders without children 1`] = ` +Object { + "container":
+
+

+ test +

+
+
, +} +`; diff --git a/test/components/views/settings/tabs/user/__snapshots__/SessionManagerTab-test.tsx.snap b/test/components/views/settings/tabs/user/__snapshots__/SessionManagerTab-test.tsx.snap index 723c9f18b59f..e3b49166efee 100644 --- a/test/components/views/settings/tabs/user/__snapshots__/SessionManagerTab-test.tsx.snap +++ b/test/components/views/settings/tabs/user/__snapshots__/SessionManagerTab-test.tsx.snap @@ -89,6 +89,17 @@ exports[` renders current session section with a verified s > Current session +
renders current session section with an unverifie > Current session +