refactor(component): convert TextDismissableBar from class to function component (#27955)

* refactor(component): convert TextDismissableBar from class to function component

* perf:Code optimized

* refactor(component):props vertically formatted, getDismissed function moved outside

* Update webapp/channels/src/components/announcement_bar/text_dismissable_bar.tsx

Co-authored-by: Daniel Espino García <larkox@gmail.com>

* refactor:setDismissed formatted vertically

* test(text_dismissable_bar):snapshot test updated

* refactor: remove type from shallow rendering in TextDismissableBar test

---------

Co-authored-by: Daniel Espino García <larkox@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Bruno
2024-08-23 16:38:03 +05:00
коммит произвёл GitHub
родитель 9a521e83b9
Коммит 1d8ce403c3
3 изменённых файлов: 50 добавлений и 74 удалений

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

@@ -20,7 +20,6 @@ exports[`components/TextDismissableBar should match snapshot 1`] = `
/>
</React.Fragment>
}
onDismissal={[MockFunction]}
showCloseButton={true}
/>
`;
@@ -45,7 +44,6 @@ exports[`components/TextDismissableBar should match snapshot, with an internal a
/>
</React.Fragment>
}
onDismissal={[MockFunction]}
showCloseButton={true}
siteURL="http://testurl.com"
/>
@@ -71,7 +69,6 @@ exports[`components/TextDismissableBar should match snapshot, with an internal u
/>
</React.Fragment>
}
onDismissal={[MockFunction]}
showCloseButton={true}
siteURL="http://testurl.com"
/>
@@ -97,7 +94,6 @@ exports[`components/TextDismissableBar should match snapshot, with ean external
/>
</React.Fragment>
}
onDismissal={[MockFunction]}
showCloseButton={true}
siteURL="http://testurl.com"
/>
@@ -123,7 +119,6 @@ exports[`components/TextDismissableBar should match snapshot, with link but with
/>
</React.Fragment>
}
onDismissal={[MockFunction]}
showCloseButton={true}
/>
`;

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

@@ -16,45 +16,35 @@ describe('components/TextDismissableBar', () => {
test('should match snapshot', () => {
const props = baseProps;
const wrapper = shallow<TextDismissableBar>(
<TextDismissableBar {...props}/>,
);
const wrapper = shallow(<TextDismissableBar {...props}/>);
expect(wrapper).toMatchSnapshot();
});
test('should match snapshot, with link but without siteURL', () => {
const props = {...baseProps, text: 'A [link](http://testurl.com/admin_console/)'};
const wrapper = shallow<TextDismissableBar>(
<TextDismissableBar {...props}/>,
);
const wrapper = shallow(<TextDismissableBar {...props}/>);
expect(wrapper).toMatchSnapshot();
});
test('should match snapshot, with an internal url', () => {
const props = {...baseProps, text: 'A [link](http://testurl.com/admin_console/) with an internal url', siteURL: 'http://testurl.com'};
const wrapper = shallow<TextDismissableBar>(
<TextDismissableBar {...props}/>,
);
const wrapper = shallow(<TextDismissableBar {...props}/>);
expect(wrapper).toMatchSnapshot();
});
test('should match snapshot, with ean external url', () => {
const props = {...baseProps, text: 'A [link](http://otherurl.com/admin_console/) with an external url', siteURL: 'http://testurl.com'};
const wrapper = shallow<TextDismissableBar>(
<TextDismissableBar {...props}/>,
);
const wrapper = shallow(<TextDismissableBar {...props}/>);
expect(wrapper).toMatchSnapshot();
});
test('should match snapshot, with an internal and an external link', () => {
const props = {...baseProps, text: 'A [link](http://testurl.com/admin_console/) with an internal url and a [link](http://other-url.com/admin_console/) with an external url', siteURL: 'http://testurl.com'};
const wrapper = shallow<TextDismissableBar>(
<TextDismissableBar {...props}/>,
);
const wrapper = shallow(<TextDismissableBar {...props}/>);
expect(wrapper).toMatchSnapshot();
});

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

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import React, {useCallback, useEffect, useState} from 'react';
import {trackEvent} from 'actions/telemetry_actions.jsx';
@@ -20,67 +20,58 @@ interface Props extends Partial<AnnouncementBarProps> {
className?: string;
}
type State = {
dismissed: boolean;
}
const options = {
singleline: true,
mentionHighlight: false,
};
export default class TextDismissableBar extends React.PureComponent<Props, State> {
constructor(props: Props) {
super(props);
const getDismissed = (text?: React.ReactNode) => localStorage.getItem(localStoragePrefix + text?.toString()) === 'true';
this.state = {
dismissed: true,
};
}
const TextDismissableBar = ({
allowDismissal,
text,
onDismissal,
...extraProps
}: Props) => {
const [dismissed, setDismissed] = useState<boolean>(() => getDismissed(text));
static getDerivedStateFromProps(props: Props) {
const dismissed = localStorage.getItem(localStoragePrefix + props.text?.toString());
return {
dismissed: (dismissed === 'true'),
};
}
useEffect(() => {
setDismissed(getDismissed(text));
}, [text]);
handleDismiss = () => {
if (!this.props.allowDismissal) {
const handleDismiss = useCallback(() => {
if (!allowDismissal) {
return;
}
trackEvent('signup', 'click_dismiss_bar');
localStorage.setItem(localStoragePrefix + this.props.text?.toString(), 'true');
this.setState({
dismissed: true,
});
if (this.props.onDismissal) {
this.props.onDismissal();
}
};
localStorage.setItem(localStoragePrefix + text?.toString(), 'true');
setDismissed(true);
onDismissal?.();
}, [allowDismissal, onDismissal, text]);
render() {
if (this.state.dismissed) {
return null;
}
const {allowDismissal, text, ...extraProps} = this.props;
return (
<AnnouncementBar
{...extraProps}
showCloseButton={allowDismissal}
handleClose={this.handleDismiss}
message={
<>
<i className='icon icon-information-outline'/>
{typeof text === 'string' ? (
<Markdown
message={text}
options={{
singleline: true,
mentionHighlight: false,
}}
/>
) : text}
</>
}
/>
);
if (dismissed) {
return null;
}
}
return (
<AnnouncementBar
{...extraProps}
showCloseButton={allowDismissal}
handleClose={handleDismiss}
message={
<>
<i className='icon icon-information-outline'/>
{typeof text === 'string' ? (
<Markdown
message={text}
options={options}
/>
) : text}
</>
}
/>
);
};
export default TextDismissableBar;