Skip to content

Commit ec619e1

Browse files
authored
Merge pull request #97785 from hoangzinh/refactor/reportnameutils-onyxconnect-76425
Remove Onyx.connect() for the key: ONYXKEYS.PERSONAL_DETAILS_LIST in src/libs/ReportNameUtils.ts
2 parents b92c6f9 + a6c5b6e commit ec619e1

6 files changed

Lines changed: 120 additions & 44 deletions

File tree

‎src/components/ReportActionItem/MoneyRequestReportPreview/usePreviewMessageAnimation.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ function usePreviewMessageAnimation({
122122
if (isPolicyExpenseChat || isTripRoom) {
123123
payerOrApproverName = getPolicyName({report: chatReport, policy, unavailableTranslation: translate('workspace.common.unavailable')});
124124
} else if (isInvoiceRoom) {
125-
payerOrApproverName = getInvoicePayerName(chatReport, translate, invoiceReceiverPolicy, invoiceReceiverPersonalDetail);
125+
payerOrApproverName = getInvoicePayerName(chatReport, translate, invoiceReceiverPersonalDetail, invoiceReceiverPolicy);
126126
} else {
127127
payerOrApproverName = getDisplayNameForParticipant({
128128
accountID: managerID,

‎src/libs/ReportNameUtils.ts‎

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
2323
* This file contains utility functions for managing and computing report names
2424
*/
2525
import {Str} from 'expensify-common';
26-
import Onyx from 'react-native-onyx';
2726

2827
import {getAddAgentRuleMessage, getDeleteAgentRuleMessage, getUpdateAgentRuleMessage} from './AgentRuleChangeLogUtils';
2928
import {convertToDisplayString} from './CurrencyUtils';
@@ -133,6 +132,7 @@ import {
133132
import {
134133
formatReportLastMessageText,
135134
getDisplayNameForParticipant,
135+
getInvoiceReceiverPersonalDetail,
136136
getMoneyRequestSpendBreakdown,
137137
getMovedActionMessage,
138138
getMovedTransactionMessage,
@@ -195,16 +195,6 @@ type ComputeReportName = {
195195
pendingDeleteMemberAccountIDs?: string[];
196196
};
197197

198-
let allPersonalDetails: OnyxEntry<PersonalDetailsList>;
199-
200-
// eslint-disable-next-line rulesdir/no-onyx-connect -- allPersonalDetails is used by the deprecated getReportName function; will be removed as part of the Onyx.connect migration
201-
Onyx.connect({
202-
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
203-
callback: (value) => {
204-
allPersonalDetails = value;
205-
},
206-
});
207-
208198
function generateArchivedReportName(reportName: string): string {
209199
return `${reportName} (${translateLocal('common.archived')}) `;
210200
}
@@ -346,7 +336,7 @@ function getInvoicesChatName({
346336
}: {
347337
report: OnyxEntry<Report>;
348338
receiverPolicy: OnyxEntry<Policy>;
349-
personalDetails?: Partial<PersonalDetailsList>;
339+
personalDetails: Partial<PersonalDetailsList> | undefined;
350340
policy: OnyxEntry<Policy>;
351341
currentUserAccountID?: number;
352342
translate: LocalizedTranslate;
@@ -361,14 +351,20 @@ function getInvoicesChatName({
361351
}
362352

363353
if (isIndividual) {
364-
return formatPhoneNumberPhoneUtils(temporaryGetDisplayNameOrDefault({passedPersonalDetails: (personalDetails ?? allPersonalDetails)?.[invoiceReceiverAccountID], translate}));
354+
return formatPhoneNumberPhoneUtils(temporaryGetDisplayNameOrDefault({passedPersonalDetails: personalDetails?.[invoiceReceiverAccountID], translate}));
365355
}
366356

367357
return getPolicyName({report, policy: receiverPolicy, unavailableTranslation: translate('workspace.common.unavailable')});
368358
}
369359

370-
function getInvoiceReportName(report: OnyxEntry<Report>, translate: LocalizedTranslate, policy?: OnyxEntry<Policy>, invoiceReceiverPolicy?: OnyxEntry<Policy>): string {
371-
const moneyRequestReportName = getMoneyRequestReportName({report, policy, invoiceReceiverPolicy, translate});
360+
function getInvoiceReportName(
361+
report: OnyxEntry<Report>,
362+
translate: LocalizedTranslate,
363+
personalDetailsList: OnyxEntry<PersonalDetailsList>,
364+
policy?: OnyxEntry<Policy>,
365+
invoiceReceiverPolicy?: OnyxEntry<Policy>,
366+
): string {
367+
const moneyRequestReportName = getMoneyRequestReportName({report, policy, invoiceReceiverPolicy, personalDetailsList, translate});
372368
const oldDotInvoiceName = report?.reportName ?? moneyRequestReportName;
373369
return isNewDotInvoice(report?.chatReportID) ? moneyRequestReportName : oldDotInvoiceName;
374370
}
@@ -381,15 +377,14 @@ function getInvoiceReportName(report: OnyxEntry<Report>, translate: LocalizedTra
381377
function getInvoicePayerName(
382378
report: OnyxEntry<Report>,
383379
translate: LocalizedTranslate,
380+
invoiceReceiverPersonalDetail: OnyxEntry<PersonalDetails> | null,
384381
invoiceReceiverPolicy?: OnyxEntry<Policy>,
385-
invoiceReceiverPersonalDetail?: PersonalDetails | null,
386382
): string {
387383
const invoiceReceiver = report?.invoiceReceiver;
388384
const isIndividual = invoiceReceiver?.type === CONST.REPORT.INVOICE_RECEIVER_TYPE.INDIVIDUAL;
389385

390386
if (isIndividual) {
391-
const personalDetail = invoiceReceiverPersonalDetail ?? allPersonalDetails?.[invoiceReceiver.accountID];
392-
return formatPhoneNumberPhoneUtils(temporaryGetDisplayNameOrDefault({passedPersonalDetails: personalDetail ?? undefined, translate}));
387+
return formatPhoneNumberPhoneUtils(temporaryGetDisplayNameOrDefault({passedPersonalDetails: invoiceReceiverPersonalDetail ?? undefined, translate}));
393388
}
394389

395390
return getPolicyName({report, policy: invoiceReceiverPolicy, unavailableTranslation: translate('workspace.common.unavailable')});
@@ -402,11 +397,13 @@ function getMoneyRequestReportName({
402397
report,
403398
policy,
404399
invoiceReceiverPolicy,
400+
personalDetailsList,
405401
translate,
406402
}: {
407403
report: OnyxEntry<Report>;
408404
policy?: OnyxEntry<Policy>;
409405
invoiceReceiverPolicy?: OnyxEntry<Policy>;
406+
personalDetailsList: OnyxEntry<PersonalDetailsList>;
410407
translate: LocalizedTranslate;
411408
}): string {
412409
// For expense reports with empty fieldList and empty reportName, return "New Report" (matches OldDot behavior)
@@ -429,7 +426,8 @@ function getMoneyRequestReportName({
429426
payerOrApproverName = getPolicyName({report: parentReport ?? report, policy, unavailableTranslation: translate('workspace.common.unavailable')});
430427
} else if (isInvoiceReport(report)) {
431428
const chatReport = getReportOrDraftReport(report?.chatReportID);
432-
payerOrApproverName = getInvoicePayerName(chatReport, translate, invoiceReceiverPolicy);
429+
const invoiceReceiverPersonalDetail = getInvoiceReceiverPersonalDetail(chatReport, personalDetailsList);
430+
payerOrApproverName = getInvoicePayerName(chatReport, translate, invoiceReceiverPersonalDetail, invoiceReceiverPolicy);
433431
} else {
434432
payerOrApproverName = getDisplayNameForParticipant({accountID: report?.managerID, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) ?? '';
435433
}
@@ -1087,7 +1085,7 @@ function computeReportName({
10871085

10881086
const policy = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${report.policyID}`];
10891087
if (isMoneyRequestReport(report)) {
1090-
formattedName = getMoneyRequestReportName({report, policy, translate});
1088+
formattedName = getMoneyRequestReportName({report, policy, personalDetailsList, translate});
10911089
}
10921090

10931091
if (isInvoiceReport(report)) {
@@ -1098,7 +1096,7 @@ function computeReportName({
10981096
chatReceiverPolicyID = (chatReceiver as {policyID: string}).policyID;
10991097
}
11001098
const invoiceReceiverPolicy = chatReceiverPolicyID ? policies?.[`${ONYXKEYS.COLLECTION.POLICY}${chatReceiverPolicyID}`] : undefined;
1101-
formattedName = getInvoiceReportName(report, translate, policy, invoiceReceiverPolicy);
1099+
formattedName = getInvoiceReportName(report, translate, personalDetailsList, policy, invoiceReceiverPolicy);
11021100
}
11031101

11041102
if (isInvoiceRoom(report)) {

‎src/libs/ReportUtils.ts‎

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,6 +1713,14 @@ function getInvoiceReceiverPolicyID(report: OnyxEntry<Report>): string | undefin
17131713
return report?.invoiceReceiver?.type === CONST.REPORT.INVOICE_RECEIVER_TYPE.BUSINESS ? report.invoiceReceiver.policyID : undefined;
17141714
}
17151715

1716+
/**
1717+
* Returns the personal details of the invoice receiver when the receiver is an individual, otherwise undefined.
1718+
*/
1719+
function getInvoiceReceiverPersonalDetail(report: OnyxEntry<Report>, personalDetailsList: OnyxEntry<PersonalDetailsList>): OnyxEntry<PersonalDetails> | null {
1720+
const invoiceReceiver = report?.invoiceReceiver;
1721+
return invoiceReceiver?.type === CONST.REPORT.INVOICE_RECEIVER_TYPE.INDIVIDUAL ? personalDetailsList?.[invoiceReceiver.accountID] : undefined;
1722+
}
1723+
17161724
// TODO: currentUserAccountID will be required eventually so this becomes a pure function. Subscribe the data via useOnyx and pass it from the component. Refactor issue: https://github.com/Expensify/App/issues/66412
17171725
function isCurrentUserInvoiceReceiver(report: OnyxEntry<Report>, currentUserAccountID?: number): boolean {
17181726
if (report?.invoiceReceiver?.type === CONST.REPORT.INVOICE_RECEIVER_TYPE.INDIVIDUAL) {
@@ -6412,7 +6420,8 @@ function getParentNavigationSubtitle(
64126420
const invoiceReceiverPolicyID = getInvoiceReceiverPolicyID(parentReport);
64136421
const invoiceReceiverPolicy = invoiceReceiverPolicyID ? allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${invoiceReceiverPolicyID}`] : undefined;
64146422
const isCurrentUserReceiver = isCurrentUserInvoiceReceiver(parentReport);
6415-
const invoicePayerName = getInvoicePayerName(parentReport, translate, invoiceReceiverPolicy);
6423+
const invoiceReceiverPersonalDetail = getInvoiceReceiverPersonalDetail(parentReport, allPersonalDetails);
6424+
const invoicePayerName = getInvoicePayerName(parentReport, translate, invoiceReceiverPersonalDetail, invoiceReceiverPolicy);
64166425

64176426
let reportName = senderWorkspaceName;
64186427
if (!isCurrentUserReceiver && invoicePayerName) {
@@ -13190,13 +13199,19 @@ function isWaitingForSubmissionFromCurrentUser(chatReport: OnyxEntry<Report>, po
1319013199
return chatReport?.isOwnPolicyExpenseChat && !policy?.harvesting?.enabled;
1319113200
}
1319213201

13193-
function getChatListItemReportName(action: ReportAction & {reportName?: string}, report: Report | undefined, conciergeReportID: string | undefined, translate: LocalizedTranslate): string {
13202+
function getChatListItemReportName(
13203+
action: ReportAction & {reportName?: string},
13204+
report: Report | undefined,
13205+
conciergeReportID: string | undefined,
13206+
translate: LocalizedTranslate,
13207+
personalDetailsList: OnyxEntry<PersonalDetailsList>,
13208+
): string {
1319413209
const reportForHeader = getReportForHeader(report);
1319513210
if (reportForHeader && isInvoiceReport(reportForHeader)) {
1319613211
// Search snapshots of invoice reports may only carry `parentReportID` as the invoice room ID, so fall back to it
1319713212
// when `chatReportID` is missing (without mutating the Onyx report) so `getInvoiceReportName` resolves the NewDot title.
1319813213
const invoiceReport = reportForHeader.chatReportID ? reportForHeader : {...reportForHeader, chatReportID: reportForHeader.parentReportID};
13199-
return getInvoiceReportName(invoiceReport, translate);
13214+
return getInvoiceReportName(invoiceReport, translate, personalDetailsList);
1320013215
}
1320113216

1320213217
if (action?.reportName) {
@@ -13996,6 +14011,7 @@ export {
1399614011
getAvailableReportFields,
1399714012
getBankAccountRoute,
1399814013
getInvoiceReceiverPolicyID,
14014+
getInvoiceReceiverPersonalDetail,
1399914015
getChatByParticipants,
1400014016
getChatRoomSubtitle,
1400114017
getChildReportNotificationPreference,

‎src/pages/inbox/report/SearchActionHeader.tsx‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import {usePersonalDetails} from '@components/OnyxListItemProvider';
12
import {useIsOnSearch} from '@components/Search/SearchScopeProvider';
23
import Text from '@components/Text';
34
import TextLink from '@components/TextLink';
@@ -35,8 +36,9 @@ function SearchActionHeaderContent({action, report, isWhisper, onPress, children
3536
const styles = useThemeStyles();
3637
const {translate} = useLocalize();
3738
const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
39+
const personalDetailsList = usePersonalDetails();
3840

39-
const reportName = getChatListItemReportName(action, report, conciergeReportID, translate);
41+
const reportName = getChatListItemReportName(action, report, conciergeReportID, translate, personalDetailsList);
4042

4143
return (
4244
<View style={[styles.p4]}>

‎tests/unit/ReportNameUtilsTest.ts‎

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,12 +1234,12 @@ describe('ReportNameUtils', () => {
12341234
expect(normalizedName).toBe('Ragnar Lothbrok');
12351235
});
12361236

1237-
test('Invoice payer name falls back to provided personal details', () => {
1237+
test('Invoice payer name resolves the receiver from the passed personal detail', () => {
12381238
const report: Report = {
12391239
reportID: 'invoice-chat-3',
12401240
invoiceReceiver: {type: CONST.REPORT.INVOICE_RECEIVER_TYPE.INDIVIDUAL, accountID: 1},
12411241
};
1242-
const name = getInvoicePayerName(report, translateLocal, undefined, null);
1242+
const name = getInvoicePayerName(report, translateLocal, participantsPersonalDetails['1']);
12431243

12441244
const normalizedName = name?.replaceAll('\u00A0', ' ');
12451245
expect(normalizedName).toBe('Ragnar Lothbrok');
@@ -1271,7 +1271,7 @@ describe('ReportNameUtils', () => {
12711271
invoiceReceiver: {type: CONST.REPORT.INVOICE_RECEIVER_TYPE.INDIVIDUAL, accountID: 424242},
12721272
};
12731273

1274-
const name = getInvoicePayerName(report, translateWithHiddenMarker, undefined, null);
1274+
const name = getInvoicePayerName(report, translateWithHiddenMarker, null);
12751275

12761276
expect(name).toBe('HiddenMarker');
12771277
});
@@ -1327,7 +1327,7 @@ describe('ReportNameUtils', () => {
13271327
invoiceReceiver: {type: CONST.REPORT.INVOICE_RECEIVER_TYPE.BUSINESS, policyID: 'missing-policy'},
13281328
};
13291329

1330-
const name = getInvoicePayerName(report, translateWithUnavailableMarker, undefined, null);
1330+
const name = getInvoicePayerName(report, translateWithUnavailableMarker, null);
13311331

13321332
expect(name).toBe('UnavailableMarker');
13331333
});
@@ -1546,10 +1546,33 @@ describe('ReportNameUtils', () => {
15461546
};
15471547
const translateWithHiddenMarker: LocalizedTranslate = (path, ...parameters) => (path === 'common.hidden' ? 'HiddenMarker' : translateLocal(path, ...parameters));
15481548

1549-
const reportName = getMoneyRequestReportName({report: iouReport, translate: translateWithHiddenMarker});
1549+
const reportName = getMoneyRequestReportName({report: iouReport, personalDetailsList: undefined, translate: translateWithHiddenMarker});
15501550
expect(reportName).toContain('HiddenMarker');
15511551
});
15521552

1553+
it('resolves the invoice payer name from the provided personal details list', async () => {
1554+
const chatReportID = '990001';
1555+
// The chat report's invoice receiver is an individual (accountID 1 = "Ragnar Lothbrok" in the list).
1556+
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`, {
1557+
reportID: chatReportID,
1558+
chatType: CONST.REPORT.CHAT_TYPE.INVOICE,
1559+
invoiceReceiver: {type: CONST.REPORT.INVOICE_RECEIVER_TYPE.INDIVIDUAL, accountID: 1},
1560+
});
1561+
await waitForBatchedUpdates();
1562+
1563+
const invoiceReport: Report = {
1564+
reportID: '990002',
1565+
type: CONST.REPORT.TYPE.INVOICE,
1566+
chatReportID,
1567+
ownerAccountID: currentUserAccountID,
1568+
total: 100,
1569+
currency: 'USD',
1570+
};
1571+
1572+
const reportName = getMoneyRequestReportName({report: invoiceReport, personalDetailsList: participantsPersonalDetails, translate: translateLocal});
1573+
expect(reportName?.replaceAll(/\s+/g, ' ')).toContain('Ragnar Lothbrok');
1574+
});
1575+
15531576
it('should return "New Report" when reportName is empty string, report is expense report, and policy has empty fieldList', () => {
15541577
// Given an expense report with empty reportName
15551578
const expenseReport: Report = {
@@ -1570,7 +1593,7 @@ describe('ReportNameUtils', () => {
15701593
};
15711594

15721595
// When we get the money request report name
1573-
const reportName = getMoneyRequestReportName({report: expenseReport, policy: policyWithEmptyFieldList, translate: translateLocal});
1596+
const reportName = getMoneyRequestReportName({report: expenseReport, policy: policyWithEmptyFieldList, personalDetailsList: undefined, translate: translateLocal});
15741597

15751598
// Then it should return "New Report"
15761599
expect(reportName).toBe(CONST.REPORT.DEFAULT_EXPENSE_REPORT_NAME);
@@ -1612,7 +1635,7 @@ describe('ReportNameUtils', () => {
16121635
};
16131636

16141637
// When we get the money request report name
1615-
const reportName = getMoneyRequestReportName({report: expenseReport, policy: policyWithFieldList, translate: translateLocal});
1638+
const reportName = getMoneyRequestReportName({report: expenseReport, policy: policyWithFieldList, personalDetailsList: undefined, translate: translateLocal});
16161639

16171640
// Then it should NOT return empty string — it should fall through to dynamic name computation
16181641
expect(reportName).not.toBe('');
@@ -1662,7 +1685,7 @@ describe('ReportNameUtils', () => {
16621685
const translateWithUnavailableMarker: LocalizedTranslate = (path, ...parameters) =>
16631686
path === 'workspace.common.unavailable' ? 'UnavailableWorkspaceMarker' : translateLocal(path, ...parameters);
16641687

1665-
const reportName = getMoneyRequestReportName({report: expenseReport, policy: policyWithoutName, translate: translateWithUnavailableMarker});
1688+
const reportName = getMoneyRequestReportName({report: expenseReport, policy: policyWithoutName, personalDetailsList: undefined, translate: translateWithUnavailableMarker});
16661689

16671690
expect(reportName).toContain('UnavailableWorkspaceMarker');
16681691
});

0 commit comments

Comments
 (0)