From 1d8ce403c3a0e5dc15645f502c74dadfb3d676cb Mon Sep 17 00:00:00 2001 From: Bruno <93909709+bruno-keiko@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:38:03 +0500 Subject: [PATCH] refactor(component): convert TextDismissableBar from class to function component (#27955) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 * 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 Co-authored-by: Mattermost Build --- .../text_dismissable_bar.test.tsx.snap | 5 - .../text_dismissable_bar.test.tsx | 20 +--- .../announcement_bar/text_dismissable_bar.tsx | 99 +++++++++---------- 3 files changed, 50 insertions(+), 74 deletions(-) diff --git a/webapp/channels/src/components/announcement_bar/__snapshots__/text_dismissable_bar.test.tsx.snap b/webapp/channels/src/components/announcement_bar/__snapshots__/text_dismissable_bar.test.tsx.snap index 4f661ef9bc..834e470294 100644 --- a/webapp/channels/src/components/announcement_bar/__snapshots__/text_dismissable_bar.test.tsx.snap +++ b/webapp/channels/src/components/announcement_bar/__snapshots__/text_dismissable_bar.test.tsx.snap @@ -20,7 +20,6 @@ exports[`components/TextDismissableBar should match snapshot 1`] = ` /> } - onDismissal={[MockFunction]} showCloseButton={true} /> `; @@ -45,7 +44,6 @@ exports[`components/TextDismissableBar should match snapshot, with an internal a /> } - onDismissal={[MockFunction]} showCloseButton={true} siteURL="http://testurl.com" /> @@ -71,7 +69,6 @@ exports[`components/TextDismissableBar should match snapshot, with an internal u /> } - onDismissal={[MockFunction]} showCloseButton={true} siteURL="http://testurl.com" /> @@ -97,7 +94,6 @@ exports[`components/TextDismissableBar should match snapshot, with ean external /> } - onDismissal={[MockFunction]} showCloseButton={true} siteURL="http://testurl.com" /> @@ -123,7 +119,6 @@ exports[`components/TextDismissableBar should match snapshot, with link but with /> } - onDismissal={[MockFunction]} showCloseButton={true} /> `; diff --git a/webapp/channels/src/components/announcement_bar/text_dismissable_bar.test.tsx b/webapp/channels/src/components/announcement_bar/text_dismissable_bar.test.tsx index 979afdc410..750ede27e1 100644 --- a/webapp/channels/src/components/announcement_bar/text_dismissable_bar.test.tsx +++ b/webapp/channels/src/components/announcement_bar/text_dismissable_bar.test.tsx @@ -16,45 +16,35 @@ describe('components/TextDismissableBar', () => { test('should match snapshot', () => { const props = baseProps; - const wrapper = shallow( - , - ); + const wrapper = shallow(); 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( - , - ); + const wrapper = shallow(); 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( - , - ); + const wrapper = shallow(); 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( - , - ); + const wrapper = shallow(); 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( - , - ); + const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); }); diff --git a/webapp/channels/src/components/announcement_bar/text_dismissable_bar.tsx b/webapp/channels/src/components/announcement_bar/text_dismissable_bar.tsx index 16477b5048..6c8933d85f 100644 --- a/webapp/channels/src/components/announcement_bar/text_dismissable_bar.tsx +++ b/webapp/channels/src/components/announcement_bar/text_dismissable_bar.tsx @@ -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 { className?: string; } -type State = { - dismissed: boolean; -} +const options = { + singleline: true, + mentionHighlight: false, +}; -export default class TextDismissableBar extends React.PureComponent { - 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(() => 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 ( - - - {typeof text === 'string' ? ( - - ) : text} - - } - /> - ); + if (dismissed) { + return null; } -} + return ( + + + {typeof text === 'string' ? ( + + ) : text} + + } + /> + ); +}; + +export default TextDismissableBar;