Migrate access history modal to functional component (#24210)

* Migrate access history modal to functional component

* Fix tests

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Daniel Espino García
2023-08-14 14:20:07 +02:00
коммит произвёл GitHub
родитель a93a01fa8f
Коммит 1f525550a5
3 изменённых файлов: 103 добавлений и 94 удалений

Просмотреть файл

@@ -7,6 +7,8 @@ import {shallow} from 'enzyme';
import AccessHistoryModal from 'components/access_history_modal/access_history_modal'; import AccessHistoryModal from 'components/access_history_modal/access_history_modal';
import AuditTable from 'components/audit_table'; import AuditTable from 'components/audit_table';
import LoadingScreen from 'components/loading_screen'; import LoadingScreen from 'components/loading_screen';
import {withIntl} from 'tests/helpers/intl-test-helper';
import {fireEvent, screen, render, waitForElementToBeRemoved, waitFor} from '@testing-library/react';
describe('components/AccessHistoryModal', () => { describe('components/AccessHistoryModal', () => {
const baseProps = { const baseProps = {
@@ -38,26 +40,23 @@ describe('components/AccessHistoryModal', () => {
expect(wrapper.find(AuditTable).exists()).toBe(true); expect(wrapper.find(AuditTable).exists()).toBe(true);
}); });
test('should have called actions.getUserAudits when onShow is called', () => { test('should have called actions.getUserAudits only when first rendered', () => {
const actions = { const actions = {
getUserAudits: jest.fn(), getUserAudits: jest.fn(),
}; };
const props = {...baseProps, actions}; const props = {...baseProps, actions};
const wrapper = shallow<AccessHistoryModal>( const view = render(withIntl(<AccessHistoryModal {...props}/>));
<AccessHistoryModal {...props}/>,
);
wrapper.instance().onShow(); expect(actions.getUserAudits).toHaveBeenCalledTimes(1);
expect(actions.getUserAudits).toHaveBeenCalledTimes(2); const newProps = {...props, currentUserId: 'foo'};
view.rerender(withIntl(<AccessHistoryModal {...newProps}/>));
expect(actions.getUserAudits).toHaveBeenCalledTimes(1);
}); });
test('should match state when onHide is called', () => { test('should hide', async () => {
const wrapper = shallow<AccessHistoryModal>( render(withIntl(<AccessHistoryModal {...baseProps}/>));
<AccessHistoryModal {...baseProps}/>, await waitFor(() => screen.getByText('Access History'));
); fireEvent.click(screen.getByLabelText('Close'));
await waitForElementToBeRemoved(() => screen.getByText('Access History'));
wrapper.setState({show: true});
wrapper.instance().onHide();
expect(wrapper.state('show')).toEqual(false);
}); });
}); });

Просмотреть файл

@@ -1,55 +1,48 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React from 'react'; import React, {useCallback, useEffect, useState} from 'react';
import {Modal} from 'react-bootstrap'; import {Modal} from 'react-bootstrap';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import AuditTable from 'components/audit_table'; import AuditTable from 'components/audit_table';
import LoadingScreen from 'components/loading_screen'; import LoadingScreen from 'components/loading_screen';
import {Audit} from '@mattermost/types/audits';
type Props = { type Props = {
onHide: () => void; onHide: () => void;
actions: { actions: {
getUserAudits: (userId: string, page?: number, perPage?: number) => void; getUserAudits: (userId: string, page?: number, perPage?: number) => void;
}; };
userAudits: any[]; userAudits: Audit[];
currentUserId: string; currentUserId: string;
} }
type State = { const AccessHistoryModal = ({
show: boolean; actions: {
} getUserAudits,
},
currentUserId,
onHide,
userAudits,
}: Props) => {
const [show, setShow] = useState(true);
export default class AccessHistoryModal extends React.PureComponent<Props, State> { const onCloseClick = useCallback(() => {
public constructor(props: Props) { setShow(false);
super(props); }, []);
this.state = { useEffect(() => {
show: true, getUserAudits(currentUserId, 0, 200);
}; }, []);
}
public onShow = () => { // public for testing
this.props.actions.getUserAudits(this.props.currentUserId, 0, 200);
};
public onHide = () => { // public for testing
this.setState({show: false});
};
public componentDidMount() {
this.onShow();
}
public render() {
let content; let content;
if (this.props.userAudits.length === 0) { if (userAudits.length === 0) {
content = (<LoadingScreen/>); content = (<LoadingScreen/>);
} else { } else {
content = ( content = (
<AuditTable <AuditTable
audits={this.props.userAudits} audits={userAudits}
showIp={true} showIp={true}
showSession={true} showSession={true}
/> />
@@ -59,9 +52,9 @@ export default class AccessHistoryModal extends React.PureComponent<Props, State
return ( return (
<Modal <Modal
dialogClassName='a11y__modal modal--scroll' dialogClassName='a11y__modal modal--scroll'
show={this.state.show} show={show}
onHide={this.onHide} onHide={onCloseClick}
onExited={this.props.onHide} onExited={onHide}
bsSize='large' bsSize='large'
role='dialog' role='dialog'
aria-labelledby='accessHistoryModalLabel' aria-labelledby='accessHistoryModalLabel'
@@ -94,5 +87,6 @@ export default class AccessHistoryModal extends React.PureComponent<Props, State
</Modal.Footer> </Modal.Footer>
</Modal> </Modal>
); );
} };
}
export default React.memo(AccessHistoryModal);

Просмотреть файл

@@ -125,7 +125,11 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
dialogType={ dialogType={
Object { Object {
"$$typeof": Symbol(react.memo), "$$typeof": Symbol(react.memo),
"WrappedComponent": [Function], "WrappedComponent": Object {
"$$typeof": Symbol(react.memo),
"compare": null,
"type": [Function],
},
"compare": null, "compare": null,
"type": [Function], "type": [Function],
} }
@@ -303,7 +307,11 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
dialogType={ dialogType={
Object { Object {
"$$typeof": Symbol(react.memo), "$$typeof": Symbol(react.memo),
"WrappedComponent": [Function], "WrappedComponent": Object {
"$$typeof": Symbol(react.memo),
"compare": null,
"type": [Function],
},
"compare": null, "compare": null,
"type": [Function], "type": [Function],
} }
@@ -481,7 +489,11 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
dialogType={ dialogType={
Object { Object {
"$$typeof": Symbol(react.memo), "$$typeof": Symbol(react.memo),
"WrappedComponent": [Function], "WrappedComponent": Object {
"$$typeof": Symbol(react.memo),
"compare": null,
"type": [Function],
},
"compare": null, "compare": null,
"type": [Function], "type": [Function],
} }
@@ -659,7 +671,11 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
dialogType={ dialogType={
Object { Object {
"$$typeof": Symbol(react.memo), "$$typeof": Symbol(react.memo),
"WrappedComponent": [Function], "WrappedComponent": Object {
"$$typeof": Symbol(react.memo),
"compare": null,
"type": [Function],
},
"compare": null, "compare": null,
"type": [Function], "type": [Function],
} }