Skip to content

Commit acfd5bc

Browse files
committed
Fix logic behind displaying expenses help content
1 parent 1b03c82 commit acfd5bc

3 files changed

Lines changed: 41 additions & 28 deletions

File tree

src/components/SidePanel/HelpComponents/HelpContent.tsx

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout';
1414
import useRootNavigationState from '@hooks/useRootNavigationState';
1515
import useThemeStyles from '@hooks/useThemeStyles';
1616
import {normalizedConfigs} from '@libs/Navigation/linkingConfig/config';
17-
import {getOriginalMessage, isMoneyRequestAction} from '@libs/ReportActionsUtils';
17+
import {getOneTransactionThreadReportAction, getOriginalMessage, isMoneyRequestAction} from '@libs/ReportActionsUtils';
1818
import {getHelpPaneReportType} from '@libs/ReportUtils';
1919
import {getExpenseType} from '@libs/TransactionUtils';
2020
import CONST from '@src/CONST';
@@ -43,14 +43,21 @@ function HelpContent({closeSidePanel}: HelpContentProps) {
4343
});
4444

4545
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${params?.reportID || String(CONST.DEFAULT_NUMBER_ID)}`, {canBeMissing: true});
46-
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
47-
const [parentReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID}`, {
48-
canEvict: false,
46+
const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.reportID}`, {canBeMissing: true});
47+
const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`, {canBeMissing: true});
48+
const [parentIOUReportAction] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID}`, {
4949
canBeMissing: true,
50+
selector: (actions) =>
51+
Object.values(actions ?? {})
52+
.filter((action) => action.reportActionID === report?.parentReportActionID)
53+
.at(0),
5054
});
51-
const parentReportAction = report?.parentReportActionID ? parentReportActions?.[report.parentReportActionID] : undefined;
52-
const linkedTransactionID = useMemo(() => (isMoneyRequestAction(parentReportAction) ? getOriginalMessage(parentReportAction)?.IOUTransactionID : undefined), [parentReportAction]);
53-
const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${linkedTransactionID}`, {canBeMissing: true});
55+
56+
const transactionID = useMemo(() => {
57+
const transactionThreadReportAction = getOneTransactionThreadReportAction(report, chatReport, reportActions ?? []);
58+
return getOriginalMessage(isMoneyRequestAction(parentIOUReportAction) ? parentIOUReportAction : transactionThreadReportAction)?.IOUTransactionID;
59+
}, [report, chatReport, reportActions, parentIOUReportAction]);
60+
const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {canBeMissing: true});
5461

