[MM-55330]: Convert ./components/widgets/popover/index.tsx from Class Component to Function Component (#25541)

* refactor: update component from class to functional component

* refactor: update failing snapshots

* refactor: use one props per line for improved readability

* refactor: fix popove type errors

* refactor: fix component and update failing tests

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Jamin
2023-12-18 09:46:20 +00:00
коммит произвёл GitHub
родитель 000ee45b5d
Коммит d69b4075e5
8 изменённых файлов: 109 добавлений и 133 удалений

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

@@ -196,7 +196,7 @@ exports[`components/ChannelHeader should match snapshot with last active display
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -229,7 +229,7 @@ exports[`components/ChannelHeader should match snapshot with last active display
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -500,7 +500,7 @@ exports[`components/ChannelHeader should match snapshot with no last active disp
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -533,7 +533,7 @@ exports[`components/ChannelHeader should match snapshot with no last active disp
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -804,7 +804,7 @@ exports[`components/ChannelHeader should render active channel files 1`] = `
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -837,7 +837,7 @@ exports[`components/ChannelHeader should render active channel files 1`] = `
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -1106,7 +1106,7 @@ exports[`components/ChannelHeader should render active flagged posts 1`] = `
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -1139,7 +1139,7 @@ exports[`components/ChannelHeader should render active flagged posts 1`] = `
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -1408,7 +1408,7 @@ exports[`components/ChannelHeader should render active mentions posts 1`] = `
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -1441,7 +1441,7 @@ exports[`components/ChannelHeader should render active mentions posts 1`] = `
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -1710,7 +1710,7 @@ exports[`components/ChannelHeader should render active pinned posts 1`] = `
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -1743,7 +1743,7 @@ exports[`components/ChannelHeader should render active pinned posts 1`] = `
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -1981,7 +1981,7 @@ exports[`components/ChannelHeader should render archived view 1`] = `
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -2014,7 +2014,7 @@ exports[`components/ChannelHeader should render archived view 1`] = `
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -2315,7 +2315,7 @@ exports[`components/ChannelHeader should render correct menu when muted 1`] = `
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -2348,7 +2348,7 @@ exports[`components/ChannelHeader should render correct menu when muted 1`] = `
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -2617,7 +2617,7 @@ exports[`components/ChannelHeader should render not active channel files 1`] = `
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -2650,7 +2650,7 @@ exports[`components/ChannelHeader should render not active channel files 1`] = `
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -2939,7 +2939,7 @@ exports[`components/ChannelHeader should render properly when custom status is e
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -2972,7 +2972,7 @@ exports[`components/ChannelHeader should render properly when custom status is e
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -3283,7 +3283,7 @@ exports[`components/ChannelHeader should render properly when custom status is s
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -3316,7 +3316,7 @@ exports[`components/ChannelHeader should render properly when custom status is s
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -3587,7 +3587,7 @@ exports[`components/ChannelHeader should render properly when empty 1`] = `
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -3620,7 +3620,7 @@ exports[`components/ChannelHeader should render properly when empty 1`] = `
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -3889,7 +3889,7 @@ exports[`components/ChannelHeader should render properly when populated 1`] = `
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -3922,7 +3922,7 @@ exports[`components/ChannelHeader should render properly when populated 1`] = `
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -4195,7 +4195,7 @@ exports[`components/ChannelHeader should render properly when populated with cha
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -4232,7 +4232,7 @@ exports[`components/ChannelHeader should render properly when populated with cha
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -4524,7 +4524,7 @@ exports[`components/ChannelHeader should render shared view 1`] = `
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -4557,7 +4557,7 @@ exports[`components/ChannelHeader should render shared view 1`] = `
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={
@@ -4836,7 +4836,7 @@ exports[`components/ChannelHeader should render the pinned icon with the pinned
show={false}
target={null}
>
<Popover
<Memo(Popover)
className="channel-header__popover"
id="header-popover"
placement="bottom"
@@ -4869,7 +4869,7 @@ exports[`components/ChannelHeader should render the pinned icon with the pinned
}
/>
</span>
</Popover>
</Memo(Popover)>
</Overlay>
<Connect(Markdown)
imageProps={

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

@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/ProfilePopover should disable start call button when user is in another call 1`] = `
<Popover
<Memo(Popover)
customStatus={null}
enableLastActiveTime={true}
id="user-profile-popover"
@@ -14,9 +14,6 @@ exports[`components/ProfilePopover should disable start call button when user is
isMobileView={false}
isUserInCall={true}
lastActivityTimestamp={1632146562846}
placement="right"
popoverSize="sm"
popoverStyle="info"
teammateNameDisplay="username"
timestampUnits={
Array [
@@ -349,11 +346,11 @@ exports[`components/ProfilePopover should disable start call button when user is
onFocus={[Function]}
tabIndex={0}
/>
</Popover>
</Memo(Popover)>
`;
exports[`components/ProfilePopover should hide add-to-channel option if not on team 1`] = `
<Popover
<Memo(Popover)
customStatus={null}
enableLastActiveTime={true}
id="user-profile-popover"
@@ -365,9 +362,6 @@ exports[`components/ProfilePopover should hide add-to-channel option if not on t
isInCurrentTeam={false}
isMobileView={false}
lastActivityTimestamp={1632146562846}
placement="right"
popoverSize="sm"
popoverStyle="info"
teammateNameDisplay="username"
timestampUnits={
Array [
@@ -619,11 +613,11 @@ exports[`components/ProfilePopover should hide add-to-channel option if not on t
onFocus={[Function]}
tabIndex={0}
/>
</Popover>
</Memo(Popover)>
`;
exports[`components/ProfilePopover should match snapshot 1`] = `
<Popover
<Memo(Popover)
customStatus={null}
enableLastActiveTime={true}
id="user-profile-popover"
@@ -635,9 +629,6 @@ exports[`components/ProfilePopover should match snapshot 1`] = `
isInCurrentTeam={true}
isMobileView={false}
lastActivityTimestamp={1632146562846}
placement="right"
popoverSize="sm"
popoverStyle="info"
teammateNameDisplay="username"
timestampUnits={
Array [
@@ -974,11 +965,11 @@ exports[`components/ProfilePopover should match snapshot 1`] = `
onFocus={[Function]}
tabIndex={0}
/>
</Popover>
</Memo(Popover)>
`;
exports[`components/ProfilePopover should match snapshot for shared user 1`] = `
<Popover
<Memo(Popover)
customStatus={null}
enableLastActiveTime={true}
id="user-profile-popover"
@@ -990,9 +981,6 @@ exports[`components/ProfilePopover should match snapshot for shared user 1`] = `
isInCurrentTeam={true}
isMobileView={false}
lastActivityTimestamp={1632146562846}
placement="right"
popoverSize="sm"
popoverStyle="info"
teammateNameDisplay="username"
timestampUnits={
Array [
@@ -1347,11 +1335,11 @@ exports[`components/ProfilePopover should match snapshot for shared user 1`] = `
onFocus={[Function]}
tabIndex={0}
/>
</Popover>
</Memo(Popover)>
`;
exports[`components/ProfilePopover should match snapshot when calls are disabled 1`] = `
<Popover
<Memo(Popover)
customStatus={null}
enableLastActiveTime={true}
id="user-profile-popover"
@@ -1363,9 +1351,6 @@ exports[`components/ProfilePopover should match snapshot when calls are disabled
isInCurrentTeam={true}
isMobileView={false}
lastActivityTimestamp={1632146562846}
placement="right"
popoverSize="sm"
popoverStyle="info"
teammateNameDisplay="username"
timestampUnits={
Array [
@@ -1668,11 +1653,11 @@ exports[`components/ProfilePopover should match snapshot when calls are disabled
onFocus={[Function]}
tabIndex={0}
/>
</Popover>
</Memo(Popover)>
`;
exports[`components/ProfilePopover should match snapshot with custom status 1`] = `
<Popover
<Memo(Popover)
customStatus={
Object {
"duration": "today",
@@ -1691,9 +1676,6 @@ exports[`components/ProfilePopover should match snapshot with custom status 1`]
isInCurrentTeam={true}
isMobileView={false}
lastActivityTimestamp={1632146562846}
placement="right"
popoverSize="sm"
popoverStyle="info"
teammateNameDisplay="username"
timestampUnits={
Array [
@@ -2068,11 +2050,11 @@ exports[`components/ProfilePopover should match snapshot with custom status 1`]
onFocus={[Function]}
tabIndex={0}
/>
</Popover>
</Memo(Popover)>
`;
exports[`components/ProfilePopover should match snapshot with custom status expired 1`] = `
<Popover
<Memo(Popover)
customStatus={
Object {
"duration": "today",
@@ -2091,9 +2073,6 @@ exports[`components/ProfilePopover should match snapshot with custom status expi
isInCurrentTeam={true}
isMobileView={false}
lastActivityTimestamp={1632146562846}
placement="right"
popoverSize="sm"
popoverStyle="info"
teammateNameDisplay="username"
timestampUnits={
Array [
@@ -2430,11 +2409,11 @@ exports[`components/ProfilePopover should match snapshot with custom status expi
onFocus={[Function]}
tabIndex={0}
/>
</Popover>
</Memo(Popover)>
`;
exports[`components/ProfilePopover should match snapshot with custom status not set but can set 1`] = `
<Popover
<Memo(Popover)
customStatus={null}
enableLastActiveTime={true}
id="user-profile-popover"
@@ -2446,9 +2425,6 @@ exports[`components/ProfilePopover should match snapshot with custom status not
isInCurrentTeam={true}
isMobileView={false}
lastActivityTimestamp={1632146562846}
placement="right"
popoverSize="sm"
popoverStyle="info"
teammateNameDisplay="username"
timestampUnits={
Array [
@@ -2720,11 +2696,11 @@ exports[`components/ProfilePopover should match snapshot with custom status not
onFocus={[Function]}
tabIndex={0}
/>
</Popover>
</Memo(Popover)>
`;
exports[`components/ProfilePopover should match snapshot with last active display 1`] = `
<Popover
<Memo(Popover)
customStatus={null}
enableLastActiveTime={true}
id="user-profile-popover"
@@ -2736,9 +2712,6 @@ exports[`components/ProfilePopover should match snapshot with last active displa
isInCurrentTeam={true}
isMobileView={false}
lastActivityTimestamp={1632146562846}
placement="right"
popoverSize="sm"
popoverStyle="info"
teammateNameDisplay="username"
timestampUnits={
Array [
@@ -3075,11 +3048,11 @@ exports[`components/ProfilePopover should match snapshot with last active displa
onFocus={[Function]}
tabIndex={0}
/>
</Popover>
</Memo(Popover)>
`;
exports[`components/ProfilePopover should match snapshot with no last active display because it is disabled 1`] = `
<Popover
<Memo(Popover)
customStatus={null}
enableLastActiveTime={false}
id="user-profile-popover"
@@ -3091,9 +3064,6 @@ exports[`components/ProfilePopover should match snapshot with no last active dis
isInCurrentTeam={true}
isMobileView={false}
lastActivityTimestamp={1632146562846}
placement="right"
popoverSize="sm"
popoverStyle="info"
teammateNameDisplay="username"
timestampUnits={
Array [
@@ -3405,7 +3375,7 @@ exports[`components/ProfilePopover should match snapshot with no last active dis
onFocus={[Function]}
tabIndex={0}
/>
</Popover>
</Memo(Popover)>
`;
exports[`components/ProfilePopover should show the start call button when isCallsDefaultEnabledOnAllChannels, isCallsCanBeDisabledOnSpecificChannels is false and callsChannelState.enabled is true 1`] = `
@@ -3649,7 +3619,7 @@ exports[`components/ProfilePopover should show the start call button when isCall
}
userId="0"
>
<Popover
<Memo(Popover)
customStatus={null}
enableLastActiveTime={true}
id="user-profile-popover"
@@ -3662,9 +3632,6 @@ exports[`components/ProfilePopover should show the start call button when isCall
isInCurrentTeam={true}
isMobileView={false}
lastActivityTimestamp={1632146562846}
placement="right"
popoverSize="sm"
popoverStyle="info"
teammateNameDisplay="username"
timestampUnits={
Array [
@@ -4508,7 +4475,7 @@ exports[`components/ProfilePopover should show the start call button when isCall
</div>
</div>
</Popover>
</Popover>
</Memo(Popover)>
</ProfilePopover>
</injectIntl(ProfilePopover)>
</Provider>

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

@@ -2,6 +2,7 @@
// See LICENSE.txt for license information.
import React from 'react';
import type {Popover as BSPopover} from 'react-bootstrap';
import {FormattedMessage} from 'react-intl';
import Popover from 'components/widgets/popover';
@@ -46,7 +47,7 @@ interface Props {
}
export default class SearchSuggestionList extends SuggestionList {
popoverRef: React.RefObject<Popover>;
popoverRef: React.RefObject<BSPopover>;
itemsContainerRef: React.RefObject<HTMLDivElement>;
suggestionReadOut: React.RefObject<HTMLDivElement>;
currentLabel: string;

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

@@ -79,7 +79,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
searchTerm=""
showUserOverlay={[MockFunction]}
>
<Popover
<Memo(Popover)
actions={
Object {
"openModal": [MockFunction],
@@ -119,9 +119,6 @@ exports[`component/user_group_popover should match snapshot 1`] = `
}
hide={[MockFunction]}
id="user-group-popover"
placement="right"
popoverSize="sm"
popoverStyle="info"
returnFocus={[MockFunction]}
searchTerm=""
showUserOverlay={[MockFunction]}
@@ -2127,7 +2124,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
</div>
</div>
</Popover>
</Popover>
</Memo(Popover)>
</Memo(UserGroupPopover)>
</Router>
</BrowserRouter>

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

@@ -429,11 +429,9 @@ exports[`components/user_settings/display/CustomThemeChooser should match, init
<OverlayTrigger
defaultOverlayShown={false}
overlay={
<Popover
<Memo(Popover)
className="code-popover"
id="code-popover"
placement="right"
popoverSize="sm"
popoverStyle="info"
>
<img
@@ -441,7 +439,7 @@ exports[`components/user_settings/display/CustomThemeChooser should match, init
src={null}
width="200"
/>
</Popover>
</Memo(Popover)>
}
placement="top"
trigger={

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

@@ -1,13 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/widgets/popover plain 1`] = `
<Popover
bsClass="popover"
bsSize="small"
bsStyle="info"
<div
class="popover popover-sm popover-info right"
id="test"
placement="right"
role="tooltip"
style="display: block;"
>
Some text
</Popover>
<div
class="arrow"
/>
<div
class="popover-content"
>
Some text
</div>
</div>
`;

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

@@ -19,32 +19,39 @@ interface Props {
style?: React.CSSProperties;
onMouseOut?: React.MouseEventHandler<BSPopover>; // didn't find a better way to satisfy typing, so for now we have a slight 'bootstrap leakage'
onMouseOver?: React.MouseEventHandler<BSPopover>;
ref?: React.Ref<BSPopover>;
}
export default class Popover extends React.PureComponent<Props> {
static defaultProps = {
placement: 'right',
popoverStyle: 'info',
popoverSize: 'sm',
const Popover = ({
placement = 'right',
popoverSize = 'sm',
children,
popoverStyle = 'info',
title,
id,
onMouseOut,
onMouseOver,
className,
style,
ref,
}: Props) => {
return (
<BSPopover
id={id}
style={style}
className={className}
bsStyle={popoverStyle}
placement={placement}
bsClass='popover'
title={title}
bsSize={popoverSize && SizeMap[popoverSize] as BSSizes} // map our sizes to bootstrap
onMouseOut={onMouseOut!}
onMouseOver={onMouseOver}
ref={ref}
>
{children}
</BSPopover>
);
};
};
render() {
const {placement, popoverSize, children, popoverStyle, title, id, onMouseOut, onMouseOver, className, style} = this.props;
return (
<BSPopover
id={id}
style={style}
className={className}
bsStyle={popoverStyle}
placement={placement}
bsClass='popover'
title={title}
bsSize={popoverSize && SizeMap[popoverSize] as BSSizes} // map our sizes to bootstrap
onMouseOut={onMouseOut!}
onMouseOver={onMouseOver}
>
{children}
</BSPopover>
);
}
}
export default React.memo(Popover);

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

@@ -1,18 +1,18 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {shallow} from 'enzyme';
import {render} from '@testing-library/react';
import React from 'react';
import Popover from '.';
describe('components/widgets/popover', () => {
test('plain', () => {
const wrapper = shallow(
const {container} = render(
<Popover id='test'>
{'Some text'}
</Popover>,
);
expect(wrapper).toMatchSnapshot();
expect(container.firstChild).toMatchSnapshot();
});
});