From 5c5512567b00a230893a89f7e30c9857ba6dd188 Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Mon, 6 Nov 2023 15:42:05 +0100 Subject: [PATCH 01/16] pass onyx data down --- .../LHNOptionsList/LHNOptionsList.js | 76 ++++++++++++++++--- .../LHNOptionsList/OptionRowLHNData.js | 17 ----- 2 files changed, 65 insertions(+), 28 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 5d63c176ea6f..1e6b1ddd438d 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -1,11 +1,15 @@ import PropTypes from 'prop-types'; -import React from 'react'; import {FlatList, View} from 'react-native'; +import React, {useCallback} from 'react'; +import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import styles from '@styles/styles'; import variables from '@styles/variables'; import CONST from '@src/CONST'; -import OptionRowLHNDataWithFocus from './OptionRowLHNDataWithFocus'; +import ONYXKEYS from '@src/ONYXKEYS'; +import OptionRowLHNDataWithFocus from '@src/components/LHNOptionsList/OptionRowLHNDataWithFocus'; +import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; +import reportPropTypes from '@pages/reportPropTypes'; const propTypes = { /** Wrapper style for the section list */ @@ -27,14 +31,37 @@ const propTypes = { /** Whether to allow option focus or not */ shouldDisableFocusOptions: PropTypes.bool, + + /** The policy which the user has access to and which the report could be tied to */ + policy: PropTypes.shape({ + /** The ID of the policy */ + id: PropTypes.string, + /** Name of the policy */ + name: PropTypes.string, + /** Avatar of the policy */ + avatar: PropTypes.string, + }), + + /** The actions from the parent report */ + parentReportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)), + + /** All reports shared with the user */ + reports: PropTypes.objectOf(reportPropTypes), + + /** Array of report actions for this report */ + reportActions: PropTypes.arrayOf(PropTypes.shape(reportActionPropTypes)), }; const defaultProps = { style: styles.flex1, shouldDisableFocusOptions: false, + reportActions: [], + reports: {}, + parentReportActions: {}, + policy: {}, }; -function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optionMode, shouldDisableFocusOptions}) { +function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optionMode, shouldDisableFocusOptions, reports, reportActions, parentReportActions, policy}) { /** * This function is used to compute the layout of any given item in our list. Since we know that each item will have the exact same height, this is a performance optimization * so that the heights can be determined before the options are rendered. Otherwise, the heights are determined when each option is rendering and it causes a lot of overhead on large @@ -62,13 +89,27 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio * * @return {Component} */ - const renderItem = ({item}) => ( - + const renderItem = useCallback( + ({item}) => { + const itemFullReport = reports[`${ONYXKEYS.COLLECTION.REPORT}${item}`]; + const itemReportActions = reportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${item}`]; + const itemParentReportActions = parentReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${itemFullReport.parentReportID}`]; + const itemPolicy = policy[`${ONYXKEYS.COLLECTION.POLICY}${itemFullReport.policyID}`]; + + return ( + + ); + }, + [onSelectRow, optionMode, parentReportActions, policy, reportActions, reports, shouldDisableFocusOptions], ); return ( @@ -96,4 +137,17 @@ LHNOptionsList.propTypes = propTypes; LHNOptionsList.defaultProps = defaultProps; LHNOptionsList.displayName = 'LHNOptionsList'; -export default LHNOptionsList; +export default withOnyx({ + reports: { + key: ONYXKEYS.COLLECTION.REPORT, + }, + reportActions: { + key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, + }, + parentReportActions: { + key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, + }, + policy: { + key: ONYXKEYS.COLLECTION.POLICY, + }, +})(LHNOptionsList); diff --git a/src/components/LHNOptionsList/OptionRowLHNData.js b/src/components/LHNOptionsList/OptionRowLHNData.js index ebba2ffe0587..a61d7667462c 100644 --- a/src/components/LHNOptionsList/OptionRowLHNData.js +++ b/src/components/LHNOptionsList/OptionRowLHNData.js @@ -163,16 +163,6 @@ const personalDetailsSelector = (personalDetails) => export default React.memo( compose( withOnyx({ - comment: { - key: ({reportID}) => `${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`, - }, - fullReport: { - key: ({reportID}) => `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, - }, - reportActions: { - key: ({reportID}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, - canEvict: false, - }, personalDetails: { key: ONYXKEYS.PERSONAL_DETAILS_LIST, selector: personalDetailsSelector, @@ -183,13 +173,6 @@ export default React.memo( }), // eslint-disable-next-line rulesdir/no-multiple-onyx-in-file withOnyx({ - parentReportActions: { - key: ({fullReport}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${fullReport.parentReportID}`, - canEvict: false, - }, - policy: { - key: ({fullReport}) => `${ONYXKEYS.COLLECTION.POLICY}${fullReport.policyID}`, - }, // Ideally, we aim to access only the last transaction for the current report by listening to changes in reportActions. // In some scenarios, a transaction might be created after reportActions have been modified. // This can lead to situations where `lastTransaction` doesn't update and retains the previous value. From db18623e62119962e863e915f448454d2f6b77c7 Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Mon, 6 Nov 2023 15:42:05 +0100 Subject: [PATCH 02/16] remove onyx hoc from OptionRowLHNData --- .../LHNOptionsList/LHNOptionsList.js | 66 ++++++++++++++++++- .../LHNOptionsList/OptionRowLHNData.js | 61 ++--------------- 2 files changed, 71 insertions(+), 56 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 1e6b1ddd438d..5807b51cbab1 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -10,6 +10,9 @@ import ONYXKEYS from '@src/ONYXKEYS'; import OptionRowLHNDataWithFocus from '@src/components/LHNOptionsList/OptionRowLHNDataWithFocus'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; import reportPropTypes from '@pages/reportPropTypes'; +import OptionRowLHNDataWithFocus from '@components/LHNOptionsList/OptionRowLHNDataWithFocus'; +import participantPropTypes from '@components/participantPropTypes'; +import * as UserUtils from '@libs/User'; const propTypes = { /** Wrapper style for the section list */ @@ -50,6 +53,20 @@ const propTypes = { /** Array of report actions for this report */ reportActions: PropTypes.arrayOf(PropTypes.shape(reportActionPropTypes)), + + /** Indicates which locale the user currently has selected */ + preferredLocale: PropTypes.string, + + /** List of users' personal details */ + personalDetails: PropTypes.objectOf(participantPropTypes), + + /** The transaction from the parent report action */ + transactions: PropTypes.arrayOf( + PropTypes.shape({ + /** The ID of the transaction */ + transactionID: PropTypes.string, + }), + ), }; const defaultProps = { @@ -59,9 +76,26 @@ const defaultProps = { reports: {}, parentReportActions: {}, policy: {}, + preferredLocale: CONST.LOCALES.DEFAULT, + personalDetails: {}, + transactions: [], }; -function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optionMode, shouldDisableFocusOptions, reports, reportActions, parentReportActions, policy}) { +function LHNOptionsList({ + style, + contentContainerStyles, + data, + onSelectRow, + optionMode, + shouldDisableFocusOptions, + reports, + reportActions, + parentReportActions, + policy, + preferredLocale, + personalDetails, + transactions, +}) { /** * This function is used to compute the layout of any given item in our list. Since we know that each item will have the exact same height, this is a performance optimization * so that the heights can be determined before the options are rendered. Otherwise, the heights are determined when each option is rendering and it causes a lot of overhead on large @@ -95,6 +129,21 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio const itemReportActions = reportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${item}`]; const itemParentReportActions = parentReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${itemFullReport.parentReportID}`]; const itemPolicy = policy[`${ONYXKEYS.COLLECTION.POLICY}${itemFullReport.policyID}`]; + const itemTransaction = itemParentReportActions ? itemParentReportActions[itemFullReport.parentReportActionID].originalMessage.IOUTransactionID : undefined; + const itemPersonalDetails = _.reduce( + personalDetails, + (finalPersonalDetails, personalData, accountID) => { + // It's OK to do param-reassignment in _.reduce() because we absolutely know the starting state of finalPersonalDetails + // eslint-disable-next-line no-param-reassign + finalPersonalDetails[accountID] = { + ...personalData, + accountID: Number(accountID), + avatar: UserUtils.getAvatar(personalData.avatar, personalData.accountID), + }; + return finalPersonalDetails; + }, + {}, + ); return ( ); }, - [onSelectRow, optionMode, parentReportActions, policy, reportActions, reports, shouldDisableFocusOptions], + [onSelectRow, optionMode, parentReportActions, personalDetails, policy, preferredLocale, reportActions, reports, shouldDisableFocusOptions, transactions], ); return ( @@ -150,4 +203,13 @@ export default withOnyx({ policy: { key: ONYXKEYS.COLLECTION.POLICY, }, + preferredLocale: { + key: ONYXKEYS.NVP_PREFERRED_LOCALE, + }, + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + }, + transactions: { + key: ONYXKEYS.COLLECTION.TRANSACTION, + }, })(LHNOptionsList); diff --git a/src/components/LHNOptionsList/OptionRowLHNData.js b/src/components/LHNOptionsList/OptionRowLHNData.js index a61d7667462c..477a66da1832 100644 --- a/src/components/LHNOptionsList/OptionRowLHNData.js +++ b/src/components/LHNOptionsList/OptionRowLHNData.js @@ -2,14 +2,11 @@ import {deepEqual} from 'fast-equals'; import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; import React, {useEffect, useMemo, useRef} from 'react'; -import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import participantPropTypes from '@components/participantPropTypes'; -import compose from '@libs/compose'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import SidebarUtils from '@libs/SidebarUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; -import * as UserUtils from '@libs/UserUtils'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; @@ -82,7 +79,6 @@ function OptionRowLHNData({ ...propsToForward }) { const reportID = propsToForward.reportID; - const parentReportAction = parentReportActions[fullReport.parentReportActionID]; const optionItemRef = useRef(); @@ -129,30 +125,6 @@ OptionRowLHNData.propTypes = propTypes; OptionRowLHNData.defaultProps = defaultProps; OptionRowLHNData.displayName = 'OptionRowLHNData'; -/** - * @param {Object} [personalDetails] - * @returns {Object|undefined} - */ -const personalDetailsSelector = (personalDetails) => - _.reduce( - personalDetails, - (finalPersonalDetails, personalData, accountID) => { - // It's OK to do param-reassignment in _.reduce() because we absolutely know the starting state of finalPersonalDetails - // eslint-disable-next-line no-param-reassign - finalPersonalDetails[accountID] = { - accountID: Number(accountID), - login: personalData.login, - displayName: personalData.displayName, - firstName: personalData.firstName, - status: personalData.status, - avatar: UserUtils.getAvatar(personalData.avatar, personalData.accountID), - fallbackIcon: personalData.fallbackIcon, - }; - return finalPersonalDetails; - }, - {}, - ); - /** * This component is rendered in a list. * On scroll we want to avoid that a item re-renders @@ -161,30 +133,11 @@ const personalDetailsSelector = (personalDetails) => * use it to prevent re-renders from parent re-renders. */ export default React.memo( - compose( - withOnyx({ - personalDetails: { - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - selector: personalDetailsSelector, - }, - preferredLocale: { - key: ONYXKEYS.NVP_PREFERRED_LOCALE, - }, - }), - // eslint-disable-next-line rulesdir/no-multiple-onyx-in-file - withOnyx({ - // Ideally, we aim to access only the last transaction for the current report by listening to changes in reportActions. - // In some scenarios, a transaction might be created after reportActions have been modified. - // This can lead to situations where `lastTransaction` doesn't update and retains the previous value. - // However, performance overhead of this is minimized by using memos inside the component. - receiptTransactions: {key: ONYXKEYS.COLLECTION.TRANSACTION}, - }), - // eslint-disable-next-line rulesdir/no-multiple-onyx-in-file - withOnyx({ - transaction: { - key: ({fullReport, parentReportActions}) => - `${ONYXKEYS.COLLECTION.TRANSACTION}${lodashGet(parentReportActions, [fullReport.parentReportActionID, 'originalMessage', 'IOUTransactionID'], '')}`, - }, - }), - )(OptionRowLHNData), + withReportCommentDrafts({ + propName: 'comment', + transformValue: (drafts, props) => { + const draftKey = `${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${props.reportID}`; + return lodashGet(drafts, draftKey, ''); + }, + })(OptionRowLHNData), ); From d1ef70e6ada2b06c9c04ba9c7c82f543d59eefb5 Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Mon, 6 Nov 2023 15:42:05 +0100 Subject: [PATCH 03/16] filter personal details list out of a single item --- .../LHNOptionsList/LHNOptionsList.js | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 5807b51cbab1..1a9af44b25e1 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -1,18 +1,18 @@ import PropTypes from 'prop-types'; import {FlatList, View} from 'react-native'; -import React, {useCallback} from 'react'; +import React, {useCallback, useMemo} from 'react'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import styles from '@styles/styles'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import OptionRowLHNDataWithFocus from '@src/components/LHNOptionsList/OptionRowLHNDataWithFocus'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; import reportPropTypes from '@pages/reportPropTypes'; import OptionRowLHNDataWithFocus from '@components/LHNOptionsList/OptionRowLHNDataWithFocus'; import participantPropTypes from '@components/participantPropTypes'; -import * as UserUtils from '@libs/User'; +import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as UserUtils from '@libs/UserUtils'; const propTypes = { /** Wrapper style for the section list */ @@ -96,6 +96,24 @@ function LHNOptionsList({ personalDetails, transactions, }) { + const itemPersonalDetails = useMemo( + () => + _.reduce( + personalDetails, + (finalPersonalDetails, personalData, accountID) => { + // It's OK to do param-reassignment in _.reduce() because we absolutely know the starting state of finalPersonalDetails + // eslint-disable-next-line no-param-reassign + finalPersonalDetails[accountID] = { + ...personalData, + accountID: Number(accountID), + avatar: UserUtils.getAvatar(personalData.avatar, personalData.accountID), + }; + return finalPersonalDetails; + }, + {}, + ), + [personalDetails], + ); /** * This function is used to compute the layout of any given item in our list. Since we know that each item will have the exact same height, this is a performance optimization * so that the heights can be determined before the options are rendered. Otherwise, the heights are determined when each option is rendering and it causes a lot of overhead on large @@ -130,21 +148,7 @@ function LHNOptionsList({ const itemParentReportActions = parentReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${itemFullReport.parentReportID}`]; const itemPolicy = policy[`${ONYXKEYS.COLLECTION.POLICY}${itemFullReport.policyID}`]; const itemTransaction = itemParentReportActions ? itemParentReportActions[itemFullReport.parentReportActionID].originalMessage.IOUTransactionID : undefined; - const itemPersonalDetails = _.reduce( - personalDetails, - (finalPersonalDetails, personalData, accountID) => { - // It's OK to do param-reassignment in _.reduce() because we absolutely know the starting state of finalPersonalDetails - // eslint-disable-next-line no-param-reassign - finalPersonalDetails[accountID] = { - ...personalData, - accountID: Number(accountID), - avatar: UserUtils.getAvatar(personalData.avatar, personalData.accountID), - }; - return finalPersonalDetails; - }, - {}, - ); - + const participantPersonalDetailList = _.values(OptionsListUtils.getPersonalDetailsForAccountIDs(itemFullReport.participantAccountIDs, itemPersonalDetails)); return ( ); }, - [onSelectRow, optionMode, parentReportActions, personalDetails, policy, preferredLocale, reportActions, reports, shouldDisableFocusOptions, transactions], + [itemPersonalDetails, onSelectRow, optionMode, parentReportActions, policy, preferredLocale, reportActions, reports, shouldDisableFocusOptions, transactions], ); return ( From ed2c4fcec6e73796598334a43b2593b4d4cab1cf Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Mon, 6 Nov 2023 15:42:06 +0100 Subject: [PATCH 04/16] update types --- src/components/LHNOptionsList/LHNOptionsList.js | 2 +- src/components/LHNOptionsList/OptionRowLHNData.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 1a9af44b25e1..afad2c4da007 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -52,7 +52,7 @@ const propTypes = { reports: PropTypes.objectOf(reportPropTypes), /** Array of report actions for this report */ - reportActions: PropTypes.arrayOf(PropTypes.shape(reportActionPropTypes)), + reportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)), /** Indicates which locale the user currently has selected */ preferredLocale: PropTypes.string, diff --git a/src/components/LHNOptionsList/OptionRowLHNData.js b/src/components/LHNOptionsList/OptionRowLHNData.js index 477a66da1832..bebdf94ef8d7 100644 --- a/src/components/LHNOptionsList/OptionRowLHNData.js +++ b/src/components/LHNOptionsList/OptionRowLHNData.js @@ -18,7 +18,7 @@ const propTypes = { isFocused: PropTypes.bool, /** List of users' personal details */ - personalDetails: PropTypes.objectOf(participantPropTypes), + personalDetails: PropTypes.arrayOf(participantPropTypes), /** The preferred language for the app */ preferredLocale: PropTypes.string, From d419ac309843af636ac6e59c1ecf8c3ace947ec8 Mon Sep 17 00:00:00 2001 From: Adam Horodyski Date: Mon, 6 Nov 2023 15:42:06 +0100 Subject: [PATCH 05/16] fix: use memoized flatlist properties --- .../LHNOptionsList/LHNOptionsList.js | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index afad2c4da007..4f1acbc2220b 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -81,6 +81,8 @@ const defaultProps = { transactions: [], }; +const keyExtractor = (item) => item; + function LHNOptionsList({ style, contentContainerStyles, @@ -124,14 +126,17 @@ function LHNOptionsList({ * * @returns {Object} */ - const getItemLayout = (itemData, index) => { - const optionHeight = optionMode === CONST.OPTION_MODE.COMPACT ? variables.optionRowHeightCompact : variables.optionRowHeight; - return { - length: optionHeight, - offset: index * optionHeight, - index, - }; - }; + const getItemLayout = useCallback( + (itemData, index) => { + const optionHeight = optionMode === CONST.OPTION_MODE.COMPACT ? variables.optionRowHeightCompact : variables.optionRowHeight; + return { + length: optionHeight, + offset: index * optionHeight, + index, + }; + }, + [optionMode], + ); /** * Function which renders a row in the list @@ -178,7 +183,7 @@ function LHNOptionsList({ showsVerticalScrollIndicator={false} data={data} testID="lhn-options-list" - keyExtractor={(item) => item} + keyExtractor={keyExtractor} stickySectionHeadersEnabled={false} renderItem={renderItem} getItemLayout={getItemLayout} From 4186a22713f94d30c4f57fbf6a0abdfca6c9e36e Mon Sep 17 00:00:00 2001 From: Adam Horodyski Date: Mon, 6 Nov 2023 15:42:06 +0100 Subject: [PATCH 06/16] fix: invalid default prop value for reportActions --- src/components/LHNOptionsList/LHNOptionsList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 4f1acbc2220b..c8fc11d88904 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -72,7 +72,7 @@ const propTypes = { const defaultProps = { style: styles.flex1, shouldDisableFocusOptions: false, - reportActions: [], + reportActions: {}, reports: {}, parentReportActions: {}, policy: {}, From 27e4e191a90890a9e99d15a14704033c8613f664 Mon Sep 17 00:00:00 2001 From: Adam Horodyski Date: Mon, 6 Nov 2023 15:42:07 +0100 Subject: [PATCH 07/16] fix: properties passed between list and list items --- .../LHNOptionsList/LHNOptionsList.js | 19 ++++++++----------- .../LHNOptionsList/OptionRowLHNData.js | 7 +++---- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index c8fc11d88904..2de44e9cae67 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -3,6 +3,7 @@ import {FlatList, View} from 'react-native'; import React, {useCallback, useMemo} from 'react'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; +import lodashGet from 'lodash/get'; import styles from '@styles/styles'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -45,9 +46,6 @@ const propTypes = { avatar: PropTypes.string, }), - /** The actions from the parent report */ - parentReportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)), - /** All reports shared with the user */ reports: PropTypes.objectOf(reportPropTypes), @@ -74,7 +72,6 @@ const defaultProps = { shouldDisableFocusOptions: false, reportActions: {}, reports: {}, - parentReportActions: {}, policy: {}, preferredLocale: CONST.LOCALES.DEFAULT, personalDetails: {}, @@ -92,7 +89,6 @@ function LHNOptionsList({ shouldDisableFocusOptions, reports, reportActions, - parentReportActions, policy, preferredLocale, personalDetails, @@ -150,9 +146,13 @@ function LHNOptionsList({ ({item}) => { const itemFullReport = reports[`${ONYXKEYS.COLLECTION.REPORT}${item}`]; const itemReportActions = reportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${item}`]; - const itemParentReportActions = parentReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${itemFullReport.parentReportID}`]; + const itemParentReportActions = reportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${itemFullReport.parentReportID}`]; const itemPolicy = policy[`${ONYXKEYS.COLLECTION.POLICY}${itemFullReport.policyID}`]; - const itemTransaction = itemParentReportActions ? itemParentReportActions[itemFullReport.parentReportActionID].originalMessage.IOUTransactionID : undefined; + const itemTransaction = `${ONYXKEYS.COLLECTION.TRANSACTION}${lodashGet( + itemParentReportActions, + [itemFullReport.parentReportActionID, 'originalMessage', 'IOUTransactionID'], + '', + )}`; const participantPersonalDetailList = _.values(OptionsListUtils.getPersonalDetailsForAccountIDs(itemFullReport.participantAccountIDs, itemPersonalDetails)); return ( ); }, - [itemPersonalDetails, onSelectRow, optionMode, parentReportActions, policy, preferredLocale, reportActions, reports, shouldDisableFocusOptions, transactions], + [itemPersonalDetails, onSelectRow, optionMode, policy, preferredLocale, reportActions, reports, shouldDisableFocusOptions, transactions], ); return ( @@ -206,9 +206,6 @@ export default withOnyx({ reportActions: { key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, }, - parentReportActions: { - key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, - }, policy: { key: ONYXKEYS.COLLECTION.POLICY, }, diff --git a/src/components/LHNOptionsList/OptionRowLHNData.js b/src/components/LHNOptionsList/OptionRowLHNData.js index bebdf94ef8d7..8e24e7915489 100644 --- a/src/components/LHNOptionsList/OptionRowLHNData.js +++ b/src/components/LHNOptionsList/OptionRowLHNData.js @@ -11,6 +11,7 @@ import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {withReportCommentDrafts} from '@components/OnyxProvider'; import OptionRowLHN, {defaultProps as baseDefaultProps, propTypes as basePropTypes} from './OptionRowLHN'; const propTypes = { @@ -41,10 +42,8 @@ const propTypes = { parentReportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)), /** The transaction from the parent report action */ - transaction: PropTypes.shape({ - /** The ID of the transaction */ - transactionID: PropTypes.string, - }), + transaction: PropTypes.string, + ...basePropTypes, }; From 0702d7fafdff27704a390c33a004674b735c90bc Mon Sep 17 00:00:00 2001 From: Adam Horodyski Date: Mon, 6 Nov 2023 15:42:07 +0100 Subject: [PATCH 08/16] fix: proptypes for transactions --- src/components/LHNOptionsList/LHNOptionsList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 2de44e9cae67..c78d1de67ddb 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -59,7 +59,7 @@ const propTypes = { personalDetails: PropTypes.objectOf(participantPropTypes), /** The transaction from the parent report action */ - transactions: PropTypes.arrayOf( + transactions: PropTypes.objectOf( PropTypes.shape({ /** The ID of the transaction */ transactionID: PropTypes.string, @@ -75,7 +75,7 @@ const defaultProps = { policy: {}, preferredLocale: CONST.LOCALES.DEFAULT, personalDetails: {}, - transactions: [], + transactions: {}, }; const keyExtractor = (item) => item; From 4d8617efeda996b7750868ef3e716b40b8f988f5 Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Mon, 6 Nov 2023 15:42:07 +0100 Subject: [PATCH 09/16] remove withReportCommentDrafts from OptionRowLHNData --- .../LHNOptionsList/LHNOptionsList.js | 35 ++++++++++++------- .../LHNOptionsList/OptionRowLHNData.js | 13 +------ 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index c78d1de67ddb..4bf28d9a8dd6 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -1,19 +1,19 @@ +import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import {FlatList, View} from 'react-native'; import React, {useCallback, useMemo} from 'react'; +import {FlatList, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; -import lodashGet from 'lodash/get'; +import participantPropTypes from '@components/participantPropTypes'; +import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as UserUtils from '@libs/UserUtils'; +import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; +import reportPropTypes from '@pages/reportPropTypes'; import styles from '@styles/styles'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; -import reportPropTypes from '@pages/reportPropTypes'; -import OptionRowLHNDataWithFocus from '@components/LHNOptionsList/OptionRowLHNDataWithFocus'; -import participantPropTypes from '@components/participantPropTypes'; -import * as OptionsListUtils from '@libs/OptionsListUtils'; -import * as UserUtils from '@libs/UserUtils'; +import OptionRowLHNDataWithFocus from './OptionRowLHNDataWithFocus'; const propTypes = { /** Wrapper style for the section list */ @@ -65,6 +65,8 @@ const propTypes = { transactionID: PropTypes.string, }), ), + /** List of draft comments */ + comments: PropTypes.objectOf(PropTypes.string), }; const defaultProps = { @@ -76,6 +78,7 @@ const defaultProps = { preferredLocale: CONST.LOCALES.DEFAULT, personalDetails: {}, transactions: {}, + comments: {}, }; const keyExtractor = (item) => item; @@ -93,6 +96,7 @@ function LHNOptionsList({ preferredLocale, personalDetails, transactions, + comments, }) { const itemPersonalDetails = useMemo( () => @@ -143,9 +147,9 @@ function LHNOptionsList({ * @return {Component} */ const renderItem = useCallback( - ({item}) => { - const itemFullReport = reports[`${ONYXKEYS.COLLECTION.REPORT}${item}`]; - const itemReportActions = reportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${item}`]; + ({item: reportID}) => { + const itemFullReport = reports[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const itemReportActions = reportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`]; const itemParentReportActions = reportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${itemFullReport.parentReportID}`]; const itemPolicy = policy[`${ONYXKEYS.COLLECTION.POLICY}${itemFullReport.policyID}`]; const itemTransaction = `${ONYXKEYS.COLLECTION.TRANSACTION}${lodashGet( @@ -153,10 +157,11 @@ function LHNOptionsList({ [itemFullReport.parentReportActionID, 'originalMessage', 'IOUTransactionID'], '', )}`; + const itemComment = comments[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] || ''; const participantPersonalDetailList = _.values(OptionsListUtils.getPersonalDetailsForAccountIDs(itemFullReport.participantAccountIDs, itemPersonalDetails)); return ( ); }, - [itemPersonalDetails, onSelectRow, optionMode, policy, preferredLocale, reportActions, reports, shouldDisableFocusOptions, transactions], + [comments, itemPersonalDetails, onSelectRow, optionMode, policy, preferredLocale, reportActions, reports, shouldDisableFocusOptions, transactions], ); return ( @@ -218,4 +224,7 @@ export default withOnyx({ transactions: { key: ONYXKEYS.COLLECTION.TRANSACTION, }, + comments: { + key: ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, + }, })(LHNOptionsList); diff --git a/src/components/LHNOptionsList/OptionRowLHNData.js b/src/components/LHNOptionsList/OptionRowLHNData.js index 8e24e7915489..1fd7d4701a3e 100644 --- a/src/components/LHNOptionsList/OptionRowLHNData.js +++ b/src/components/LHNOptionsList/OptionRowLHNData.js @@ -1,5 +1,4 @@ import {deepEqual} from 'fast-equals'; -import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; import React, {useEffect, useMemo, useRef} from 'react'; import _ from 'underscore'; @@ -10,8 +9,6 @@ import * as TransactionUtils from '@libs/TransactionUtils'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import {withReportCommentDrafts} from '@components/OnyxProvider'; import OptionRowLHN, {defaultProps as baseDefaultProps, propTypes as basePropTypes} from './OptionRowLHN'; const propTypes = { @@ -131,12 +128,4 @@ OptionRowLHNData.displayName = 'OptionRowLHNData'; * Thats also why the React.memo is used on the outer component here, as we just * use it to prevent re-renders from parent re-renders. */ -export default React.memo( - withReportCommentDrafts({ - propName: 'comment', - transformValue: (drafts, props) => { - const draftKey = `${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${props.reportID}`; - return lodashGet(drafts, draftKey, ''); - }, - })(OptionRowLHNData), -); +export default React.memo(OptionRowLHNData); From caf6556551aaa434646193bceb38e08de28e85b8 Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Mon, 6 Nov 2023 15:42:07 +0100 Subject: [PATCH 10/16] remove accountID reassignment --- src/components/LHNOptionsList/LHNOptionsList.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 4bf28d9a8dd6..71b96e454bf1 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -107,7 +107,6 @@ function LHNOptionsList({ // eslint-disable-next-line no-param-reassign finalPersonalDetails[accountID] = { ...personalData, - accountID: Number(accountID), avatar: UserUtils.getAvatar(personalData.avatar, personalData.accountID), }; return finalPersonalDetails; From 92cbee89240cc3941df4e9490a7a5b585d41362f Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Mon, 6 Nov 2023 15:42:08 +0100 Subject: [PATCH 11/16] remove unnecessary reduce fn --- .../LHNOptionsList/LHNOptionsList.js | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 71b96e454bf1..91f1e26e621d 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -1,12 +1,11 @@ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useCallback, useMemo} from 'react'; +import React, {useCallback} from 'react'; import {FlatList, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import participantPropTypes from '@components/participantPropTypes'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import * as UserUtils from '@libs/UserUtils'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; import reportPropTypes from '@pages/reportPropTypes'; import styles from '@styles/styles'; @@ -98,23 +97,6 @@ function LHNOptionsList({ transactions, comments, }) { - const itemPersonalDetails = useMemo( - () => - _.reduce( - personalDetails, - (finalPersonalDetails, personalData, accountID) => { - // It's OK to do param-reassignment in _.reduce() because we absolutely know the starting state of finalPersonalDetails - // eslint-disable-next-line no-param-reassign - finalPersonalDetails[accountID] = { - ...personalData, - avatar: UserUtils.getAvatar(personalData.avatar, personalData.accountID), - }; - return finalPersonalDetails; - }, - {}, - ), - [personalDetails], - ); /** * This function is used to compute the layout of any given item in our list. Since we know that each item will have the exact same height, this is a performance optimization * so that the heights can be determined before the options are rendered. Otherwise, the heights are determined when each option is rendering and it causes a lot of overhead on large @@ -157,7 +139,7 @@ function LHNOptionsList({ '', )}`; const itemComment = comments[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] || ''; - const participantPersonalDetailList = _.values(OptionsListUtils.getPersonalDetailsForAccountIDs(itemFullReport.participantAccountIDs, itemPersonalDetails)); + const participantPersonalDetailList = _.values(OptionsListUtils.getPersonalDetailsForAccountIDs(itemFullReport.participantAccountIDs, personalDetails)); return ( ); }, - [comments, itemPersonalDetails, onSelectRow, optionMode, policy, preferredLocale, reportActions, reports, shouldDisableFocusOptions, transactions], + [comments, onSelectRow, optionMode, personalDetails, policy, preferredLocale, reportActions, reports, shouldDisableFocusOptions, transactions], ); return ( From a105947edc1a04dbd98936b3095f10683ea45722 Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Mon, 6 Nov 2023 15:42:08 +0100 Subject: [PATCH 12/16] update namings of props --- src/components/LHNOptionsList/LHNOptionsList.js | 12 ++++++------ src/components/LHNOptionsList/OptionRowLHNData.js | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 91f1e26e621d..7cc3bab04fe7 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -65,7 +65,7 @@ const propTypes = { }), ), /** List of draft comments */ - comments: PropTypes.objectOf(PropTypes.string), + draftComments: PropTypes.objectOf(PropTypes.string), }; const defaultProps = { @@ -77,7 +77,7 @@ const defaultProps = { preferredLocale: CONST.LOCALES.DEFAULT, personalDetails: {}, transactions: {}, - comments: {}, + draftComments: {}, }; const keyExtractor = (item) => item; @@ -95,7 +95,7 @@ function LHNOptionsList({ preferredLocale, personalDetails, transactions, - comments, + draftComments, }) { /** * This function is used to compute the layout of any given item in our list. Since we know that each item will have the exact same height, this is a performance optimization @@ -138,7 +138,7 @@ function LHNOptionsList({ [itemFullReport.parentReportActionID, 'originalMessage', 'IOUTransactionID'], '', )}`; - const itemComment = comments[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] || ''; + const itemComment = draftComments[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] || ''; const participantPersonalDetailList = _.values(OptionsListUtils.getPersonalDetailsForAccountIDs(itemFullReport.participantAccountIDs, personalDetails)); return ( ); }, - [comments, onSelectRow, optionMode, personalDetails, policy, preferredLocale, reportActions, reports, shouldDisableFocusOptions, transactions], + [draftComments, onSelectRow, optionMode, personalDetails, policy, preferredLocale, reportActions, reports, shouldDisableFocusOptions, transactions], ); return ( @@ -205,7 +205,7 @@ export default withOnyx({ transactions: { key: ONYXKEYS.COLLECTION.TRANSACTION, }, - comments: { + draftComments: { key: ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, }, })(LHNOptionsList); diff --git a/src/components/LHNOptionsList/OptionRowLHNData.js b/src/components/LHNOptionsList/OptionRowLHNData.js index 1fd7d4701a3e..4db32ed8bd2a 100644 --- a/src/components/LHNOptionsList/OptionRowLHNData.js +++ b/src/components/LHNOptionsList/OptionRowLHNData.js @@ -39,7 +39,7 @@ const propTypes = { parentReportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)), /** The transaction from the parent report action */ - transaction: PropTypes.string, + transactionID: PropTypes.string, ...basePropTypes, }; @@ -50,7 +50,7 @@ const defaultProps = { fullReport: {}, policy: {}, parentReportActions: {}, - transaction: {}, + transactionID: undefined, preferredLocale: CONST.LOCALES.DEFAULT, ...baseDefaultProps, }; @@ -71,7 +71,7 @@ function OptionRowLHNData({ policy, receiptTransactions, parentReportActions, - transaction, + transactionID, ...propsToForward }) { const reportID = propsToForward.reportID; @@ -97,7 +97,7 @@ function OptionRowLHNData({ // Listen parentReportAction to update title of thread report when parentReportAction changed // Listen to transaction to update title of transaction report when transaction changed // eslint-disable-next-line react-hooks/exhaustive-deps - }, [fullReport, linkedTransaction, reportActions, personalDetails, preferredLocale, policy, parentReportAction, transaction]); + }, [fullReport, linkedTransaction, reportActions, personalDetails, preferredLocale, policy, parentReportAction, transactionID]); useEffect(() => { if (!optionItem || optionItem.hasDraftComment || !comment || comment.length <= 0 || isFocused) { From 5210444eb0fafb4a0cc7b381474572eee8b0d359 Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Mon, 6 Nov 2023 15:42:08 +0100 Subject: [PATCH 13/16] remove OptionRowLHNDataWithFocus --- .../LHNOptionsList/LHNOptionsList.js | 62 +++++++++++-------- .../OptionRowLHNDataWithFocus.js | 39 ------------ 2 files changed, 35 insertions(+), 66 deletions(-) delete mode 100644 src/components/LHNOptionsList/OptionRowLHNDataWithFocus.js diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 7cc3bab04fe7..58de600720a5 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -5,6 +5,8 @@ import {FlatList, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import participantPropTypes from '@components/participantPropTypes'; +import withCurrentReportID, {withCurrentReportIDDefaultProps, withCurrentReportIDPropTypes} from '@components/withCurrentReportID'; +import compose from '@libs/compose'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; import reportPropTypes from '@pages/reportPropTypes'; @@ -12,7 +14,7 @@ import styles from '@styles/styles'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import OptionRowLHNDataWithFocus from './OptionRowLHNDataWithFocus'; +import OptionRowLHNData from './OptionRowLHNData'; const propTypes = { /** Wrapper style for the section list */ @@ -66,6 +68,7 @@ const propTypes = { ), /** List of draft comments */ draftComments: PropTypes.objectOf(PropTypes.string), + ...withCurrentReportIDPropTypes, }; const defaultProps = { @@ -78,6 +81,7 @@ const defaultProps = { personalDetails: {}, transactions: {}, draftComments: {}, + ...withCurrentReportIDDefaultProps, }; const keyExtractor = (item) => item; @@ -96,6 +100,7 @@ function LHNOptionsList({ personalDetails, transactions, draftComments, + currentReportID, }) { /** * This function is used to compute the layout of any given item in our list. Since we know that each item will have the exact same height, this is a performance optimization @@ -141,7 +146,7 @@ function LHNOptionsList({ const itemComment = draftComments[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] || ''; const participantPersonalDetailList = _.values(OptionsListUtils.getPersonalDetailsForAccountIDs(itemFullReport.participantAccountIDs, personalDetails)); return ( - ); }, - [draftComments, onSelectRow, optionMode, personalDetails, policy, preferredLocale, reportActions, reports, shouldDisableFocusOptions, transactions], + [currentReportID, draftComments, onSelectRow, optionMode, personalDetails, policy, preferredLocale, reportActions, reports, shouldDisableFocusOptions, transactions], ); return ( @@ -186,26 +191,29 @@ LHNOptionsList.propTypes = propTypes; LHNOptionsList.defaultProps = defaultProps; LHNOptionsList.displayName = 'LHNOptionsList'; -export default withOnyx({ - reports: { - key: ONYXKEYS.COLLECTION.REPORT, - }, - reportActions: { - key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, - }, - policy: { - key: ONYXKEYS.COLLECTION.POLICY, - }, - preferredLocale: { - key: ONYXKEYS.NVP_PREFERRED_LOCALE, - }, - personalDetails: { - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - }, - transactions: { - key: ONYXKEYS.COLLECTION.TRANSACTION, - }, - draftComments: { - key: ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, - }, -})(LHNOptionsList); +export default compose( + withCurrentReportID, + withOnyx({ + reports: { + key: ONYXKEYS.COLLECTION.REPORT, + }, + reportActions: { + key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, + }, + policy: { + key: ONYXKEYS.COLLECTION.POLICY, + }, + preferredLocale: { + key: ONYXKEYS.NVP_PREFERRED_LOCALE, + }, + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + }, + transactions: { + key: ONYXKEYS.COLLECTION.TRANSACTION, + }, + draftComments: { + key: ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, + }, + }), +)(LHNOptionsList); diff --git a/src/components/LHNOptionsList/OptionRowLHNDataWithFocus.js b/src/components/LHNOptionsList/OptionRowLHNDataWithFocus.js deleted file mode 100644 index 67e90bcbb0e0..000000000000 --- a/src/components/LHNOptionsList/OptionRowLHNDataWithFocus.js +++ /dev/null @@ -1,39 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import withCurrentReportID, {withCurrentReportIDDefaultProps, withCurrentReportIDPropTypes} from '@components/withCurrentReportID'; -import OptionRowLHNData from './OptionRowLHNData'; - -const propTypes = { - ...withCurrentReportIDPropTypes, - shouldDisableFocusOptions: PropTypes.bool, -}; - -const defaultProps = { - ...withCurrentReportIDDefaultProps, - shouldDisableFocusOptions: false, -}; - -/** - * Wrapper component for OptionRowLHNData that calculates isFocused prop based on currentReportID. - * This is extracted from OptionRowLHNData to prevent unnecessary re-renders when currentReportID changes. - * @returns {React.Component} OptionRowLHNData component with isFocused prop - */ -function OptionRowLHNDataWithFocus({currentReportID, shouldDisableFocusOptions, ...props}) { - // We only want to pass a boolean to the memoized component, - // instead of a changing number (so we prevent unnecessary re-renders). - const isFocused = !shouldDisableFocusOptions && currentReportID === props.reportID; - - return ( - - ); -} - -OptionRowLHNDataWithFocus.defaultProps = defaultProps; -OptionRowLHNDataWithFocus.propTypes = propTypes; -OptionRowLHNDataWithFocus.displayName = 'OptionRowLHNDataWithFocus'; - -export default withCurrentReportID(OptionRowLHNDataWithFocus); From c491848bfda2ae25daccf12ee55c904877cee967 Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Mon, 6 Nov 2023 15:42:09 +0100 Subject: [PATCH 14/16] use usePersonalDetails --- src/components/LHNOptionsList/LHNOptionsList.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 58de600720a5..f7bb03373c8f 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -4,7 +4,7 @@ import React, {useCallback} from 'react'; import {FlatList, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; -import participantPropTypes from '@components/participantPropTypes'; +import {usePersonalDetails} from '@components/OnyxProvider'; import withCurrentReportID, {withCurrentReportIDDefaultProps, withCurrentReportIDPropTypes} from '@components/withCurrentReportID'; import compose from '@libs/compose'; import * as OptionsListUtils from '@libs/OptionsListUtils'; @@ -56,9 +56,6 @@ const propTypes = { /** Indicates which locale the user currently has selected */ preferredLocale: PropTypes.string, - /** List of users' personal details */ - personalDetails: PropTypes.objectOf(participantPropTypes), - /** The transaction from the parent report action */ transactions: PropTypes.objectOf( PropTypes.shape({ @@ -97,11 +94,11 @@ function LHNOptionsList({ reportActions, policy, preferredLocale, - personalDetails, transactions, draftComments, currentReportID, }) { + const personalDetails = usePersonalDetails(); /** * This function is used to compute the layout of any given item in our list. Since we know that each item will have the exact same height, this is a performance optimization * so that the heights can be determined before the options are rendered. Otherwise, the heights are determined when each option is rendering and it causes a lot of overhead on large @@ -145,6 +142,7 @@ function LHNOptionsList({ )}`; const itemComment = draftComments[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] || ''; const participantPersonalDetailList = _.values(OptionsListUtils.getPersonalDetailsForAccountIDs(itemFullReport.participantAccountIDs, personalDetails)); + return ( Date: Mon, 6 Nov 2023 15:42:09 +0100 Subject: [PATCH 15/16] Revert "use usePersonalDetails" This reverts commit f525c48e68416f30c6dc62cd5076ca9cb4544d61. --- src/components/LHNOptionsList/LHNOptionsList.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index f7bb03373c8f..58de600720a5 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -4,7 +4,7 @@ import React, {useCallback} from 'react'; import {FlatList, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; -import {usePersonalDetails} from '@components/OnyxProvider'; +import participantPropTypes from '@components/participantPropTypes'; import withCurrentReportID, {withCurrentReportIDDefaultProps, withCurrentReportIDPropTypes} from '@components/withCurrentReportID'; import compose from '@libs/compose'; import * as OptionsListUtils from '@libs/OptionsListUtils'; @@ -56,6 +56,9 @@ const propTypes = { /** Indicates which locale the user currently has selected */ preferredLocale: PropTypes.string, + /** List of users' personal details */ + personalDetails: PropTypes.objectOf(participantPropTypes), + /** The transaction from the parent report action */ transactions: PropTypes.objectOf( PropTypes.shape({ @@ -94,11 +97,11 @@ function LHNOptionsList({ reportActions, policy, preferredLocale, + personalDetails, transactions, draftComments, currentReportID, }) { - const personalDetails = usePersonalDetails(); /** * This function is used to compute the layout of any given item in our list. Since we know that each item will have the exact same height, this is a performance optimization * so that the heights can be determined before the options are rendered. Otherwise, the heights are determined when each option is rendering and it causes a lot of overhead on large @@ -142,7 +145,6 @@ function LHNOptionsList({ )}`; const itemComment = draftComments[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] || ''; const participantPersonalDetailList = _.values(OptionsListUtils.getPersonalDetailsForAccountIDs(itemFullReport.participantAccountIDs, personalDetails)); - return ( Date: Mon, 6 Nov 2023 15:42:09 +0100 Subject: [PATCH 16/16] fix tests --- src/components/LHNOptionsList/LHNOptionsList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 58de600720a5..3986773aca87 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -134,7 +134,7 @@ function LHNOptionsList({ */ const renderItem = useCallback( ({item: reportID}) => { - const itemFullReport = reports[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const itemFullReport = reports[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] || {}; const itemReportActions = reportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`]; const itemParentReportActions = reportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${itemFullReport.parentReportID}`]; const itemPolicy = policy[`${ONYXKEYS.COLLECTION.POLICY}${itemFullReport.policyID}`];