From 0ec956a70c68785b6f9c998cb067912e75b135d0 Mon Sep 17 00:00:00 2001 From: Pavlo Tsimura Date: Thu, 11 Apr 2024 08:30:51 +0200 Subject: [PATCH 1/2] Fix: treat only Expense and IOU reports as one-transaction ones --- src/libs/ReportActionsUtils.ts | 8 +++++++- src/libs/ReportUtils.ts | 6 +++--- src/pages/home/ReportScreen.tsx | 13 ++++++------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index b09f58b969f0..504bbba5d964 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -216,7 +216,13 @@ function isTransactionThread(parentReportAction: OnyxEntry | Empty /** * Returns the reportID for the transaction thread associated with a report by iterating over the reportActions and identifying the IOU report actions with a childReportID. Returns a reportID if there is exactly one transaction thread for the report, and null otherwise. */ -function getOneTransactionThreadReportID(reportActions: OnyxEntry | ReportAction[]): string | null { +function getOneTransactionThreadReportID(reportID: string, reportActions: OnyxEntry | ReportAction[]): string | null { + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + if (report?.type !== CONST.REPORT.TYPE.IOU && report?.type !== CONST.REPORT.TYPE.EXPENSE) { + // If the report is not an IOU or Expense report, it shouldn't be treated as one-transaction report. + return null; + } + const reportActionsArray = Object.values(reportActions ?? {}); if (!reportActionsArray.length) { diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 85f5c414dbe4..e49c2f25ccc4 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1305,7 +1305,7 @@ function isMoneyRequestReport(reportOrID: OnyxEntry | EmptyObject | stri */ function isOneTransactionReport(reportID: string): boolean { const reportActions = reportActionsByReport?.[reportID] ?? ([] as ReportAction[]); - return ReportActionsUtils.getOneTransactionThreadReportID(reportActions) !== null; + return ReportActionsUtils.getOneTransactionThreadReportID(reportID, reportActions) !== null; } /** @@ -1313,7 +1313,7 @@ function isOneTransactionReport(reportID: string): boolean { */ function isOneTransactionThread(reportID: string, parentReportID: string): boolean { const parentReportActions = reportActionsByReport?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`] ?? ([] as ReportAction[]); - const transactionThreadReportID = ReportActionsUtils.getOneTransactionThreadReportID(parentReportActions); + const transactionThreadReportID = ReportActionsUtils.getOneTransactionThreadReportID(parentReportID, parentReportActions); return reportID === transactionThreadReportID; } @@ -5014,7 +5014,7 @@ function canUserPerformWriteAction(report: OnyxEntry) { function getOriginalReportID(reportID: string, reportAction: OnyxEntry): string | undefined { const reportActions = reportActionsByReport?.[reportID]; const currentReportAction = reportActions?.[reportAction?.reportActionID ?? ''] ?? null; - const transactionThreadReportID = ReportActionsUtils.getOneTransactionThreadReportID(reportActions ?? ([] as ReportAction[])); + const transactionThreadReportID = ReportActionsUtils.getOneTransactionThreadReportID(reportID, reportActions ?? ([] as ReportAction[])); if (transactionThreadReportID !== null) { return Object.keys(currentReportAction ?? {}).length === 0 ? transactionThreadReportID : reportID; } diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 8b9a057d4e93..b93daf4f097b 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -2,10 +2,10 @@ import {useIsFocused} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; import lodashIsEqual from 'lodash/isEqual'; import React, {memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react'; -import {InteractionManager, View} from 'react-native'; import type {FlatList, ViewStyle} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; +import {InteractionManager, View} from 'react-native'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; import type {LayoutChangeEvent} from 'react-native/Libraries/Types/CoreEventTypes'; import Banner from '@components/Banner'; import BlockingView from '@components/BlockingViews/BlockingView'; @@ -18,8 +18,8 @@ import OfflineWithFeedback from '@components/OfflineWithFeedback'; import ReportActionsSkeletonView from '@components/ReportActionsSkeletonView'; import ScreenWrapper from '@components/ScreenWrapper'; import TaskHeaderActionButton from '@components/TaskHeaderActionButton'; -import withCurrentReportID from '@components/withCurrentReportID'; import type {CurrentReportIDContextValue} from '@components/withCurrentReportID'; +import withCurrentReportID from '@components/withCurrentReportID'; import useAppFocusEvent from '@hooks/useAppFocusEvent'; import useLocalize from '@hooks/useLocalize'; import usePrevious from '@hooks/usePrevious'; @@ -47,8 +47,8 @@ import {isEmptyObject} from '@src/types/utils/EmptyObject'; import HeaderView from './HeaderView'; import ReportActionsView from './report/ReportActionsView'; import ReportFooter from './report/ReportFooter'; -import {ActionListContext, ReactionListContext} from './ReportScreenContext'; import type {ActionListContextType, ReactionListRef, ScrollPosition} from './ReportScreenContext'; +import {ActionListContext, ReactionListContext} from './ReportScreenContext'; type ReportScreenOnyxPropsWithoutParentReportAction = { /** Get modal status */ @@ -253,8 +253,7 @@ function ReportScreen({ if (!sortedAllReportActions.length) { return []; } - const currentRangeOfReportActions = ReportActionsUtils.getContinuousReportActionChain(sortedAllReportActions, reportActionIDFromRoute); - return currentRangeOfReportActions; + return ReportActionsUtils.getContinuousReportActionChain(sortedAllReportActions, reportActionIDFromRoute); }, [reportActionIDFromRoute, sortedAllReportActions]); // Define here because reportActions are recalculated before mount, allowing data to display faster than useEffect can trigger. @@ -333,7 +332,7 @@ function ReportScreen({ ); } - const transactionThreadReportID = useMemo(() => ReportActionsUtils.getOneTransactionThreadReportID(reportActions ?? []), [reportActions]); + const transactionThreadReportID = useMemo(() => ReportActionsUtils.getOneTransactionThreadReportID(report.reportID, reportActions ?? []), [report.reportID, reportActions]); if (ReportUtils.isMoneyRequestReport(report)) { headerView = ( Date: Thu, 11 Apr 2024 11:03:37 +0200 Subject: [PATCH 2/2] Move the comment Co-authored-by: Monil Bhavsar --- src/libs/ReportActionsUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 504bbba5d964..135e9eece17d 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -217,9 +217,9 @@ function isTransactionThread(parentReportAction: OnyxEntry | Empty * Returns the reportID for the transaction thread associated with a report by iterating over the reportActions and identifying the IOU report actions with a childReportID. Returns a reportID if there is exactly one transaction thread for the report, and null otherwise. */ function getOneTransactionThreadReportID(reportID: string, reportActions: OnyxEntry | ReportAction[]): string | null { + // If the report is not an IOU or Expense report, it shouldn't be treated as one-transaction report. const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (report?.type !== CONST.REPORT.TYPE.IOU && report?.type !== CONST.REPORT.TYPE.EXPENSE) { - // If the report is not an IOU or Expense report, it shouldn't be treated as one-transaction report. return null; }