From 410c7a2f09176702bfe8f60d1f49436980cedcc8 Mon Sep 17 00:00:00 2001 From: truph01 Date: Tue, 29 Jul 2025 11:58:55 +0700 Subject: [PATCH 1/8] fix: Remove call to getReportNameValuePairs() in method canSeeDefaultRoom --- src/libs/ReportUtils.ts | 14 +++++++------- .../home/report/ReportActionItemParentAction.tsx | 6 ++++-- .../report/withReportAndReportActionOrNotFound.tsx | 4 +++- src/pages/home/report/withReportOrNotFound.tsx | 5 +++-- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index d9981d9d2666..8a8e56265589 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -7864,11 +7864,11 @@ function isIOUOwnedByCurrentUser(report: OnyxEntry, allReportsDict?: Ony * Assuming the passed in report is a default room, lets us know whether we can see it or not, based on permissions and * the various subsets of users we've allowed to use default rooms. */ -function canSeeDefaultRoom(report: OnyxEntry, betas: OnyxEntry): boolean { +function canSeeDefaultRoom(report: OnyxEntry, betas: OnyxEntry, isReportArchived = false): boolean { // Include archived rooms // This will get removed as part of https://github.com/Expensify/App/issues/59961 // eslint-disable-next-line deprecation/deprecation - if (isArchivedNonExpenseReport(report, !!getReportNameValuePairs(report?.reportID)?.private_isArchived)) { + if (isArchivedNonExpenseReport(report, isReportArchived)) { return true; } @@ -7886,9 +7886,9 @@ function canSeeDefaultRoom(report: OnyxEntry, betas: OnyxEntry): return Permissions.isBetaEnabled(CONST.BETAS.DEFAULT_ROOMS, betas ?? []); } -function canAccessReport(report: OnyxEntry, betas: OnyxEntry): boolean { +function canAccessReport(report: OnyxEntry, betas: OnyxEntry, isReportArchived = false): boolean { // We hide default rooms (it's basically just domain rooms now) from people who aren't on the defaultRooms beta. - if (isDefaultRoom(report) && !canSeeDefaultRoom(report, betas)) { + if (isDefaultRoom(report) && !canSeeDefaultRoom(report, betas, isReportArchived)) { return false; } @@ -8199,7 +8199,7 @@ function reasonForReportToBeInOptionList({ return null; } - if (!canAccessReport(report, betas)) { + if (!canAccessReport(report, betas, isReportArchived)) { return null; } @@ -9291,8 +9291,8 @@ function isReportParticipant(accountID: number | undefined, report: OnyxEntry): boolean { - return (isReportParticipant(currentUserAccountID, report) || isPublicRoom(report)) && canAccessReport(report, allBetas); +function canCurrentUserOpenReport(report: OnyxEntry, isReportArchived = false): boolean { + return (isReportParticipant(currentUserAccountID, report) || isPublicRoom(report)) && canAccessReport(report, allBetas, isReportArchived); } function shouldUseFullTitleToDisplay(report: OnyxEntry): boolean { diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index 76df12c156cc..ea4d4d295808 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -3,6 +3,7 @@ import {View} from 'react-native'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import useNetwork from '@hooks/useNetwork'; +import useReportIsArchived from '@hooks/useReportIsArchived'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useThemeStyles from '@hooks/useThemeStyles'; import onyxSubscribe from '@libs/onyxSubscribe'; @@ -81,6 +82,7 @@ function ReportActionItemParentAction({ const [allAncestors, setAllAncestors] = useState([]); const {isOffline} = useNetwork(); const {isInNarrowPaneModal} = useResponsiveLayout(); + const isReportArchived = useReportIsArchived(report?.reportID); useEffect(() => { const unsubscribeReports: Array<() => void> = []; @@ -137,14 +139,14 @@ function ReportActionItemParentAction({ {shouldDisplayThreadDivider && ( )} navigateToLinkedReportAction(ancestor, isInNarrowPaneModal, canUserPerformWriteAction, isOffline) : undefined } diff --git a/src/pages/home/report/withReportAndReportActionOrNotFound.tsx b/src/pages/home/report/withReportAndReportActionOrNotFound.tsx index 69c24c392a79..a28699fa7b2e 100644 --- a/src/pages/home/report/withReportAndReportActionOrNotFound.tsx +++ b/src/pages/home/report/withReportAndReportActionOrNotFound.tsx @@ -4,6 +4,7 @@ import React, {useEffect, useMemo} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import FullscreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import useOnyx from '@hooks/useOnyx'; +import useReportIsArchived from '@hooks/useReportIsArchived'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import {openReport} from '@libs/actions/Report'; import getComponentDisplayName from '@libs/getComponentDisplayName'; @@ -83,7 +84,8 @@ export default function Date: Tue, 29 Jul 2025 15:47:43 +0700 Subject: [PATCH 2/8] fix: Create unit test --- tests/unit/ReportUtilsTest.ts | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index c25a9bc3cb09..60b999754ced 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -31,6 +31,7 @@ import { canHoldUnholdReportAction, canJoinChat, canLeaveChat, + canSeeDefaultRoom, canUserPerformWriteAction, findLastAccessedReport, getAllAncestorReportActions, @@ -216,6 +217,10 @@ const personalDetails: PersonalDetailsList = { accountID: 7, login: 'owner@test.com', }, + '8': { + accountID: 8, + login: CONST.EMAIL.GUIDES_DOMAIN, + }, }; const rules = { @@ -4877,4 +4882,38 @@ describe('ReportUtils', () => { expect(getReportStatusTranslation(undefined, CONST.REPORT.STATUS_NUM.OPEN)).toBe(''); }); }); + describe('canSeeDefaultRoom', () => { + it('should return true if report is archived room ', () => { + const betas = [CONST.BETAS.DEFAULT_ROOMS]; + const report: Report = { + ...createRandomReport(40002), + type: CONST.REPORT.TYPE.CHAT, + participants: buildParticipantsFromAccountIDs([currentUserAccountID, 1]), + }; + expect(canSeeDefaultRoom(report, betas, true)).toBe(true); + }); + it('should return true if the room has an assigned guide', () => { + const betas = [CONST.BETAS.DEFAULT_ROOMS]; + const report: Report = { + ...createRandomReport(40002), + participants: { + '1': {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, + '8': {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, + }, + }; + Onyx.set(ONYXKEYS.PERSONAL_DETAILS_LIST, personalDetails).then(() => { + expect(canSeeDefaultRoom(report, betas, false)).toBe(true); + }); + }); + it('should return true if the report is admin room', () => { + const betas = [CONST.BETAS.DEFAULT_ROOMS]; + const report: Report = { + ...createRandomReport(40002), + chatType: CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, + }; + Onyx.set(ONYXKEYS.PERSONAL_DETAILS_LIST, personalDetails).then(() => { + expect(canSeeDefaultRoom(report, betas, false)).toBe(true); + }); + }); + }); }); From 6a41be831d6704e34913fb3b3a694b4117097055 Mon Sep 17 00:00:00 2001 From: truph01 Date: Wed, 30 Jul 2025 13:50:17 +0700 Subject: [PATCH 3/8] fix: ReportActionItemParentAction component --- .../home/report/ReportActionItemParentAction.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index ea4d4d295808..3e0d31a05f88 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -3,7 +3,7 @@ import {View} from 'react-native'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import useNetwork from '@hooks/useNetwork'; -import useReportIsArchived from '@hooks/useReportIsArchived'; +import useOnyx from '@hooks/useOnyx'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useThemeStyles from '@hooks/useThemeStyles'; import onyxSubscribe from '@libs/onyxSubscribe'; @@ -14,6 +14,7 @@ import { canUserPerformWriteAction as canUserPerformWriteActionReportUtils, getAllAncestorReportActionIDs, getAllAncestorReportActions, + isArchivedReport, navigateToLinkedReportAction, } from '@libs/ReportUtils'; import {navigateToConciergeChatAndDeleteReport} from '@userActions/Report'; @@ -82,7 +83,7 @@ function ReportActionItemParentAction({ const [allAncestors, setAllAncestors] = useState([]); const {isOffline} = useNetwork(); const {isInNarrowPaneModal} = useResponsiveLayout(); - const isReportArchived = useReportIsArchived(report?.reportID); + const [reportNameValuePairs] = useOnyx(ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS, {canBeMissing: true}); useEffect(() => { const unsubscribeReports: Array<() => void> = []; @@ -126,7 +127,8 @@ function ReportActionItemParentAction({ const ancestorReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${ancestor.report.reportID}`]; const canUserPerformWriteAction = canUserPerformWriteActionReportUtils(ancestorReport); const shouldDisplayThreadDivider = !isTripPreview(ancestor.reportAction); - + const reportNameValuePair = reportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${ancestorReports.current?.[ancestor?.report?.reportID]?.reportID}`]; + const isAncestorReportArchived = isArchivedReport(reportNameValuePair); return ( )} navigateToLinkedReportAction(ancestor, isInNarrowPaneModal, canUserPerformWriteAction, isOffline) : undefined } From bfe20fdac09576e3a9e8ab411ca6281b0b5b5b4a Mon Sep 17 00:00:00 2001 From: truph01 Date: Thu, 31 Jul 2025 12:13:35 +0700 Subject: [PATCH 4/8] fix: apply selector to useOnyx --- .../report/ReportActionItemParentAction.tsx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index 3e0d31a05f88..c64678199208 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -83,7 +83,23 @@ function ReportActionItemParentAction({ const [allAncestors, setAllAncestors] = useState([]); const {isOffline} = useNetwork(); const {isInNarrowPaneModal} = useResponsiveLayout(); - const [reportNameValuePairs] = useOnyx(ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS, {canBeMissing: true}); + const [reportNameValuePairs] = useOnyx(ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS, { + canBeMissing: true, + selector: (allPairs) => { + const ancestorIDsToSelect = new Set(allAncestors.map(({report: reportAncestor}) => reportAncestor.reportID)); + + return Object.entries(allPairs ?? {}).reduce( + (acc, [key, value]) => { + const id = key.split('_').at(1); + if (ancestorIDsToSelect.has(id ?? '')) { + acc[key] = value; + } + return acc; + }, + {} as Record, + ); + }, + }); useEffect(() => { const unsubscribeReports: Array<() => void> = []; From 8e74e1b90bd6da6ca54ebffa159feba2313fff7e Mon Sep 17 00:00:00 2001 From: truph01 Date: Thu, 31 Jul 2025 12:27:35 +0700 Subject: [PATCH 5/8] fix: lint --- .../report/ReportActionItemParentAction.tsx | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index c64678199208..90c698884ce0 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -87,17 +87,13 @@ function ReportActionItemParentAction({ canBeMissing: true, selector: (allPairs) => { const ancestorIDsToSelect = new Set(allAncestors.map(({report: reportAncestor}) => reportAncestor.reportID)); - - return Object.entries(allPairs ?? {}).reduce( - (acc, [key, value]) => { - const id = key.split('_').at(1); - if (ancestorIDsToSelect.has(id ?? '')) { - acc[key] = value; - } - return acc; - }, - {} as Record, - ); + return Object.entries(allPairs ?? {}).reduce((acc, [key, value]) => { + const id = key.split('_').at(1); + if (ancestorIDsToSelect.has(id ?? '') && acc) { + acc[key] = value; + } + return acc; + }, {} as OnyxCollection); }, }); From 7f22699c20eb34a185cd8195466649372e4c0cbd Mon Sep 17 00:00:00 2001 From: truph01 Date: Thu, 31 Jul 2025 12:32:08 +0700 Subject: [PATCH 6/8] fix: lint --- src/pages/home/report/ReportActionItemParentAction.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index 90c698884ce0..2fe6c2fcc6fb 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -89,7 +89,7 @@ function ReportActionItemParentAction({ const ancestorIDsToSelect = new Set(allAncestors.map(({report: reportAncestor}) => reportAncestor.reportID)); return Object.entries(allPairs ?? {}).reduce((acc, [key, value]) => { const id = key.split('_').at(1); - if (ancestorIDsToSelect.has(id ?? '') && acc) { + if (id && ancestorIDsToSelect.has(id) && acc) { acc[key] = value; } return acc; From cb8dd7002c95e378d029b17e927630afbb3dcf30 Mon Sep 17 00:00:00 2001 From: truph01 Date: Thu, 31 Jul 2025 15:41:12 +0700 Subject: [PATCH 7/8] fix: don't use reduce --- .../home/report/ReportActionItemParentAction.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index 2fe6c2fcc6fb..7c12f2979d0f 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -86,14 +86,14 @@ function ReportActionItemParentAction({ const [reportNameValuePairs] = useOnyx(ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS, { canBeMissing: true, selector: (allPairs) => { - const ancestorIDsToSelect = new Set(allAncestors.map(({report: reportAncestor}) => reportAncestor.reportID)); - return Object.entries(allPairs ?? {}).reduce((acc, [key, value]) => { - const id = key.split('_').at(1); - if (id && ancestorIDsToSelect.has(id) && acc) { - acc[key] = value; - } - return acc; - }, {} as OnyxCollection); + const ancestorIDsToSelect = new Set(ancestorIDs.current.reportIDs); + + return Object.fromEntries( + Object.entries(allPairs ?? {}).filter(([key]) => { + const id = key.split('_').at(1); + return id && ancestorIDsToSelect.has(id); + }), + ); }, }); From 44fdf80dff45a02474b4423e636c3f7915accecd Mon Sep 17 00:00:00 2001 From: truph01 Date: Thu, 31 Jul 2025 23:58:44 +0700 Subject: [PATCH 8/8] fix: refactor selector function and use buildParticipantsFromAccountIDs in test --- src/libs/ReportUtils.ts | 2 -- src/pages/home/report/ReportActionItemParentAction.tsx | 5 +++-- tests/unit/ReportUtilsTest.ts | 5 +---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 3430ac5d6ab2..82b3010b1434 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -7871,8 +7871,6 @@ function isIOUOwnedByCurrentUser(report: OnyxEntry, allReportsDict?: Ony */ function canSeeDefaultRoom(report: OnyxEntry, betas: OnyxEntry, isReportArchived = false): boolean { // Include archived rooms - // This will get removed as part of https://github.com/Expensify/App/issues/59961 - // eslint-disable-next-line deprecation/deprecation if (isArchivedNonExpenseReport(report, isReportArchived)) { return true; } diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index 7c12f2979d0f..eb0468d65907 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -83,7 +83,7 @@ function ReportActionItemParentAction({ const [allAncestors, setAllAncestors] = useState([]); const {isOffline} = useNetwork(); const {isInNarrowPaneModal} = useResponsiveLayout(); - const [reportNameValuePairs] = useOnyx(ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS, { + const [ancestorReportNameValuePairs] = useOnyx(ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS, { canBeMissing: true, selector: (allPairs) => { const ancestorIDsToSelect = new Set(ancestorIDs.current.reportIDs); @@ -139,7 +139,8 @@ function ReportActionItemParentAction({ const ancestorReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${ancestor.report.reportID}`]; const canUserPerformWriteAction = canUserPerformWriteActionReportUtils(ancestorReport); const shouldDisplayThreadDivider = !isTripPreview(ancestor.reportAction); - const reportNameValuePair = reportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${ancestorReports.current?.[ancestor?.report?.reportID]?.reportID}`]; + const reportNameValuePair = + ancestorReportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${ancestorReports.current?.[ancestor?.report?.reportID]?.reportID}`]; const isAncestorReportArchived = isArchivedReport(reportNameValuePair); return ( { const betas = [CONST.BETAS.DEFAULT_ROOMS]; const report: Report = { ...createRandomReport(40002), - participants: { - '1': {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, - '8': {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, - }, + participants: buildParticipantsFromAccountIDs([currentUserAccountID, 8]), }; Onyx.set(ONYXKEYS.PERSONAL_DETAILS_LIST, personalDetails).then(() => { expect(canSeeDefaultRoom(report, betas, false)).toBe(true);