diff --git a/src/components/ShowContextMenuContext.ts b/src/components/ShowContextMenuContext.ts index 7ae3ca4fb825..51290263be2c 100644 --- a/src/components/ShowContextMenuContext.ts +++ b/src/components/ShowContextMenuContext.ts @@ -65,3 +65,4 @@ function showContextMenuForReport( } export {ShowContextMenuContext, showContextMenuForReport}; +export type {ShowContextMenuContextProps}; diff --git a/src/pages/home/report/ReportActionItem.tsx b/src/pages/home/report/ReportActionItem.tsx index 3bcdc1033b24..fffc8bbbbdd9 100644 --- a/src/pages/home/report/ReportActionItem.tsx +++ b/src/pages/home/report/ReportActionItem.tsx @@ -21,18 +21,14 @@ import RenderHTML from '@components/RenderHTML'; import type {ActionableItem} from '@components/ReportActionItem/ActionableItemButtons'; import ActionableItemButtons from '@components/ReportActionItem/ActionableItemButtons'; import ChronosOOOListActions from '@components/ReportActionItem/ChronosOOOListActions'; -import MoneyReportView from '@components/ReportActionItem/MoneyReportView'; import MoneyRequestAction from '@components/ReportActionItem/MoneyRequestAction'; -import MoneyRequestView from '@components/ReportActionItem/MoneyRequestView'; import RenameAction from '@components/ReportActionItem/RenameAction'; import ReportPreview from '@components/ReportActionItem/ReportPreview'; import TaskAction from '@components/ReportActionItem/TaskAction'; import TaskPreview from '@components/ReportActionItem/TaskPreview'; -import TaskView from '@components/ReportActionItem/TaskView'; import TripDetailsView from '@components/ReportActionItem/TripDetailsView'; import TripRoomPreview from '@components/ReportActionItem/TripRoomPreview'; import {ShowContextMenuContext} from '@components/ShowContextMenuContext'; -import SpacerView from '@components/SpacerView'; import Text from '@components/Text'; import UnreadActionIndicator from '@components/UnreadActionIndicator'; import useLocalize from '@hooks/useLocalize'; @@ -53,7 +49,6 @@ import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import SelectionScraper from '@libs/SelectionScraper'; -import * as TransactionUtils from '@libs/TransactionUtils'; import {ReactionListContext} from '@pages/home/ReportScreenContext'; import * as BankAccounts from '@userActions/BankAccounts'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; @@ -63,21 +58,19 @@ import * as ReportActions from '@userActions/ReportActions'; import * as Session from '@userActions/Session'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; -import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; import type {Errors} from '@src/types/onyx/OnyxCommon'; import type {JoinWorkspaceResolution} from '@src/types/onyx/OriginalMessage'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import AnimatedEmptyStateBackground from './AnimatedEmptyStateBackground'; import {RestrictedReadOnlyContextMenuActions} from './ContextMenu/ContextMenuActions'; import MiniReportActionContextMenu from './ContextMenu/MiniReportActionContextMenu'; import * as ReportActionContextMenu from './ContextMenu/ReportActionContextMenu'; import {hideContextMenu} from './ContextMenu/ReportActionContextMenu'; import LinkPreviewer from './LinkPreviewer'; import ReportActionItemBasicMessage from './ReportActionItemBasicMessage'; -import ReportActionItemCreated from './ReportActionItemCreated'; +import ReportActionItemContentCreated from './ReportActionItemContentCreated'; import ReportActionItemDraft from './ReportActionItemDraft'; import ReportActionItemGrouped from './ReportActionItemGrouped'; import ReportActionItemMessage from './ReportActionItemMessage'; @@ -105,12 +98,6 @@ type ReportActionItemOnyxProps = { /** The user's wallet account */ userWallet: OnyxEntry; - /** The policy which the user has access to and which the report is tied to */ - policy: OnyxEntry; - - /** Transaction associated with this report, if any */ - transaction: OnyxEntry; - /** The transaction (linked with the report action) route error */ linkedTransactionRouteError: NonNullable> | null; }; @@ -186,12 +173,11 @@ function ReportActionItem({ userWallet, shouldHideThreadDividerLine = false, shouldShowSubscriptAvatar = false, - policy, - transaction, onPress = undefined, isFirstVisibleReportAction = false, shouldUseThreadDividerLine = false, linkedTransactionRouteError, + parentReportActionForTransactionThread, }: ReportActionItemProps) { const {translate} = useLocalize(); const {isSmallScreenWidth} = useWindowDimensions(); @@ -216,7 +202,6 @@ function ReportActionItem({ const originalReportID = ReportUtils.getOriginalReportID(report.reportID, action); const originalReport = report.reportID === originalReportID ? report : ReportUtils.getReport(originalReportID); const isReportActionLinked = linkedReportActionID && action.reportActionID && linkedReportActionID === action.reportActionID; - const transactionCurrency = TransactionUtils.getCurrency(transaction); const reportScrollManager = useReportScrollManager(); const isActionableWhisper = ReportActionsUtils.isActionableMentionWhisper(action) || ReportActionsUtils.isActionableTrackExpense(action) || ReportActionsUtils.isActionableReportMentionWhisper(action); @@ -489,22 +474,6 @@ function ReportActionItem({ ]; }, [action, isActionableWhisper, report.reportID]); - const renderThreadDivider = useMemo( - () => - shouldHideThreadDividerLine ? ( - - ) : ( - - ), - [shouldHideThreadDividerLine, styles.reportHorizontalRule, report.reportID], - ); - /** * Get the content of ReportActionItem * @param hovered whether the ReportActionItem is hovered @@ -811,113 +780,15 @@ function ReportActionItem({ } if (action.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) { - if (ReportActionsUtils.isTransactionThread(parentReportAction)) { - const isReversedTransaction = ReportActionsUtils.isReversedTransaction(parentReportAction); - if (ReportActionsUtils.isDeletedParentAction(parentReportAction) || isReversedTransaction) { - let message: TranslationPaths; - if (isReversedTransaction) { - message = 'parentReportAction.reversedTransaction'; - } else { - message = 'parentReportAction.deletedExpense'; - } - return ( - - - - - ${translate(message)}`} /> - - - - - ); - } - return ( - - - - {renderThreadDivider} - - - ); - } - if (ReportUtils.isTaskReport(report)) { - if (ReportUtils.isCanceledTaskReport(report, parentReportAction)) { - return ( - - - - - ${translate('parentReportAction.deletedTask')}`} /> - - - - - ); - } - return ( - - - - - {renderThreadDivider} - - - ); - } - - if (ReportUtils.isExpenseReport(report) || ReportUtils.isIOUReport(report) || ReportUtils.isInvoiceReport(report)) { - return ( - - {transactionThreadReport && !isEmptyObject(transactionThreadReport) ? ( - <> - {transactionCurrency !== report.currency && ( - <> - - {renderThreadDivider} - - )} - - - - {renderThreadDivider} - - - - ) : ( - <> - - {renderThreadDivider} - - )} - - ); - } + const transactionID = (parentReportActionForTransactionThread as OnyxTypes.OriginalMessageIOU)?.originalMessage.IOUTransactionID; return ( - ); } @@ -1061,10 +932,6 @@ export default withOnyx({ }, initialValue: {} as OnyxTypes.Report, }, - policy: { - key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY}${report.policyID ?? -1}`, - initialValue: {} as OnyxTypes.Policy, - }, emojiReactions: { key: ({action}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${action.reportActionID}`, initialValue: {}, @@ -1072,14 +939,6 @@ export default withOnyx({ userWallet: { key: ONYXKEYS.USER_WALLET, }, - transaction: { - key: ({parentReportActionForTransactionThread}) => { - const transactionID = (parentReportActionForTransactionThread as OnyxTypes.OriginalMessageIOU)?.originalMessage.IOUTransactionID - ? (parentReportActionForTransactionThread as OnyxTypes.OriginalMessageIOU).originalMessage.IOUTransactionID - : 0; - return `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`; - }, - }, linkedTransactionRouteError: { key: ({action}) => `${ONYXKEYS.COLLECTION.TRANSACTION}${(action as OnyxTypes.OriginalMessageIOU)?.originalMessage?.IOUTransactionID ?? -1}`, selector: (transaction: OnyxEntry) => transaction?.errorFields?.route ?? null, @@ -1118,10 +977,8 @@ export default withOnyx({ prevProps.report?.nonReimbursableTotal === nextProps.report?.nonReimbursableTotal && prevProps.linkedReportActionID === nextProps.linkedReportActionID && lodashIsEqual(prevProps.report.fieldList, nextProps.report.fieldList) && - lodashIsEqual(prevProps.policy, nextProps.policy) && lodashIsEqual(prevProps.transactionThreadReport, nextProps.transactionThreadReport) && lodashIsEqual(prevProps.reportActions, nextProps.reportActions) && - lodashIsEqual(prevProps.transaction, nextProps.transaction) && lodashIsEqual(prevProps.linkedTransactionRouteError, nextProps.linkedTransactionRouteError) && lodashIsEqual(prevParentReportAction, nextParentReportAction) && prevProps.modal?.willAlertModalBecomeVisible === nextProps.modal?.willAlertModalBecomeVisible diff --git a/src/pages/home/report/ReportActionItemContentCreated.tsx b/src/pages/home/report/ReportActionItemContentCreated.tsx new file mode 100644 index 000000000000..a48d1d370db2 --- /dev/null +++ b/src/pages/home/report/ReportActionItemContentCreated.tsx @@ -0,0 +1,202 @@ +import lodashIsEqual from 'lodash/isEqual'; +import React, {memo, useMemo} from 'react'; +import {View} from 'react-native'; +import {useOnyx} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; +import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import RenderHTML from '@components/RenderHTML'; +import MoneyReportView from '@components/ReportActionItem/MoneyReportView'; +import MoneyRequestView from '@components/ReportActionItem/MoneyRequestView'; +import TaskView from '@components/ReportActionItem/TaskView'; +import {ShowContextMenuContext} from '@components/ShowContextMenuContext'; +import type {ShowContextMenuContextProps} from '@components/ShowContextMenuContext'; +import SpacerView from '@components/SpacerView'; +import UnreadActionIndicator from '@components/UnreadActionIndicator'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as ReportActionsUtils from '@libs/ReportActionsUtils'; +import * as ReportUtils from '@libs/ReportUtils'; +import * as TransactionUtils from '@libs/TransactionUtils'; +import type {TranslationPaths} from '@src/languages/types'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type * as OnyxTypes from '@src/types/onyx'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import AnimatedEmptyStateBackground from './AnimatedEmptyStateBackground'; +import ReportActionItemCreated from './ReportActionItemCreated'; +import ReportActionItemSingle from './ReportActionItemSingle'; + +type ReportActionItemContentCreatedProps = { + /** The context value containing the report and action data, along with the show context menu props */ + contextValue: ShowContextMenuContextProps & { + report: OnyxTypes.Report; + action: OnyxTypes.ReportAction; + }; + + /** Report action belonging to the report's parent */ + parentReportAction: OnyxEntry; + + /** The transaction ID */ + transactionID: string | undefined; + + /** The draft message */ + draftMessage: string | undefined; + + /** Flag to show, hide the thread divider line */ + shouldHideThreadDividerLine: boolean; +}; + +function ReportActionItemContentCreated({contextValue, parentReportAction, transactionID, draftMessage, shouldHideThreadDividerLine}: ReportActionItemContentCreatedProps) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + + const {report, action, transactionThreadReport} = contextValue; + + const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report.policyID ?? '-1'}`); + const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID ?? '-1'}`); + + const transactionCurrency = TransactionUtils.getCurrency(transaction); + + const renderThreadDivider = useMemo( + () => + shouldHideThreadDividerLine ? ( + + ) : ( + + ), + [shouldHideThreadDividerLine, report.reportID, styles.reportHorizontalRule], + ); + + if (ReportActionsUtils.isTransactionThread(parentReportAction)) { + const isReversedTransaction = ReportActionsUtils.isReversedTransaction(parentReportAction); + + if (ReportActionsUtils.isDeletedParentAction(parentReportAction) || isReversedTransaction) { + let message: TranslationPaths; + + if (isReversedTransaction) { + message = 'parentReportAction.reversedTransaction'; + } else { + message = 'parentReportAction.deletedExpense'; + } + + return ( + + + + + ${translate(message)}`} /> + + + + + ); + } + + return ( + + + + {renderThreadDivider} + + + ); + } + + if (ReportUtils.isTaskReport(report)) { + if (ReportUtils.isCanceledTaskReport(report, parentReportAction)) { + return ( + + + + + ${translate('parentReportAction.deletedTask')}`} /> + + + + + ); + } + + return ( + + + + + {renderThreadDivider} + + + ); + } + + if (ReportUtils.isExpenseReport(report) || ReportUtils.isIOUReport(report) || ReportUtils.isInvoiceReport(report)) { + return ( + + {transactionThreadReport && !isEmptyObject(transactionThreadReport) ? ( + <> + {transactionCurrency !== report.currency && ( + <> + + {renderThreadDivider} + + )} + + + + {renderThreadDivider} + + + + ) : ( + <> + + {renderThreadDivider} + + )} + + ); + } + + return ( + + ); +} + +ReportActionItemContentCreated.displayName = 'ReportActionItemContentCreated'; + +export default memo( + ReportActionItemContentCreated, + (prevProps, nextProps) => + lodashIsEqual(prevProps.contextValue, nextProps.contextValue) && + lodashIsEqual(prevProps.parentReportAction, nextProps.parentReportAction) && + prevProps.transactionID === nextProps.transactionID && + prevProps.draftMessage === nextProps.draftMessage && + prevProps.shouldHideThreadDividerLine === nextProps.shouldHideThreadDividerLine, +);