diff --git a/src/libs/IOUAmountSubmission.ts b/src/libs/IOUAmountSubmission.ts index c9fec5ad3ddf..312f7057c0da 100644 --- a/src/libs/IOUAmountSubmission.ts +++ b/src/libs/IOUAmountSubmission.ts @@ -228,7 +228,17 @@ function buildReportParticipants(args: SubmitAmountArgs) { const privateIsArchived = !!allReportNVPs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${participant.reportID}`]?.private_isArchived; return participantAccountID ? getParticipantsOption(participant, allPersonalDetails, translate) - : getReportOption(participant, privateIsArchived, policy, allPersonalDetails, conciergeReportID, reportAttributesReports, reportDraft, currentUserPersonalDetails.accountID); + : getReportOption( + participant, + privateIsArchived, + policy, + allPersonalDetails, + conciergeReportID, + reportAttributesReports, + reportDraft, + currentUserPersonalDetails.accountID, + translate, + ); }); } diff --git a/src/libs/OptionsListUtils/index.ts b/src/libs/OptionsListUtils/index.ts index c24d640dc3e1..15038ea0db00 100644 --- a/src/libs/OptionsListUtils/index.ts +++ b/src/libs/OptionsListUtils/index.ts @@ -1270,8 +1270,8 @@ function getReportOption( reportAttributesDerived: ReportAttributesDerivedValue['reports'] | undefined, reportDraft: OnyxEntry, currentUserAccountID: number, + translate: LocalizedTranslate, policyTags?: OnyxCollection, - visibleReportActionsData: VisibleReportActionsDerivedValue = {}, ): OptionData { const report = getReportOrDraftReport(participant.reportID, undefined, undefined, reportDraft); const visibleParticipantAccountIDs = getParticipantsAccountIDsForDisplay(report, true); @@ -1289,20 +1289,20 @@ function getReportOption( }, reportAttributesDerived, policyTags: reportPolicyTags, - visibleReportActionsData, + visibleReportActionsData: {}, conciergeReportID, currentUserAccountID, }); // Update text & alternateText because createOption returns workspace name only if report is owned by the user if (option.isSelfDM) { - option.alternateText = translateLocal('reportActionsView.yourSpace'); + option.alternateText = translate('reportActionsView.yourSpace'); } else if (option.isInvoiceRoom) { option.text = deprecatedGetReportName(report, reportAttributesDerived); - option.alternateText = translateLocal('workspace.common.invoices'); + option.alternateText = translate('workspace.common.invoices'); } else { - option.text = getPolicyName({report, policy}); - option.alternateText = translateLocal('workspace.common.workspace'); + option.text = getPolicyName({report, policy, unavailableTranslation: translate('workspace.common.unavailable')}); + option.alternateText = translate('workspace.common.workspace'); if (report?.policyID) { const submitToAccountID = getSubmitToAccountID(policy, report, getLoginByAccountID(report?.ownerAccountID, personalDetails)); @@ -1310,7 +1310,7 @@ function getReportOption( const subtitle = submitsToAccountDetails?.displayName ?? submitsToAccountDetails?.login; if (subtitle) { - option.alternateText = translateLocal('iou.submitsTo', subtitle ?? ''); + option.alternateText = translate('iou.submitsTo', subtitle ?? ''); } } } @@ -1330,6 +1330,7 @@ function getReportDisplayOption( personalDetails: OnyxEntry, privateIsArchived: boolean | undefined, policy: OnyxEntry, + translate: LocalizedTranslate, reportAttributesDerived?: ReportAttributesDerivedValue['reports'], policyTags?: OnyxEntry, visibleReportActionsData: VisibleReportActionsDerivedValue = {}, @@ -1353,17 +1354,17 @@ function getReportDisplayOption( // Update text & alternateText because createOption returns workspace name only if report is owned by the user if (option.isSelfDM) { - option.alternateText = translateLocal('reportActionsView.yourSpace'); + option.alternateText = translate('reportActionsView.yourSpace'); } else if (option.isInvoiceRoom) { option.text = deprecatedGetReportName(report, reportAttributesDerived); - option.alternateText = translateLocal('workspace.common.invoices'); + option.alternateText = translate('workspace.common.invoices'); } else if (unknownUserDetails) { option.text = unknownUserDetails.text ?? unknownUserDetails.login; option.alternateText = unknownUserDetails.login; option.participantsList = [{...unknownUserDetails, displayName: unknownUserDetails.login, accountID: unknownUserDetails.accountID ?? CONST.DEFAULT_NUMBER_ID}]; } else if (report?.ownerAccountID !== 0 || !option.text) { - option.text = getPolicyName({report, policy}); - option.alternateText = translateLocal('workspace.common.workspace'); + option.text = getPolicyName({report, policy, unavailableTranslation: translate('workspace.common.unavailable')}); + option.alternateText = translate('workspace.common.workspace'); } option.isDisabled = true; option.isSelected = false; @@ -1380,6 +1381,7 @@ function getPolicyExpenseReportOption( personalDetails: OnyxEntry, expenseReport: OnyxEntry, policy: OnyxEntry, + translate: LocalizedTranslate, reportAttributesDerived?: ReportAttributesDerivedValue['reports'], policyTags?: OnyxEntry, visibleReportActionsData: VisibleReportActionsDerivedValue = {}, @@ -1404,8 +1406,8 @@ function getPolicyExpenseReportOption( }); // Update text & alternateText because createOption returns workspace name only if report is owned by the user - option.text = getPolicyName({report: expenseReport, policy}); - option.alternateText = translateLocal('workspace.common.workspace'); + option.text = getPolicyName({report: expenseReport, policy, unavailableTranslation: translate('workspace.common.unavailable')}); + option.alternateText = translate('workspace.common.workspace'); option.isSelected = participant.selected; option.selected = participant.selected; // Keep for backwards compatibility return option; @@ -3160,7 +3162,7 @@ function formatSectionsFromSearchTerm( const expenseReport = getReportByID(participant.reportID); const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${expenseReport?.reportID}`]; const expenseReportPolicy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${expenseReport?.policyID}`]; - return getPolicyExpenseReportOption(participant, privateIsArchived, personalDetails, expenseReport, expenseReportPolicy, reportAttributesDerived); + return getPolicyExpenseReportOption(participant, privateIsArchived, personalDetails, expenseReport, expenseReportPolicy, translate, reportAttributesDerived); } return getParticipantsOption(participant, personalDetails, translate); }) @@ -3192,7 +3194,7 @@ function formatSectionsFromSearchTerm( const expenseReport = getReportByID(participant.reportID); const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${expenseReport?.reportID}`]; const expenseReportPolicy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${expenseReport?.policyID}`]; - return getPolicyExpenseReportOption(participant, privateIsArchived, personalDetails, expenseReport, expenseReportPolicy, reportAttributesDerived); + return getPolicyExpenseReportOption(participant, privateIsArchived, personalDetails, expenseReport, expenseReportPolicy, translate, reportAttributesDerived); } return getParticipantsOption(participant, personalDetails, translate); }) diff --git a/src/libs/actions/IOU/MoneyRequest.ts b/src/libs/actions/IOU/MoneyRequest.ts index e3c3fec5690c..91b95fbb74df 100644 --- a/src/libs/actions/IOU/MoneyRequest.ts +++ b/src/libs/actions/IOU/MoneyRequest.ts @@ -255,7 +255,7 @@ function getMoneyRequestParticipantOptions( const participantAccountID = participant?.accountID ?? CONST.DEFAULT_NUMBER_ID; return participantAccountID ? getParticipantsOption(participant, personalDetails, translate) - : getReportOption(participant, privateIsArchived, policy, personalDetails, conciergeReportID, reportAttributesDerived, reportDraft, currentUserAccountID); + : getReportOption(participant, privateIsArchived, policy, personalDetails, conciergeReportID, reportAttributesDerived, reportDraft, currentUserAccountID, translate); }); } diff --git a/src/pages/Share/ShareDetailsPage.tsx b/src/pages/Share/ShareDetailsPage.tsx index 64e23c563e9f..c75fa7081a0a 100644 --- a/src/pages/Share/ShareDetailsPage.tsx +++ b/src/pages/Share/ShareDetailsPage.tsx @@ -82,8 +82,8 @@ function ShareDetailsPage({route}: ShareDetailsPageProps) { const ancestors = useAncestors(report); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`); const displayReport = useMemo( - () => getReportDisplayOption(report, unknownUserDetails, personalDetails, privateIsArchived, policy, reportAttributesDerived), - [report, unknownUserDetails, personalDetails, privateIsArchived, reportAttributesDerived, policy], + () => getReportDisplayOption(report, unknownUserDetails, personalDetails, privateIsArchived, policy, translate, reportAttributesDerived), + [report, unknownUserDetails, personalDetails, privateIsArchived, reportAttributesDerived, policy, translate], ); const shouldShowAttachment = !isTextShared; diff --git a/src/pages/Share/SubmitDetailsPage.tsx b/src/pages/Share/SubmitDetailsPage.tsx index 095da0bdf8f5..c4f8704f5d46 100644 --- a/src/pages/Share/SubmitDetailsPage.tsx +++ b/src/pages/Share/SubmitDetailsPage.tsx @@ -212,7 +212,17 @@ function SubmitDetailsPage({ const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${participant.reportID}`]; return participant?.accountID ? getParticipantsOption(participant, personalDetails, translate) - : getReportOption(participant, privateIsArchived, policy, personalDetails, conciergeReportID, reportAttributesDerived, reportDraft, currentUserPersonalDetails.accountID); + : getReportOption( + participant, + privateIsArchived, + policy, + personalDetails, + conciergeReportID, + reportAttributesDerived, + reportDraft, + currentUserPersonalDetails.accountID, + translate, + ); }); const isPolicyExpenseChat = participants?.some((participant) => participant.isPolicyExpenseChat); diff --git a/src/pages/iou/DynamicSplitBillDetailsPage.tsx b/src/pages/iou/DynamicSplitBillDetailsPage.tsx index ee0d2e423a87..dfdd2e0cdf0c 100644 --- a/src/pages/iou/DynamicSplitBillDetailsPage.tsx +++ b/src/pages/iou/DynamicSplitBillDetailsPage.tsx @@ -76,7 +76,7 @@ function DynamicSplitBillDetailsPage({report, reportAction}: SplitBillDetailsPag if (isPolicyExpenseChat(report)) { participants = [ getParticipantsOption({accountID: participantAccountIDs.at(0), selected: true, reportID: ''}, personalDetails, translate), - getPolicyExpenseReportOption({...report, selected: true, reportID}, privateIsArchived, personalDetails, report, policy, reportAttributesDerived), + getPolicyExpenseReportOption({...report, selected: true, reportID}, privateIsArchived, personalDetails, report, policy, translate, reportAttributesDerived), ]; } else { participants = participantAccountIDs.map((accountID) => getParticipantsOption({accountID, selected: true, reportID: ''}, personalDetails, translate)); diff --git a/src/pages/iou/request/MoneyRequestAttendeeSelector.tsx b/src/pages/iou/request/MoneyRequestAttendeeSelector.tsx index 2e226d38e7fb..e5a4050eb1a7 100644 --- a/src/pages/iou/request/MoneyRequestAttendeeSelector.tsx +++ b/src/pages/iou/request/MoneyRequestAttendeeSelector.tsx @@ -269,7 +269,15 @@ function MoneyRequestAttendeeSelector({attendees = [], onFinish, onAttendeesAdde const isPolicyExpenseChat = participant?.isPolicyExpenseChat ?? false; const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${userToInviteExpenseReport?.reportID}`]; return isPolicyExpenseChat - ? getPolicyExpenseReportOption(participant, privateIsArchived, personalDetails, userToInviteExpenseReport, userToInviteExpenseReportPolicy, reportAttributesDerived) + ? getPolicyExpenseReportOption( + participant, + privateIsArchived, + personalDetails, + userToInviteExpenseReport, + userToInviteExpenseReportPolicy, + translate, + reportAttributesDerived, + ) : getParticipantsOption(participant, personalDetails, translate); }) as OptionData[], sectionIndex: 3, diff --git a/src/pages/iou/request/ParticipantSearchResults.tsx b/src/pages/iou/request/ParticipantSearchResults.tsx index b3f758c2555e..4cec59a7e776 100644 --- a/src/pages/iou/request/ParticipantSearchResults.tsx +++ b/src/pages/iou/request/ParticipantSearchResults.tsx @@ -369,7 +369,15 @@ function ParticipantSearchResults({ const isPolicyExpenseChat = participant?.isPolicyExpenseChat ?? false; const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${userToInviteExpenseReport?.reportID}`]; return isPolicyExpenseChat - ? getPolicyExpenseReportOption(participant, privateIsArchived, personalDetails, userToInviteExpenseReport, userToInviteExpenseReportPolicy, reportAttributesDerived) + ? getPolicyExpenseReportOption( + participant, + privateIsArchived, + personalDetails, + userToInviteExpenseReport, + userToInviteExpenseReportPolicy, + translate, + reportAttributesDerived, + ) : getParticipantsOption(participant, personalDetails, translate); }), sectionIndex: 5, diff --git a/src/pages/iou/request/step/IOURequestStepAmount.tsx b/src/pages/iou/request/step/IOURequestStepAmount.tsx index ad3b459dbe53..af7e6cd50086 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.tsx +++ b/src/pages/iou/request/step/IOURequestStepAmount.tsx @@ -199,7 +199,17 @@ function IOURequestStepAmount({ const privateIsArchived = !!allReportNVPs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${participant.reportID}`]?.private_isArchived; return participantAccountID ? getParticipantsOption(participant, personalDetails, translate) - : getReportOption(participant, privateIsArchived, policy, personalDetails, conciergeReportID, reportAttributesDerived, reportDraft, currentUserPersonalDetails.accountID); + : getReportOption( + participant, + privateIsArchived, + policy, + personalDetails, + conciergeReportID, + reportAttributesDerived, + reportDraft, + currentUserPersonalDetails.accountID, + translate, + ); }); const participant = participants.at(0); const policyTags = useMoneyRequestPolicyTags({ diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx index f87652e8ad1e..887b973cc64b 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx @@ -293,6 +293,7 @@ function IOURequestStepConfirmation({ reportAttributesDerived, participantReportDraft, currentUserPersonalDetails.accountID, + translate, ); }) ?? [], [ diff --git a/tests/unit/OptionsListUtilsTest.tsx b/tests/unit/OptionsListUtilsTest.tsx index 4c88a27e66bb..9c5b4c108f13 100644 --- a/tests/unit/OptionsListUtilsTest.tsx +++ b/tests/unit/OptionsListUtilsTest.tsx @@ -6340,7 +6340,7 @@ describe('OptionsListUtils', () => { const personalDetails: PersonalDetailsList = PERSONAL_DETAILS; // When we call getReportDisplayOption - const result = getReportDisplayOption(report, undefined, personalDetails, undefined, undefined); + const result = getReportDisplayOption(report, undefined, personalDetails, undefined, undefined, translateLocal); // Then it should return an option with isSelfDM and alternateText set expect(result.isSelfDM).toBe(true); @@ -6360,7 +6360,7 @@ describe('OptionsListUtils', () => { const personalDetails: PersonalDetailsList = PERSONAL_DETAILS; // When we call getReportDisplayOption - const result = getReportDisplayOption(report, undefined, personalDetails, undefined, undefined); + const result = getReportDisplayOption(report, undefined, personalDetails, undefined, undefined, translateLocal); // Then it should return an option with invoice room text and alternateText expect(result.isInvoiceRoom).toBe(true); @@ -6382,7 +6382,7 @@ describe('OptionsListUtils', () => { const personalDetails: PersonalDetailsList = PERSONAL_DETAILS; // When we call getReportDisplayOption - const result = getReportDisplayOption(report, unknownUserDetails, personalDetails, undefined, undefined); + const result = getReportDisplayOption(report, unknownUserDetails, personalDetails, undefined, undefined, translateLocal); // Then it should return an option with unknownUserDetails data expect(result.text).toBe('Unknown User'); @@ -6403,7 +6403,7 @@ describe('OptionsListUtils', () => { const personalDetails: PersonalDetailsList = PERSONAL_DETAILS; // When we call getReportDisplayOption - const result = getReportDisplayOption(report, undefined, personalDetails, undefined, undefined); + const result = getReportDisplayOption(report, undefined, personalDetails, undefined, undefined, translateLocal); // Then it should return an option with workspace name expect(result.text).toBe(POLICY.name); @@ -6432,7 +6432,7 @@ describe('OptionsListUtils', () => { }; // When we call getReportDisplayOption with custom personalDetails - const result = getReportDisplayOption(report, undefined, customPersonalDetails, undefined, undefined); + const result = getReportDisplayOption(report, undefined, customPersonalDetails, undefined, undefined, translateLocal); // Then it should use the custom personalDetails parameter expect(result).toBeDefined(); @@ -6449,7 +6449,7 @@ describe('OptionsListUtils', () => { const emptyPersonalDetails: PersonalDetailsList = {}; // When we call getReportDisplayOption - const result = getReportDisplayOption(report, undefined, emptyPersonalDetails, undefined, undefined); + const result = getReportDisplayOption(report, undefined, emptyPersonalDetails, undefined, undefined, translateLocal); // Then it should not throw and return a valid option expect(result).toBeDefined(); @@ -6461,7 +6461,7 @@ describe('OptionsListUtils', () => { const personalDetails: PersonalDetailsList = PERSONAL_DETAILS; // When we call getReportDisplayOption with undefined report - const result = getReportDisplayOption(undefined, undefined, personalDetails, undefined, undefined); + const result = getReportDisplayOption(undefined, undefined, personalDetails, undefined, undefined, translateLocal); // Then it should return a valid option (createOption handles undefined) expect(result).toBeDefined(); @@ -6584,7 +6584,7 @@ describe('OptionsListUtils', () => { isPolicyExpenseChat: true, }; - const option = getReportOption(participant, undefined, policy, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, policy, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option.text).toBe('Test Workspace'); expect(option.alternateText).toBe(translateLocal('workspace.common.workspace')); @@ -6639,12 +6639,13 @@ describe('OptionsListUtils', () => { isPolicyExpenseChat: true, }; - const option = getReportOption(participant, undefined, policy, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + // Pass the real personalDetails so the submits-to subtitle resolves to a name + const option = getReportOption(participant, undefined, policy, personalDetails, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option.text).toBe('Test Workspace with Submit'); - // The submitsTo logic may or may not apply depending on complex approval rules - // Just verify the option was created correctly - expect(option.alternateText).toBeDefined(); + // For a BASIC-approval policy the report submits to the default approver (the owner), + // so the subtitle is produced by the injected translate via the `iou.submitsTo` copy + expect(option.alternateText).toBe(translateLocal('iou.submitsTo', 'Report Owner')); }); it('should mark draft reports as disabled', async () => { @@ -6662,7 +6663,7 @@ describe('OptionsListUtils', () => { reportID, }; - const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, report, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, report, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option.isDisabled).toBe(true); }); @@ -6703,7 +6704,7 @@ describe('OptionsListUtils', () => { isSelfDM: true, }; - const option = getReportOption(participant, undefined, POLICY, personalDetails, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, personalDetails, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); // The option.isSelfDM is set by createOption based on the report type // Just verify the alternateText is correct for self DM @@ -6738,7 +6739,7 @@ describe('OptionsListUtils', () => { isInvoiceRoom: true, }; - const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option.isInvoiceRoom).toBe(true); expect(option.alternateText).toBe(translateLocal('workspace.common.invoices')); @@ -6780,7 +6781,7 @@ describe('OptionsListUtils', () => { }); await waitForBatchedUpdates(); - const option = getReportOption(participant, !!reportNameValuePair?.private_isArchived, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, !!reportNameValuePair?.private_isArchived, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option.text).toBe(POLICY.name); expect(option.alternateText).toBeTruthy(); @@ -6823,7 +6824,7 @@ describe('OptionsListUtils', () => { }); await waitForBatchedUpdates(); - const option = getReportOption(participant, !!reportNameValuePair?.private_isArchived, POLICY, {}, undefined, {}, draftReport, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, !!reportNameValuePair?.private_isArchived, POLICY, {}, undefined, {}, draftReport, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option.isDisabled).toBe(true); }); @@ -6842,7 +6843,7 @@ describe('OptionsListUtils', () => { const participant: Participant = {reportID, selected: false}; // Pass reportDraft = undefined → not a draft, should NOT be disabled - const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option.isDisabled).toBeFalsy(); }); @@ -6858,7 +6859,7 @@ describe('OptionsListUtils', () => { const participant: Participant = {reportID, selected: false}; // Pass reportDraft explicitly → should be disabled regardless of Onyx state - const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, draftReport, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, draftReport, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option.isDisabled).toBe(true); }); @@ -6878,7 +6879,7 @@ describe('OptionsListUtils', () => { const participant: Participant = {reportID, selected: false}; // Callers are responsible for passing reportDraft explicitly — undefined means not disabled - const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option.isDisabled).toBeFalsy(); }); @@ -6900,7 +6901,7 @@ describe('OptionsListUtils', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, report); await waitForBatchedUpdates(); - const option = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, !!reportNameValuePair?.private_isArchived, undefined); + const option = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, !!reportNameValuePair?.private_isArchived, undefined, translateLocal); expect(option).toBeDefined(); expect(option.reportID).toBe(reportID); @@ -6923,7 +6924,7 @@ describe('OptionsListUtils', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, report); await waitForBatchedUpdates(); - const option = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, !!reportNameValuePair?.private_isArchived, undefined); + const option = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, !!reportNameValuePair?.private_isArchived, undefined, translateLocal); expect(option).toBeDefined(); expect(option.reportID).toBe(reportID); @@ -6943,7 +6944,7 @@ describe('OptionsListUtils', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, report); await waitForBatchedUpdates(); - const option = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, undefined, undefined); + const option = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, undefined, undefined, translateLocal); expect(option).toBeDefined(); expect(option.reportID).toBe(reportID); @@ -6967,7 +6968,7 @@ describe('OptionsListUtils', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, report); await waitForBatchedUpdates(); - const option = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, !!reportNameValuePair?.private_isArchived, undefined); + const option = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, !!reportNameValuePair?.private_isArchived, undefined, translateLocal); expect(option).toBeDefined(); expect(option.reportID).toBe(reportID); @@ -6991,7 +6992,7 @@ describe('OptionsListUtils', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, report); await waitForBatchedUpdates(); - const option = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, !!reportNameValuePair?.private_isArchived, undefined); + const option = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, !!reportNameValuePair?.private_isArchived, undefined, translateLocal); expect(option).toBeDefined(); expect(option.reportID).toBe(reportID); @@ -7014,7 +7015,7 @@ describe('OptionsListUtils', () => { selected: true, }; - const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option.isSelected).toBe(true); expect(option.selected).toBe(true); @@ -7035,7 +7036,7 @@ describe('OptionsListUtils', () => { reportID, }; - const option = getReportOption(participant, undefined, undefined, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, undefined, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option).toBeDefined(); expect(option.text).toBeDefined(); @@ -7057,7 +7058,7 @@ describe('OptionsListUtils', () => { }; // Test that the function works with reportAttributesDerived parameter (optional) - const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option).toBeDefined(); }); @@ -7093,7 +7094,7 @@ describe('OptionsListUtils', () => { reportID, }; - const option = getReportOption(participant, undefined, POLICY, testPersonalDetails, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, testPersonalDetails, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option).toBeDefined(); // The createOption function uses personalDetails to build display names @@ -7156,7 +7157,7 @@ describe('OptionsListUtils', () => { isPolicyExpenseChat: true, }; - const option = getReportOption(participant, undefined, policy, testPersonalDetails, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, policy, testPersonalDetails, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option).toBeDefined(); expect(option.text).toBe('Test Workspace with Approver'); @@ -7181,7 +7182,7 @@ describe('OptionsListUtils', () => { }; // Pass empty personalDetails - const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option).toBeDefined(); expect(option.text).toBeDefined(); @@ -7203,7 +7204,7 @@ describe('OptionsListUtils', () => { }; // Pass undefined personalDetails - const option = getReportOption(participant, undefined, POLICY, undefined, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, undefined, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option).toBeDefined(); expect(option.text).toBeDefined(); @@ -7253,7 +7254,7 @@ describe('OptionsListUtils', () => { isInvoiceRoom: true, }; - const option = getReportOption(participant, undefined, POLICY, testPersonalDetails, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, testPersonalDetails, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option).toBeDefined(); expect(option.isInvoiceRoom).toBe(true); @@ -7275,7 +7276,7 @@ describe('OptionsListUtils', () => { const participant = {reportID}; - const option = getReportOption(participant, undefined, POLICY, {}, conciergeReportID, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, {}, conciergeReportID, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option).toBeDefined(); expect(option.reportID).toBe(reportID); @@ -7294,7 +7295,7 @@ describe('OptionsListUtils', () => { const participant = {reportID}; - const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option).toBeDefined(); expect(option.reportID).toBe(reportID); @@ -7331,7 +7332,7 @@ describe('OptionsListUtils', () => { // Passing conciergeReportID matching the reportID identifies this as the Concierge chat, // which affects getMovedTransactionMessage to use CONST.CONCIERGE_DISPLAY_NAME ('Concierge') - const option = getReportOption(participant, undefined, POLICY, testPersonalDetails, conciergeReportID, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const option = getReportOption(participant, undefined, POLICY, testPersonalDetails, conciergeReportID, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); expect(option).toBeDefined(); expect(option.reportID).toBe(reportID); @@ -7351,8 +7352,8 @@ describe('OptionsListUtils', () => { const participant = {reportID}; - const optionWithConcierge = getReportOption(participant, undefined, POLICY, {}, differentConciergeReportID, undefined, undefined, CONST.DEFAULT_NUMBER_ID); - const optionWithoutConcierge = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID); + const optionWithConcierge = getReportOption(participant, undefined, POLICY, {}, differentConciergeReportID, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); + const optionWithoutConcierge = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined, CONST.DEFAULT_NUMBER_ID, translateLocal); // Both should produce the same result since the IDs don't match expect(optionWithConcierge.reportID).toBe(optionWithoutConcierge.reportID); @@ -7410,7 +7411,7 @@ describe('OptionsListUtils', () => { selected: true, }; - const option = getPolicyExpenseReportOption(participant, undefined, testPersonalDetails, report, undefined); + const option = getPolicyExpenseReportOption(participant, undefined, testPersonalDetails, report, undefined, translateLocal); expect(option).toBeDefined(); expect(option.text).toBe('Test Workspace Policy'); @@ -7418,6 +7419,31 @@ describe('OptionsListUtils', () => { expect(option.isSelected).toBe(true); }); + it('routes the workspace subtitle through the injected translate function', async () => { + const reportID = '9001'; + const testPolicyID = 'policyMarker'; + const report: Report = { + reportID, + reportName: 'Marker Workspace Policy', + type: CONST.REPORT.TYPE.CHAT, + chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, + policyID: testPolicyID, + isOwnPolicyExpenseChat: true, + ownerAccountID: 1, + }; + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, report); + await waitForBatchedUpdates(); + + // A translate that tags the workspace subtitle so we can prove the option used the injected translate + const translateWithMarker: LocalizedTranslate = (path, ...parameters) => (path === 'workspace.common.workspace' ? 'WorkspaceMarker' : translateLocal(path, ...parameters)); + + const participant = {reportID, policyID: testPolicyID, isPolicyExpenseChat: true, selected: false}; + const option = getPolicyExpenseReportOption(participant, undefined, {}, report, undefined, translateWithMarker); + + // The subtitle resolves to the marker, proving the option builder used the injected translate (not translateLocal) + expect(option.alternateText).toBe('WorkspaceMarker'); + }); + it('should use personalDetails to create option with participant info', async () => { const reportID = '202'; const testPolicyID = 'policy202'; @@ -7475,7 +7501,7 @@ describe('OptionsListUtils', () => { isPolicyExpenseChat: true, }; - const option = getPolicyExpenseReportOption(participant, undefined, testPersonalDetails, report, undefined); + const option = getPolicyExpenseReportOption(participant, undefined, testPersonalDetails, report, undefined, translateLocal); expect(option).toBeDefined(); expect(option.text).toBe('Team Workspace'); @@ -7521,7 +7547,7 @@ describe('OptionsListUtils', () => { }; // Should not throw when personalDetails is empty - const option = getPolicyExpenseReportOption(participant, undefined, {}, report, undefined); + const option = getPolicyExpenseReportOption(participant, undefined, {}, report, undefined, translateLocal); expect(option).toBeDefined(); expect(option.text).toBe('Workspace Without Details'); @@ -7567,7 +7593,7 @@ describe('OptionsListUtils', () => { }; // Should not throw when personalDetails is undefined - const option = getPolicyExpenseReportOption(participant, undefined, undefined, report, undefined); + const option = getPolicyExpenseReportOption(participant, undefined, undefined, report, undefined, translateLocal); expect(option).toBeDefined(); expect(option.text).toBe('Workspace Undefined Details'); @@ -7621,10 +7647,10 @@ describe('OptionsListUtils', () => { selected: false, }; - const optionSelected = getPolicyExpenseReportOption(participantSelected, undefined, {}, report, undefined); + const optionSelected = getPolicyExpenseReportOption(participantSelected, undefined, {}, report, undefined, translateLocal); // eslint-disable-next-line rulesdir/no-negated-variables - const optionNotSelected = getPolicyExpenseReportOption(participantNotSelected, undefined, {}, report, undefined); + const optionNotSelected = getPolicyExpenseReportOption(participantNotSelected, undefined, {}, report, undefined, translateLocal); expect(optionSelected.isSelected).toBe(true); expect(optionSelected.selected).toBe(true); @@ -7682,7 +7708,7 @@ describe('OptionsListUtils', () => { selected: false, }; - const option = getPolicyExpenseReportOption(participant, true, testPersonalDetails, report, undefined); + const option = getPolicyExpenseReportOption(participant, true, testPersonalDetails, report, undefined, translateLocal); expect(option).toBeDefined(); expect(option.private_isArchived).toBe(true); @@ -7728,7 +7754,7 @@ describe('OptionsListUtils', () => { isPolicyExpenseChat: true, }; - const option = getPolicyExpenseReportOption(participant, undefined, {}, report, undefined); + const option = getPolicyExpenseReportOption(participant, undefined, {}, report, undefined, translateLocal); expect(option).toBeDefined(); expect(option?.private_isArchived).toBeUndefined(); @@ -8273,7 +8299,7 @@ describe('OptionsListUtils', () => { await waitForBatchedUpdates(); // When we call getReportDisplayOption with chat report - const option = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, undefined, undefined); + const option = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, undefined, undefined, translateLocal); // Then the option should be created successfully using the reports collection expect(option).toBeDefined(); @@ -8314,7 +8340,7 @@ describe('OptionsListUtils', () => { }; // When we call getPolicyExpenseReportOption with report passed directly - const option = getPolicyExpenseReportOption(participant, undefined, PERSONAL_DETAILS, report, undefined); + const option = getPolicyExpenseReportOption(participant, undefined, PERSONAL_DETAILS, report, undefined, translateLocal); // Then the option should be created successfully expect(option).toBeDefined(); @@ -8805,7 +8831,7 @@ describe('OptionsListUtils', () => { }, }; - const result = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, undefined, POLICY); + const result = getReportDisplayOption(report, undefined, PERSONAL_DETAILS, undefined, POLICY, translateLocal); expect(result).toBeDefined(); expect(result.policyID).toBe(policyID); }); @@ -8834,7 +8860,7 @@ describe('OptionsListUtils', () => { selected: true, }; - const result = getPolicyExpenseReportOption(participant, undefined, PERSONAL_DETAILS, report, POLICY); + const result = getPolicyExpenseReportOption(participant, undefined, PERSONAL_DETAILS, report, POLICY, translateLocal); expect(result).toBeDefined(); expect(result.policyID).toBe(policyID); });