From 877c95df8f2789cf60a9d546bfa4ec6deb6e242a Mon Sep 17 00:00:00 2001 From: Kerry Date: Mon, 17 Oct 2022 17:14:49 +0200 Subject: [PATCH] device manager - add spinners while devices are signing out (#9433) --- .../settings/devices/_FilteredDeviceList.pcss | 4 +++ res/css/views/elements/_AccessibleButton.pcss | 2 ++ .../settings/devices/FilteredDeviceList.tsx | 7 ++++ .../tabs/user/SessionManagerTab-test.tsx | 32 +++++++++++++++++-- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/res/css/components/views/settings/devices/_FilteredDeviceList.pcss b/res/css/components/views/settings/devices/_FilteredDeviceList.pcss index d60c9628fb..d34270e8ad 100644 --- a/res/css/components/views/settings/devices/_FilteredDeviceList.pcss +++ b/res/css/components/views/settings/devices/_FilteredDeviceList.pcss @@ -45,4 +45,8 @@ limitations under the License. .mx_FilteredDeviceList_headerButton { flex-shrink: 0; + // override inline button styling + display: flex !important; + flex-direction: row; + gap: $spacing-8; } diff --git a/res/css/views/elements/_AccessibleButton.pcss b/res/css/views/elements/_AccessibleButton.pcss index f891e810be..dd3d0945e0 100644 --- a/res/css/views/elements/_AccessibleButton.pcss +++ b/res/css/views/elements/_AccessibleButton.pcss @@ -25,6 +25,8 @@ limitations under the License. &.mx_AccessibleButton_kind_primary_sm, &.mx_AccessibleButton_kind_link, &.mx_AccessibleButton_kind_link_inline, + &.mx_AccessibleButton_kind_danger_inline, + &.mx_AccessibleButton_kind_content_inline, &.mx_AccessibleButton_kind_link_sm { opacity: 0.4; } diff --git a/src/components/views/settings/devices/FilteredDeviceList.tsx b/src/components/views/settings/devices/FilteredDeviceList.tsx index 31ed9f2dca..9bc216a086 100644 --- a/src/components/views/settings/devices/FilteredDeviceList.tsx +++ b/src/components/views/settings/devices/FilteredDeviceList.tsx @@ -37,6 +37,7 @@ import { } from './types'; import { DevicesState } from './useOwnDevices'; import FilteredDeviceListHeader from './FilteredDeviceListHeader'; +import Spinner from '../../elements/Spinner'; interface Props { devices: DevicesDictionary; @@ -183,6 +184,7 @@ const DeviceListItem: React.FC<{ onClick={onDeviceExpandToggle} device={device} > + { isSigningOut && } onSignOutDevices(selectedDeviceIds)} className='mx_FilteredDeviceList_headerButton' > + { isSigningOut && } { _t('Sign out') } setSelectedDeviceIds([])} className='mx_FilteredDeviceList_headerButton' > diff --git a/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx b/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx index ed10e64336..5bcb6cc36c 100644 --- a/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx +++ b/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx @@ -69,7 +69,7 @@ describe('', () => { }; const alicesInactiveDevice = { - device_id: 'alices_older_mobile_device', + device_id: 'alices_older_inactive_mobile_device', last_seen_ts: Date.now() - (INACTIVE_DEVICE_AGE_MS + 1000), }; @@ -105,7 +105,7 @@ describe('', () => { const toggleDeviceDetails = ( getByTestId: ReturnType['getByTestId'], deviceId: ExtendedDevice['device_id'], - ) => { + ): void => { // open device detail const tile = getByTestId(`device-tile-${deviceId}`); const toggle = tile.querySelector('[aria-label="Toggle device details"]') as Element; @@ -115,11 +115,18 @@ describe('', () => { const toggleDeviceSelection = ( getByTestId: ReturnType['getByTestId'], deviceId: ExtendedDevice['device_id'], - ) => { + ): void => { const checkbox = getByTestId(`device-tile-checkbox-${deviceId}`); fireEvent.click(checkbox); }; + const getDeviceTile = ( + getByTestId: ReturnType['getByTestId'], + deviceId: ExtendedDevice['device_id'], + ): HTMLElement => { + return getByTestId(`device-tile-${deviceId}`); + }; + const setFilter = async ( container: HTMLElement, option: DeviceSecurityVariation | string, @@ -749,6 +756,7 @@ describe('', () => { it('deletes multiple devices', async () => { mockClient.getDevices.mockResolvedValue({ devices: [ alicesDevice, alicesMobileDevice, alicesOlderMobileDevice, + alicesInactiveDevice, ] }); mockClient.deleteMultipleDevices.mockResolvedValue({}); @@ -763,6 +771,24 @@ describe('', () => { fireEvent.click(getByTestId('sign-out-selection-cta')); + // buttons disabled in list header + expect(getByTestId('sign-out-selection-cta').getAttribute('aria-disabled')).toBeTruthy(); + expect(getByTestId('cancel-selection-cta').getAttribute('aria-disabled')).toBeTruthy(); + // spinner rendered in list header + expect(getByTestId('sign-out-selection-cta').querySelector('.mx_Spinner')).toBeTruthy(); + + // spinners on signing out devices + expect(getDeviceTile( + getByTestId, alicesMobileDevice.device_id, + ).querySelector('.mx_Spinner')).toBeTruthy(); + expect(getDeviceTile( + getByTestId, alicesOlderMobileDevice.device_id, + ).querySelector('.mx_Spinner')).toBeTruthy(); + // no spinner for device that is not signing out + expect(getDeviceTile( + getByTestId, alicesInactiveDevice.device_id, + ).querySelector('.mx_Spinner')).toBeFalsy(); + // delete called with both ids expect(mockClient.deleteMultipleDevices).toHaveBeenCalledWith( [