diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index c3b377783b13..bf1a9f994c37 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -675,12 +675,12 @@ function getLatestReportActionFromOnyxData(onyxData: OnyxUpdate[] | null): OnyxE /** * Find the transaction associated with this reportAction, if one exists. */ -function getLinkedTransactionID(reportID: string, reportActionID: string): string | null { - const reportAction = allReportActions?.[reportID]?.[reportActionID]; +function getLinkedTransactionID(reportActionOrID: string | OnyxEntry, reportID?: string): string | null { + const reportAction = typeof reportActionOrID === 'string' ? allReportActions?.[reportID ?? '']?.[reportActionOrID] : reportActionOrID; if (!reportAction || reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.IOU) { return null; } - return reportAction.originalMessage.IOUTransactionID ?? null; + return reportAction.originalMessage?.IOUTransactionID ?? null; } function getReportAction(reportID: string, reportActionID: string): OnyxEntry { diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index a2bf892b96b4..bd9bda427452 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -61,6 +61,7 @@ import isReportMessageAttachment from './isReportMessageAttachment'; import localeCompare from './LocaleCompare'; import * as LocalePhoneNumber from './LocalePhoneNumber'; import * as Localize from './Localize'; +import Log from './Log'; import {isEmailPublicDomain} from './LoginUtils'; import ModifiedExpenseMessage from './ModifiedExpenseMessage'; import linkingConfig from './Navigation/linkingConfig'; @@ -2487,15 +2488,6 @@ function getLinkedTransaction(reportAction: OnyxEntry | EmptyObject { - return allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] ?? {}; -} - /** * Given a parent IOU report action get report name for the LHN. */ @@ -5195,7 +5187,7 @@ function getVisibleMemberIDs(report: OnyxEntry): number[] { /** * Return iou report action display message */ -function getIOUReportActionDisplayMessage(reportAction: OnyxEntry): string { +function getIOUReportActionDisplayMessage(reportAction: OnyxEntry, transaction?: OnyxEntry, shouldLog = false): string { if (reportAction?.actionName !== CONST.REPORT.ACTIONS.TYPE.IOU) { return ''; } @@ -5225,7 +5217,15 @@ function getIOUReportActionDisplayMessage(reportAction: OnyxEntry) return Localize.translateLocal(translationKey, {amount: formattedAmount, payer: ''}); } - const transaction = getTransaction(originalMessage.IOUTransactionID ?? ''); + // This log to server is temporary and needed to determine if there is a case we need the transaction param + // when we call getIOUReportActionDisplayMessage from ReportActionItemMessage + if (shouldLog) { + Log.alert('Transaction Param Used when getIOUReportActionDisplayMessage was called from ReportActionItemMessage', { + reportActionID: reportAction.reportActionID, + originalMessageType: originalMessage.type, + }); + } + const transactionDetails = getTransactionDetails(!isEmptyObject(transaction) ? transaction : null); const formattedAmount = CurrencyUtils.convertToDisplayString(transactionDetails?.amount ?? 0, transactionDetails?.currency); const isRequestSettled = isSettled(originalMessage.IOUReportID); diff --git a/src/libs/actions/ReportActions.ts b/src/libs/actions/ReportActions.ts index 66deb8aca065..ae886e0309dc 100644 --- a/src/libs/actions/ReportActions.ts +++ b/src/libs/actions/ReportActions.ts @@ -22,7 +22,7 @@ function clearReportActionErrors(reportID: string, reportAction: ReportAction, k }); // If there's a linked transaction, delete that too - const linkedTransactionID = ReportActionUtils.getLinkedTransactionID(originalReportID ?? '', reportAction.reportActionID); + const linkedTransactionID = ReportActionUtils.getLinkedTransactionID(reportAction.reportActionID, originalReportID ?? ''); if (linkedTransactionID) { Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${linkedTransactionID}`, null); } diff --git a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx index 10c7dddf2631..07a894251fd4 100755 --- a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx +++ b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx @@ -14,11 +14,12 @@ import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useStyleUtils from '@hooks/useStyleUtils'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Beta, ReportAction, ReportActions} from '@src/types/onyx'; +import type {Beta, ReportAction, ReportActions, Transaction} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {ContextMenuAction, ContextMenuActionPayload} from './ContextMenuActions'; import ContextMenuActions from './ContextMenuActions'; @@ -31,6 +32,9 @@ type BaseReportActionContextMenuOnyxProps = { /** All of the actions of the report */ reportActions: OnyxEntry; + + /** The transaction linked to the report action this context menu is attached to. */ + transaction: OnyxEntry; }; type BaseReportActionContextMenuProps = BaseReportActionContextMenuOnyxProps & { @@ -106,6 +110,7 @@ function BaseReportActionContextMenu({ selection = '', draftMessage = '', reportActionID, + transaction, reportID, betas, reportActions, @@ -252,6 +257,7 @@ function BaseReportActionContextMenu({ textTranslateKey === 'reportActionContextMenu.deleteAction' || textTranslateKey === 'reportActionContextMenu.deleteConfirmation'; const text = textTranslateKey && (isKeyInActionUpdateKeys ? translate(textTranslateKey, {action: reportAction}) : translate(textTranslateKey)); + const transactionPayload = textTranslateKey === 'reportActionContextMenu.copyToClipboard' && transaction && {transaction}; const isMenuAction = textTranslateKey === 'reportActionContextMenu.menu'; return ( @@ -268,7 +274,7 @@ function BaseReportActionContextMenu({ key={contextAction.textTranslateKey} onPress={(event) => interceptAnonymousUser( - () => contextAction.onPress?.(closePopup, {...payload, event, ...(isMenuAction ? {anchorRef: threedotRef} : {})}), + () => contextAction.onPress?.(closePopup, {...payload, ...transactionPayload, event, ...(isMenuAction ? {anchorRef: threedotRef} : {})}), contextAction.isAnonymousAction, ) } @@ -292,6 +298,12 @@ export default withOnyx `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${originalReportID}`, canEvict: false, }, + transaction: { + key: ({reportActions, reportActionID}) => { + const reportAction = reportActions?.[reportActionID]; + return `${ONYXKEYS.COLLECTION.TRANSACTION}${(reportAction && ReportActionsUtils.getLinkedTransactionID(reportAction)) ?? 0}`; + }, + }, })( memo(BaseReportActionContextMenu, (prevProps, nextProps) => { const {reportActions: prevReportActions, ...prevPropsWithoutReportActions} = prevProps; diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index ea65ab40ac0a..dfc1edb32ba1 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -27,7 +27,7 @@ import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ROUTES from '@src/ROUTES'; -import type {Beta, ReportAction, ReportActionReactions, Report as ReportType} from '@src/types/onyx'; +import type {Beta, ReportAction, ReportActionReactions, Report as ReportType, Transaction} from '@src/types/onyx'; import type IconAsset from '@src/types/utils/IconAsset'; import type {ContextMenuAnchor} from './ReportActionContextMenu'; import {hideContextMenu, showDeleteModal} from './ReportActionContextMenu'; @@ -65,6 +65,7 @@ type ShouldShow = ( type ContextMenuActionPayload = { reportAction: ReportAction; + transaction?: OnyxEntry; reportID: string; draftMessage: string; selection: string; @@ -341,7 +342,7 @@ const ContextMenuActions: ContextMenuAction[] = [ // If return value is true, we switch the `text` and `icon` on // `ContextMenuItem` with `successText` and `successIcon` which will fall back to // the `text` and `icon` - onPress: (closePopover, {reportAction, selection, reportID}) => { + onPress: (closePopover, {reportAction, transaction, selection, reportID}) => { const isReportPreviewAction = ReportActionsUtils.isReportPreviewAction(reportAction); const messageHtml = getActionHtml(reportAction); const messageText = ReportActionsUtils.getReportActionMessageText(reportAction); @@ -365,7 +366,7 @@ const ContextMenuActions: ContextMenuAction[] = [ const displayMessage = ReportUtils.getReimbursementDeQueuedActionMessage(reportAction, expenseReport); Clipboard.setString(displayMessage); } else if (ReportActionsUtils.isMoneyRequestAction(reportAction)) { - const displayMessage = ReportUtils.getIOUReportActionDisplayMessage(reportAction); + const displayMessage = ReportUtils.getIOUReportActionDisplayMessage(reportAction, transaction); Clipboard.setString(displayMessage); } else if (ReportActionsUtils.isCreatedTaskReportAction(reportAction)) { const taskPreviewMessage = TaskUtils.getTaskCreatedMessage(reportAction); diff --git a/src/pages/home/report/ContextMenu/MiniReportActionContextMenu/types.ts b/src/pages/home/report/ContextMenu/MiniReportActionContextMenu/types.ts index b7c3d6214094..b18c932fd7e2 100644 --- a/src/pages/home/report/ContextMenu/MiniReportActionContextMenu/types.ts +++ b/src/pages/home/report/ContextMenu/MiniReportActionContextMenu/types.ts @@ -1,6 +1,6 @@ import type {BaseReportActionContextMenuProps} from '@pages/home/report/ContextMenu/BaseReportActionContextMenu'; -type MiniReportActionContextMenuProps = Omit & { +type MiniReportActionContextMenuProps = Omit & { /** Should the reportAction this menu is attached to have the appearance of being grouped with the previous reportAction? */ displayAsGroup?: boolean; }; diff --git a/src/pages/home/report/ReportActionItemMessage.tsx b/src/pages/home/report/ReportActionItemMessage.tsx index e7ac957a0800..eec0b825e454 100644 --- a/src/pages/home/report/ReportActionItemMessage.tsx +++ b/src/pages/home/report/ReportActionItemMessage.tsx @@ -2,18 +2,26 @@ import type {ReactElement} from 'react'; import React from 'react'; import type {StyleProp, TextStyle, ViewStyle} from 'react-native'; import {View} from 'react-native'; +import {withOnyx} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; -import type {ReportAction} from '@src/types/onyx'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type {ReportAction, Transaction} from '@src/types/onyx'; import type {OriginalMessageAddComment} from '@src/types/onyx/OriginalMessage'; import TextCommentFragment from './comment/TextCommentFragment'; import ReportActionItemFragment from './ReportActionItemFragment'; -type ReportActionItemMessageProps = { +type ReportActionItemMessageOnyxProps = { + /** The transaction linked to the report action. */ + transaction: OnyxEntry; +}; + +type ReportActionItemMessageProps = ReportActionItemMessageOnyxProps & { /** The report action */ action: ReportAction; @@ -30,7 +38,7 @@ type ReportActionItemMessageProps = { reportID: string; }; -function ReportActionItemMessage({action, displayAsGroup, reportID, style, isHidden = false}: ReportActionItemMessageProps) { +function ReportActionItemMessage({action, transaction, displayAsGroup, reportID, style, isHidden = false}: ReportActionItemMessageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -58,7 +66,7 @@ function ReportActionItemMessage({action, displayAsGroup, reportID, style, isHid const originalMessage = action.actionName === CONST.REPORT.ACTIONS.TYPE.IOU ? action.originalMessage : null; const iouReportID = originalMessage?.IOUReportID; if (iouReportID) { - iouMessage = ReportUtils.getIOUReportActionDisplayMessage(action); + iouMessage = ReportUtils.getIOUReportActionDisplayMessage(action, transaction, true); } } @@ -115,4 +123,8 @@ function ReportActionItemMessage({action, displayAsGroup, reportID, style, isHid ReportActionItemMessage.displayName = 'ReportActionItemMessage'; -export default ReportActionItemMessage; +export default withOnyx({ + transaction: { + key: ({action}) => `${ONYXKEYS.COLLECTION.TRANSACTION}${ReportActionsUtils.getLinkedTransactionID(action) ?? 0}`, + }, +})(ReportActionItemMessage);