diff --git a/src/components/AvatarWithDisplayName.tsx b/src/components/AvatarWithDisplayName.tsx index c3eb57f10989..1566da321c66 100644 --- a/src/components/AvatarWithDisplayName.tsx +++ b/src/components/AvatarWithDisplayName.tsx @@ -5,6 +5,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; +import useReportIsArchived from '@hooks/useReportIsArchived'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -169,7 +170,8 @@ function AvatarWithDisplayName({ const parentReportActionParam = report?.parentReportActionID ? parentReportActions?.[report.parentReportActionID] : undefined; const title = getReportName(report, undefined, parentReportActionParam, personalDetails, invoiceReceiverPolicy, reportAttributes); const subtitle = getChatRoomSubtitle(report, {isCreateExpenseFlow: true}); - const parentNavigationSubtitleData = getParentNavigationSubtitle(report); + const isReportArchived = useReportIsArchived(report?.reportID); + const parentNavigationSubtitleData = getParentNavigationSubtitle(report, isReportArchived); const isMoneyRequestOrReport = isMoneyRequestReport(report) || isMoneyRequest(report) || isTrackExpenseReport(report) || isInvoiceReport(report); const ownerPersonalDetails = getPersonalDetailsForAccountIDs(report?.ownerAccountID ? [report.ownerAccountID] : [], personalDetails); const displayNamesWithTooltips = getDisplayNamesWithTooltips(Object.values(ownerPersonalDetails), false, localeCompare); diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 4321df8ac0d0..6d22a675dd9c 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -5526,7 +5526,7 @@ function getPendingChatMembers(accountIDs: number[], previousPendingChatMembers: /** * Gets the parent navigation subtitle for the report */ -function getParentNavigationSubtitle(report: OnyxEntry): ParentNavigationSummaryParams { +function getParentNavigationSubtitle(report: OnyxEntry, isReportArchived = false): ParentNavigationSummaryParams { const parentReport = getParentReport(report); if (isEmptyObject(parentReport)) { const ownerAccountID = report?.ownerAccountID; @@ -5550,9 +5550,7 @@ function getParentNavigationSubtitle(report: OnyxEntry): ParentNavigatio if (isInvoiceReport(report) || isInvoiceRoom(parentReport)) { let reportName = `${getPolicyName({report: parentReport})} & ${getInvoicePayerName(parentReport)}`; - // This will get removed as part of https://github.com/Expensify/App/issues/59961 - // eslint-disable-next-line deprecation/deprecation - if (isArchivedNonExpenseReport(parentReport, !!getReportNameValuePairs(parentReport?.reportID)?.private_isArchived)) { + if (isArchivedNonExpenseReport(parentReport, isReportArchived)) { reportName += ` (${translateLocal('common.archived')})`; } diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index e22e313fd2eb..e175cf41a6d5 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -198,7 +198,7 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail const isReportArchived = useReportIsArchived(report?.reportID); const isArchivedRoom = useMemo(() => isArchivedNonExpenseReport(report, isReportArchived), [report, isReportArchived]); const shouldDisableRename = useMemo(() => shouldDisableRenameUtil(report, isReportArchived), [report, isReportArchived]); - const parentNavigationSubtitleData = getParentNavigationSubtitle(report); + const parentNavigationSubtitleData = getParentNavigationSubtitle(report, isReportArchived); const base62ReportID = getBase62ReportID(Number(report.reportID)); // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps -- policy is a dependency because `getChatRoomSubtitle` calls `getPolicyName` which in turn retrieves the value from the `policy` value stored in Onyx const chatRoomSubtitle = useMemo(() => { diff --git a/src/pages/ShareCodePage.tsx b/src/pages/ShareCodePage.tsx index 5e226db9e7bd..244deaa11347 100644 --- a/src/pages/ShareCodePage.tsx +++ b/src/pages/ShareCodePage.tsx @@ -15,6 +15,7 @@ import ScrollView from '@components/ScrollView'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useEnvironment from '@hooks/useEnvironment'; import useLocalize from '@hooks/useLocalize'; +import useReportIsArchived from '@hooks/useReportIsArchived'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import Clipboard from '@libs/Clipboard'; @@ -75,6 +76,7 @@ function ShareCodePage({report, policy, backTo}: ShareCodePageProps) { const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const isReport = !!report?.reportID; + const isReportArchived = useReportIsArchived(report?.reportID); const subtitle = useMemo(() => { if (isReport) { @@ -88,11 +90,11 @@ function ShareCodePage({report, policy, backTo}: ShareCodePageProps) { .join(' & '); } - return getParentNavigationSubtitle(report).workspaceName ?? getChatRoomSubtitle(report); + return getParentNavigationSubtitle(report, isReportArchived).workspaceName ?? getChatRoomSubtitle(report); } return currentUserPersonalDetails.login; - }, [report, currentUserPersonalDetails, isReport]); + }, [isReport, currentUserPersonalDetails.login, report, isReportArchived]); const title = isReport ? getReportName(report) : (currentUserPersonalDetails.displayName ?? ''); const urlWithTrailingSlash = addTrailingForwardSlash(environmentURL); diff --git a/src/pages/home/HeaderView.tsx b/src/pages/home/HeaderView.tsx index 84c7a51ec231..3994e812e1e1 100644 --- a/src/pages/home/HeaderView.tsx +++ b/src/pages/home/HeaderView.tsx @@ -26,6 +26,7 @@ import useLoadingBarVisibility from '@hooks/useLoadingBarVisibility'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePolicy from '@hooks/usePolicy'; +import useReportIsArchived from '@hooks/useReportIsArchived'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useSubscriptionPlan from '@hooks/useSubscriptionPlan'; import useTheme from '@hooks/useTheme'; @@ -133,7 +134,8 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked, // Use sorted display names for the title for group chats on native small screen widths const title = getReportName(reportHeaderData, policy, parentReportAction, personalDetails, invoiceReceiverPolicy); const subtitle = getChatRoomSubtitle(reportHeaderData); - const parentNavigationSubtitleData = getParentNavigationSubtitle(reportHeaderData); + const isReportHeaderDataArchived = useReportIsArchived(reportHeaderData?.reportID); + const parentNavigationSubtitleData = getParentNavigationSubtitle(reportHeaderData, isReportHeaderDataArchived); const reportDescription = Parser.htmlToText(getReportDescription(report)); const policyName = getPolicyName({report, returnEmptyIfNotFound: true}); const policyDescription = getPolicyDescriptionText(policy); diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 4a99d2009a51..606839bb5e5d 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -44,6 +44,7 @@ import { getInvoiceChatByParticipants, getMoneyReportPreviewName, getMostRecentlyVisitedReport, + getParentNavigationSubtitle, getParticipantsList, getPolicyExpenseChat, getReasonAndReportActionThatRequiresAttention, @@ -921,6 +922,48 @@ describe('ReportUtils', () => { }); }); + describe('getParentNavigationSubtitle', () => { + const baseArchivedPolicyExpenseChat = { + reportID: '2', + lastReadTime: '2024-02-01 04:56:47.233', + parentReportActionID: '1', + parentReportID: '1', + reportName: 'Base Report', + type: CONST.REPORT.TYPE.INVOICE, + }; + + const reports: Report[] = [ + { + reportID: '1', + lastReadTime: '2024-02-01 04:56:47.233', + reportName: 'Report', + policyName: 'A workspace', + invoiceReceiver: {type: CONST.REPORT.INVOICE_RECEIVER_TYPE.INDIVIDUAL, accountID: 1}, + }, + baseArchivedPolicyExpenseChat, + ]; + + beforeAll(() => { + const reportCollectionDataSet = toCollectionDataSet(ONYXKEYS.COLLECTION.REPORT, reports, (report) => report.reportID); + Onyx.multiSet({ + ...reportCollectionDataSet, + }); + return waitForBatchedUpdates(); + }); + + it('should return the correct parent navigation subtitle for the archived invoice report', () => { + const actual = getParentNavigationSubtitle(baseArchivedPolicyExpenseChat, true); + const normalizedActual = {...actual, reportName: actual.reportName?.replace(/\u00A0/g, ' ')}; + expect(normalizedActual).toEqual({reportName: 'A workspace & Ragnar Lothbrok (archived)'}); + }); + + it('should return the correct parent navigation subtitle for the non archived invoice report', () => { + const actual = getParentNavigationSubtitle(baseArchivedPolicyExpenseChat, false); + const normalizedActual = {...actual, reportName: actual.reportName?.replace(/\u00A0/g, ' ')}; + expect(normalizedActual).toEqual({reportName: 'A workspace & Ragnar Lothbrok'}); + }); + }); + describe('requiresAttentionFromCurrentUser', () => { afterEach(async () => { await Onyx.clear();