From 30275bfb090502b1ca8bdabc2ff67d00d313d88c Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Thu, 5 Feb 2026 15:29:05 -0700 Subject: [PATCH 1/7] Remove dead code --- src/libs/ReportUtils.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index f11888f22e05d..913f676258b86 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -10778,16 +10778,6 @@ function getIndicatedMissingPaymentMethod( return !hasCreditBankAccount(bankAccountList) ? 'bankAccount' : undefined; } -/** - * Checks if report chat contains missing payment method - */ -function hasMissingPaymentMethod(userWalletTierName: string | undefined, iouReportID: string | undefined, bankAccountList: OnyxEntry): boolean { - const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`] ?? {}; - return Object.values(reportActions) - .filter(Boolean) - .some((action) => getIndicatedMissingPaymentMethod(userWalletTierName, iouReportID, action, bankAccountList) !== undefined); -} - /** * Used from expense actions to decide if we need to build an optimistic expense report. * Create a new report if: @@ -12890,7 +12880,6 @@ export { hasExpensifyGuidesEmails, hasHeldExpenses, hasIOUWaitingOnCurrentUserBankAccount, - hasMissingPaymentMethod, hasNonReimbursableTransactions, hasOnlyHeldExpenses, hasOnlyTransactionsWithPendingRoutes, From f7d14444effd6969ec49eb8eea0d6f2ea69762f9 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Fri, 6 Feb 2026 08:41:08 -0700 Subject: [PATCH 2/7] Begin refactoring of getOriginalReportID --- .../MoneyRequestReportActionsList.tsx | 3 +- src/components/ShowContextMenuContext.ts | 2 +- src/libs/ReportUtils.ts | 4 +- src/libs/actions/Report/index.ts | 8 ++-- src/libs/actions/ReportActions.ts | 2 +- src/pages/FlagCommentPage.tsx | 3 +- src/pages/ReportDetailsPage.tsx | 3 +- .../DuplicateTransactionItem.tsx | 2 +- .../BaseReportActionContextMenu.tsx | 1 + .../report/ContextMenu/ContextMenuActions.tsx | 23 ++++++++--- .../PopoverReportActionContextMenu.tsx | 5 ++- .../report/ReportActionItemMessageEdit.tsx | 3 +- .../ReportActionItemMessageWithExplain.tsx | 7 +++- .../report/ReportActionItemParentAction.tsx | 2 +- src/pages/inbox/report/ReportActionsList.tsx | 3 +- tests/unit/ReportUtilsTest.ts | 39 +++++++++++++++++++ 16 files changed, 86 insertions(+), 24 deletions(-) diff --git a/src/components/MoneyRequestReportView/MoneyRequestReportActionsList.tsx b/src/components/MoneyRequestReportView/MoneyRequestReportActionsList.tsx index c21deb495d39d..9017c94666b48 100644 --- a/src/components/MoneyRequestReportView/MoneyRequestReportActionsList.tsx +++ b/src/components/MoneyRequestReportView/MoneyRequestReportActionsList.tsx @@ -160,6 +160,7 @@ function MoneyRequestReportActionsList({ const personalDetails = usePersonalDetails(); const [emojiReactions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}`, {canBeMissing: true}); const [draftMessage] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}`, {canBeMissing: true}); + const [reportActionsFromOnyx] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, {canBeMissing: true}); const [tryNewDot] = useOnyx(ONYXKEYS.NVP_TRY_NEW_DOT, {canBeMissing: false}); const isTryNewDotNVPDismissed = !!tryNewDot?.classicRedirect?.dismissed; @@ -557,7 +558,7 @@ function MoneyRequestReportActionsList({ hasNextActionMadeBySameActor(visibleReportActions, index); const actionEmojiReactions = emojiReactions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${reportAction.reportActionID}`]; - const originalReportID = getOriginalReportID(report.reportID, reportAction); + const originalReportID = getOriginalReportID(report.reportID, reportAction, reportActionsFromOnyx); const reportDraftMessages = draftMessage?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${originalReportID}`]; const matchingDraftMessage = reportDraftMessages?.[reportAction.reportActionID]; const matchingDraftMessageString = matchingDraftMessage?.message; diff --git a/src/components/ShowContextMenuContext.ts b/src/components/ShowContextMenuContext.ts index 90c873002c090..f56e6e62e8eca 100644 --- a/src/components/ShowContextMenuContext.ts +++ b/src/components/ShowContextMenuContext.ts @@ -62,7 +62,7 @@ function showContextMenuForReport( contextMenuAnchor: anchor, report: { reportID, - originalReportID: reportID ? getOriginalReportID(reportID, action) : undefined, + originalReportID: reportID ? getOriginalReportID(reportID, action, undefined) : undefined, isArchivedRoom, }, reportAction: { diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 913f676258b86..a5fd67f801cd1 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -9931,11 +9931,11 @@ function canUserPerformWriteAction(report: OnyxEntry, isReportArchived: /** * Returns ID of the original report from which the given reportAction is first created. */ -function getOriginalReportID(reportID: string | undefined, reportAction: OnyxInputOrEntry): string | undefined { +function getOriginalReportID(reportID: string | undefined, reportAction: OnyxInputOrEntry, reportActionsParam: OnyxEntry | undefined): string | undefined { if (!reportID) { return undefined; } - const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`]; + const reportActions = reportActionsParam ?? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`]; const currentReportAction = reportAction?.reportActionID ? reportActions?.[reportAction.reportActionID] : undefined; const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.chatReportID}`]; diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index b0244a7a3ae78..90b03e067bdac 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -2092,7 +2092,7 @@ function deleteReportComment( currentEmail: string, ) { const reportID = report?.reportID; - const originalReportID = getOriginalReportID(reportID, reportAction); + const originalReportID = getOriginalReportID(reportID, reportAction, undefined); const reportActionID = reportAction.reportActionID; if (!reportActionID || !originalReportID || !reportID) { @@ -2420,13 +2420,13 @@ function editReportComment( /** Deletes the draft for a comment report action. */ function deleteReportActionDraft(reportID: string | undefined, reportAction: ReportAction) { - const originalReportID = getOriginalReportID(reportID, reportAction); + const originalReportID = getOriginalReportID(reportID, reportAction, undefined); Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${originalReportID}`, {[reportAction.reportActionID]: null}); } /** Saves the draft for a comment report action. This will put the comment into "edit mode" */ function saveReportActionDraft(reportID: string | undefined, reportAction: ReportAction, draftMessage: string) { - const originalReportID = getOriginalReportID(reportID, reportAction); + const originalReportID = getOriginalReportID(reportID, reportAction, undefined); Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${originalReportID}`, {[reportAction.reportActionID]: {message: draftMessage}}); } @@ -3761,7 +3761,7 @@ function toggleEmojiReaction( currentUserAccountID: number, ignoreSkinToneOnCompare = false, ) { - const originalReportID = getOriginalReportID(reportID, reportAction); + const originalReportID = getOriginalReportID(reportID, reportAction, undefined); if (!originalReportID) { return; diff --git a/src/libs/actions/ReportActions.ts b/src/libs/actions/ReportActions.ts index fe23be8b09d87..739e87d7625c2 100644 --- a/src/libs/actions/ReportActions.ts +++ b/src/libs/actions/ReportActions.ts @@ -27,7 +27,7 @@ Onyx.connect({ }); function clearReportActionErrors(reportID: string, reportAction: ReportAction, keys?: string[]) { - const originalReportID = getOriginalReportID(reportID, reportAction); + const originalReportID = getOriginalReportID(reportID, reportAction, undefined); if (!reportAction?.reportActionID) { return; diff --git a/src/pages/FlagCommentPage.tsx b/src/pages/FlagCommentPage.tsx index e5cedc052bd06..83b39775a2473 100644 --- a/src/pages/FlagCommentPage.tsx +++ b/src/pages/FlagCommentPage.tsx @@ -60,7 +60,8 @@ function FlagCommentPage({parentReportAction, route, report, parentReport, repor if (isChatThread(report) && reportAction?.reportActionID === parentReportAction?.reportActionID) { reportID = parentReport?.reportID; } - const originalReportID = getOriginalReportID(reportID, reportAction); + const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {canBeMissing: true}); + const originalReportID = getOriginalReportID(reportID, reportAction, reportActions); const [originalReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${originalReportID}`, {canBeMissing: true}); const isOriginalReportArchived = useReportIsArchived(originalReportID); diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 1228d714b6aaf..b96e0ad62f2b8 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -176,6 +176,7 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID, {canBeMissing: true}); const {reportActions} = usePaginatedReportActions(report.reportID); + const [reportActionsForOriginalReportID] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, {canBeMissing: true}); const {removeTransaction} = useSearchContext(); @@ -439,7 +440,7 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail } if (isTrackExpenseReport && !isDeletedParentAction) { - const actionReportID = getOriginalReportID(report.reportID, parentReportAction); + const actionReportID = getOriginalReportID(report.reportID, parentReportAction, reportActionsForOriginalReportID); const whisperAction = getTrackExpenseActionableWhisper(iouTransactionID, moneyRequestReport?.reportID); const actionableWhisperReportActionID = whisperAction?.reportActionID; items.push({ diff --git a/src/pages/TransactionDuplicate/DuplicateTransactionItem.tsx b/src/pages/TransactionDuplicate/DuplicateTransactionItem.tsx index 43d8ed26b7016..89571c7070489 100644 --- a/src/pages/TransactionDuplicate/DuplicateTransactionItem.tsx +++ b/src/pages/TransactionDuplicate/DuplicateTransactionItem.tsx @@ -43,7 +43,7 @@ function DuplicateTransactionItem({transaction, index, allReports, policies, onP return IOUTransactionID === transaction?.transactionID; }); - const originalReportID = getOriginalReportID(report?.reportID, action); + const originalReportID = getOriginalReportID(report?.reportID, action, reportActions); const [draftMessage] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${originalReportID}`, { canBeMissing: true, diff --git a/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx b/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx index 13c300f003b91..f26c6919df8cf 100755 --- a/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx +++ b/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx @@ -364,6 +364,7 @@ function BaseReportActionContextMenu({ const payload: ContextMenuActionPayload = { // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style reportAction: (reportAction ?? null) as ReportAction, + reportActions, reportID, report, draftMessage, diff --git a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx index e507a4be8d03c..d0e799fb4846f 100644 --- a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx @@ -182,7 +182,19 @@ import { import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ROUTES from '@src/ROUTES'; -import type {Beta, Card, Download as DownloadOnyx, OnyxInputOrEntry, Policy, PolicyTagLists, ReportAction, ReportActionReactions, Report as ReportType, Transaction} from '@src/types/onyx'; +import type { + Beta, + Card, + Download as DownloadOnyx, + OnyxInputOrEntry, + Policy, + PolicyTagLists, + ReportAction, + ReportActionReactions, + ReportActions, + Report as ReportType, + Transaction, +} from '@src/types/onyx'; import type IconAsset from '@src/types/utils/IconAsset'; import type WithSentryLabel from '@src/types/utils/SentryLabel'; import KeyboardUtils from '@src/utils/keyboard'; @@ -237,6 +249,7 @@ type ShouldShow = (args: { type ContextMenuActionPayload = { reportAction: ReportAction; + reportActions: OnyxEntry; transaction?: OnyxEntry; reportID: string | undefined; currentUserAccountID: number; @@ -460,12 +473,12 @@ const ContextMenuActions: ContextMenuAction[] = [ return hasReasoning(reportAction); }, - onPress: (closePopover, {reportAction, reportID, translate, currentUserPersonalDetails}) => { + onPress: (closePopover, {reportAction, reportActions, reportID, translate, currentUserPersonalDetails}) => { if (!reportID) { return; } - const originalReportID = getOriginalReportID(reportID, reportAction); + const originalReportID = getOriginalReportID(reportID, reportAction, reportActions); if (closePopover) { hideContextMenu(false, () => { KeyboardUtils.dismiss().then(() => { @@ -1084,8 +1097,8 @@ const ContextMenuActions: ContextMenuAction[] = [ const isDynamicWorkflowRoutedAction = isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.DYNAMIC_EXTERNAL_WORKFLOW_ROUTED); return type === CONST.CONTEXT_MENU_TYPES.REPORT_ACTION && !isAttachmentTarget && !isMessageDeleted(reportAction) && !isDynamicWorkflowRoutedAction; }, - onPress: (closePopover, {reportAction, reportID}) => { - const originalReportID = getOriginalReportID(reportID, reportAction); + onPress: (closePopover, {reportAction, reportActions, reportID}) => { + const originalReportID = getOriginalReportID(reportID, reportAction, reportActions); getEnvironmentURL().then((environmentURL) => { const reportActionID = reportAction?.reportActionID; Clipboard.setString(`${environmentURL}/r/${originalReportID}/${reportActionID}`); diff --git a/src/pages/inbox/report/ContextMenu/PopoverReportActionContextMenu.tsx b/src/pages/inbox/report/ContextMenu/PopoverReportActionContextMenu.tsx index 44543b1aa41ed..d9d890f9565b3 100644 --- a/src/pages/inbox/report/ContextMenu/PopoverReportActionContextMenu.tsx +++ b/src/pages/inbox/report/ContextMenu/PopoverReportActionContextMenu.tsx @@ -56,7 +56,8 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro const selectionRef = useRef(''); const reportActionDraftMessageRef = useRef(undefined); const isReportArchived = useReportIsArchived(reportIDRef.current); - const isOriginalReportArchived = useReportIsArchived(getOriginalReportID(reportIDRef.current, reportActionRef.current)); + const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportIDRef.current}`, {canBeMissing: true}); + const isOriginalReportArchived = useReportIsArchived(getOriginalReportID(reportIDRef.current, reportActionRef.current, reportActions)); const {iouReport, chatReport, isChatIOUReportArchived} = useGetIOUReportFromReportAction(reportActionRef.current); const {transitionActionSheetState} = useActionSheetAwareScrollViewActions(); @@ -332,7 +333,7 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro policy, }); - const [originalReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getOriginalReportID(reportIDRef.current, reportActionRef.current)}`, { + const [originalReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getOriginalReportID(reportIDRef.current, reportActionRef.current, reportActions)}`, { canBeMissing: true, }); const ancestorsRef = useRef([]); diff --git a/src/pages/inbox/report/ReportActionItemMessageEdit.tsx b/src/pages/inbox/report/ReportActionItemMessageEdit.tsx index 5c624142612fd..ac421a99ea121 100644 --- a/src/pages/inbox/report/ReportActionItemMessageEdit.tsx +++ b/src/pages/inbox/report/ReportActionItemMessageEdit.tsx @@ -151,8 +151,9 @@ function ReportActionItemMessageEdit({ // The ref to check whether the comment saving is in progress const isCommentPendingSaved = useRef(false); const [originalReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${originalReportID}`, {canBeMissing: true}); + const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${originalReportID}`, {canBeMissing: true}); const isOriginalReportArchived = useReportIsArchived(originalReportID); - const originalParentReportID = getOriginalReportID(originalReportID, action); + const originalParentReportID = getOriginalReportID(originalReportID, action, reportActions); const isOriginalParentReportArchived = useReportIsArchived(originalParentReportID); const ancestors = useAncestors(originalReport); const icons = useMemoizedLazyExpensifyIcons(['Checkmark', 'Close']); diff --git a/src/pages/inbox/report/ReportActionItemMessageWithExplain.tsx b/src/pages/inbox/report/ReportActionItemMessageWithExplain.tsx index df389bda9da6d..01c7b5504d37e 100644 --- a/src/pages/inbox/report/ReportActionItemMessageWithExplain.tsx +++ b/src/pages/inbox/report/ReportActionItemMessageWithExplain.tsx @@ -4,10 +4,12 @@ import type {OnyxEntry} from 'react-native-onyx'; import RenderHTML from '@components/RenderHTML'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; +import useOnyx from '@hooks/useOnyx'; import {explain} from '@libs/actions/Report'; import {hasReasoning} from '@libs/ReportActionsUtils'; import {getOriginalReportID} from '@libs/ReportUtils'; import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; import type {ReportAction} from '@src/types/onyx'; import ReportActionItemBasicMessage from './ReportActionItemBasicMessage'; @@ -29,6 +31,7 @@ type ReportActionItemMessageWithExplainProps = { function ReportActionItemMessageWithExplain({message, action, reportID}: ReportActionItemMessageWithExplainProps) { const {translate} = useLocalize(); const personalDetail = useCurrentUserPersonalDetails(); + const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {canBeMissing: true}); const actionHasReasoning = hasReasoning(action); const computedMessage = actionHasReasoning ? `${message}${translate('iou.AskToExplain')}` : message; @@ -39,10 +42,10 @@ function ReportActionItemMessageWithExplain({message, action, reportID}: ReportA return; } - const actionOriginalReportID = getOriginalReportID(reportID, action); + const actionOriginalReportID = getOriginalReportID(reportID, action, reportActions); explain(action, actionOriginalReportID, translate, personalDetail?.timezone); }, - [action, reportID, translate, personalDetail?.timezone], + [action, reportID, reportActions, translate, personalDetail?.timezone], ); return ( diff --git a/src/pages/inbox/report/ReportActionItemParentAction.tsx b/src/pages/inbox/report/ReportActionItemParentAction.tsx index 5ea1a0a704ad3..21873a5063312 100644 --- a/src/pages/inbox/report/ReportActionItemParentAction.tsx +++ b/src/pages/inbox/report/ReportActionItemParentAction.tsx @@ -161,7 +161,7 @@ function ReportActionItemParentAction({ const shouldDisplayThreadDivider = !isTripPreview(ancestorReportAction); const isAncestorReportArchived = isArchivedReport(ancestorsReportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${ancestorReport.reportID}`]); - const originalReportID = getOriginalReportID(ancestorReport.reportID, ancestorReportAction); + const originalReportID = getOriginalReportID(ancestorReport.reportID, ancestorReportAction, undefined); const reportDraftMessages = originalReportID ? allDraftMessages?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${originalReportID}`] : undefined; const matchingDraftMessage = reportDraftMessages?.[ancestorReportAction.reportActionID]; const matchingDraftMessageString = matchingDraftMessage?.message; diff --git a/src/pages/inbox/report/ReportActionsList.tsx b/src/pages/inbox/report/ReportActionsList.tsx index d33222752e842..ae49da2903dc6 100644 --- a/src/pages/inbox/report/ReportActionsList.tsx +++ b/src/pages/inbox/report/ReportActionsList.tsx @@ -185,6 +185,7 @@ function ReportActionsList({ const [isUserValidated] = useOnyx(ONYXKEYS.ACCOUNT, {selector: isUserValidatedSelector, canBeMissing: true}); const [draftMessage] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}`, {canBeMissing: true}); const [emojiReactions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}`, {canBeMissing: true}); + const [reportActionsFromOnyx] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, {canBeMissing: true}); const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID, {canBeMissing: true}); const [tryNewDot] = useOnyx(ONYXKEYS.NVP_TRY_NEW_DOT, {canBeMissing: false}); const isTryNewDotNVPDismissed = !!tryNewDot?.classicRedirect?.dismissed; @@ -679,7 +680,7 @@ function ReportActionsList({ const renderItem = useCallback( ({item: reportAction, index}: ListRenderItemInfo) => { - const originalReportID = getOriginalReportID(report.reportID, reportAction); + const originalReportID = getOriginalReportID(report.reportID, reportAction, reportActionsFromOnyx); const reportDraftMessages = draftMessage?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${originalReportID}`]; const matchingDraftMessage = reportDraftMessages?.[reportAction.reportActionID]; const matchingDraftMessageString = matchingDraftMessage?.message; diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index efe60d0a7926f..c252421cc356a 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -72,6 +72,7 @@ import { getIOUReportActionDisplayMessage, getMoneyReportPreviewName, getMostRecentlyVisitedReport, + getOriginalReportID, getOutstandingChildRequest, getParentNavigationSubtitle, getParticipantsList, @@ -12020,4 +12021,42 @@ describe('ReportUtils', () => { expect(result).toBe('Report Fallback Name'); }); }); + + describe('getOriginalReportID', () => { + it('should return undefined when reportID is undefined', () => { + const reportAction = createRandomReportAction(1); + const result = getOriginalReportID(undefined, reportAction, undefined); + expect(result).toBeUndefined(); + }); + + it('should return reportID when currentReportAction exists in reportActions', () => { + const reportID = '123'; + const reportAction = createRandomReportAction(1); + const reportActions = { + [reportAction.reportActionID]: reportAction, + }; + + const result = getOriginalReportID(reportID, reportAction, reportActions); + expect(result).toBe(reportID); + }); + + it('should return reportID when reportActions is undefined but reportAction has no reportActionID', () => { + const reportID = '123'; + const reportAction = { + ...createRandomReportAction(1), + reportActionID: undefined, + } as unknown as ReportAction; + + const result = getOriginalReportID(reportID, reportAction, undefined); + expect(result).toBe(reportID); + }); + + it('should return reportID when reportActions is empty and no thread conditions apply', () => { + const reportID = '123'; + const reportAction = createRandomReportAction(1); + + const result = getOriginalReportID(reportID, reportAction, {}); + expect(result).toBe(reportID); + }); + }); }); From 6f2cc8606ea1f2fa7dc23f55748605445b1fdc5b Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Fri, 6 Feb 2026 08:55:35 -0700 Subject: [PATCH 3/7] Simplify PR --- .../MoneyRequestReportView/MoneyRequestReportActionsList.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/MoneyRequestReportView/MoneyRequestReportActionsList.tsx b/src/components/MoneyRequestReportView/MoneyRequestReportActionsList.tsx index 9017c94666b48..bf0f1bb257fbe 100644 --- a/src/components/MoneyRequestReportView/MoneyRequestReportActionsList.tsx +++ b/src/components/MoneyRequestReportView/MoneyRequestReportActionsList.tsx @@ -160,7 +160,6 @@ function MoneyRequestReportActionsList({ const personalDetails = usePersonalDetails(); const [emojiReactions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}`, {canBeMissing: true}); const [draftMessage] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}`, {canBeMissing: true}); - const [reportActionsFromOnyx] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, {canBeMissing: true}); const [tryNewDot] = useOnyx(ONYXKEYS.NVP_TRY_NEW_DOT, {canBeMissing: false}); const isTryNewDotNVPDismissed = !!tryNewDot?.classicRedirect?.dismissed; @@ -558,7 +557,7 @@ function MoneyRequestReportActionsList({ hasNextActionMadeBySameActor(visibleReportActions, index); const actionEmojiReactions = emojiReactions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${reportAction.reportActionID}`]; - const originalReportID = getOriginalReportID(report.reportID, reportAction, reportActionsFromOnyx); + const originalReportID = getOriginalReportID(report.reportID, reportAction, undefined); const reportDraftMessages = draftMessage?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${originalReportID}`]; const matchingDraftMessage = reportDraftMessages?.[reportAction.reportActionID]; const matchingDraftMessageString = matchingDraftMessage?.message; From 71edcd34dbd137598954d62b84257e218d6dc0b6 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Fri, 6 Feb 2026 10:48:44 -0700 Subject: [PATCH 4/7] Add dependency to effect --- src/pages/ReportDetailsPage.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index b96e0ad62f2b8..4281eb991ee63 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -622,6 +622,7 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail allTransactionDrafts, activePolicy, parentReport, + reportActionsForOriginalReportID, ]); const displayNamesWithTooltips = useMemo(() => { From a351f64b3fe8cbc06b0ab1bb368d54872fb61fab Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Fri, 6 Feb 2026 10:49:37 -0700 Subject: [PATCH 5/7] Add dependency to callback --- src/pages/inbox/report/ReportActionsList.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/inbox/report/ReportActionsList.tsx b/src/pages/inbox/report/ReportActionsList.tsx index 02a3c09a19b22..bfb903bca0f8f 100644 --- a/src/pages/inbox/report/ReportActionsList.tsx +++ b/src/pages/inbox/report/ReportActionsList.tsx @@ -768,6 +768,7 @@ function ReportActionsList({ isReportArchived, reportNameValuePairs?.origin, reportNameValuePairs?.originalID, + reportActionsFromOnyx, ], ); From f0b390ad68ec32259196399a6f9ffff3834185d1 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Fri, 6 Feb 2026 12:23:21 -0700 Subject: [PATCH 6/7] Pass actions from report, not the original report --- .../ContextMenu/BaseReportActionContextMenu.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx b/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx index f26c6919df8cf..5490842c6cc3c 100755 --- a/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx +++ b/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx @@ -159,18 +159,22 @@ function BaseReportActionContextMenu({ const {isProduction} = useEnvironment(); const threeDotRef = useRef(null); const [betas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: true}); - const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${originalReportID}`, { + const [reportActionsForOriginalReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${originalReportID}`, { canBeMissing: true, canEvict: false, selector: withDEWRoutedActionsObject, }); + const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, { + canBeMissing: true, + canEvict: false, + }); const reportAction: OnyxEntry = useMemo(() => { - if (isEmptyObject(reportActions) || reportActionID === '0' || reportActionID === '-1' || !reportActionID) { + if (isEmptyObject(reportActionsForOriginalReport) || reportActionID === '0' || reportActionID === '-1' || !reportActionID) { return; } - return reportActions[reportActionID]; - }, [reportActions, reportActionID]); + return reportActionsForOriginalReport[reportActionID]; + }, [reportActionsForOriginalReport, reportActionID]); const transactionID = getLinkedTransactionID(reportAction); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`, {canBeMissing: true}); const [isDebugModeEnabled] = useOnyx(ONYXKEYS.IS_DEBUG_MODE_ENABLED, {canBeMissing: true}); From 9acac4af2eeafe2bfff00ee8b64f091961828e44 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Fri, 6 Feb 2026 12:30:10 -0700 Subject: [PATCH 7/7] Revert onyx change and then pass only the original report ID since it already exists --- .../BaseReportActionContextMenu.tsx | 14 ++++------- .../report/ContextMenu/ContextMenuActions.tsx | 23 ++++--------------- 2 files changed, 9 insertions(+), 28 deletions(-) diff --git a/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx b/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx index 5490842c6cc3c..b8a5d33ee3455 100755 --- a/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx +++ b/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx @@ -159,22 +159,18 @@ function BaseReportActionContextMenu({ const {isProduction} = useEnvironment(); const threeDotRef = useRef(null); const [betas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: true}); - const [reportActionsForOriginalReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${originalReportID}`, { + const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${originalReportID}`, { canBeMissing: true, canEvict: false, selector: withDEWRoutedActionsObject, }); - const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, { - canBeMissing: true, - canEvict: false, - }); const reportAction: OnyxEntry = useMemo(() => { - if (isEmptyObject(reportActionsForOriginalReport) || reportActionID === '0' || reportActionID === '-1' || !reportActionID) { + if (isEmptyObject(reportActions) || reportActionID === '0' || reportActionID === '-1' || !reportActionID) { return; } - return reportActionsForOriginalReport[reportActionID]; - }, [reportActionsForOriginalReport, reportActionID]); + return reportActions[reportActionID]; + }, [reportActions, reportActionID]); const transactionID = getLinkedTransactionID(reportAction); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`, {canBeMissing: true}); const [isDebugModeEnabled] = useOnyx(ONYXKEYS.IS_DEBUG_MODE_ENABLED, {canBeMissing: true}); @@ -368,8 +364,8 @@ function BaseReportActionContextMenu({ const payload: ContextMenuActionPayload = { // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style reportAction: (reportAction ?? null) as ReportAction, - reportActions, reportID, + originalReportID, report, draftMessage, selection, diff --git a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx index d0e799fb4846f..19dcdf6f1cc9d 100644 --- a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx @@ -152,7 +152,6 @@ import { getIOUReportActionDisplayMessage, getMovedActionMessage, getMovedTransactionMessage, - getOriginalReportID, getPolicyChangeMessage, getReimbursementDeQueuedOrCanceledActionMessage, getReimbursementQueuedActionMessage, @@ -182,19 +181,7 @@ import { import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ROUTES from '@src/ROUTES'; -import type { - Beta, - Card, - Download as DownloadOnyx, - OnyxInputOrEntry, - Policy, - PolicyTagLists, - ReportAction, - ReportActionReactions, - ReportActions, - Report as ReportType, - Transaction, -} from '@src/types/onyx'; +import type {Beta, Card, Download as DownloadOnyx, OnyxInputOrEntry, Policy, PolicyTagLists, ReportAction, ReportActionReactions, Report as ReportType, Transaction} from '@src/types/onyx'; import type IconAsset from '@src/types/utils/IconAsset'; import type WithSentryLabel from '@src/types/utils/SentryLabel'; import KeyboardUtils from '@src/utils/keyboard'; @@ -249,9 +236,9 @@ type ShouldShow = (args: { type ContextMenuActionPayload = { reportAction: ReportAction; - reportActions: OnyxEntry; transaction?: OnyxEntry; reportID: string | undefined; + originalReportID: string | undefined; currentUserAccountID: number; report: OnyxEntry; policy?: OnyxEntry; @@ -473,12 +460,11 @@ const ContextMenuActions: ContextMenuAction[] = [ return hasReasoning(reportAction); }, - onPress: (closePopover, {reportAction, reportActions, reportID, translate, currentUserPersonalDetails}) => { + onPress: (closePopover, {reportAction, reportID, originalReportID, translate, currentUserPersonalDetails}) => { if (!reportID) { return; } - const originalReportID = getOriginalReportID(reportID, reportAction, reportActions); if (closePopover) { hideContextMenu(false, () => { KeyboardUtils.dismiss().then(() => { @@ -1097,8 +1083,7 @@ const ContextMenuActions: ContextMenuAction[] = [ const isDynamicWorkflowRoutedAction = isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.DYNAMIC_EXTERNAL_WORKFLOW_ROUTED); return type === CONST.CONTEXT_MENU_TYPES.REPORT_ACTION && !isAttachmentTarget && !isMessageDeleted(reportAction) && !isDynamicWorkflowRoutedAction; }, - onPress: (closePopover, {reportAction, reportActions, reportID}) => { - const originalReportID = getOriginalReportID(reportID, reportAction, reportActions); + onPress: (closePopover, {reportAction, originalReportID}) => { getEnvironmentURL().then((environmentURL) => { const reportActionID = reportAction?.reportActionID; Clipboard.setString(`${environmentURL}/r/${originalReportID}/${reportActionID}`);