Device manager - device tile main click target (#9409)

* change device tile click to toggle details instead of selection

* lint

* test current device section click

* stuck cypress
This commit is contained in:
Kerry 2022-10-14 13:43:20 +02:00 committed by GitHub
parent 77543b32d4
commit 17fce6ccb2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 69 additions and 22 deletions

View file

@ -74,8 +74,8 @@ describe("Device manager", () => {
cy.get('.mx_FilteredDeviceList_list').find('.mx_FilteredDeviceList_listItem').should('have.length', 3); cy.get('.mx_FilteredDeviceList_list').find('.mx_FilteredDeviceList_listItem').should('have.length', 3);
// select two sessions // select two sessions
cy.get('.mx_FilteredDeviceList_list .mx_FilteredDeviceList_listItem').first().click(); cy.get('.mx_FilteredDeviceList_list .mx_FilteredDeviceList_listItem .mx_Checkbox').first().click();
cy.get('.mx_FilteredDeviceList_list .mx_FilteredDeviceList_listItem').last().click(); cy.get('.mx_FilteredDeviceList_list .mx_FilteredDeviceList_listItem .mx_Checkbox').last().click();
// sign out from list selection action buttons // sign out from list selection action buttons
cy.get('[data-testid="sign-out-selection-cta"]').click(); cy.get('[data-testid="sign-out-selection-cta"]').click();
// list updated after sign out // list updated after sign out
@ -84,7 +84,7 @@ describe("Device manager", () => {
cy.get('[data-testid="unverified-devices-cta"]').should('have.text', 'View all (1)'); cy.get('[data-testid="unverified-devices-cta"]').should('have.text', 'View all (1)');
const sessionName = `Alice's device`; const sessionName = `Alice's device`;
// select the first session // open the first session
cy.get('.mx_FilteredDeviceList_list .mx_FilteredDeviceList_listItem').first().within(() => { cy.get('.mx_FilteredDeviceList_list .mx_FilteredDeviceList_listItem').first().within(() => {
cy.get('[aria-label="Toggle device details"]').click(); cy.get('[aria-label="Toggle device details"]').click();

View file

@ -21,6 +21,10 @@ limitations under the License.
width: 100%; width: 100%;
} }
.mx_DeviceTile_interactive {
cursor: pointer;
}
.mx_DeviceTile_info { .mx_DeviceTile_info {
flex: 1 1 0; flex: 1 1 0;
} }

View file

@ -19,7 +19,6 @@ limitations under the License.
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
width: 100%; width: 100%;
cursor: pointer;
} }
.mx_SelectableDeviceTile_checkbox { .mx_SelectableDeviceTile_checkbox {

View file

@ -173,7 +173,7 @@ export default class DevicesPanelEntry extends React.Component<IProps, IState> {
return ( return (
<div className="mx_DevicesPanel_device"> <div className="mx_DevicesPanel_device">
<SelectableDeviceTile device={extendedDevice} onClick={this.onDeviceToggled} isSelected={this.props.selected}> <SelectableDeviceTile device={extendedDevice} onSelect={this.onDeviceToggled} isSelected={this.props.selected}>
{ buttons } { buttons }
</SelectableDeviceTile> </SelectableDeviceTile>
</div> </div>

View file

@ -105,6 +105,7 @@ const CurrentDeviceSection: React.FC<Props> = ({
{ !!device && <> { !!device && <>
<DeviceTile <DeviceTile
device={device} device={device}
onClick={() => setIsExpanded(!isExpanded)}
> >
<DeviceExpandDetailsButton <DeviceExpandDetailsButton
data-testid='current-session-toggle-details' data-testid='current-session-toggle-details'

View file

@ -15,6 +15,7 @@ limitations under the License.
*/ */
import React, { Fragment } from "react"; import React, { Fragment } from "react";
import classNames from "classnames";
import { Icon as InactiveIcon } from '../../../../../res/img/element-icons/settings/inactive.svg'; import { Icon as InactiveIcon } from '../../../../../res/img/element-icons/settings/inactive.svg';
import { _t } from "../../../../languageHandler"; import { _t } from "../../../../languageHandler";
@ -23,6 +24,7 @@ import Heading from "../../typography/Heading";
import { INACTIVE_DEVICE_AGE_DAYS, isDeviceInactive } from "./filter"; import { INACTIVE_DEVICE_AGE_DAYS, isDeviceInactive } from "./filter";
import { ExtendedDevice } from "./types"; import { ExtendedDevice } from "./types";
import { DeviceTypeIcon } from "./DeviceTypeIcon"; import { DeviceTypeIcon } from "./DeviceTypeIcon";
import { preventDefaultWrapper } from "../../../../utils/NativeEventUtils";
export interface DeviceTileProps { export interface DeviceTileProps {
device: ExtendedDevice; device: ExtendedDevice;
isSelected?: boolean; isSelected?: boolean;
@ -88,13 +90,20 @@ const DeviceTile: React.FC<DeviceTileProps> = ({
{ id: 'deviceId', value: device.device_id }, { id: 'deviceId', value: device.device_id },
]; ];
return <div className="mx_DeviceTile" data-testid={`device-tile-${device.device_id}`}> return <div
className={classNames(
"mx_DeviceTile",
{ "mx_DeviceTile_interactive": !!onClick },
)}
data-testid={`device-tile-${device.device_id}`}
onClick={onClick}
>
<DeviceTypeIcon <DeviceTypeIcon
isVerified={device.isVerified} isVerified={device.isVerified}
isSelected={isSelected} isSelected={isSelected}
deviceType={device.deviceType} deviceType={device.deviceType}
/> />
<div className="mx_DeviceTile_info" onClick={onClick}> <div className="mx_DeviceTile_info">
<DeviceTileName device={device} /> <DeviceTileName device={device} />
<div className="mx_DeviceTile_metadata"> <div className="mx_DeviceTile_metadata">
{ metadata.map(({ id, value }, index) => { metadata.map(({ id, value }, index) =>
@ -107,7 +116,7 @@ const DeviceTile: React.FC<DeviceTileProps> = ({
) } ) }
</div> </div>
</div> </div>
<div className="mx_DeviceTile_actions"> <div className="mx_DeviceTile_actions" onClick={preventDefaultWrapper(() => {})}>
{ children } { children }
</div> </div>
</div>; </div>;

View file

@ -179,7 +179,8 @@ const DeviceListItem: React.FC<{
}) => <li className='mx_FilteredDeviceList_listItem'> }) => <li className='mx_FilteredDeviceList_listItem'>
<SelectableDeviceTile <SelectableDeviceTile
isSelected={isSelected} isSelected={isSelected}
onClick={toggleSelected} onSelect={toggleSelected}
onClick={onDeviceExpandToggle}
device={device} device={device}
> >
<DeviceExpandDetailsButton <DeviceExpandDetailsButton

View file

@ -21,15 +21,22 @@ import DeviceTile, { DeviceTileProps } from './DeviceTile';
interface Props extends DeviceTileProps { interface Props extends DeviceTileProps {
isSelected: boolean; isSelected: boolean;
onClick: () => void; onSelect: () => void;
onClick?: () => void;
} }
const SelectableDeviceTile: React.FC<Props> = ({ children, device, isSelected, onClick }) => { const SelectableDeviceTile: React.FC<Props> = ({
children,
device,
isSelected,
onSelect,
onClick,
}) => {
return <div className='mx_SelectableDeviceTile'> return <div className='mx_SelectableDeviceTile'>
<StyledCheckbox <StyledCheckbox
kind={CheckboxStyle.Solid} kind={CheckboxStyle.Solid}
checked={isSelected} checked={isSelected}
onChange={onClick} onChange={onSelect}
className='mx_SelectableDeviceTile_checkbox' className='mx_SelectableDeviceTile_checkbox'
id={`device-tile-checkbox-${device.device_id}`} id={`device-tile-checkbox-${device.device_id}`}
data-testid={`device-tile-checkbox-${device.device_id}`} data-testid={`device-tile-checkbox-${device.device_id}`}

View file

@ -67,6 +67,23 @@ describe('<CurrentDeviceSection />', () => {
expect(container).toMatchSnapshot(); expect(container).toMatchSnapshot();
}); });
it('displays device details on main tile click', () => {
const { getByTestId, container } = render(getComponent({ device: alicesUnverifiedDevice }));
act(() => {
fireEvent.click(getByTestId(`device-tile-${alicesUnverifiedDevice.device_id}`));
});
expect(container.getElementsByClassName('mx_DeviceDetails').length).toBeTruthy();
act(() => {
fireEvent.click(getByTestId(`device-tile-${alicesUnverifiedDevice.device_id}`));
});
// device details are hidden
expect(container.getElementsByClassName('mx_DeviceDetails').length).toBeFalsy();
});
it('displays device details on toggle click', () => { it('displays device details on toggle click', () => {
const { container, getByTestId } = render(getComponent({ device: alicesUnverifiedDevice })); const { container, getByTestId } = render(getComponent({ device: alicesUnverifiedDevice }));

View file

@ -46,6 +46,14 @@ describe('<DeviceTile />', () => {
expect(container).toMatchSnapshot(); expect(container).toMatchSnapshot();
}); });
it('applies interactive class when tile has click handler', () => {
const onClick = jest.fn();
const { getByTestId } = render(getComponent({ onClick }));
expect(
getByTestId('device-tile-123').className.includes('mx_DeviceTile_interactive'),
).toBeTruthy();
});
it('renders a verified device with no metadata', () => { it('renders a verified device with no metadata', () => {
const { container } = render(getComponent()); const { container } = render(getComponent());
expect(container).toMatchSnapshot(); expect(container).toMatchSnapshot();

View file

@ -30,6 +30,7 @@ describe('<SelectableDeviceTile />', () => {
deviceType: DeviceType.Unknown, deviceType: DeviceType.Unknown,
}; };
const defaultProps = { const defaultProps = {
onSelect: jest.fn(),
onClick: jest.fn(), onClick: jest.fn(),
device, device,
children: <div>test</div>, children: <div>test</div>,
@ -48,15 +49,15 @@ describe('<SelectableDeviceTile />', () => {
expect(container.querySelector(`#device-tile-checkbox-${device.device_id}`)).toMatchSnapshot(); expect(container.querySelector(`#device-tile-checkbox-${device.device_id}`)).toMatchSnapshot();
}); });
it('calls onClick on checkbox click', () => { it('calls onSelect on checkbox click', () => {
const onClick = jest.fn(); const onSelect = jest.fn();
const { container } = render(getComponent({ onClick })); const { container } = render(getComponent({ onSelect }));
act(() => { act(() => {
fireEvent.click(container.querySelector(`#device-tile-checkbox-${device.device_id}`)); fireEvent.click(container.querySelector(`#device-tile-checkbox-${device.device_id}`));
}); });
expect(onClick).toHaveBeenCalled(); expect(onSelect).toHaveBeenCalled();
}); });
it('calls onClick on device tile info click', () => { it('calls onClick on device tile info click', () => {

View file

@ -181,7 +181,7 @@ exports[`<CurrentDeviceSection /> renders device and correct security card when
class="mx_SettingsSubsection_content" class="mx_SettingsSubsection_content"
> >
<div <div
class="mx_DeviceTile" class="mx_DeviceTile mx_DeviceTile_interactive"
data-testid="device-tile-alices_device" data-testid="device-tile-alices_device"
> >
<div <div
@ -317,7 +317,7 @@ exports[`<CurrentDeviceSection /> renders device and correct security card when
class="mx_SettingsSubsection_content" class="mx_SettingsSubsection_content"
> >
<div <div
class="mx_DeviceTile" class="mx_DeviceTile mx_DeviceTile_interactive"
data-testid="device-tile-alices_device" data-testid="device-tile-alices_device"
> >
<div <div

View file

@ -35,7 +35,7 @@ exports[`<SelectableDeviceTile /> renders unselected device tile with checkbox 1
</label> </label>
</span> </span>
<div <div
class="mx_DeviceTile" class="mx_DeviceTile mx_DeviceTile_interactive"
data-testid="device-tile-my-device" data-testid="device-tile-my-device"
> >
<div <div

View file

@ -45,7 +45,7 @@ exports[`<SessionManagerTab /> current session section renders current session s
class="mx_SettingsSubsection_content" class="mx_SettingsSubsection_content"
> >
<div <div
class="mx_DeviceTile" class="mx_DeviceTile mx_DeviceTile_interactive"
data-testid="device-tile-alices_device" data-testid="device-tile-alices_device"
> >
<div <div
@ -167,7 +167,7 @@ exports[`<SessionManagerTab /> current session section renders current session s
class="mx_SettingsSubsection_content" class="mx_SettingsSubsection_content"
> >
<div <div
class="mx_DeviceTile" class="mx_DeviceTile mx_DeviceTile_interactive"
data-testid="device-tile-alices_device" data-testid="device-tile-alices_device"
> >
<div <div
@ -334,7 +334,7 @@ exports[`<SessionManagerTab /> goes to filtered list from security recommendatio
exports[`<SessionManagerTab /> sets device verification status correctly 1`] = ` exports[`<SessionManagerTab /> sets device verification status correctly 1`] = `
<div <div
class="mx_DeviceTile" class="mx_DeviceTile mx_DeviceTile_interactive"
data-testid="device-tile-alices_device" data-testid="device-tile-alices_device"
> >
<div <div