From 4ef5645a53a4a2c9dd561bdb6618e874dcc47cc7 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Wed, 15 Feb 2023 14:51:48 +0100 Subject: [PATCH 01/12] Moving up the reportActions sorting --- src/pages/home/ReportScreen.js | 85 +++++++++++++++++++- src/pages/home/report/ReportActionCompose.js | 15 ++-- src/pages/home/report/ReportActionsView.js | 19 ++--- src/pages/home/report/ReportFooter.js | 4 +- 4 files changed, 99 insertions(+), 24 deletions(-) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 467ce7b70a70..b60b49f7a0c9 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -33,6 +33,7 @@ import reportPropTypes from '../reportPropTypes'; import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; import ReportHeaderSkeletonView from '../../components/ReportHeaderSkeletonView'; import withViewportOffsetTop, {viewportOffsetTopPropTypes} from '../../components/withViewportOffsetTop'; +import * as ReportActionsUtils from '../../libs/ReportActionsUtils'; const propTypes = { /** Navigation route context info provided by react navigation */ @@ -111,6 +112,9 @@ class ReportScreen extends React.Component { this.chatWithAccountManager = this.chatWithAccountManager.bind(this); this.dismissBanner = this.dismissBanner.bind(this); + // We need this.sortedAndFilteredReportActions to be set before this.state is initialized because the function to calculate the newMarkerReportActionID uses the sorted report actions + this.sortedAndFilteredReportActions = this.getSortedReportActionsForDisplay(props.reportActions); + this.state = { skeletonViewContainerHeight: reportActionsListViewHeight, isBannerVisible: true, @@ -123,6 +127,60 @@ class ReportScreen extends React.Component { Navigation.setIsReportScreenIsReady(); } + shouldComponentUpdate(nextProps) { + if (!_.isEqual(nextProps.reportActions, this.props.reportActions)) { + this.sortedAndFilteredReportActions = this.getSortedReportActionsForDisplay(nextProps.reportActions); + + return true; + } + + if (nextProps.report.isLoadingMoreReportActions !== this.props.report.isLoadingMoreReportActions) { + return true; + } + + if (nextProps.report.isLoadingReportActions !== this.props.report.isLoadingReportActions) { + return true; + } + + if (nextProps.report.lastReadTime !== this.props.report.lastReadTime) { + return true; + } + + if (this.props.isSmallScreenWidth !== nextProps.isSmallScreenWidth) { + return true; + } + + if (this.props.isDrawerOpen !== nextProps.isDrawerOpen) { + return true; + } + + if (lodashGet(this.props.report, 'hasOutstandingIOU') !== lodashGet(nextProps.report, 'hasOutstandingIOU')) { + return true; + } + + if (this.props.isComposerFullSize !== nextProps.isComposerFullSize) { + return true; + } + + if (this.props.isSidebarLoaded !== nextProps.isSidebarLoaded) { + return true; + } + + if (this.props.personalDetails !== nextProps.personalDetails) { + return true; + } + + if (this.props.policies !== nextProps.policies) { + return true; + } + + if (this.props.betas !== nextProps.betas) { + return true; + } + + return !_.isEqual(lodashGet(this.props.report, 'icons', []), lodashGet(nextProps.report, 'icons', [])); + } + componentDidUpdate(prevProps) { if (this.props.route.params.reportID === prevProps.route.params.reportID) { return; @@ -139,6 +197,29 @@ class ReportScreen extends React.Component { Report.addComment(getReportID(this.props.route), text); } + /** + * @param {Object} reportActions + * @returns {Array} + */ + getSortedReportActionsForDisplay(reportActions) { + // HACK ALERT: We're temporarily filtering out any reportActions keyed by sequenceNumber + // to prevent bugs during the migration from sequenceNumber -> reportActionID + const filteredReportActions = _.filter(reportActions, (reportAction, key) => { + if (!reportAction) { + return false; + } + + if (String(reportAction.sequenceNumber) === key) { + return false; + } + + return true; + }); + + const sortedReportActions = ReportActionsUtils.getSortedReportActions(filteredReportActions, true); + return ReportActionsUtils.filterReportActionsForDisplay(sortedReportActions); + } + /** * When false the ReportActionsView will completely unmount and we will show a loader until it returns true. * @@ -269,7 +350,7 @@ class ReportScreen extends React.Component { {(this.isReportReadyForDisplay() && !isLoadingInitialReportActions) && ( <> ReportUtils.canEditReportAction(this.props.reportActions[key]), + const lastReportAction = _.find( + this.props.reportActions, + action => ReportUtils.canEditReportAction(action), ); - if (reportActionKey !== -1 && this.props.reportActions[reportActionKey]) { - const {reportActionID, message} = this.props.reportActions[reportActionKey]; - Report.saveReportActionDraft(this.props.reportID, reportActionID, _.last(message).html); + if (lastReportAction !== -1 && lastReportAction) { + Report.saveReportActionDraft(this.props.reportID, lastReportAction.reportActionID, _.last(lastReportAction.message).html); } } } diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index ec5128bfc04d..60831b0ec442 100755 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -63,12 +63,9 @@ class ReportActionsView extends React.Component { this.unsubscribeVisibilityListener = null; this.hasCachedActions = _.size(props.reportActions) > 0; - // We need this.sortedAndFilteredReportActions to be set before this.state is initialized because the function to calculate the newMarkerReportActionID uses the sorted report actions - this.sortedAndFilteredReportActions = this.getSortedReportActionsForDisplay(props.reportActions); - this.state = { isFloatingMessageCounterVisible: false, - newMarkerReportActionID: ReportUtils.getNewMarkerReportActionID(this.props.report, this.sortedAndFilteredReportActions), + newMarkerReportActionID: ReportUtils.getNewMarkerReportActionID(this.props.report, props.reportActions), }; this.currentScrollOffset = 0; @@ -129,7 +126,6 @@ class ReportActionsView extends React.Component { shouldComponentUpdate(nextProps, nextState) { if (!_.isEqual(nextProps.reportActions, this.props.reportActions)) { - this.sortedAndFilteredReportActions = this.getSortedReportActionsForDisplay(nextProps.reportActions); this.mostRecentIOUReportActionID = ReportActionsUtils.getMostRecentIOUReportActionID(nextProps.reportActions); return true; } @@ -200,7 +196,7 @@ class ReportActionsView extends React.Component { if (didReportBecomeVisible) { this.setState({ newMarkerReportActionID: ReportUtils.isUnread(this.props.report) - ? ReportUtils.getNewMarkerReportActionID(this.props.report, this.sortedAndFilteredReportActions) + ? ReportUtils.getNewMarkerReportActionID(this.props.report, this.props.reportActions) : '', }); this.openReportIfNecessary(); @@ -208,8 +204,8 @@ class ReportActionsView extends React.Component { // If the report is unread, we want to check if the number of actions has decreased. If so, then it seems that one of them was deleted. In this case, if the deleted action was the // one marking the unread point, we need to recalculate which action should be the unread marker. - if (ReportUtils.isUnread(this.props.report) && ReportActionsUtils.filterReportActionsForDisplay(prevProps.reportActions).length > this.sortedAndFilteredReportActions.length) { - this.setState({newMarkerReportActionID: ReportUtils.getNewMarkerReportActionID(this.props.report, this.sortedAndFilteredReportActions)}); + if (ReportUtils.isUnread(this.props.report) && ReportActionsUtils.filterReportActionsForDisplay(prevProps.reportActions).length > this.props.reportActions.length) { + this.setState({newMarkerReportActionID: ReportUtils.getNewMarkerReportActionID(this.props.report, this.props.reportActions)}); } // When the user navigates to the LHN the ReportActionsView doesn't unmount and just remains hidden. @@ -225,7 +221,7 @@ class ReportActionsView extends React.Component { const didManuallyMarkReportAsUnread = (prevProps.report.lastReadTime !== this.props.report.lastReadTime) && ReportUtils.isUnread(this.props.report); if (didManuallyMarkReportAsUnread) { - this.setState({newMarkerReportActionID: ReportUtils.getNewMarkerReportActionID(this.props.report, this.sortedAndFilteredReportActions)}); + this.setState({newMarkerReportActionID: ReportUtils.getNewMarkerReportActionID(this.props.report, this.props.reportActions)}); } // Ensures subscription event succeeds when the report/workspace room is created optimistically. @@ -303,7 +299,7 @@ class ReportActionsView extends React.Component { return; } - const oldestReportAction = _.last(this.sortedAndFilteredReportActions); + const oldestReportAction = _.last(this.props.reportActions); // Don't load more chats if we're already at the beginning of the chat history if (oldestReportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) { @@ -367,7 +363,6 @@ class ReportActionsView extends React.Component { if (!_.size(this.props.reportActions)) { return null; } - return ( <> {!this.props.isComposerFullSize && ( @@ -380,7 +375,7 @@ class ReportActionsView extends React.Component { report={this.props.report} onScroll={this.trackScroll} onLayout={this.recordTimeToMeasureItemLayout} - sortedReportActions={this.sortedAndFilteredReportActions} + sortedReportActions={this.props.reportActions} mostRecentIOUReportActionID={this.mostRecentIOUReportActionID} isLoadingMoreReportActions={this.props.report.isLoadingMoreReportActions} loadMoreChats={this.loadMoreChats} diff --git a/src/pages/home/report/ReportFooter.js b/src/pages/home/report/ReportFooter.js index 29fea5e2ed19..b436538edfda 100644 --- a/src/pages/home/report/ReportFooter.js +++ b/src/pages/home/report/ReportFooter.js @@ -24,7 +24,7 @@ const propTypes = { report: reportPropTypes, /** Report actions for the current report */ - reportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)), + reportActions: PropTypes.arrayOf(PropTypes.shape(reportActionPropTypes)), /** Offline status */ isOffline: PropTypes.bool.isRequired, @@ -50,7 +50,7 @@ const propTypes = { const defaultProps = { report: {reportID: '0'}, - reportActions: {}, + reportActions: [], onSubmitComment: () => {}, errors: {}, pendingAction: null, From 0d1f7687a9175a2c016be8077b30f28614cda643 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Thu, 16 Feb 2023 17:22:53 +0100 Subject: [PATCH 02/12] Updated props and removed shouldComponentUpdate --- src/pages/home/report/ReportActionsView.js | 53 +--------------------- 1 file changed, 2 insertions(+), 51 deletions(-) diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index 12c66be0fef7..b85b7916d395 100755 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -30,7 +30,7 @@ const propTypes = { report: reportPropTypes.isRequired, /** Array of report actions for this report */ - reportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)), + reportActions: PropTypes.arrayOf(PropTypes.shape(reportActionPropTypes)), /** The session of the logged in person */ session: PropTypes.shape({ @@ -50,7 +50,7 @@ const propTypes = { }; const defaultProps = { - reportActions: {}, + reportActions: [], session: {}, }; @@ -128,55 +128,6 @@ class ReportActionsView extends React.Component { }); } - shouldComponentUpdate(nextProps, nextState) { - if (!_.isEqual(nextProps.reportActions, this.props.reportActions)) { - this.mostRecentIOUReportActionID = ReportActionsUtils.getMostRecentIOUReportActionID(nextProps.reportActions); - return true; - } - - if (lodashGet(nextProps.network, 'isOffline') !== lodashGet(this.props.network, 'isOffline')) { - return true; - } - - if (nextProps.report.isLoadingMoreReportActions !== this.props.report.isLoadingMoreReportActions) { - return true; - } - - if (nextProps.report.isLoadingReportActions !== this.props.report.isLoadingReportActions) { - return true; - } - - if (nextProps.report.lastReadTime !== this.props.report.lastReadTime) { - return true; - } - - if (nextState.isFloatingMessageCounterVisible !== this.state.isFloatingMessageCounterVisible) { - return true; - } - - if (nextState.newMarkerReportActionID !== this.state.newMarkerReportActionID) { - return true; - } - - if (this.props.isSmallScreenWidth !== nextProps.isSmallScreenWidth) { - return true; - } - - if (this.props.isDrawerOpen !== nextProps.isDrawerOpen) { - return true; - } - - if (lodashGet(this.props.report, 'hasOutstandingIOU') !== lodashGet(nextProps.report, 'hasOutstandingIOU')) { - return true; - } - - if (this.props.isComposerFullSize !== nextProps.isComposerFullSize) { - return true; - } - - return !_.isEqual(lodashGet(this.props.report, 'icons', []), lodashGet(nextProps.report, 'icons', [])); - } - componentDidUpdate(prevProps) { const isReportFullyVisible = this.getIsReportFullyVisible(); From 0d91a370ff7b843dbe5f66d57176ca42b72cda2f Mon Sep 17 00:00:00 2001 From: Eduardo Date: Thu, 16 Feb 2023 17:40:01 +0100 Subject: [PATCH 03/12] Fixed isPinned --- src/pages/home/ReportScreen.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index b60b49f7a0c9..9ee840caa0a5 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -142,6 +142,10 @@ class ReportScreen extends React.Component { return true; } + if (nextProps.report.isPinned !== this.props.report.isPinned) { + return true; + } + if (nextProps.report.lastReadTime !== this.props.report.lastReadTime) { return true; } From f54539a301703ff3adf99e7bf1667bdb0611ff44 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Thu, 23 Feb 2023 10:57:14 +0100 Subject: [PATCH 04/12] replace local function for utils --- src/pages/home/ReportScreen.js | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 9ee840caa0a5..200307a02615 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -113,7 +113,7 @@ class ReportScreen extends React.Component { this.dismissBanner = this.dismissBanner.bind(this); // We need this.sortedAndFilteredReportActions to be set before this.state is initialized because the function to calculate the newMarkerReportActionID uses the sorted report actions - this.sortedAndFilteredReportActions = this.getSortedReportActionsForDisplay(props.reportActions); + this.sortedAndFilteredReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(props.reportActions); this.state = { skeletonViewContainerHeight: reportActionsListViewHeight, @@ -129,7 +129,7 @@ class ReportScreen extends React.Component { shouldComponentUpdate(nextProps) { if (!_.isEqual(nextProps.reportActions, this.props.reportActions)) { - this.sortedAndFilteredReportActions = this.getSortedReportActionsForDisplay(nextProps.reportActions); + this.sortedAndFilteredReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(nextProps.reportActions); return true; } @@ -201,29 +201,6 @@ class ReportScreen extends React.Component { Report.addComment(getReportID(this.props.route), text); } - /** - * @param {Object} reportActions - * @returns {Array} - */ - getSortedReportActionsForDisplay(reportActions) { - // HACK ALERT: We're temporarily filtering out any reportActions keyed by sequenceNumber - // to prevent bugs during the migration from sequenceNumber -> reportActionID - const filteredReportActions = _.filter(reportActions, (reportAction, key) => { - if (!reportAction) { - return false; - } - - if (String(reportAction.sequenceNumber) === key) { - return false; - } - - return true; - }); - - const sortedReportActions = ReportActionsUtils.getSortedReportActions(filteredReportActions, true); - return ReportActionsUtils.filterReportActionsForDisplay(sortedReportActions); - } - /** * When false the ReportActionsView will completely unmount and we will show a loader until it returns true. * From e1834f17d13d784c7f7d4e02a698284901061f8f Mon Sep 17 00:00:00 2001 From: Eduardo Date: Fri, 24 Feb 2023 14:23:21 +0100 Subject: [PATCH 05/12] removed call to unexisting function --- src/pages/home/report/ReportActionsView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index ffb097bfba8f..93d2b6e86ebd 100755 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -158,7 +158,7 @@ class ReportActionsView extends React.Component { // If the report is unread, we want to check if the number of actions has decreased. If so, then it seems that one of them was deleted. In this case, if the deleted action was the // one marking the unread point, we need to recalculate which action should be the unread marker. - if (ReportUtils.isUnread(this.props.report) && ReportActionsUtils.filterReportActionsForDisplay(prevProps.reportActions).length > this.props.reportActions.length) { + if (ReportUtils.isUnread(this.props.report) && prevProps.reportActions.length > this.props.reportActions.length) { this.setState({ newMarkerReportActionID: ReportUtils.getNewMarkerReportActionID(this.props.report, this.props.reportActions), }); From 5ec7c3915484ecc8e1755a3f06245c7e4cca288c Mon Sep 17 00:00:00 2001 From: Eduardo Date: Mon, 27 Feb 2023 11:02:40 +0100 Subject: [PATCH 06/12] added participants check to rerender the report screen component --- src/pages/home/ReportScreen.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 200307a02615..a933bbdde824 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -162,6 +162,10 @@ class ReportScreen extends React.Component { return true; } + if (lodashGet(this.props.report, 'participants') !== lodashGet(nextProps.report, 'participants')) { + return true; + } + if (this.props.isComposerFullSize !== nextProps.isComposerFullSize) { return true; } From 8114e7dcb751d1a52a04c9a2e85b8a1f186d2f5c Mon Sep 17 00:00:00 2001 From: Eduardo Date: Tue, 28 Feb 2023 15:16:48 +0100 Subject: [PATCH 07/12] removed shouldComponentUpdate and sort the reports on componentDidUpdate --- src/pages/home/ReportScreen.js | 72 +++------------------------------- 1 file changed, 6 insertions(+), 66 deletions(-) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index a933bbdde824..ac0f46f5d187 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -127,75 +127,15 @@ class ReportScreen extends React.Component { Navigation.setIsReportScreenIsReady(); } - shouldComponentUpdate(nextProps) { - if (!_.isEqual(nextProps.reportActions, this.props.reportActions)) { - this.sortedAndFilteredReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(nextProps.reportActions); - - return true; - } - - if (nextProps.report.isLoadingMoreReportActions !== this.props.report.isLoadingMoreReportActions) { - return true; - } - - if (nextProps.report.isLoadingReportActions !== this.props.report.isLoadingReportActions) { - return true; - } - - if (nextProps.report.isPinned !== this.props.report.isPinned) { - return true; - } - - if (nextProps.report.lastReadTime !== this.props.report.lastReadTime) { - return true; - } - - if (this.props.isSmallScreenWidth !== nextProps.isSmallScreenWidth) { - return true; - } - - if (this.props.isDrawerOpen !== nextProps.isDrawerOpen) { - return true; - } - - if (lodashGet(this.props.report, 'hasOutstandingIOU') !== lodashGet(nextProps.report, 'hasOutstandingIOU')) { - return true; - } - - if (lodashGet(this.props.report, 'participants') !== lodashGet(nextProps.report, 'participants')) { - return true; - } - - if (this.props.isComposerFullSize !== nextProps.isComposerFullSize) { - return true; - } - - if (this.props.isSidebarLoaded !== nextProps.isSidebarLoaded) { - return true; - } - - if (this.props.personalDetails !== nextProps.personalDetails) { - return true; - } - - if (this.props.policies !== nextProps.policies) { - return true; - } - - if (this.props.betas !== nextProps.betas) { - return true; - } - - return !_.isEqual(lodashGet(this.props.report, 'icons', []), lodashGet(nextProps.report, 'icons', [])); - } - componentDidUpdate(prevProps) { - if (this.props.route.params.reportID === prevProps.route.params.reportID) { - return; + if (this.props.route.params.reportID !== prevProps.route.params.reportID) { + this.fetchReportIfNeeded(); + toggleReportActionComposeView(true); } - this.fetchReportIfNeeded(); - toggleReportActionComposeView(true); + if (!_.isEqual(prevProps.reportActions, this.props.reportActions)) { + this.sortedAndFilteredReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(this.props.reportActions); + } } /** From 112ce8adf1504c8421a57560750aaf4f0ab427b7 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Wed, 1 Mar 2023 12:52:44 +0100 Subject: [PATCH 08/12] added the sorted report actions into the state and moved back the shouldComponentUpdate to ReportActionsView --- src/pages/home/ReportScreen.js | 13 +++--- src/pages/home/report/ReportActionsView.js | 49 ++++++++++++++++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index ac0f46f5d187..a57560fae8c4 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -112,12 +112,14 @@ class ReportScreen extends React.Component { this.chatWithAccountManager = this.chatWithAccountManager.bind(this); this.dismissBanner = this.dismissBanner.bind(this); - // We need this.sortedAndFilteredReportActions to be set before this.state is initialized because the function to calculate the newMarkerReportActionID uses the sorted report actions - this.sortedAndFilteredReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(props.reportActions); + // We need sortedAndFilteredReportActions to be set before this.state is initialized + // because the function to calculate the newMarkerReportActionID (ReportActionsView) uses the sorted report actions + const sortedAndFilteredReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(props.reportActions); this.state = { skeletonViewContainerHeight: reportActionsListViewHeight, isBannerVisible: true, + sortedAndFilteredReportActions, }; } @@ -134,7 +136,8 @@ class ReportScreen extends React.Component { } if (!_.isEqual(prevProps.reportActions, this.props.reportActions)) { - this.sortedAndFilteredReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(this.props.reportActions); + const sortedAndFilteredReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(this.props.reportActions); + this.setState({sortedAndFilteredReportActions}); } } @@ -275,7 +278,7 @@ class ReportScreen extends React.Component { {(this.isReportReadyForDisplay() && !isLoadingInitialReportActions) && ( <> Date: Wed, 1 Mar 2023 18:09:48 +0100 Subject: [PATCH 09/12] moved up the getLastClosedAction function to handle archived room reasons --- src/components/ArchivedReportFooter.js | 15 ++------------- src/pages/archivedReportPropTypes.js | 15 +++++++++++++++ src/pages/home/ReportScreen.js | 8 ++++++++ src/pages/home/report/ReportFooter.js | 24 +++++++++++++----------- 4 files changed, 38 insertions(+), 24 deletions(-) create mode 100644 src/pages/archivedReportPropTypes.js diff --git a/src/components/ArchivedReportFooter.js b/src/components/ArchivedReportFooter.js index bd795f8db476..bf93a60d1c0e 100644 --- a/src/components/ArchivedReportFooter.js +++ b/src/components/ArchivedReportFooter.js @@ -10,23 +10,12 @@ import personalDetailsPropType from '../pages/personalDetailsPropType'; import ONYXKEYS from '../ONYXKEYS'; import * as ReportUtils from '../libs/ReportUtils'; import reportPropTypes from '../pages/reportPropTypes'; +import archivedReportPropTypes from '../pages/archivedReportPropTypes'; import styles from '../styles/styles'; 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, - }), + reportClosedAction: archivedReportPropTypes, /** The archived report */ report: reportPropTypes.isRequired, diff --git a/src/pages/archivedReportPropTypes.js b/src/pages/archivedReportPropTypes.js new file mode 100644 index 000000000000..5926e9895e5e --- /dev/null +++ b/src/pages/archivedReportPropTypes.js @@ -0,0 +1,15 @@ +import PropTypes from 'prop-types'; + +export default 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, +}); diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index a57560fae8c4..43e15b84e032 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -195,6 +195,12 @@ class ReportScreen extends React.Component { return null; } + const isArchivedRoom = ReportUtils.isArchivedRoom(this.props.report); + let reportClosedAction = null; + if (isArchivedRoom) { + reportClosedAction = ReportActionsUtils.getLastClosedReportAction(this.props.reportActions); + } + // We are either adding a workspace room, or we're creating a chat, it isn't possible for both of these to be pending, or to have errors for the same report at the same time, so // simply looking up the first truthy value for each case will get the relevant property if it's set. const reportID = getReportID(this.props.route); @@ -293,6 +299,8 @@ class ReportScreen extends React.Component { report={this.props.report} isComposerFullSize={this.props.isComposerFullSize} onSubmitComment={this.onSubmitComment} + isArchivedRoom={isArchivedRoom} + reportClosedAction={reportClosedAction} /> )} diff --git a/src/pages/home/report/ReportFooter.js b/src/pages/home/report/ReportFooter.js index b72335e78e41..ae484b7d88e7 100644 --- a/src/pages/home/report/ReportFooter.js +++ b/src/pages/home/report/ReportFooter.js @@ -6,7 +6,6 @@ import {View, Keyboard} from 'react-native'; import CONST from '../../../CONST'; import ReportActionCompose from './ReportActionCompose'; -import * as ReportUtils from '../../../libs/ReportUtils'; import SwipeableView from '../../../components/SwipeableView'; import OfflineIndicator from '../../../components/OfflineIndicator'; import OfflineWithFeedback from '../../../components/OfflineWithFeedback'; @@ -17,7 +16,7 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '../../../componen import styles from '../../../styles/styles'; import reportActionPropTypes from './reportActionPropTypes'; import reportPropTypes from '../../reportPropTypes'; -import * as ReportActionsUtils from '../../../libs/ReportActionsUtils'; +import archivedReportPropTypes from '../../archivedReportPropTypes'; const propTypes = { /** Report object for the current report */ @@ -45,6 +44,12 @@ const propTypes = { /** Whether user interactions should be disabled */ shouldDisableCompose: PropTypes.bool, + /** The report action that closed the report */ + reportClosedAction: archivedReportPropTypes, + + /** Whether the report is archived */ + isArchivedRoom: PropTypes.bool, + ...windowDimensionsPropTypes, }; @@ -56,6 +61,8 @@ const defaultProps = { pendingAction: null, shouldShowComposeInput: true, shouldDisableCompose: false, + reportClosedAction: null, + isArchivedRoom: false, }; class ReportFooter extends React.Component { @@ -67,19 +74,14 @@ class ReportFooter extends React.Component { } render() { - const isArchivedRoom = ReportUtils.isArchivedRoom(this.props.report); - let reportClosedAction; - if (isArchivedRoom) { - reportClosedAction = ReportActionsUtils.getLastClosedReportAction(this.props.reportActions); - } - const hideComposer = isArchivedRoom || !_.isEmpty(this.props.errors); + const hideComposer = this.props.isArchivedRoom || !_.isEmpty(this.props.errors); return ( <> - {(isArchivedRoom || hideComposer) && ( + {(this.props.isArchivedRoom || hideComposer) && ( - {isArchivedRoom && ( + {this.props.isArchivedRoom && ( )} From 2b1a943b7602a3f767d27d06b0a81f41f0ec3c3e Mon Sep 17 00:00:00 2001 From: Eduardo Date: Fri, 3 Mar 2023 17:43:30 +0100 Subject: [PATCH 10/12] Changed the sorting to be in Onyx select --- src/pages/home/ReportScreen.js | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 43e15b84e032..8b8e68925eaa 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -112,14 +112,9 @@ class ReportScreen extends React.Component { this.chatWithAccountManager = this.chatWithAccountManager.bind(this); this.dismissBanner = this.dismissBanner.bind(this); - // We need sortedAndFilteredReportActions to be set before this.state is initialized - // because the function to calculate the newMarkerReportActionID (ReportActionsView) uses the sorted report actions - const sortedAndFilteredReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(props.reportActions); - this.state = { skeletonViewContainerHeight: reportActionsListViewHeight, isBannerVisible: true, - sortedAndFilteredReportActions, }; } @@ -130,15 +125,12 @@ class ReportScreen extends React.Component { } componentDidUpdate(prevProps) { - if (this.props.route.params.reportID !== prevProps.route.params.reportID) { - this.fetchReportIfNeeded(); - toggleReportActionComposeView(true); + if (this.props.route.params.reportID === prevProps.route.params.reportID) { + return; } - if (!_.isEqual(prevProps.reportActions, this.props.reportActions)) { - const sortedAndFilteredReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(this.props.reportActions); - this.setState({sortedAndFilteredReportActions}); - } + this.fetchReportIfNeeded(); + toggleReportActionComposeView(true); } /** @@ -284,7 +276,7 @@ class ReportScreen extends React.Component { {(this.isReportReadyForDisplay() && !isLoadingInitialReportActions) && ( <> `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${getReportID(route)}`, canEvict: false, + selector: ReportActionsUtils.getSortedReportActionsForDisplay, }, report: { key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${getReportID(route)}`, From 42ce48304130484f1907f15c9e491f85eb831083 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Mon, 6 Mar 2023 12:09:53 +0100 Subject: [PATCH 11/12] ArchivedReportFooter listening directly the reportsAction and getting the closeAction --- src/components/ArchivedReportFooter.js | 21 +++++++++++++++++++-- src/pages/archivedReportPropTypes.js | 15 --------------- src/pages/home/ReportScreen.js | 8 -------- src/pages/home/report/ReportFooter.js | 19 ++++++------------- 4 files changed, 25 insertions(+), 38 deletions(-) delete mode 100644 src/pages/archivedReportPropTypes.js diff --git a/src/components/ArchivedReportFooter.js b/src/components/ArchivedReportFooter.js index bf93a60d1c0e..44dd223e8bbc 100644 --- a/src/components/ArchivedReportFooter.js +++ b/src/components/ArchivedReportFooter.js @@ -10,12 +10,24 @@ import personalDetailsPropType from '../pages/personalDetailsPropType'; import ONYXKEYS from '../ONYXKEYS'; import * as ReportUtils from '../libs/ReportUtils'; import reportPropTypes from '../pages/reportPropTypes'; -import archivedReportPropTypes from '../pages/archivedReportPropTypes'; +import * as ReportActionsUtils from '../libs/ReportActionsUtils'; import styles from '../styles/styles'; const propTypes = { /** The reason this report was archived */ - reportClosedAction: archivedReportPropTypes, + 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: reportPropTypes.isRequired, @@ -79,5 +91,10 @@ export default compose( policies: { key: ONYXKEYS.COLLECTION.POLICY, }, + reportClosedAction: { + key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, + canEvict: false, + selector: ReportActionsUtils.getLastClosedReportAction, + }, }), )(ArchivedReportFooter); diff --git a/src/pages/archivedReportPropTypes.js b/src/pages/archivedReportPropTypes.js deleted file mode 100644 index 5926e9895e5e..000000000000 --- a/src/pages/archivedReportPropTypes.js +++ /dev/null @@ -1,15 +0,0 @@ -import PropTypes from 'prop-types'; - -export default 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, -}); diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 8b8e68925eaa..b147f5e16230 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -187,12 +187,6 @@ class ReportScreen extends React.Component { return null; } - const isArchivedRoom = ReportUtils.isArchivedRoom(this.props.report); - let reportClosedAction = null; - if (isArchivedRoom) { - reportClosedAction = ReportActionsUtils.getLastClosedReportAction(this.props.reportActions); - } - // We are either adding a workspace room, or we're creating a chat, it isn't possible for both of these to be pending, or to have errors for the same report at the same time, so // simply looking up the first truthy value for each case will get the relevant property if it's set. const reportID = getReportID(this.props.route); @@ -291,8 +285,6 @@ class ReportScreen extends React.Component { report={this.props.report} isComposerFullSize={this.props.isComposerFullSize} onSubmitComment={this.onSubmitComment} - isArchivedRoom={isArchivedRoom} - reportClosedAction={reportClosedAction} /> )} diff --git a/src/pages/home/report/ReportFooter.js b/src/pages/home/report/ReportFooter.js index ae484b7d88e7..7a505c4b07f3 100644 --- a/src/pages/home/report/ReportFooter.js +++ b/src/pages/home/report/ReportFooter.js @@ -3,7 +3,6 @@ import _ from 'underscore'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import {View, Keyboard} from 'react-native'; - import CONST from '../../../CONST'; import ReportActionCompose from './ReportActionCompose'; import SwipeableView from '../../../components/SwipeableView'; @@ -16,7 +15,7 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '../../../componen import styles from '../../../styles/styles'; import reportActionPropTypes from './reportActionPropTypes'; import reportPropTypes from '../../reportPropTypes'; -import archivedReportPropTypes from '../../archivedReportPropTypes'; +import * as ReportUtils from '../../../libs/ReportUtils'; const propTypes = { /** Report object for the current report */ @@ -44,12 +43,6 @@ const propTypes = { /** Whether user interactions should be disabled */ shouldDisableCompose: PropTypes.bool, - /** The report action that closed the report */ - reportClosedAction: archivedReportPropTypes, - - /** Whether the report is archived */ - isArchivedRoom: PropTypes.bool, - ...windowDimensionsPropTypes, }; @@ -61,8 +54,6 @@ const defaultProps = { pendingAction: null, shouldShowComposeInput: true, shouldDisableCompose: false, - reportClosedAction: null, - isArchivedRoom: false, }; class ReportFooter extends React.Component { @@ -74,12 +65,14 @@ class ReportFooter extends React.Component { } render() { - const hideComposer = this.props.isArchivedRoom || !_.isEmpty(this.props.errors); + const isArchivedRoom = ReportUtils.isArchivedRoom(this.props.report); + const hideComposer = isArchivedRoom || !_.isEmpty(this.props.errors); + return ( <> - {(this.props.isArchivedRoom || hideComposer) && ( + {(isArchivedRoom || hideComposer) && ( - {this.props.isArchivedRoom && ( + {isArchivedRoom && ( Date: Mon, 6 Mar 2023 12:38:35 +0100 Subject: [PATCH 12/12] Updated prop type from reportActions --- src/pages/home/ReportScreen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index b147f5e16230..d0de441dd08f 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -52,7 +52,7 @@ const propTypes = { report: reportPropTypes, /** Array of report actions for this report */ - reportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)), + reportActions: PropTypes.arrayOf(PropTypes.shape(reportActionPropTypes)), /** Whether the composer is full size */ isComposerFullSize: PropTypes.bool,