From a9e922c240936395b8626c51e5d2d13bd0cc4f63 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Fri, 24 Apr 2026 01:35:04 +0700 Subject: [PATCH 1/8] feat: make personalDetails a required field in navigateToAndOpenChildReport --- src/libs/actions/Report/index.ts | 3 +-- .../ContextMenu/BaseReportActionContextMenu.tsx | 2 ++ .../report/ContextMenu/ContextMenuActions.tsx | 8 +++++--- src/pages/inbox/report/ReportActionItemThread.tsx | 3 ++- tests/actions/ReportTest.ts | 14 +++++++------- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index c222c62dacf0..7971d8558e9a 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -2120,8 +2120,7 @@ function navigateToAndOpenChildReport( currentUserAccountID: number, introSelected: OnyxEntry, betas: OnyxEntry, - // TODO: personalDetails should be a required field in follow-up PRs https://github.com/Expensify/App/issues/73656 - personalDetails?: OnyxEntry, + personalDetails: OnyxEntry, ) { const report = childReport ?? createChildReport(childReport, parentReportAction, parentReport, currentUserAccountID, introSelected, betas, personalDetails); diff --git a/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx b/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx index 969ff12cdb6b..8fa1e6cf6e8f 100755 --- a/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx +++ b/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx @@ -244,6 +244,7 @@ function BaseReportActionContextMenu({ const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST); const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); + const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); const isTryNewDotNVPDismissed = !!tryNewDot?.classicRedirect?.dismissed; const session = useSession(); @@ -417,6 +418,7 @@ function BaseReportActionContextMenu({ bankAccountList, isOffline, conciergeReportID, + personalDetails, }; if ('renderContent' in contextAction) { diff --git a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx index 8484702fa9af..7b38d18af0d8 100644 --- a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx @@ -207,6 +207,7 @@ import type { Download as DownloadOnyx, IntroSelected, OnyxInputOrEntry, + PersonalDetailsList, Policy, PolicyTagLists, ReportAction, @@ -302,6 +303,7 @@ type ContextMenuActionPayload = { introSelected: OnyxEntry; isSelfTourViewed: boolean | undefined; betas: OnyxEntry; + personalDetails: OnyxEntry; isDelegateAccessRestricted?: boolean; showDelegateNoAccessModal?: () => void; currentUserPersonalDetails: ReturnType; @@ -443,16 +445,16 @@ const ContextMenuActions: ContextMenuAction[] = [ } return !shouldDisableThread(reportAction, isThreadReportParentAction, isArchivedRoom); }, - onPress: (closePopover, {reportAction, childReport, originalReport, currentUserAccountID, introSelected, betas}) => { + onPress: (closePopover, {reportAction, childReport, originalReport, currentUserAccountID, introSelected, betas, personalDetails}) => { if (closePopover) { hideContextMenu(false, () => { KeyboardUtils.dismiss().then(() => { - navigateToAndOpenChildReport(childReport, reportAction, originalReport, currentUserAccountID, introSelected, betas); + navigateToAndOpenChildReport(childReport, reportAction, originalReport, currentUserAccountID, introSelected, betas, personalDetails); }); }); return; } - navigateToAndOpenChildReport(childReport, reportAction, originalReport, currentUserAccountID, introSelected, betas); + navigateToAndOpenChildReport(childReport, reportAction, originalReport, currentUserAccountID, introSelected, betas, personalDetails); }, getDescription: () => {}, sentryLabel: CONST.SENTRY_LABEL.CONTEXT_MENU.REPLY_IN_THREAD, diff --git a/src/pages/inbox/report/ReportActionItemThread.tsx b/src/pages/inbox/report/ReportActionItemThread.tsx index def30f62b538..715e7947df2f 100644 --- a/src/pages/inbox/report/ReportActionItemThread.tsx +++ b/src/pages/inbox/report/ReportActionItemThread.tsx @@ -47,6 +47,7 @@ function ReportActionItemThread({numberOfReplies, accountIDs, mostRecentReply, r const [childReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportAction.childReportID}`); const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [betas] = useOnyx(ONYXKEYS.BETAS); + const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); const numberOfRepliesText = numberOfReplies > CONST.MAX_THREAD_REPLIES_PREVIEW ? `${CONST.MAX_THREAD_REPLIES_PREVIEW}+` : `${numberOfReplies}`; const replyText = numberOfReplies === 1 ? translate('threads.reply') : translate('threads.replies'); @@ -57,7 +58,7 @@ function ReportActionItemThread({numberOfReplies, accountIDs, mostRecentReply, r { - navigateToAndOpenChildReport(childReport, reportAction, report, currentUserAccountID, introSelected, betas); + navigateToAndOpenChildReport(childReport, reportAction, report, currentUserAccountID, introSelected, betas, personalDetails); }} role={CONST.ROLE.BUTTON} accessibilityLabel={`${numberOfReplies} ${replyText}`} diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index 4cdbcbc7d710..c9f7625a508e 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -4574,7 +4574,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined); + Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); await waitForBatchedUpdates(); expect(Navigation.navigate).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(EXISTING_CHILD_REPORT.reportID)); @@ -4593,7 +4593,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined); + Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); await waitForBatchedUpdates(); expect(Navigation.navigate).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(MOCK_NEW_THREAD_REPORT_ID)); @@ -4608,7 +4608,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, {} as OnyxTypes.ReportAction, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined); + Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, {} as OnyxTypes.ReportAction, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); await waitForBatchedUpdates(); expect(Navigation.navigate).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(EXISTING_CHILD_REPORT.reportID)); @@ -4627,7 +4627,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined); + Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); await waitForBatchedUpdates(); expect(Navigation.navigate).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(MOCK_NEW_THREAD_REPORT_ID)); @@ -4646,7 +4646,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined); + Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); await waitForBatchedUpdates(); // Verify navigation happened with the new thread report @@ -4671,7 +4671,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, undefined, undefined); + Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, undefined, undefined, undefined); await waitForBatchedUpdates(); expect(Navigation.navigate).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(EXISTING_CHILD_REPORT.reportID)); @@ -4691,7 +4691,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, testBetas); + Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, testBetas, undefined); await waitForBatchedUpdates(); TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.OPEN_REPORT, 1); From 534164e6bdbad27ed2b3eac7b0aa1230bec0e1d5 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Fri, 24 Apr 2026 01:55:20 +0700 Subject: [PATCH 2/8] feat: handle another part --- .../MoneyRequestReceiptView.tsx | 5 +- src/components/ReportActionItem/TaskView.tsx | 2 +- src/libs/actions/Report/index.ts | 23 ++++----- src/libs/actions/Task.ts | 3 +- src/pages/Debug/Report/DebugReportPage.tsx | 3 +- .../report/ContextMenu/ContextMenuActions.tsx | 8 ++- .../inbox/report/ReportActionItemCreated.tsx | 3 +- .../report/ReportActionItemParentAction.tsx | 26 +++++++++- src/pages/settings/HelpPage/HelpPage.tsx | 6 +-- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 2 +- tests/actions/ReportTest.ts | 49 ++++++++++--------- 11 files changed, 78 insertions(+), 52 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx index f2678c433a5b..ec0860c03aee 100644 --- a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx +++ b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx @@ -135,6 +135,7 @@ function MoneyRequestReceiptView({ const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); const [betas] = useOnyx(ONYXKEYS.BETAS); + const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); const [isLoading, setIsLoading] = useState(true); const parentReportAction = report?.parentReportActionID ? parentReportActions?.[report.parentReportActionID] : undefined; @@ -366,7 +367,7 @@ function MoneyRequestReceiptView({ } if (transaction?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { if (chatReport?.reportID && getCreationReportErrors(chatReport)) { - navigateToConciergeChatAndDeleteReport(chatReport.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, true, true); + navigateToConciergeChatAndDeleteReport(chatReport.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, true, true, personalDetails); return; } if (parentReportAction) { @@ -403,7 +404,7 @@ function MoneyRequestReceiptView({ if (isInNarrowPaneModal) { Navigation.goBack(); } - navigateToConciergeChatAndDeleteReport(report.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, true, true); + navigateToConciergeChatAndDeleteReport(report.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, true, true, personalDetails); } }; diff --git a/src/components/ReportActionItem/TaskView.tsx b/src/components/ReportActionItem/TaskView.tsx index 649553a362b8..a098bc14a74c 100644 --- a/src/components/ReportActionItem/TaskView.tsx +++ b/src/components/ReportActionItem/TaskView.tsx @@ -118,7 +118,7 @@ function TaskView({report, parentReport, action}: TaskViewProps) { clearTaskErrors(report, conciergeReportID, accountID, introSelected, betas, isSelfTourViewed)} + onClose={() => clearTaskErrors(report, conciergeReportID, accountID, introSelected, betas, isSelfTourViewed, personalDetails)} errorRowStyles={styles.ph5} > diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index 7971d8558e9a..cf5b44fec3f4 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -2069,8 +2069,7 @@ function navigateToAndOpenReportWithAccountIDs( introSelected: OnyxEntry, isSelfTourViewed: boolean | undefined, betas: OnyxEntry, - // TODO: personalDetails should be a required field in follow-up PRs https://github.com/Expensify/App/issues/73656 - personalDetails?: OnyxEntry, + personalDetails: OnyxEntry, ) { let newChat: OptimisticChatReport | undefined; const participants = participantAccountIDs.map((accountID): ParticipantInfo => { @@ -2094,8 +2093,7 @@ function navigateToAndOpenReportWithAccountIDs( newReportObject: newChat, parentReportActionID: '0', participants, - // TODO: allPersonalDetails fallback should be removed in follow-up PRs https://github.com/Expensify/App/issues/73656 - personalDetails: personalDetails ?? allPersonalDetails, + personalDetails, betas, }); } @@ -3059,9 +3057,8 @@ function toggleSubscribeToChildReport( introSelected: OnyxEntry, isSelfTourViewed: boolean | undefined, betas: OnyxEntry, - prevNotificationPreference?: NotificationPreference, - // TODO: personalDetails should be a required field in follow-up PRs https://github.com/Expensify/App/issues/73656 - personalDetails?: OnyxEntry, + prevNotificationPreference: NotificationPreference | undefined, + personalDetails: OnyxEntry, ) { if (childReportID) { openReport({reportID: childReportID, introSelected, betas, isSelfTourViewed}); @@ -3105,8 +3102,7 @@ function toggleSubscribeToChildReport( reportID: newChat.reportID, introSelected, participants, - // TODO: allPersonalDetails fallback should be removed in follow-up PRs https://github.com/Expensify/App/issues/73656 - personalDetails: personalDetails ?? allPersonalDetails, + personalDetails, newReportObject: newChat, parentReportActionID: parentReportAction.reportActionID, isSelfTourViewed, @@ -3996,8 +3992,7 @@ function navigateToConciergeChatAndDeleteReport( betas: OnyxEntry, shouldPopToTop = false, shouldDeleteChildReports = false, - // TODO: personalDetails should be a required field in follow-up PRs https://github.com/Expensify/App/issues/73656 - personalDetails?: OnyxEntry, + personalDetails: OnyxEntry, ) { // Dismiss the current report screen and replace it with Concierge Chat if (shouldPopToTop) { @@ -4005,8 +4000,7 @@ function navigateToConciergeChatAndDeleteReport( } else { Navigation.goBack(); } - // TODO: allPersonalDetails fallback should be removed in follow-up PRs https://github.com/Expensify/App/issues/73656 - navigateToConciergeChat(conciergeReportID, introSelected, currentUserAccountID, isSelfTourViewed, betas, false, undefined, undefined, undefined, personalDetails ?? allPersonalDetails); + navigateToConciergeChat(conciergeReportID, introSelected, currentUserAccountID, isSelfTourViewed, betas, false, undefined, undefined, undefined, personalDetails); // eslint-disable-next-line @typescript-eslint/no-deprecated InteractionManager.runAfterInteractions(() => { deleteReport(reportID, shouldDeleteChildReports); @@ -4020,6 +4014,7 @@ function clearCreateChatError( currentUserAccountID: number, betas: OnyxEntry, isSelfTourViewed: boolean | undefined, + personalDetails: OnyxEntry, ) { const metaData = getReportMetadata(report?.reportID); const isOptimisticReport = metaData?.isOptimisticReport; @@ -4028,7 +4023,7 @@ function clearCreateChatError( return; } - navigateToConciergeChatAndDeleteReport(report?.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, undefined, true); + navigateToConciergeChatAndDeleteReport(report?.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, undefined, true, personalDetails); } /** diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index b9bcd906628e..bc88e34af9cc 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -1416,6 +1416,7 @@ function clearTaskErrors( introSelected: OnyxEntry, betas: OnyxEntry, isSelfTourViewed: boolean | undefined, + personalDetails: OnyxEntry, ) { const reportID = report?.reportID; if (!reportID) { @@ -1426,7 +1427,7 @@ function clearTaskErrors( if (report?.pendingFields?.createChat === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`, report.parentReportActionID ? {[report.parentReportActionID]: null} : {}); - navigateToConciergeChatAndDeleteReport(reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas); + navigateToConciergeChatAndDeleteReport(reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, undefined, undefined, personalDetails); return; } diff --git a/src/pages/Debug/Report/DebugReportPage.tsx b/src/pages/Debug/Report/DebugReportPage.tsx index 1510b45cfddc..10edbabd0bff 100644 --- a/src/pages/Debug/Report/DebugReportPage.tsx +++ b/src/pages/Debug/Report/DebugReportPage.tsx @@ -74,6 +74,7 @@ function DebugReportPage({ const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); + const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); const {accountID: currentUserAccountID} = useCurrentUserPersonalDetails(); const transactionID = DebugUtils.getTransactionID(report, reportActions); const isReportArchived = useReportIsArchived(reportID); @@ -166,7 +167,7 @@ function DebugReportPage({ Debug.setDebugData(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, data); }} onDelete={() => { - navigateToConciergeChatAndDeleteReport(reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, true, true); + navigateToConciergeChatAndDeleteReport(reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, true, true, personalDetails); }} validate={DebugUtils.validateReportDraftProperty} > diff --git a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx index 7b38d18af0d8..9569a03b2b52 100644 --- a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx @@ -646,7 +646,7 @@ const ContextMenuActions: ContextMenuAction[] = [ (shouldDisplayThreadReplies || (!isDeletedAction && !isArchivedRoom)) ); }, - onPress: (closePopover, {reportAction, currentUserAccountID, originalReport, introSelected, isSelfTourViewed, betas}) => { + onPress: (closePopover, {reportAction, currentUserAccountID, originalReport, introSelected, isSelfTourViewed, betas, personalDetails}) => { const childReportNotificationPreference = getChildReportNotificationPreferenceReportUtils(reportAction); if (closePopover) { hideContextMenu(false, () => { @@ -660,6 +660,7 @@ const ContextMenuActions: ContextMenuAction[] = [ isSelfTourViewed, betas, childReportNotificationPreference, + personalDetails, ); }); return; @@ -675,6 +676,7 @@ const ContextMenuActions: ContextMenuAction[] = [ isSelfTourViewed, betas, childReportNotificationPreference, + personalDetails, ); }, getDescription: () => {}, @@ -703,7 +705,7 @@ const ContextMenuActions: ContextMenuAction[] = [ (shouldDisplayThreadReplies || (!isDeletedAction && !isArchivedRoom)) ); }, - onPress: (closePopover, {reportAction, currentUserAccountID, originalReport, introSelected, isSelfTourViewed, betas}) => { + onPress: (closePopover, {reportAction, currentUserAccountID, originalReport, introSelected, isSelfTourViewed, betas, personalDetails}) => { const childReportNotificationPreference = getChildReportNotificationPreferenceReportUtils(reportAction); if (closePopover) { hideContextMenu(false, () => { @@ -717,6 +719,7 @@ const ContextMenuActions: ContextMenuAction[] = [ isSelfTourViewed, betas, childReportNotificationPreference, + personalDetails, ); }); return; @@ -732,6 +735,7 @@ const ContextMenuActions: ContextMenuAction[] = [ isSelfTourViewed, betas, childReportNotificationPreference, + personalDetails, ); }, getDescription: () => {}, diff --git a/src/pages/inbox/report/ReportActionItemCreated.tsx b/src/pages/inbox/report/ReportActionItemCreated.tsx index fd09bd3eb800..38519181ee31 100644 --- a/src/pages/inbox/report/ReportActionItemCreated.tsx +++ b/src/pages/inbox/report/ReportActionItemCreated.tsx @@ -36,6 +36,7 @@ function ReportActionItemCreated({reportID, policyID}: ReportActionItemCreatedPr const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [betas] = useOnyx(ONYXKEYS.BETAS); const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); + const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); const {accountID: currentUserAccountID} = useCurrentUserPersonalDetails(); if (!isChatReport(report)) { @@ -49,7 +50,7 @@ function ReportActionItemCreated({reportID, policyID}: ReportActionItemCreatedPr pendingAction={report?.pendingFields?.addWorkspaceRoom ?? report?.pendingFields?.createChat} errors={report?.errorFields?.addWorkspaceRoom ?? report?.errorFields?.createChat} errorRowStyles={[styles.ml10, styles.mr2]} - onClose={() => clearCreateChatError(report, conciergeReportID, introSelected, currentUserAccountID, betas, isSelfTourViewed)} + onClose={() => clearCreateChatError(report, conciergeReportID, introSelected, currentUserAccountID, betas, isSelfTourViewed, personalDetails)} > diff --git a/src/pages/inbox/report/ReportActionItemParentAction.tsx b/src/pages/inbox/report/ReportActionItemParentAction.tsx index 8d21b7af6445..c934700486f8 100644 --- a/src/pages/inbox/report/ReportActionItemParentAction.tsx +++ b/src/pages/inbox/report/ReportActionItemParentAction.tsx @@ -201,7 +201,19 @@ function ReportActionItemParentAction({ report?.errorFields?.createChatThread ?? (report?.errorFields?.createChat ? getMicroSecondOnyxErrorWithTranslationKey('report.genericCreateReportFailureMessage') : null) } errorRowStyles={[styles.ml10, styles.mr2]} - onClose={() => navigateToConciergeChatAndDeleteReport(report?.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, allBetas, undefined, true)} + onClose={() => + navigateToConciergeChatAndDeleteReport( + report?.reportID, + conciergeReportID, + currentUserAccountID, + introSelected, + isSelfTourViewed, + allBetas, + undefined, + true, + personalDetails, + ) + } > {ancestors.map((ancestor) => { const {report: ancestorReport, reportAction: ancestorReportAction} = ancestor; @@ -227,7 +239,17 @@ function ReportActionItemParentAction({ errors={ancestorReport?.errorFields?.addWorkspaceRoom ?? ancestorReport?.errorFields?.createChat} errorRowStyles={[styles.ml10, styles.mr2]} onClose={() => - navigateToConciergeChatAndDeleteReport(ancestorReport.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, allBetas) + navigateToConciergeChatAndDeleteReport( + ancestorReport.reportID, + conciergeReportID, + currentUserAccountID, + introSelected, + isSelfTourViewed, + allBetas, + undefined, + undefined, + personalDetails, + ) } > {shouldDisplayThreadDivider && ( diff --git a/src/pages/settings/HelpPage/HelpPage.tsx b/src/pages/settings/HelpPage/HelpPage.tsx index c0ec3147e173..44e5f662f157 100644 --- a/src/pages/settings/HelpPage/HelpPage.tsx +++ b/src/pages/settings/HelpPage/HelpPage.tsx @@ -65,7 +65,7 @@ function HelpPage() { description: translate('initialSettingsPage.helpPage.accountManagerDescription'), icon: accountManagerDetails.avatar, iconType: CONST.ICON_TYPE_AVATAR, - onPress: () => navigateToAndOpenReportWithAccountIDs([accountManagerDetails.accountID], currentUserAccountID, introSelected, isSelfTourViewed, betas), + onPress: () => navigateToAndOpenReportWithAccountIDs([accountManagerDetails.accountID], currentUserAccountID, introSelected, isSelfTourViewed, betas, personalDetails), shouldShowRightIcon: true, wrapperStyle: [styles.sectionMenuItemTopDescription], sentryLabel: CONST.SENTRY_LABEL.SETTINGS_HELP.ACCOUNT_MANAGER, @@ -80,7 +80,7 @@ function HelpPage() { description: translate('initialSettingsPage.helpPage.partnerManagerDescription'), icon: partnerManagerDetails.avatar, iconType: CONST.ICON_TYPE_AVATAR, - onPress: () => navigateToAndOpenReportWithAccountIDs([partnerManagerDetails.accountID], currentUserAccountID, introSelected, isSelfTourViewed, betas), + onPress: () => navigateToAndOpenReportWithAccountIDs([partnerManagerDetails.accountID], currentUserAccountID, introSelected, isSelfTourViewed, betas, personalDetails), shouldShowRightIcon: true, wrapperStyle: [styles.sectionMenuItemTopDescription], sentryLabel: CONST.SENTRY_LABEL.SETTINGS_HELP.PARTNER_MANAGER, @@ -95,7 +95,7 @@ function HelpPage() { description: translate('initialSettingsPage.helpPage.guideDescription'), icon: guideDetails.avatar, iconType: CONST.ICON_TYPE_AVATAR, - onPress: () => navigateToAndOpenReportWithAccountIDs([guideDetails.accountID], currentUserAccountID, introSelected, isSelfTourViewed, betas), + onPress: () => navigateToAndOpenReportWithAccountIDs([guideDetails.accountID], currentUserAccountID, introSelected, isSelfTourViewed, betas, personalDetails), shouldShowRightIcon: true, wrapperStyle: [styles.sectionMenuItemTopDescription], sentryLabel: CONST.SENTRY_LABEL.SETTINGS_HELP.GUIDE, diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index f6a1c34fbc6b..782e537aaa1a 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -360,7 +360,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, personalDetails, isLoadingR return; } setShowErrorModal(false); - navigateToAndOpenReportWithAccountIDs([policy.ownerAccountID], currentUserPersonalDetails.accountID, introSelected, isSelfTourViewed, betas); + navigateToAndOpenReportWithAccountIDs([policy.ownerAccountID], currentUserPersonalDetails.accountID, introSelected, isSelfTourViewed, betas, personalDetails); }} html={translate('workflowsPayerPage.shareBankAccount.errorDescription', { admin: selectedPayerDetails?.displayName ?? '', diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index c9f7625a508e..bac01b44af1c 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -325,7 +325,7 @@ describe('actions/Report', () => { return waitForBatchedUpdates() .then(() => { - Report.clearCreateChatError(REPORT, CONCIERGE_REPORT_ID, {choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, TEST_USER_ACCOUNT_ID, undefined, false); + Report.clearCreateChatError(REPORT, CONCIERGE_REPORT_ID, {choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, TEST_USER_ACCOUNT_ID, undefined, false, undefined); return waitForBatchedUpdates(); }) .then( @@ -358,7 +358,7 @@ describe('actions/Report', () => { return waitForBatchedUpdates() .then(() => { - Report.clearCreateChatError(REPORT, CONCIERGE_REPORT_ID, INTRO_SELECTED, TEST_USER_ACCOUNT_ID, undefined, false); + Report.clearCreateChatError(REPORT, CONCIERGE_REPORT_ID, INTRO_SELECTED, TEST_USER_ACCOUNT_ID, undefined, false, undefined); return waitForBatchedUpdates(); }) .then( @@ -390,7 +390,7 @@ describe('actions/Report', () => { return waitForBatchedUpdates() .then(() => { - Report.clearCreateChatError(REPORT, CONCIERGE_REPORT_ID, INTRO_SELECTED, TEST_USER_ACCOUNT_ID, undefined, false); + Report.clearCreateChatError(REPORT, CONCIERGE_REPORT_ID, INTRO_SELECTED, TEST_USER_ACCOUNT_ID, undefined, false, undefined); return waitForBatchedUpdates(); }) .then( @@ -433,7 +433,7 @@ describe('actions/Report', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_METADATA}${REPORT.reportID}`, {isOptimisticReport: true}); await waitForBatchedUpdates(); - Report.clearCreateChatError(REPORT, undefined, INTRO_SELECTED, TEST_USER_ACCOUNT_ID, betas, false); + Report.clearCreateChatError(REPORT, undefined, INTRO_SELECTED, TEST_USER_ACCOUNT_ID, betas, false, undefined); await waitForBatchedUpdates(); TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.OPEN_REPORT, 1); @@ -4436,7 +4436,7 @@ describe('actions/Report', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, testReport); await waitForBatchedUpdates(); - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); + Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined, undefined, undefined); await waitForBatchedUpdates(); @@ -4450,7 +4450,7 @@ describe('actions/Report', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, testReport); await waitForBatchedUpdates(); - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, true); + Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, true, undefined, undefined); await waitForBatchedUpdates(); @@ -4463,7 +4463,7 @@ describe('actions/Report', () => { await waitForBatchedUpdates(); expect(() => { - Report.navigateToConciergeChatAndDeleteReport(undefined, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); + Report.navigateToConciergeChatAndDeleteReport(undefined, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined, undefined, undefined); }).not.toThrow(); }); @@ -4472,7 +4472,7 @@ describe('actions/Report', () => { await waitForBatchedUpdates(); expect(() => { - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, undefined, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); + Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, undefined, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined, undefined, undefined); }).not.toThrow(); await waitForBatchedUpdates(); @@ -4486,7 +4486,7 @@ describe('actions/Report', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, testReport); await waitForBatchedUpdates(); - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, false, true); + Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, false, true, undefined); await waitForBatchedUpdates(); @@ -4499,7 +4499,7 @@ describe('actions/Report', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, testReport); await waitForBatchedUpdates(); - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, true, true); + Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, true, true, undefined); await waitForBatchedUpdates(); @@ -4513,7 +4513,7 @@ describe('actions/Report', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, testReport); await waitForBatchedUpdates(); - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); + Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined, undefined, undefined); await waitForBatchedUpdates(); @@ -4528,7 +4528,7 @@ describe('actions/Report', () => { await waitForBatchedUpdates(); expect(() => { - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, undefined, undefined, undefined); + Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, undefined, undefined, undefined, undefined, undefined, undefined); }).not.toThrow(); await waitForBatchedUpdates(); @@ -4542,7 +4542,7 @@ describe('actions/Report', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, testReport); await waitForBatchedUpdates(); - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, true, undefined); + Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, true, undefined, undefined, undefined, undefined); await waitForBatchedUpdates(); @@ -4864,7 +4864,7 @@ describe('actions/Report', () => { await waitForBatchedUpdates(); expect(() => { - Report.toggleSubscribeToChildReport(CHILD_REPORT_ID, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, false, undefined, 'hidden'); + Report.toggleSubscribeToChildReport(CHILD_REPORT_ID, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, false, undefined, 'hidden', undefined); }).not.toThrow(); }); @@ -4882,7 +4882,7 @@ describe('actions/Report', () => { await waitForBatchedUpdates(); expect(() => { - Report.toggleSubscribeToChildReport(undefined, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, false, undefined); + Report.toggleSubscribeToChildReport(undefined, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, false, undefined, undefined, undefined); }).not.toThrow(); }); @@ -4900,7 +4900,7 @@ describe('actions/Report', () => { await waitForBatchedUpdates(); expect(() => { - Report.toggleSubscribeToChildReport(CHILD_REPORT_ID, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, undefined, true, undefined, 'hidden'); + Report.toggleSubscribeToChildReport(CHILD_REPORT_ID, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, undefined, true, undefined, 'hidden', undefined); }).not.toThrow(); }); @@ -4927,6 +4927,7 @@ describe('actions/Report', () => { true, undefined, CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS, + undefined, ); }).not.toThrow(); }); @@ -4945,7 +4946,7 @@ describe('actions/Report', () => { await waitForBatchedUpdates(); expect(() => { - Report.toggleSubscribeToChildReport(undefined, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, true, undefined); + Report.toggleSubscribeToChildReport(undefined, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, true, undefined, undefined, undefined); }).not.toThrow(); }); @@ -4963,7 +4964,7 @@ describe('actions/Report', () => { await waitForBatchedUpdates(); expect(() => { - Report.toggleSubscribeToChildReport(undefined, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, false, undefined); + Report.toggleSubscribeToChildReport(undefined, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, false, undefined, undefined, undefined); }).not.toThrow(); }); @@ -4981,7 +4982,7 @@ describe('actions/Report', () => { await waitForBatchedUpdates(); expect(() => { - Report.toggleSubscribeToChildReport(CHILD_REPORT_ID, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, true, undefined, 'hidden'); + Report.toggleSubscribeToChildReport(CHILD_REPORT_ID, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, true, undefined, 'hidden', undefined); }).not.toThrow(); }); @@ -4999,7 +5000,7 @@ describe('actions/Report', () => { await waitForBatchedUpdates(); expect(() => { - Report.toggleSubscribeToChildReport(CHILD_REPORT_ID, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, false, undefined); + Report.toggleSubscribeToChildReport(CHILD_REPORT_ID, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, false, undefined, undefined, undefined); }).not.toThrow(); }); @@ -5018,7 +5019,7 @@ describe('actions/Report', () => { await waitForBatchedUpdates(); expect(() => { - Report.toggleSubscribeToChildReport(CHILD_REPORT_ID, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, undefined, testBetas, 'hidden'); + Report.toggleSubscribeToChildReport(CHILD_REPORT_ID, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, undefined, testBetas, 'hidden', undefined); }).not.toThrow(); }); @@ -5037,7 +5038,7 @@ describe('actions/Report', () => { await waitForBatchedUpdates(); expect(() => { - Report.toggleSubscribeToChildReport(undefined, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, undefined, testBetas); + Report.toggleSubscribeToChildReport(undefined, TEST_USER_ACCOUNT_ID, PARENT_REPORT_ACTION, PARENT_REPORT, INTRO_SELECTED, undefined, testBetas, undefined, undefined); }).not.toThrow(); }); }); @@ -6559,7 +6560,7 @@ describe('actions/Report', () => { const testIntroSelected: OnyxTypes.IntroSelected = {choice: CONST.ONBOARDING_CHOICES.ADMIN}; - Report.navigateToAndOpenReportWithAccountIDs([PARTICIPANT_ACCOUNT_ID], TEST_USER_ACCOUNT_ID, testIntroSelected, isSelfTourViewed, undefined); + Report.navigateToAndOpenReportWithAccountIDs([PARTICIPANT_ACCOUNT_ID], TEST_USER_ACCOUNT_ID, testIntroSelected, isSelfTourViewed, undefined, undefined); await waitForBatchedUpdates(); TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.OPEN_REPORT, 1); @@ -6586,7 +6587,7 @@ describe('actions/Report', () => { const testIntroSelected: OnyxTypes.IntroSelected = {choice: CONST.ONBOARDING_CHOICES.ADMIN}; - Report.navigateToAndOpenReportWithAccountIDs([PARTICIPANT_ACCOUNT_ID], TEST_USER_ACCOUNT_ID, testIntroSelected, false, undefined); + Report.navigateToAndOpenReportWithAccountIDs([PARTICIPANT_ACCOUNT_ID], TEST_USER_ACCOUNT_ID, testIntroSelected, false, undefined, undefined); await waitForBatchedUpdates(); TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.OPEN_REPORT, 0); From 757d51f085f8756c37e5e6242626ecea59daf334 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Mon, 27 Apr 2026 02:08:55 +0700 Subject: [PATCH 3/8] fix: lints --- src/components/ReportActionItem/MoneyRequestReceiptView.tsx | 4 ++-- src/libs/actions/Report/index.ts | 4 ++-- src/libs/actions/Task.ts | 2 +- src/pages/Debug/Report/DebugReportPage.tsx | 3 ++- src/pages/inbox/report/ReportActionItemParentAction.tsx | 4 ++-- tests/actions/ReportTest.ts | 6 +++--- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx index 130e6a899879..a8444e5a706f 100644 --- a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx +++ b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx @@ -365,7 +365,7 @@ function MoneyRequestReceiptView({ } if (transaction?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { if (chatReport?.reportID && getCreationReportErrors(chatReport)) { - navigateToConciergeChatAndDeleteReport(chatReport.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, true, true, personalDetails); + navigateToConciergeChatAndDeleteReport(chatReport.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, personalDetails, true, true); return; } if (parentReportAction) { @@ -402,7 +402,7 @@ function MoneyRequestReceiptView({ if (isInNarrowPaneModal) { Navigation.goBack(); } - navigateToConciergeChatAndDeleteReport(report.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, true, true, personalDetails); + navigateToConciergeChatAndDeleteReport(report.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, personalDetails, true, true); } }; diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index 2a5ce5222e0f..e2b526c993fc 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -4031,9 +4031,9 @@ function navigateToConciergeChatAndDeleteReport( introSelected: OnyxEntry, isSelfTourViewed: boolean | undefined, betas: OnyxEntry, + personalDetails: OnyxEntry, shouldPopToTop = false, shouldDeleteChildReports = false, - personalDetails: OnyxEntry, ) { // Dismiss the current report screen and replace it with Concierge Chat if (shouldPopToTop) { @@ -4064,7 +4064,7 @@ function clearCreateChatError( return; } - navigateToConciergeChatAndDeleteReport(report?.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, undefined, true, personalDetails); + navigateToConciergeChatAndDeleteReport(report?.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, personalDetails, undefined, true); } /** diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 16e9d6fe0e91..907d68a9f46e 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -1427,7 +1427,7 @@ function clearTaskErrors( if (report?.pendingFields?.createChat === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`, report.parentReportActionID ? {[report.parentReportActionID]: null} : {}); - navigateToConciergeChatAndDeleteReport(reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, undefined, undefined, personalDetails); + navigateToConciergeChatAndDeleteReport(reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, personalDetails, undefined, undefined); return; } diff --git a/src/pages/Debug/Report/DebugReportPage.tsx b/src/pages/Debug/Report/DebugReportPage.tsx index 8d6031a6b456..d4d4c31663b2 100644 --- a/src/pages/Debug/Report/DebugReportPage.tsx +++ b/src/pages/Debug/Report/DebugReportPage.tsx @@ -170,7 +170,7 @@ function DebugReportPage({ Debug.setDebugData(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, data); }} onDelete={() => { - navigateToConciergeChatAndDeleteReport(reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, true, true, personalDetails); + navigateToConciergeChatAndDeleteReport(reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, personalDetails, true, true); }} validate={DebugUtils.validateReportDraftProperty} > @@ -229,6 +229,7 @@ function DebugReportPage({ styles.textSupporting, theme.cardBG, transactionID, + personalDetails, translate, icons.Eye, currentUserAccountID, diff --git a/src/pages/inbox/report/ReportActionItemParentAction.tsx b/src/pages/inbox/report/ReportActionItemParentAction.tsx index 75691e383435..2570e91bd1f2 100644 --- a/src/pages/inbox/report/ReportActionItemParentAction.tsx +++ b/src/pages/inbox/report/ReportActionItemParentAction.tsx @@ -192,9 +192,9 @@ function ReportActionItemParentAction({ introSelected, isSelfTourViewed, allBetas, + personalDetails, undefined, true, - personalDetails, ) } > @@ -228,9 +228,9 @@ function ReportActionItemParentAction({ introSelected, isSelfTourViewed, allBetas, + personalDetails, undefined, undefined, - personalDetails, ) } > diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index 43ddb036172b..27bc828b13ae 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -4650,7 +4650,7 @@ describe('actions/Report', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, testReport); await waitForBatchedUpdates(); - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, true, undefined, undefined); + Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined, true, undefined); await waitForBatchedUpdates(); @@ -4686,7 +4686,7 @@ describe('actions/Report', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, testReport); await waitForBatchedUpdates(); - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, false, true, undefined); + Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined, false, true); await waitForBatchedUpdates(); @@ -4699,7 +4699,7 @@ describe('actions/Report', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, testReport); await waitForBatchedUpdates(); - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, true, true, undefined); + Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined, true, true); await waitForBatchedUpdates(); From d846c10f7c3749d6c603d9610d581ff39f383fbe Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Fri, 1 May 2026 17:40:57 +0700 Subject: [PATCH 4/8] fix: use hook instead of onyx --- src/components/ReportActionItem/MoneyRequestReceiptView.tsx | 3 ++- src/pages/Debug/Report/DebugReportPage.tsx | 3 ++- .../inbox/report/ContextMenu/BaseReportActionContextMenu.tsx | 4 ++-- src/pages/inbox/report/ReportActionItemCreated.tsx | 3 ++- src/pages/inbox/report/ReportActionItemThread.tsx | 3 ++- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx index 6a7464078164..d2ba88fd7065 100644 --- a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx +++ b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx @@ -9,6 +9,7 @@ import AttachmentPicker from '@components/AttachmentPicker'; import Icon from '@components/Icon'; import {ModalActions} from '@components/Modal/Global/ModalContext'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import {usePersonalDetails} from '@components/OnyxListItemProvider'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import PressableWithoutFocus from '@components/Pressable/PressableWithoutFocus'; import ReceiptAudit, {ReceiptAuditMessages} from '@components/ReceiptAudit'; @@ -134,7 +135,7 @@ function MoneyRequestReceiptView({ const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); const [betas] = useOnyx(ONYXKEYS.BETAS); - const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); + const personalDetails = usePersonalDetails(); const delegateAccountID = useDelegateAccountID(); const [isLoading, setIsLoading] = useState(true); diff --git a/src/pages/Debug/Report/DebugReportPage.tsx b/src/pages/Debug/Report/DebugReportPage.tsx index d4d4c31663b2..704392e45db2 100644 --- a/src/pages/Debug/Report/DebugReportPage.tsx +++ b/src/pages/Debug/Report/DebugReportPage.tsx @@ -4,6 +4,7 @@ import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import Button from '@components/Button'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import {usePersonalDetails} from '@components/OnyxListItemProvider'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; @@ -76,7 +77,7 @@ function DebugReportPage({ const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); - const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); + const personalDetails = usePersonalDetails(); const {accountID: currentUserAccountID} = useCurrentUserPersonalDetails(); const transactionID = DebugUtils.getTransactionID(report, reportActions); const isReportArchived = useReportIsArchived(reportID); diff --git a/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx b/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx index 77f57b59d7b7..31eda8e12a6e 100755 --- a/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx +++ b/src/pages/inbox/report/ContextMenu/BaseReportActionContextMenu.tsx @@ -12,7 +12,7 @@ import CompactMenuContext from '@components/CompactMenuContext'; import ContextMenuItem from '@components/ContextMenuItem'; import {useDelegateNoAccessActions, useDelegateNoAccessState} from '@components/DelegateNoAccessModalProvider'; import FocusTrapForModal from '@components/FocusTrap/FocusTrapForModal'; -import {useSession} from '@components/OnyxListItemProvider'; +import {usePersonalDetails, useSession} from '@components/OnyxListItemProvider'; import useArrowKeyFocusManager from '@hooks/useArrowKeyFocusManager'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useDelegateAccountID from '@hooks/useDelegateAccountID'; @@ -245,7 +245,7 @@ function BaseReportActionContextMenu({ const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST); const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); - const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); + const personalDetails = usePersonalDetails(); const delegateAccountID = useDelegateAccountID(); const isTryNewDotNVPDismissed = !!tryNewDot?.classicRedirect?.dismissed; diff --git a/src/pages/inbox/report/ReportActionItemCreated.tsx b/src/pages/inbox/report/ReportActionItemCreated.tsx index 1e3f710c162e..f6adfef98160 100644 --- a/src/pages/inbox/report/ReportActionItemCreated.tsx +++ b/src/pages/inbox/report/ReportActionItemCreated.tsx @@ -2,6 +2,7 @@ import {hasSeenTourSelector} from '@selectors/Onboarding'; import React, {memo} from 'react'; import {View} from 'react-native'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import {usePersonalDetails} from '@components/OnyxListItemProvider'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import ReportActionAvatars from '@components/ReportActionAvatars'; import ReportWelcomeText from '@components/ReportWelcomeText'; @@ -36,7 +37,7 @@ function ReportActionItemCreated({reportID, policyID}: ReportActionItemCreatedPr const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [betas] = useOnyx(ONYXKEYS.BETAS); const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); - const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); + const personalDetails = usePersonalDetails(); const {accountID: currentUserAccountID} = useCurrentUserPersonalDetails(); if (!isChatReport(report)) { diff --git a/src/pages/inbox/report/ReportActionItemThread.tsx b/src/pages/inbox/report/ReportActionItemThread.tsx index 715e7947df2f..c6b49b0e2f86 100644 --- a/src/pages/inbox/report/ReportActionItemThread.tsx +++ b/src/pages/inbox/report/ReportActionItemThread.tsx @@ -2,6 +2,7 @@ import React from 'react'; import type {GestureResponderEvent} from 'react-native'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; +import {usePersonalDetails} from '@components/OnyxListItemProvider'; import PressableWithSecondaryInteraction from '@components/PressableWithSecondaryInteraction'; import ReportActionAvatars from '@components/ReportActionAvatars'; import Text from '@components/Text'; @@ -47,7 +48,7 @@ function ReportActionItemThread({numberOfReplies, accountIDs, mostRecentReply, r const [childReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportAction.childReportID}`); const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [betas] = useOnyx(ONYXKEYS.BETAS); - const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); + const personalDetails = usePersonalDetails(); const numberOfRepliesText = numberOfReplies > CONST.MAX_THREAD_REPLIES_PREVIEW ? `${CONST.MAX_THREAD_REPLIES_PREVIEW}+` : `${numberOfReplies}`; const replyText = numberOfReplies === 1 ? translate('threads.reply') : translate('threads.replies'); From d410151b27efcc0b7aac4e759336e86d1c780d13 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Fri, 8 May 2026 15:07:21 +0700 Subject: [PATCH 5/8] fix: refactoring --- .../MoneyRequestReceiptView.tsx | 54 +++++++++++-- src/components/ReportActionItem/TaskView.tsx | 14 +++- src/libs/actions/Report/index.ts | 38 ++++++++- src/libs/actions/Task.ts | 19 ++++- src/pages/Debug/Report/DebugReportPage.tsx | 39 ++++++++-- .../inbox/report/ReportActionItemCreated.tsx | 37 +++++++-- .../report/ReportActionItemParentAction.tsx | 13 +++- tests/actions/ReportTest.ts | 78 +++++++++++++++---- 8 files changed, 250 insertions(+), 42 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx index cf7f53a15c3d..fbb7432e6e08 100644 --- a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx +++ b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx @@ -1,6 +1,6 @@ import {hasSeenTourSelector} from '@selectors/Onboarding'; import mapValues from 'lodash/mapValues'; -import React, {useEffect, useMemo, useRef, useState} from 'react'; +import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import type {StyleProp, ViewStyle} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; @@ -9,7 +9,6 @@ import AttachmentPicker from '@components/AttachmentPicker'; import Icon from '@components/Icon'; import {ModalActions} from '@components/Modal/Global/ModalContext'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; -import {usePersonalDetails} from '@components/OnyxListItemProvider'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import PressableWithoutFocus from '@components/Pressable/PressableWithoutFocus'; import ReceiptAudit, {ReceiptAuditMessages} from '@components/ReceiptAudit'; @@ -71,6 +70,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; +import type PersonalDetails from '@src/types/onyx/PersonalDetails'; import type {TransactionPendingFieldsKey} from '@src/types/onyx/Transaction'; import type {FileObject} from '@src/types/utils/Attachment'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; @@ -112,6 +112,13 @@ const receiptImageViolationNames = new Set([ const receiptFieldViolationNames = new Set([CONST.VIOLATIONS.MODIFIED_AMOUNT, CONST.VIOLATIONS.MODIFIED_DATE]); +const findConciergePersonalDetail = (list: OnyxEntry): OnyxEntry => { + if (!list) { + return undefined; + } + return Object.values(list).find((detail): detail is PersonalDetails => detail?.login === CONST.EMAIL.CONCIERGE); +}; + function MoneyRequestReceiptView({ report, readonly = false, @@ -134,7 +141,17 @@ function MoneyRequestReceiptView({ const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); const [betas] = useOnyx(ONYXKEYS.BETAS); - const personalDetails = usePersonalDetails(); + const [conciergePersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: findConciergePersonalDetail}); + const reportOwnerSelector = useCallback( + (list: OnyxEntry): OnyxEntry => (report?.ownerAccountID ? (list?.[report.ownerAccountID] ?? undefined) : undefined), + [report?.ownerAccountID], + ); + const [reportOwnerPersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: reportOwnerSelector}, [reportOwnerSelector]); + const chatReportOwnerSelector = useCallback( + (list: OnyxEntry): OnyxEntry => (chatReport?.ownerAccountID ? (list?.[chatReport.ownerAccountID] ?? undefined) : undefined), + [chatReport?.ownerAccountID], + ); + const [chatReportOwnerPersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: chatReportOwnerSelector}, [chatReportOwnerSelector]); const delegateAccountID = useDelegateAccountID(); const [isLoading, setIsLoading] = useState(true); @@ -163,7 +180,8 @@ function MoneyRequestReceiptView({ const didReceiptScanSucceed = hasReceipt && didReceiptScanSucceedTransactionUtils(transaction); const isInvoice = isInvoiceReport(moneyRequestReport); const isChatReportArchived = useReportIsArchived(moneyRequestReport?.chatReportID); - const {login: currentUserLogin, accountID: currentUserAccountID, timezone: currentUserTimezone} = useCurrentUserPersonalDetails(); + const currentUserPersonalDetail = useCurrentUserPersonalDetails(); + const {login: currentUserLogin, accountID: currentUserAccountID, timezone: currentUserTimezone} = currentUserPersonalDetail; const theme = useTheme(); const ancestors = useAncestors(report); const {hovered, bind: hoverBind} = useHover(); @@ -368,7 +386,19 @@ function MoneyRequestReceiptView({ } if (transaction?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { if (chatReport?.reportID && getCreationReportErrors(chatReport)) { - navigateToConciergeChatAndDeleteReport(chatReport.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, personalDetails, true, true); + navigateToConciergeChatAndDeleteReport( + chatReport.reportID, + conciergeReportID, + currentUserAccountID, + introSelected, + isSelfTourViewed, + betas, + chatReportOwnerPersonalDetail, + currentUserPersonalDetail, + conciergePersonalDetail, + true, + true, + ); return; } if (parentReportAction) { @@ -405,7 +435,19 @@ function MoneyRequestReceiptView({ if (isInNarrowPaneModal) { Navigation.goBack(); } - navigateToConciergeChatAndDeleteReport(report.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, personalDetails, true, true); + navigateToConciergeChatAndDeleteReport( + report.reportID, + conciergeReportID, + currentUserAccountID, + introSelected, + isSelfTourViewed, + betas, + reportOwnerPersonalDetail, + currentUserPersonalDetail, + conciergePersonalDetail, + true, + true, + ); } }; diff --git a/src/components/ReportActionItem/TaskView.tsx b/src/components/ReportActionItem/TaskView.tsx index a098bc14a74c..212572aa1790 100644 --- a/src/components/ReportActionItem/TaskView.tsx +++ b/src/components/ReportActionItem/TaskView.tsx @@ -118,7 +118,19 @@ function TaskView({report, parentReport, action}: TaskViewProps) { clearTaskErrors(report, conciergeReportID, accountID, introSelected, betas, isSelfTourViewed, personalDetails)} + onClose={() => + clearTaskErrors( + report, + conciergeReportID, + accountID, + introSelected, + betas, + isSelfTourViewed, + report?.ownerAccountID ? (personalDetails?.[report.ownerAccountID] ?? undefined) : undefined, + currentUserPersonalDetails, + (personalDetails ? Object.values(personalDetails).find((detail) => detail?.login === CONST.EMAIL.CONCIERGE) : undefined) ?? undefined, + ) + } errorRowStyles={styles.ph5} > diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index d58ad2914bbd..07d6863ba98a 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -229,6 +229,7 @@ import type { VisibleReportActionsDerivedValue, } from '@src/types/onyx'; import type {Decision} from '@src/types/onyx/OriginalMessage'; +import type PersonalDetails from '@src/types/onyx/PersonalDetails'; import type {CurrentUserPersonalDetails, Timezone} from '@src/types/onyx/PersonalDetails'; import type {ConnectionName} from '@src/types/onyx/Policy'; import type {NotificationPreference, Participants, Participant as ReportParticipant, RoomVisibility, WriteCapability} from '@src/types/onyx/Report'; @@ -428,6 +429,20 @@ Onyx.connect({ }, }); +/** + * Builds a partial PersonalDetailsList containing only the records passed in. Skips entries with no accountID. + */ +function buildPersonalDetailsList(details: Array>): PersonalDetailsList { + const result: PersonalDetailsList = {}; + for (const detail of details) { + if (detail?.accountID == null) { + continue; + } + result[detail.accountID] = detail; + } + return result; +} + const typingWatchTimers: Record = {}; let reportIDDeeplinkedFromOldDot: string | undefined; @@ -4112,7 +4127,9 @@ function navigateToConciergeChatAndDeleteReport( introSelected: OnyxEntry, isSelfTourViewed: boolean | undefined, betas: OnyxEntry, - personalDetails: OnyxEntry, + reportOwnerPersonalDetail: OnyxEntry, + currentUserPersonalDetail: OnyxEntry, + conciergePersonalDetail: OnyxEntry, shouldPopToTop = false, shouldDeleteChildReports = false, ) { @@ -4122,6 +4139,7 @@ function navigateToConciergeChatAndDeleteReport( } else { Navigation.goBack(); } + const personalDetails = buildPersonalDetailsList([reportOwnerPersonalDetail, currentUserPersonalDetail, conciergePersonalDetail]); navigateToConciergeChat(conciergeReportID, introSelected, currentUserAccountID, isSelfTourViewed, betas, false, undefined, undefined, undefined, personalDetails); // eslint-disable-next-line @typescript-eslint/no-deprecated InteractionManager.runAfterInteractions(() => { @@ -4136,7 +4154,9 @@ function clearCreateChatError( currentUserAccountID: number, betas: OnyxEntry, isSelfTourViewed: boolean | undefined, - personalDetails: OnyxEntry, + reportOwnerPersonalDetail: OnyxEntry, + currentUserPersonalDetail: OnyxEntry, + conciergePersonalDetail: OnyxEntry, ) { const metaData = getReportMetadata(report?.reportID); const isOptimisticReport = metaData?.isOptimisticReport; @@ -4145,7 +4165,19 @@ function clearCreateChatError( return; } - navigateToConciergeChatAndDeleteReport(report?.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, personalDetails, undefined, true); + navigateToConciergeChatAndDeleteReport( + report?.reportID, + conciergeReportID, + currentUserAccountID, + introSelected, + isSelfTourViewed, + betas, + reportOwnerPersonalDetail, + currentUserPersonalDetail, + conciergePersonalDetail, + undefined, + true, + ); } /** diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index da8b60a995b2..d5637bf22511 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -25,6 +25,7 @@ import ROUTES from '@src/ROUTES'; import type {Route} from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; import type {Icon} from '@src/types/onyx/OnyxCommon'; +import type PersonalDetails from '@src/types/onyx/PersonalDetails'; import type {ReportActions} from '@src/types/onyx/ReportAction'; import type ReportAction from '@src/types/onyx/ReportAction'; import type {OnyxData} from '@src/types/onyx/Request'; @@ -1421,7 +1422,9 @@ function clearTaskErrors( introSelected: OnyxEntry, betas: OnyxEntry, isSelfTourViewed: boolean | undefined, - personalDetails: OnyxEntry, + reportOwnerPersonalDetail: OnyxEntry, + currentUserPersonalDetail: OnyxEntry, + conciergePersonalDetail: OnyxEntry, ) { const reportID = report?.reportID; if (!reportID) { @@ -1432,7 +1435,19 @@ function clearTaskErrors( if (report?.pendingFields?.createChat === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`, report.parentReportActionID ? {[report.parentReportActionID]: null} : {}); - navigateToConciergeChatAndDeleteReport(reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, personalDetails, undefined, undefined); + navigateToConciergeChatAndDeleteReport( + reportID, + conciergeReportID, + currentUserAccountID, + introSelected, + isSelfTourViewed, + betas, + reportOwnerPersonalDetail, + currentUserPersonalDetail, + conciergePersonalDetail, + undefined, + undefined, + ); return; } diff --git a/src/pages/Debug/Report/DebugReportPage.tsx b/src/pages/Debug/Report/DebugReportPage.tsx index 5b51de0cb1f1..86f6c52f8a24 100644 --- a/src/pages/Debug/Report/DebugReportPage.tsx +++ b/src/pages/Debug/Report/DebugReportPage.tsx @@ -4,7 +4,6 @@ import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import Button from '@components/Button'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import {usePersonalDetails} from '@components/OnyxListItemProvider'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; @@ -33,9 +32,17 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type {ReportAttributesDerivedValue} from '@src/types/onyx'; +import type {PersonalDetailsList, ReportAttributesDerivedValue} from '@src/types/onyx'; +import type PersonalDetails from '@src/types/onyx/PersonalDetails'; import DebugReportActions from './DebugReportActions'; +const findConciergePersonalDetail = (list: OnyxEntry): OnyxEntry => { + if (!list) { + return undefined; + } + return Object.values(list).find((detail): detail is PersonalDetails => detail?.login === CONST.EMAIL.CONCIERGE); +}; + type DebugReportPageProps = PlatformStackScreenProps; type Metadata = { @@ -77,8 +84,14 @@ function DebugReportPage({ const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); - const personalDetails = usePersonalDetails(); - const {accountID: currentUserAccountID, login: currentUserLogin} = useCurrentUserPersonalDetails(); + const currentUserPersonalDetail = useCurrentUserPersonalDetails(); + const {accountID: currentUserAccountID, login: currentUserLogin} = currentUserPersonalDetail; + const [conciergePersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: findConciergePersonalDetail}); + const reportOwnerSelector = useCallback( + (list: OnyxEntry): OnyxEntry => (report?.ownerAccountID ? (list?.[report.ownerAccountID] ?? undefined) : undefined), + [report?.ownerAccountID], + ); + const [reportOwnerPersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: reportOwnerSelector}, [reportOwnerSelector]); const transactionID = DebugUtils.getTransactionID(report, reportActions); const isReportArchived = useReportIsArchived(reportID); @@ -187,7 +200,19 @@ function DebugReportPage({ Debug.setDebugData(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, data); }} onDelete={() => { - navigateToConciergeChatAndDeleteReport(reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, personalDetails, true, true); + navigateToConciergeChatAndDeleteReport( + reportID, + conciergeReportID, + currentUserAccountID, + introSelected, + isSelfTourViewed, + betas, + reportOwnerPersonalDetail, + currentUserPersonalDetail, + conciergePersonalDetail, + true, + true, + ); }} validate={DebugUtils.validateReportDraftProperty} > @@ -246,7 +271,6 @@ function DebugReportPage({ styles.textSupporting, theme.cardBG, transactionID, - personalDetails, translate, icons.Eye, currentUserAccountID, @@ -254,6 +278,9 @@ function DebugReportPage({ introSelected, isSelfTourViewed, betas, + reportOwnerPersonalDetail, + currentUserPersonalDetail, + conciergePersonalDetail, ], ); diff --git a/src/pages/inbox/report/ReportActionItemCreated.tsx b/src/pages/inbox/report/ReportActionItemCreated.tsx index f6adfef98160..73bd35438fab 100644 --- a/src/pages/inbox/report/ReportActionItemCreated.tsx +++ b/src/pages/inbox/report/ReportActionItemCreated.tsx @@ -1,8 +1,8 @@ import {hasSeenTourSelector} from '@selectors/Onboarding'; -import React, {memo} from 'react'; +import React, {memo, useCallback} from 'react'; import {View} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; -import {usePersonalDetails} from '@components/OnyxListItemProvider'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import ReportActionAvatars from '@components/ReportActionAvatars'; import ReportWelcomeText from '@components/ReportWelcomeText'; @@ -16,8 +16,17 @@ import {isChatReport, isCurrentUserInvoiceReceiver, isInvoiceRoom, navigateToDet import {clearCreateChatError} from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {PersonalDetailsList} from '@src/types/onyx'; +import type PersonalDetails from '@src/types/onyx/PersonalDetails'; import AnimatedEmptyStateBackground from './AnimatedEmptyStateBackground'; +const findConciergePersonalDetail = (list: OnyxEntry): OnyxEntry => { + if (!list) { + return undefined; + } + return Object.values(list).find((detail): detail is PersonalDetails => detail?.login === CONST.EMAIL.CONCIERGE); +}; + type ReportActionItemCreatedProps = { /** The id of the report */ reportID: string | undefined; @@ -37,8 +46,14 @@ function ReportActionItemCreated({reportID, policyID}: ReportActionItemCreatedPr const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [betas] = useOnyx(ONYXKEYS.BETAS); const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); - const personalDetails = usePersonalDetails(); - const {accountID: currentUserAccountID} = useCurrentUserPersonalDetails(); + const currentUserPersonalDetail = useCurrentUserPersonalDetails(); + const {accountID: currentUserAccountID} = currentUserPersonalDetail; + const [conciergePersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: findConciergePersonalDetail}); + const reportOwnerSelector = useCallback( + (list: OnyxEntry): OnyxEntry => (report?.ownerAccountID ? (list?.[report.ownerAccountID] ?? undefined) : undefined), + [report?.ownerAccountID], + ); + const [reportOwnerPersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: reportOwnerSelector}, [reportOwnerSelector]); if (!isChatReport(report)) { return null; @@ -51,7 +66,19 @@ function ReportActionItemCreated({reportID, policyID}: ReportActionItemCreatedPr pendingAction={report?.pendingFields?.addWorkspaceRoom ?? report?.pendingFields?.createChat} errors={report?.errorFields?.addWorkspaceRoom ?? report?.errorFields?.createChat} errorRowStyles={[styles.ml10, styles.mr2]} - onClose={() => clearCreateChatError(report, conciergeReportID, introSelected, currentUserAccountID, betas, isSelfTourViewed, personalDetails)} + onClose={() => + clearCreateChatError( + report, + conciergeReportID, + introSelected, + currentUserAccountID, + betas, + isSelfTourViewed, + reportOwnerPersonalDetail, + currentUserPersonalDetail, + conciergePersonalDetail, + ) + } > diff --git a/src/pages/inbox/report/ReportActionItemParentAction.tsx b/src/pages/inbox/report/ReportActionItemParentAction.tsx index 9ecdb9d81d4d..9cb4049d2a14 100644 --- a/src/pages/inbox/report/ReportActionItemParentAction.tsx +++ b/src/pages/inbox/report/ReportActionItemParentAction.tsx @@ -21,6 +21,7 @@ import { shouldExcludeAncestorReportAction, } from '@libs/ReportUtils'; import {navigateToConciergeChatAndDeleteReport} from '@userActions/Report'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {PersonalDetailsList, Report, ReportAction, ReportActions, ReportActionsDrafts, ReportNameValuePairs, Transaction} from '@src/types/onyx'; import AnimatedEmptyStateBackground from './AnimatedEmptyStateBackground'; @@ -94,7 +95,9 @@ function ReportActionItemParentAction({ const {isInNarrowPaneModal} = useResponsiveLayout(); const transactionID = isMoneyRequestAction(action) && getOriginalMessage(action)?.IOUTransactionID; const [allBetas] = useOnyx(ONYXKEYS.BETAS); - const {accountID: currentUserAccountID} = useCurrentUserPersonalDetails(); + const currentUserPersonalDetail = useCurrentUserPersonalDetails(); + const {accountID: currentUserAccountID} = currentUserPersonalDetail; + const conciergePersonalDetail = personalDetails ? Object.values(personalDetails).find((detail) => detail?.login === CONST.EMAIL.CONCIERGE) : undefined; const getLinkedTransactionRouteError = useCallback((transaction: OnyxEntry) => { return transaction?.errorFields?.route; @@ -184,7 +187,9 @@ function ReportActionItemParentAction({ introSelected, isSelfTourViewed, allBetas, - personalDetails, + report?.ownerAccountID ? (personalDetails?.[report.ownerAccountID] ?? undefined) : undefined, + currentUserPersonalDetail, + conciergePersonalDetail ?? undefined, undefined, true, ) @@ -220,7 +225,9 @@ function ReportActionItemParentAction({ introSelected, isSelfTourViewed, allBetas, - personalDetails, + ancestorReport.ownerAccountID ? (personalDetails?.[ancestorReport.ownerAccountID] ?? undefined) : undefined, + currentUserPersonalDetail, + conciergePersonalDetail ?? undefined, undefined, undefined, ) diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index 0190541fd201..8eff72967e05 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -326,7 +326,17 @@ describe('actions/Report', () => { return waitForBatchedUpdates() .then(() => { - Report.clearCreateChatError(REPORT, CONCIERGE_REPORT_ID, {choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, TEST_USER_ACCOUNT_ID, undefined, false, undefined); + Report.clearCreateChatError( + REPORT, + CONCIERGE_REPORT_ID, + {choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, + TEST_USER_ACCOUNT_ID, + undefined, + false, + undefined, + undefined, + undefined, + ); return waitForBatchedUpdates(); }) .then( @@ -359,7 +369,7 @@ describe('actions/Report', () => { return waitForBatchedUpdates() .then(() => { - Report.clearCreateChatError(REPORT, CONCIERGE_REPORT_ID, INTRO_SELECTED, TEST_USER_ACCOUNT_ID, undefined, false, undefined); + Report.clearCreateChatError(REPORT, CONCIERGE_REPORT_ID, INTRO_SELECTED, TEST_USER_ACCOUNT_ID, undefined, false, undefined, undefined, undefined); return waitForBatchedUpdates(); }) .then( @@ -391,7 +401,7 @@ describe('actions/Report', () => { return waitForBatchedUpdates() .then(() => { - Report.clearCreateChatError(REPORT, CONCIERGE_REPORT_ID, INTRO_SELECTED, TEST_USER_ACCOUNT_ID, undefined, false, undefined); + Report.clearCreateChatError(REPORT, CONCIERGE_REPORT_ID, INTRO_SELECTED, TEST_USER_ACCOUNT_ID, undefined, false, undefined, undefined, undefined); return waitForBatchedUpdates(); }) .then( @@ -434,7 +444,7 @@ describe('actions/Report', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_METADATA}${REPORT.reportID}`, {isOptimisticReport: true}); await waitForBatchedUpdates(); - Report.clearCreateChatError(REPORT, undefined, INTRO_SELECTED, TEST_USER_ACCOUNT_ID, betas, false, undefined); + Report.clearCreateChatError(REPORT, undefined, INTRO_SELECTED, TEST_USER_ACCOUNT_ID, betas, false, undefined, undefined, undefined); await waitForBatchedUpdates(); TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.OPEN_REPORT, 1); @@ -4704,7 +4714,19 @@ describe('actions/Report', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, testReport); await waitForBatchedUpdates(); - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined, true, undefined); + Report.navigateToConciergeChatAndDeleteReport( + REPORT_ID, + CONCIERGE_REPORT_ID, + TEST_USER_ACCOUNT_ID, + INTRO_SELECTED, + undefined, + undefined, + undefined, + undefined, + undefined, + true, + undefined, + ); await waitForBatchedUpdates(); @@ -4740,7 +4762,19 @@ describe('actions/Report', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, testReport); await waitForBatchedUpdates(); - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined, false, true); + Report.navigateToConciergeChatAndDeleteReport( + REPORT_ID, + CONCIERGE_REPORT_ID, + TEST_USER_ACCOUNT_ID, + INTRO_SELECTED, + undefined, + undefined, + undefined, + undefined, + undefined, + false, + true, + ); await waitForBatchedUpdates(); @@ -4753,7 +4787,19 @@ describe('actions/Report', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, testReport); await waitForBatchedUpdates(); - Report.navigateToConciergeChatAndDeleteReport(REPORT_ID, CONCIERGE_REPORT_ID, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined, true, true); + Report.navigateToConciergeChatAndDeleteReport( + REPORT_ID, + CONCIERGE_REPORT_ID, + TEST_USER_ACCOUNT_ID, + INTRO_SELECTED, + undefined, + undefined, + undefined, + undefined, + undefined, + true, + true, + ); await waitForBatchedUpdates(); @@ -4828,7 +4874,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); + Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined); await waitForBatchedUpdates(); expect(Navigation.navigate).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(EXISTING_CHILD_REPORT.reportID)); @@ -4847,7 +4893,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); + Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined); await waitForBatchedUpdates(); expect(Navigation.navigate).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(MOCK_NEW_THREAD_REPORT_ID)); @@ -4862,7 +4908,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, {} as OnyxTypes.ReportAction, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); + Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, {} as OnyxTypes.ReportAction, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined); await waitForBatchedUpdates(); expect(Navigation.navigate).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(EXISTING_CHILD_REPORT.reportID)); @@ -4881,7 +4927,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); + Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined); await waitForBatchedUpdates(); expect(Navigation.navigate).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(MOCK_NEW_THREAD_REPORT_ID)); @@ -4900,7 +4946,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); + Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined); await waitForBatchedUpdates(); // Verify navigation happened with the new thread report @@ -4925,7 +4971,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, undefined, undefined, undefined); + Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, undefined, undefined, undefined, undefined); await waitForBatchedUpdates(); expect(Navigation.navigate).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(EXISTING_CHILD_REPORT.reportID)); @@ -4945,7 +4991,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, testBetas, undefined); + Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, testBetas, undefined, undefined); await waitForBatchedUpdates(); TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.OPEN_REPORT, 1); @@ -4979,7 +5025,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, introSelected, undefined, isSelfTourViewed); + Report.navigateToAndOpenChildReport(undefined, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, introSelected, undefined, undefined, isSelfTourViewed); await waitForBatchedUpdates(); TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.OPEN_REPORT, 1); @@ -5017,7 +5063,7 @@ describe('actions/Report', () => { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${PARENT_REPORT_ID}`, PARENT_REPORT); await waitForBatchedUpdates(); - Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined); + Report.navigateToAndOpenChildReport(EXISTING_CHILD_REPORT, PARENT_REPORT_ACTION, PARENT_REPORT, TEST_USER_ACCOUNT_ID, INTRO_SELECTED, undefined, undefined, undefined); await waitForBatchedUpdates(); expect(Navigation.navigate).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(EXISTING_CHILD_REPORT.reportID)); From 3157d7da5593ce369d7f1a01e48c5de30c9f7ef6 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Fri, 8 May 2026 15:14:13 +0700 Subject: [PATCH 6/8] fix: selector --- .../MoneyRequestReceiptView.tsx | 23 ++++--------------- src/pages/Debug/Report/DebugReportPage.tsx | 18 ++++----------- .../inbox/report/ReportActionItemCreated.tsx | 20 ++++------------ src/selectors/PersonalDetails.ts | 15 +++++++++++- 4 files changed, 27 insertions(+), 49 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx index fbb7432e6e08..7501030063ce 100644 --- a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx +++ b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx @@ -1,6 +1,7 @@ import {hasSeenTourSelector} from '@selectors/Onboarding'; +import {conciergePersonalDetailSelector, personalDetailByAccountIDSelector} from '@selectors/PersonalDetails'; import mapValues from 'lodash/mapValues'; -import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; +import React, {useEffect, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import type {StyleProp, ViewStyle} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; @@ -70,7 +71,6 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; -import type PersonalDetails from '@src/types/onyx/PersonalDetails'; import type {TransactionPendingFieldsKey} from '@src/types/onyx/Transaction'; import type {FileObject} from '@src/types/utils/Attachment'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; @@ -112,13 +112,6 @@ const receiptImageViolationNames = new Set([ const receiptFieldViolationNames = new Set([CONST.VIOLATIONS.MODIFIED_AMOUNT, CONST.VIOLATIONS.MODIFIED_DATE]); -const findConciergePersonalDetail = (list: OnyxEntry): OnyxEntry => { - if (!list) { - return undefined; - } - return Object.values(list).find((detail): detail is PersonalDetails => detail?.login === CONST.EMAIL.CONCIERGE); -}; - function MoneyRequestReceiptView({ report, readonly = false, @@ -141,16 +134,10 @@ function MoneyRequestReceiptView({ const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); const [betas] = useOnyx(ONYXKEYS.BETAS); - const [conciergePersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: findConciergePersonalDetail}); - const reportOwnerSelector = useCallback( - (list: OnyxEntry): OnyxEntry => (report?.ownerAccountID ? (list?.[report.ownerAccountID] ?? undefined) : undefined), - [report?.ownerAccountID], - ); + const [conciergePersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: conciergePersonalDetailSelector}); + const reportOwnerSelector = useMemo(() => personalDetailByAccountIDSelector(report?.ownerAccountID), [report?.ownerAccountID]); const [reportOwnerPersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: reportOwnerSelector}, [reportOwnerSelector]); - const chatReportOwnerSelector = useCallback( - (list: OnyxEntry): OnyxEntry => (chatReport?.ownerAccountID ? (list?.[chatReport.ownerAccountID] ?? undefined) : undefined), - [chatReport?.ownerAccountID], - ); + const chatReportOwnerSelector = useMemo(() => personalDetailByAccountIDSelector(chatReport?.ownerAccountID), [chatReport?.ownerAccountID]); const [chatReportOwnerPersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: chatReportOwnerSelector}, [chatReportOwnerSelector]); const delegateAccountID = useDelegateAccountID(); diff --git a/src/pages/Debug/Report/DebugReportPage.tsx b/src/pages/Debug/Report/DebugReportPage.tsx index 86f6c52f8a24..de6fa1130a0f 100644 --- a/src/pages/Debug/Report/DebugReportPage.tsx +++ b/src/pages/Debug/Report/DebugReportPage.tsx @@ -1,4 +1,5 @@ import {hasSeenTourSelector} from '@selectors/Onboarding'; +import {conciergePersonalDetailSelector, personalDetailByAccountIDSelector} from '@selectors/PersonalDetails'; import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; @@ -32,17 +33,9 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type {PersonalDetailsList, ReportAttributesDerivedValue} from '@src/types/onyx'; -import type PersonalDetails from '@src/types/onyx/PersonalDetails'; +import type {ReportAttributesDerivedValue} from '@src/types/onyx'; import DebugReportActions from './DebugReportActions'; -const findConciergePersonalDetail = (list: OnyxEntry): OnyxEntry => { - if (!list) { - return undefined; - } - return Object.values(list).find((detail): detail is PersonalDetails => detail?.login === CONST.EMAIL.CONCIERGE); -}; - type DebugReportPageProps = PlatformStackScreenProps; type Metadata = { @@ -86,11 +79,8 @@ function DebugReportPage({ const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); const currentUserPersonalDetail = useCurrentUserPersonalDetails(); const {accountID: currentUserAccountID, login: currentUserLogin} = currentUserPersonalDetail; - const [conciergePersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: findConciergePersonalDetail}); - const reportOwnerSelector = useCallback( - (list: OnyxEntry): OnyxEntry => (report?.ownerAccountID ? (list?.[report.ownerAccountID] ?? undefined) : undefined), - [report?.ownerAccountID], - ); + const [conciergePersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: conciergePersonalDetailSelector}); + const reportOwnerSelector = useMemo(() => personalDetailByAccountIDSelector(report?.ownerAccountID), [report?.ownerAccountID]); const [reportOwnerPersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: reportOwnerSelector}, [reportOwnerSelector]); const transactionID = DebugUtils.getTransactionID(report, reportActions); const isReportArchived = useReportIsArchived(reportID); diff --git a/src/pages/inbox/report/ReportActionItemCreated.tsx b/src/pages/inbox/report/ReportActionItemCreated.tsx index 73bd35438fab..2824f6c899ad 100644 --- a/src/pages/inbox/report/ReportActionItemCreated.tsx +++ b/src/pages/inbox/report/ReportActionItemCreated.tsx @@ -1,7 +1,7 @@ import {hasSeenTourSelector} from '@selectors/Onboarding'; -import React, {memo, useCallback} from 'react'; +import {conciergePersonalDetailSelector, personalDetailByAccountIDSelector} from '@selectors/PersonalDetails'; +import React, {memo, useMemo} from 'react'; import {View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import ReportActionAvatars from '@components/ReportActionAvatars'; @@ -16,17 +16,8 @@ import {isChatReport, isCurrentUserInvoiceReceiver, isInvoiceRoom, navigateToDet import {clearCreateChatError} from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {PersonalDetailsList} from '@src/types/onyx'; -import type PersonalDetails from '@src/types/onyx/PersonalDetails'; import AnimatedEmptyStateBackground from './AnimatedEmptyStateBackground'; -const findConciergePersonalDetail = (list: OnyxEntry): OnyxEntry => { - if (!list) { - return undefined; - } - return Object.values(list).find((detail): detail is PersonalDetails => detail?.login === CONST.EMAIL.CONCIERGE); -}; - type ReportActionItemCreatedProps = { /** The id of the report */ reportID: string | undefined; @@ -48,11 +39,8 @@ function ReportActionItemCreated({reportID, policyID}: ReportActionItemCreatedPr const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); const currentUserPersonalDetail = useCurrentUserPersonalDetails(); const {accountID: currentUserAccountID} = currentUserPersonalDetail; - const [conciergePersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: findConciergePersonalDetail}); - const reportOwnerSelector = useCallback( - (list: OnyxEntry): OnyxEntry => (report?.ownerAccountID ? (list?.[report.ownerAccountID] ?? undefined) : undefined), - [report?.ownerAccountID], - ); + const [conciergePersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: conciergePersonalDetailSelector}); + const reportOwnerSelector = useMemo(() => personalDetailByAccountIDSelector(report?.ownerAccountID), [report?.ownerAccountID]); const [reportOwnerPersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: reportOwnerSelector}, [reportOwnerSelector]); if (!isChatReport(report)) { diff --git a/src/selectors/PersonalDetails.ts b/src/selectors/PersonalDetails.ts index 4d1713da063e..b1487f86adab 100644 --- a/src/selectors/PersonalDetails.ts +++ b/src/selectors/PersonalDetails.ts @@ -1,11 +1,24 @@ import type {OnyxEntry} from 'react-native-onyx'; import CONST from '@src/CONST'; import type {PersonalDetailsList, Report} from '@src/types/onyx'; +import type PersonalDetails from '@src/types/onyx/PersonalDetails'; const personalDetailsSelector = (accountID: number) => (personalDetailsList: OnyxEntry) => personalDetailsList?.[accountID]; const personalDetailsLoginSelector = (accountID: number) => (personalDetailsList: OnyxEntry) => personalDetailsList?.[accountID]?.login; +const personalDetailByAccountIDSelector = + (accountID: number | undefined) => + (personalDetailsList: OnyxEntry): OnyxEntry => + accountID ? (personalDetailsList?.[accountID] ?? undefined) : undefined; + +const conciergePersonalDetailSelector = (personalDetailsList: OnyxEntry): OnyxEntry => { + if (!personalDetailsList) { + return undefined; + } + return Object.values(personalDetailsList).find((detail): detail is PersonalDetails => detail?.login === CONST.EMAIL.CONCIERGE); +}; + const accountIDToLoginSelector = (reportsToArchive: Report[]) => (personalDetailsList: OnyxEntry) => { const map: Record = {}; for (const report of reportsToArchive) { @@ -17,4 +30,4 @@ const accountIDToLoginSelector = (reportsToArchive: Report[]) => (personalDetail return map; }; -export {personalDetailsSelector, personalDetailsLoginSelector, accountIDToLoginSelector}; +export {personalDetailsSelector, personalDetailsLoginSelector, personalDetailByAccountIDSelector, conciergePersonalDetailSelector, accountIDToLoginSelector}; From a532c91d88c6321098299eba2cf8bd7f5d31c459 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Fri, 8 May 2026 15:29:41 +0700 Subject: [PATCH 7/8] fix: linter --- src/libs/actions/Report/index.ts | 1 + tests/ui/components/BaseReportActionContextMenuTest.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index 07d6863ba98a..066f44eb1133 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -4120,6 +4120,7 @@ function deleteReport(reportID: string | undefined, shouldDeleteChildReports = f /** * @param reportID The reportID of the policy report (workspace room) */ +// eslint-disable-next-line @typescript-eslint/max-params function navigateToConciergeChatAndDeleteReport( reportID: string | undefined, conciergeReportID: string | undefined, diff --git a/tests/ui/components/BaseReportActionContextMenuTest.tsx b/tests/ui/components/BaseReportActionContextMenuTest.tsx index c955d985a3d8..c0c0141564de 100644 --- a/tests/ui/components/BaseReportActionContextMenuTest.tsx +++ b/tests/ui/components/BaseReportActionContextMenuTest.tsx @@ -47,6 +47,7 @@ jest.mock('@components/FocusTrap/FocusTrapForModal', () => { jest.mock('@components/OnyxListItemProvider', () => ({ useSession: () => ({encryptedAuthToken: 'token'}), + usePersonalDetails: () => ({}), })); jest.mock('@hooks/useArrowKeyFocusManager', () => () => [-1, jest.fn()] as const); From b248f43aa5507a40631def7afed7cf28129e65cb Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Mon, 18 May 2026 22:56:48 +0700 Subject: [PATCH 8/8] fix: update conciergePersonalDetailSelector --- src/selectors/PersonalDetails.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/selectors/PersonalDetails.ts b/src/selectors/PersonalDetails.ts index b1487f86adab..3fbae1fe6aa3 100644 --- a/src/selectors/PersonalDetails.ts +++ b/src/selectors/PersonalDetails.ts @@ -12,12 +12,7 @@ const personalDetailByAccountIDSelector = (personalDetailsList: OnyxEntry): OnyxEntry => accountID ? (personalDetailsList?.[accountID] ?? undefined) : undefined; -const conciergePersonalDetailSelector = (personalDetailsList: OnyxEntry): OnyxEntry => { - if (!personalDetailsList) { - return undefined; - } - return Object.values(personalDetailsList).find((detail): detail is PersonalDetails => detail?.login === CONST.EMAIL.CONCIERGE); -}; +const conciergePersonalDetailSelector = personalDetailByAccountIDSelector(CONST.ACCOUNT_ID.CONCIERGE); const accountIDToLoginSelector = (reportsToArchive: Report[]) => (personalDetailsList: OnyxEntry) => { const map: Record = {};