diff --git a/webapp/channels/src/components/widgets/menu/menu_modals/submenu_modal/__snapshots__/submenu_modal.test.tsx.snap b/webapp/channels/src/components/widgets/menu/menu_modals/submenu_modal/__snapshots__/submenu_modal.test.tsx.snap index c91bfd8a46..45e4970d3d 100644 --- a/webapp/channels/src/components/widgets/menu/menu_modals/submenu_modal/__snapshots__/submenu_modal.test.tsx.snap +++ b/webapp/channels/src/components/widgets/menu/menu_modals/submenu_modal/__snapshots__/submenu_modal.test.tsx.snap @@ -33,6 +33,7 @@ exports[`components/submenu_modal should match snapshot 1`] = ` { expect(wrapper).toMatchSnapshot(); }); - test('should match state when onHide is called', () => { - const wrapper = shallow( + test('should hide on modal body click', async () => { + const view = render(withIntl( , - ); + )); - wrapper.setState({show: true}); - wrapper.instance().onHide(); - expect(wrapper.state('show')).toEqual(false); + screen.getByText('Text A'); + screen.getByText('Text B'); + screen.getByText('Text C'); + + fireEvent.click(view.getByTestId('SubMenuModalBody')); + + await waitForElementToBeRemoved(() => screen.getByText('Text A')); + expect(screen.queryAllByText('Text B').length).toBe(0); + expect(screen.queryAllByText('Text C').length).toBe(0); }); test('should have called click function when button is clicked', async () => { diff --git a/webapp/channels/src/components/widgets/menu/menu_modals/submenu_modal/submenu_modal.tsx b/webapp/channels/src/components/widgets/menu/menu_modals/submenu_modal/submenu_modal.tsx index 3f9ea96a1e..1f75c74c3b 100644 --- a/webapp/channels/src/components/widgets/menu/menu_modals/submenu_modal/submenu_modal.tsx +++ b/webapp/channels/src/components/widgets/menu/menu_modals/submenu_modal/submenu_modal.tsx @@ -1,10 +1,9 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React from 'react'; +import React, {useCallback, useMemo, useState} from 'react'; import {Modal} from 'react-bootstrap'; - -import * as Utils from 'utils/utils'; +import {useIntl} from 'react-intl'; import Menu from '../../menu'; import type SubMenuItem from '../../menu_items/submenu_item'; @@ -17,63 +16,61 @@ type Props = { onExited: () => void; } -type State = { - show: boolean; -} +const SubMenuModal = ({ + elements, + onExited, +}: Props) => { + const [show, setShow] = useState(true); + const intl = useIntl(); -export default class SubMenuModal extends React.PureComponent { - public constructor(props: Props) { - super(props); - this.state = { - show: true, - }; - } + const onHide = useCallback(() => { + setShow(false); + }, []); - public onHide = () => { //public because it is used on tests - this.setState({show: false}); - }; - - public render() { - let SubMenuItems; - if (this.props.elements) { - SubMenuItems = this.props.elements.map((element) => { - return ( - - ); - }); + const subMenuItems = useMemo(() => { + if (!elements) { + return undefined; } - return ( - - - - - {SubMenuItems} - -
- - - + return elements.map( + (element) => ( + ), ); - } -} + }, [elements]); + + return ( + + + + + {subMenuItems} + +
+ + + + ); +}; + +export default React.memo(SubMenuModal);