From 753336d024d3e3ed6a81256b754aa0ef3847ae37 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Thu, 26 May 2022 22:54:05 -0700 Subject: [PATCH 1/8] Make Banner just render html --- src/components/Banner.js | 19 +++---------------- src/stories/Banner.stories.js | 5 ++--- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/components/Banner.js b/src/components/Banner.js index 9c67174f0386..a7ac463646f1 100644 --- a/src/components/Banner.js +++ b/src/components/Banner.js @@ -5,21 +5,13 @@ import Hoverable from './Hoverable'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import RenderHTML from './RenderHTML'; -import Text from './Text'; import styles from '../styles/styles'; import * as StyleUtils from '../styles/StyleUtils'; import getButtonState from '../libs/getButtonState'; const propTypes = { - /** Text to display in the banner. */ - text: PropTypes.string.isRequired, - - /** Should this component render the text as HTML? */ - shouldRenderHTML: PropTypes.bool, -}; - -const defaultProps = { - shouldRenderHTML: false, + /** HTML to display in the banner. */ + html: PropTypes.string.isRequired, }; const Banner = props => ( @@ -39,18 +31,13 @@ const Banner = props => ( fill={StyleUtils.getIconFillColor(getButtonState(isHovered))} /> - { - props.shouldRenderHTML - ? - : {props.text} - } + )} ); Banner.propTypes = propTypes; -Banner.defaultProps = defaultProps; Banner.displayName = 'Banner'; export default memo(Banner); diff --git a/src/stories/Banner.stories.js b/src/stories/Banner.stories.js index 247489d49711..99de89c94490 100644 --- a/src/stories/Banner.stories.js +++ b/src/stories/Banner.stories.js @@ -18,13 +18,12 @@ const Template = args => ; // See: https://storybook.js.org/docs/react/writing-stories/introduction#using-args const InfoBanner = Template.bind({}); InfoBanner.args = { - text: 'This is an informational banner', + html: 'This is an informational banner', }; const HTMLBanner = Template.bind({}); HTMLBanner.args = { - text: 'This is a informational banner containing HTML', - shouldRenderHTML: true, + html: 'This is a informational banner containing HTML', }; export default story; From 1380b211d73b6460ea5b511f095e58ff68c0912f Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Thu, 26 May 2022 22:55:45 -0700 Subject: [PATCH 2/8] Implement ReportUtils.getArchivedText --- src/components/ArchivedReportFooter.js | 54 ++++---------------------- src/libs/ReportUtils.js | 38 ++++++++++++++++++ src/pages/home/ReportScreen.js | 8 +--- 3 files changed, 47 insertions(+), 53 deletions(-) diff --git a/src/components/ArchivedReportFooter.js b/src/components/ArchivedReportFooter.js index bcb204c98369..b1fb3737c8c9 100644 --- a/src/components/ArchivedReportFooter.js +++ b/src/components/ArchivedReportFooter.js @@ -1,4 +1,3 @@ -import lodashGet from 'lodash/get'; import React from 'react'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; @@ -9,29 +8,18 @@ import compose from '../libs/compose'; import personalDetailsPropType from '../pages/personalDetailsPropType'; import ONYXKEYS from '../ONYXKEYS'; import * as ReportUtils from '../libs/ReportUtils'; +import reportActionPropTypes from '../pages/home/report/reportActionPropTypes'; const propTypes = { - /** The reason this report was archived */ - reportClosedAction: PropTypes.shape({ - /** Message attached to the report closed action */ - originalMessage: PropTypes.shape({ - /** The reason the report was closed */ - reason: PropTypes.string.isRequired, - - /** (For accountMerged reason only), the email of the previous owner of this report. */ - oldLogin: PropTypes.string, - - /** (For accountMerged reason only), the email of the account the previous owner was merged into */ - newLogin: PropTypes.string, - }).isRequired, - }), - /** The archived report */ report: PropTypes.shape({ - /** The policy this report is attached to */ - policyID: PropTypes.string, + /** The email of the owner of the report */ + ownerEmail: PropTypes.string, }).isRequired, + /** Array of report actions for this report */ + reportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)).isRequired, + /** Personal details of all users */ personalDetails: PropTypes.objectOf(personalDetailsPropType).isRequired, @@ -44,40 +32,14 @@ const propTypes = { ...withLocalizePropTypes, }; -const defaultProps = { - reportClosedAction: { - originalMessage: { - reason: CONST.REPORT.ARCHIVE_REASON.DEFAULT, - }, - }, -}; - const ArchivedReportFooter = (props) => { - const archiveReason = lodashGet(props.reportClosedAction, 'originalMessage.reason', CONST.REPORT.ARCHIVE_REASON.DEFAULT); - let displayName = lodashGet(props.personalDetails, `${props.report.ownerEmail}.displayName`, props.report.ownerEmail); - - let oldDisplayName; - if (archiveReason === CONST.REPORT.ARCHIVE_REASON.ACCOUNT_MERGED) { - const newLogin = props.reportClosedAction.originalMessage.newLogin; - const oldLogin = props.reportClosedAction.originalMessage.oldLogin; - displayName = lodashGet(props.personalDetails, `${newLogin}.displayName`, newLogin); - oldDisplayName = lodashGet(props.personalDetails, `${oldLogin}.displayName`, oldLogin); - } - + const archivedText = ReportUtils.getArchivedText(props.report, props.reportActions, props.personalDetails, props.policies) || CONST.REPORT.ARCHIVE_REASON.DEFAULT; return ( - ${displayName}`, - oldDisplayName: `${oldDisplayName}`, - policyName: `${ReportUtils.getPolicyName(props.report, props.policies)}`, - })} - shouldRenderHTML={archiveReason !== CONST.REPORT.ARCHIVE_REASON.DEFAULT} - /> + ); }; ArchivedReportFooter.propTypes = propTypes; -ArchivedReportFooter.defaultProps = defaultProps; ArchivedReportFooter.displayName = 'ArchivedReportFooter'; export default compose( diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 144962be04ca..16dce96c3c33 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -1,6 +1,7 @@ import _ from 'underscore'; import Str from 'expensify-common/lib/str'; import lodashGet from 'lodash/get'; +import lodashFindLast from 'lodash/findLast'; import Onyx from 'react-native-onyx'; import ONYXKEYS from '../ONYXKEYS'; import CONST from '../CONST'; @@ -502,6 +503,42 @@ function navigateToDetailsPage(report) { Navigation.navigate(ROUTES.getReportParticipantsRoute(report.reportID)); } +/** + * Get the text explaining why a report was archived. + * + * @param {Object} report + * @param {Object} reportActions + * @param {Object} personalDetails + * @param {Object} policies + * @returns {String|null} + */ +function getArchivedText(report, reportActions, personalDetails, policies) { + if (!isArchivedRoom(report)) { + return null; + } + + const reportClosedAction = lodashFindLast(reportActions, action => action.actionName === CONST.REPORT.ACTIONS.TYPE.CLOSED); + if (!reportClosedAction) { + return null; + } + + const archiveReason = lodashGet(reportClosedAction, 'originalMessage.reason', CONST.REPORT.ARCHIVE_REASON.DEFAULT); + let displayName = lodashGet(personalDetails, `${report.ownerEmail}.displayName`, report.ownerEmail); + let oldDisplayName; + if (archiveReason === CONST.REPORT.ARCHIVE_REASON.ACCOUNT_MERGED) { + const newLogin = reportClosedAction.originalMessage.newLogin; + const oldLogin = reportClosedAction.originalMessage.oldLogin; + displayName = lodashGet(personalDetails, `${newLogin}.displayName`, newLogin); + oldDisplayName = lodashGet(personalDetails, `${oldLogin}.displayName`, oldLogin); + } + + return Localize.translateLocal(`reportArchiveReasons.${archiveReason}`, { + displayName: `${displayName}`, + oldDisplayName: `${oldDisplayName}`, + policyName: `${getPolicyName(report, policies)}`, + }); +} + export { getReportParticipantsTitle, isReportMessageAttachment, @@ -529,4 +566,5 @@ export { getDisplayNamesWithTooltips, getReportName, navigateToDetailsPage, + getArchivedText, }; diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index c1e7de21137f..0141cc4c66b2 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -165,13 +165,7 @@ class ReportScreen extends React.Component { } const reportID = getReportID(this.props.route); - const isArchivedRoom = ReportUtils.isArchivedRoom(this.props.report); - let reportClosedAction; - if (isArchivedRoom) { - reportClosedAction = lodashFindLast(this.props.reportActions, action => action.actionName === CONST.REPORT.ACTIONS.TYPE.CLOSED); - } - return ( ) : ( From 3e0115e1ce07ea00b6031113d531963373570101 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Thu, 26 May 2022 22:56:22 -0700 Subject: [PATCH 3/8] Use ReportUtils.getArchivedText in ReportWelcomeText for archived workspace chats --- src/components/ReportWelcomeText.js | 52 ++++++++++++++++++----------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/components/ReportWelcomeText.js b/src/components/ReportWelcomeText.js index 528397ade9c6..d1631014c536 100644 --- a/src/components/ReportWelcomeText.js +++ b/src/components/ReportWelcomeText.js @@ -13,6 +13,7 @@ import ONYXKEYS from '../ONYXKEYS'; import Navigation from '../libs/Navigation/Navigation'; import ROUTES from '../ROUTES'; import Tooltip from './Tooltip'; +import RenderHTML from './RenderHTML'; const personalDetailsPropTypes = PropTypes.shape({ /** The login of the person (either email or phone number) */ @@ -32,7 +33,7 @@ const propTypes = { /* Onyx Props */ - /** All of the personal details for everyone */ + /** All the personal details for everyone */ personalDetails: PropTypes.objectOf(personalDetailsPropTypes).isRequired, /** The policies which the user has access to and which the report could be tied to */ @@ -52,6 +53,8 @@ const ReportWelcomeText = (props) => { const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(props.report); const isChatRoom = ReportUtils.isChatRoom(props.report); const isDefault = !(isChatRoom || isPolicyExpenseChat); + const isArchivedRoom = ReportUtils.isArchivedRoom(props.report); + const reportArchivedText = ReportUtils.getArchivedText(props.report, props.reportActions, props.personalDetails, props.policies); const participants = lodashGet(props.report, 'participants', []); const isMultipleParticipant = participants.length > 1; const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips( @@ -62,25 +65,30 @@ const ReportWelcomeText = (props) => { return ( {isPolicyExpenseChat && ( - <> - {/* Add align center style individually because of limited style inheritance in React Native https://reactnative.dev/docs/text#limited-style-inheritance */} - - {props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartOne')} - - - {/* Use the policyExpenseChat owner's first name or their email if it's undefined or an empty string */} - {lodashGet(props.personalDetails, [props.report.ownerEmail, 'firstName']) || props.report.ownerEmail} - - - {props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartTwo')} - - - {ReportUtils.getPolicyName(props.report, props.policies)} - - - {props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartThree')} - - + isArchivedRoom + ? ( + + ) : ( + <> + {/* Add align center style individually because of limited style inheritance in React Native https://reactnative.dev/docs/text#limited-style-inheritance */} + + {props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartOne')} + + + {/* Use the policyExpenseChat owner's first name or their email if it's undefined or an empty string */} + {lodashGet(props.personalDetails, [props.report.ownerEmail, 'firstName']) || props.report.ownerEmail} + + + {props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartTwo')} + + + {ReportUtils.getPolicyName(props.report, props.policies)} + + + {props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartThree')} + + + ) )} {isChatRoom && ( <> @@ -136,5 +144,9 @@ export default compose( policies: { key: ONYXKEYS.COLLECTION.POLICY, }, + reportActions: { + key: props => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${props.report.reportID}`, + canEvict: false, + }, }), )(ReportWelcomeText); From 06d300f3f7829f67b00901fbd1df9cb6a02277e0 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Thu, 26 May 2022 23:00:34 -0700 Subject: [PATCH 4/8] Remove unnecessary parens --- src/components/ReportWelcomeText.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/ReportWelcomeText.js b/src/components/ReportWelcomeText.js index d1631014c536..4db3eaa6b205 100644 --- a/src/components/ReportWelcomeText.js +++ b/src/components/ReportWelcomeText.js @@ -66,9 +66,8 @@ const ReportWelcomeText = (props) => { {isPolicyExpenseChat && ( isArchivedRoom - ? ( - - ) : ( + ? + : ( <> {/* Add align center style individually because of limited style inheritance in React Native https://reactnative.dev/docs/text#limited-style-inheritance */} From d1b84cf5c6c66899a911d806e91797cbb59c4d16 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Thu, 26 May 2022 23:06:23 -0700 Subject: [PATCH 5/8] Fix JS style --- src/pages/home/ReportScreen.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 0141cc4c66b2..e8ebd17d4110 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -3,7 +3,6 @@ import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; import {Keyboard, View} from 'react-native'; import _ from 'underscore'; -import lodashFindLast from 'lodash/findLast'; import styles from '../../styles/styles'; import ScreenWrapper from '../../components/ScreenWrapper'; import HeaderView from './HeaderView'; From b1c383ae11f643f1b3ba88ef4cbb34d7cd733aad Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Fri, 27 May 2022 10:39:08 -0700 Subject: [PATCH 6/8] Return default from ReportUtils.getArchivedText --- src/components/ArchivedReportFooter.js | 2 +- src/libs/ReportUtils.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/ArchivedReportFooter.js b/src/components/ArchivedReportFooter.js index b1fb3737c8c9..15284640e14a 100644 --- a/src/components/ArchivedReportFooter.js +++ b/src/components/ArchivedReportFooter.js @@ -33,7 +33,7 @@ const propTypes = { }; const ArchivedReportFooter = (props) => { - const archivedText = ReportUtils.getArchivedText(props.report, props.reportActions, props.personalDetails, props.policies) || CONST.REPORT.ARCHIVE_REASON.DEFAULT; + const archivedText = ReportUtils.getArchivedText(props.report, props.reportActions, props.personalDetails, props.policies); return ( ); diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 16dce96c3c33..099ebc9a802c 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -514,12 +514,12 @@ function navigateToDetailsPage(report) { */ function getArchivedText(report, reportActions, personalDetails, policies) { if (!isArchivedRoom(report)) { - return null; + return Localize.translateLocal(`reportArchiveReasons.${CONST.REPORT.ARCHIVE_REASON.DEFAULT}`); } const reportClosedAction = lodashFindLast(reportActions, action => action.actionName === CONST.REPORT.ACTIONS.TYPE.CLOSED); if (!reportClosedAction) { - return null; + return Localize.translateLocal(`reportArchiveReasons.${CONST.REPORT.ARCHIVE_REASON.DEFAULT}`);; } const archiveReason = lodashGet(reportClosedAction, 'originalMessage.reason', CONST.REPORT.ARCHIVE_REASON.DEFAULT); From 1169ee51ea0c417eccf16b6ba3ae223aeff338c9 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Fri, 27 May 2022 11:26:59 -0700 Subject: [PATCH 7/8] Remove extra semicolon --- src/libs/ReportUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 099ebc9a802c..4a50afedf598 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -519,7 +519,7 @@ function getArchivedText(report, reportActions, personalDetails, policies) { const reportClosedAction = lodashFindLast(reportActions, action => action.actionName === CONST.REPORT.ACTIONS.TYPE.CLOSED); if (!reportClosedAction) { - return Localize.translateLocal(`reportArchiveReasons.${CONST.REPORT.ARCHIVE_REASON.DEFAULT}`);; + return Localize.translateLocal(`reportArchiveReasons.${CONST.REPORT.ARCHIVE_REASON.DEFAULT}`); } const archiveReason = lodashGet(reportClosedAction, 'originalMessage.reason', CONST.REPORT.ARCHIVE_REASON.DEFAULT); From 3fc71fc9e473fe85f0f7afe3dda1f9affc7d4e3b Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Fri, 27 May 2022 11:37:48 -0700 Subject: [PATCH 8/8] fix JS style --- src/components/ArchivedReportFooter.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/ArchivedReportFooter.js b/src/components/ArchivedReportFooter.js index 15284640e14a..af5be5de4d1a 100644 --- a/src/components/ArchivedReportFooter.js +++ b/src/components/ArchivedReportFooter.js @@ -1,7 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; -import CONST from '../CONST'; import Banner from './Banner'; import withLocalize, {withLocalizePropTypes} from './withLocalize'; import compose from '../libs/compose';