5562
const route = useMemo(() => {
5663
const path = normalizedConfigs[routeName]?.path;
@@ -61,13 +68,14 @@ function HelpContent({closeSidePanel}: HelpContentProps) {
6168

6269
const cleanedPath = path.replaceAll('?', '');
6370
const expenseType = getExpenseType(transaction);
64-
65-
if (expenseType) {
71+
const reportType = getHelpPaneReportType(report);
72+
73+
if (expenseType && reportType !== CONST.REPORT.HELP_TYPE.EXPENSE_REPORT) {
6674
return cleanedPath.replaceAll(':reportID', `:${CONST.REPORT.HELP_TYPE.EXPENSE}/:${expenseType}`);
6775
}
6876

69-
if (report) {
70-
return cleanedPath.replaceAll(':reportID', `:${getHelpPaneReportType(report)}`);
77+
if (reportType) {
78+
return cleanedPath.replaceAll(':reportID', `:${reportType}`);
7179
}
7280

7381
return cleanedPath;

src/libs/ReportActionsUtils.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,7 +1198,7 @@ function isTagModificationAction(actionName: string): boolean {
11981198
* Used for Send Money flow, which is a special case where we have no IOU create action and only one IOU pay action.
11991199
* In other reports, pay actions do not count as a transactions, but this is an exception to this rule.
12001200
*/
1201-
function getSendMoneyFlowOneTransactionThreadID(actions: OnyxEntry<ReportActions> | ReportAction[], chatReport: OnyxEntry<Report>) {
1201+
function getSendMoneyFlowOneTransactionReportAction(actions: OnyxEntry<ReportActions> | ReportAction[], chatReport: OnyxEntry<Report>): ReportAction<'IOU'> | undefined {
12021202
if (!chatReport) {
12031203
return undefined;
12041204
}
@@ -1218,7 +1218,7 @@ function getSendMoneyFlowOneTransactionThreadID(actions: OnyxEntry<ReportActions
12181218
// ...and can only be triggered on DM chats
12191219
const isDM = type === CONST.REPORT.TYPE.CHAT && !chatType && !(parentReportID && parentReportActionID);
12201220

1221-
return isFirstActionPay && isDM ? iouActions.at(0)?.childReportID : undefined;
1221+
return isFirstActionPay && isDM ? iouActions.at(0) : undefined;
12221222
}
12231223

12241224
/** Whether action has no linked report by design */
@@ -1256,13 +1256,13 @@ const isIOUActionMatchingTransactionList = (
12561256
* Gets the reportID for the transaction thread associated with a report by iterating over the reportActions and identifying the IOU report actions.
12571257
* Returns a reportID if there is exactly one transaction thread for the report, and null otherwise.
12581258
*/
1259-
function getOneTransactionThreadReportID(
1259+
function getOneTransactionThreadReportAction(
12601260
report: OnyxEntry<Report>,
12611261
chatReport: OnyxEntry<Report>,
12621262
reportActions: OnyxEntry<ReportActions> | ReportAction[],
12631263
isOffline: boolean | undefined = undefined,
12641264
reportTransactionIDs?: string[],
1265-
): string | undefined {
1265+
): ReportAction<'IOU'> | undefined {
12661266
// If the report is not an IOU, Expense report, or Invoice, it shouldn't be treated as one-transaction report.
12671267
if (report?.type !== CONST.REPORT.TYPE.IOU && report?.type !== CONST.REPORT.TYPE.EXPENSE && report?.type !== CONST.REPORT.TYPE.INVOICE) {
12681268
return;
@@ -1273,10 +1273,10 @@ function getOneTransactionThreadReportID(
12731273
return;
12741274
}
12751275

1276-
const sendMoneyFlowID = getSendMoneyFlowOneTransactionThreadID(reportActions, chatReport);
1276+
const sendMoneyFlow = getSendMoneyFlowOneTransactionReportAction(reportActions, chatReport);
12771277

1278-
if (sendMoneyFlowID) {
1279-
return sendMoneyFlowID;
1278+
if (sendMoneyFlow?.childReportID) {
1279+
return sendMoneyFlow;
12801280
}
12811281

12821282
const iouRequestActions = [];
@@ -1322,7 +1322,11 @@ function getOneTransactionThreadReportID(
13221322
}
13231323

13241324
// Ensure we have a childReportID associated with the IOU report action
1325-
return singleAction?.childReportID;
1325+
return singleAction;
1326+
}
1327+
1328+
function getOneTransactionThreadReportID(...args: Parameters<typeof getOneTransactionThreadReportAction>): string | undefined {
1329+
return getOneTransactionThreadReportAction(...args)?.childReportID;
13261330
}
13271331

13281332
/**
@@ -2968,6 +2972,7 @@ export {
29682972
getMessageOfOldDotReportAction,
29692973
getMostRecentIOURequestActionID,
29702974
getNumberOfMoneyRequests,
2975+
getOneTransactionThreadReportAction,
29712976
getOneTransactionThreadReportID,
29722977
getOriginalMessage,
29732978
getAddedApprovalRuleMessage,
@@ -3091,7 +3096,7 @@ export {
30913096
getWorkspaceDescriptionUpdatedMessage,
30923097
getWorkspaceReportFieldAddMessage,
30933098
getWorkspaceCustomUnitRateAddedMessage,
3094-
getSendMoneyFlowOneTransactionThreadID,
3099+
getSendMoneyFlowOneTransactionReportAction,
30953100
getWorkspaceTagUpdateMessage,
30963101
getWorkspaceReportFieldUpdateMessage,
30973102
getWorkspaceReportFieldDeleteMessage,

tests/unit/ReportActionsUtilsTest.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {actionR14932 as mockIOUAction, originalMessageR14932 as mockOriginalMess
66
import {chatReportR14932 as mockChatReport, iouReportR14932 as mockIOUReport} from '../../__mocks__/reportData/reports';
77
import CONST from '../../src/CONST';
88
import * as ReportActionsUtils from '../../src/libs/ReportActionsUtils';
9-
import {getOneTransactionThreadReportID, getOriginalMessage, getSendMoneyFlowOneTransactionThreadID, isIOUActionMatchingTransactionList} from '../../src/libs/ReportActionsUtils';
9+
import {getOneTransactionThreadReportID, getOriginalMessage, getSendMoneyFlowOneTransactionReportAction, isIOUActionMatchingTransactionList} from '../../src/libs/ReportActionsUtils';
1010
import ONYXKEYS from '../../src/ONYXKEYS';
1111
import type {Report, ReportAction} from '../../src/types/onyx';
1212
import {createRandomReport} from '../utils/collections/reports';
@@ -856,7 +856,7 @@ describe('ReportActionsUtils', () => {
856856
});
857857
});
858858

859-
describe('getSendMoneyFlowOneTransactionThreadID', () => {
859+
describe('getSendMoneyFlowOneTransactionReportAction', () => {
860860
const mockChatReportID = `${ONYXKEYS.COLLECTION.REPORT}REPORT` as const;
861861
const mockDMChatReportID = `${ONYXKEYS.COLLECTION.REPORT}REPORT_DM` as const;
862862
const childReportID = `${ONYXKEYS.COLLECTION.REPORT}childReport123` as const;
@@ -891,27 +891,27 @@ describe('ReportActionsUtils', () => {
891891
};
892892

893893
it('should return undefined for a single non-IOU action', () => {
894-
expect(getSendMoneyFlowOneTransactionThreadID([nonIOUAction], mockedReports[mockDMChatReportID])).toBeUndefined();
894+
expect(getSendMoneyFlowOneTransactionReportAction([nonIOUAction], mockedReports[mockDMChatReportID])?.childReportID).toBeUndefined();
895895
});
896896

897897
it('should return undefined for multiple IOU actions regardless of type', () => {
898-
expect(getSendMoneyFlowOneTransactionThreadID([payAction, payAction], mockedReports[mockDMChatReportID])).toBeUndefined();
898+
expect(getSendMoneyFlowOneTransactionReportAction([payAction, payAction], mockedReports[mockDMChatReportID])?.childReportID).toBeUndefined();
899899
});
900900

901901
it('should return undefined for a single IOU action that is not `Pay`', () => {
902-
expect(getSendMoneyFlowOneTransactionThreadID([createAction], mockedReports[mockDMChatReportID])).toBeUndefined();
902+
expect(getSendMoneyFlowOneTransactionReportAction([createAction], mockedReports[mockDMChatReportID])?.childReportID).toBeUndefined();
903903
});
904904

905905
it('should return the appropriate childReportID for a valid single `Pay` IOU action in DM chat', () => {
906-
expect(getSendMoneyFlowOneTransactionThreadID([payAction], mockedReports[mockDMChatReportID])).toEqual(childReportID);
906+
expect(getSendMoneyFlowOneTransactionReportAction([payAction], mockedReports[mockDMChatReportID])?.childReportID).toEqual(childReportID);
907907
});
908908

909909
it('should return undefined for a valid single `Pay` IOU action in a chat that is not DM', () => {
910-
expect(getSendMoneyFlowOneTransactionThreadID([payAction], mockedReports[mockChatReportID])).toBeUndefined();
910+
expect(getSendMoneyFlowOneTransactionReportAction([payAction], mockedReports[mockChatReportID])?.childReportID).toBeUndefined();
911911
});
912912

913913
it('should return undefined for a valid `Pay` IOU action in DM chat that has also a create IOU action', () => {
914-
expect(getSendMoneyFlowOneTransactionThreadID([payAction, createAction], mockedReports[mockDMChatReportID])).toBeUndefined();
914+
expect(getSendMoneyFlowOneTransactionReportAction([payAction, createAction], mockedReports[mockDMChatReportID])?.childReportID).toBeUndefined();
915915
});
916916
});
917917

0 commit comments

Comments
 (0)