From 8f8c69c8a5bdd42388c8d3ed43a748fd512e1bd8 Mon Sep 17 00:00:00 2001 From: truph01 Date: Thu, 11 Jun 2026 16:53:41 +0700 Subject: [PATCH 01/17] fix: refactor completeOnboarding --- src/hooks/useAutoCreateSubmitWorkspace.ts | 3 +++ src/hooks/useAutoCreateTrackWorkspace.ts | 3 +++ src/libs/ReportUtils.ts | 7 +++++-- src/libs/actions/Report/index.ts | 4 ++++ .../BaseOnboardingInterestedFeatures.tsx | 3 +++ .../BaseOnboardingPersonalDetails.tsx | 3 +++ src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx | 2 ++ .../OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx | 2 ++ 8 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/hooks/useAutoCreateSubmitWorkspace.ts b/src/hooks/useAutoCreateSubmitWorkspace.ts index 950dfa08cd0d..bbc3937ba8d9 100644 --- a/src/hooks/useAutoCreateSubmitWorkspace.ts +++ b/src/hooks/useAutoCreateSubmitWorkspace.ts @@ -43,6 +43,7 @@ function useAutoCreateSubmitWorkspace() { [], ); const [hasEditableGroupPolicy] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {selector: groupPolicySelector}); + const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); const autoCreateSubmitWorkspace = useCallback( (firstName: string, lastName: string) => { @@ -80,6 +81,7 @@ function useAutoCreateSubmitWorkspace() { onboardingPolicyID: newPolicyID, introSelected, isSelfTourViewed, + reports: allReports, }); setOnboardingAdminsChatReportID(); @@ -105,6 +107,7 @@ function useAutoCreateSubmitWorkspace() { betas, hasActiveAdminPolicies, shouldUseNarrowLayout, + allReports, ], ); diff --git a/src/hooks/useAutoCreateTrackWorkspace.ts b/src/hooks/useAutoCreateTrackWorkspace.ts index 7dc07f940edd..231b0155e830 100644 --- a/src/hooks/useAutoCreateTrackWorkspace.ts +++ b/src/hooks/useAutoCreateTrackWorkspace.ts @@ -52,6 +52,7 @@ function useAutoCreateTrackWorkspace() { const [conciergeChatReportID = ''] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); const [onboardingValues] = useOnyx(ONYXKEYS.NVP_ONBOARDING); + const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); const archivedReportsIDSet = useArchivedReportsIDSet(); const {isBetaEnabled} = usePermissions(); @@ -105,6 +106,7 @@ function useAutoCreateTrackWorkspace() { personalTrackGoal: onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.TRACK_PERSONAL && !!personalTrackGoal ? personalTrackGoal : undefined, introSelected, isSelfTourViewed, + reports: allReports, }); if (isSidePanelReportSupported) { @@ -157,6 +159,7 @@ function useAutoCreateTrackWorkspace() { conciergeChatReportID, archivedReportsIDSet, mergedAccountConciergeReportID, + allReports, ], ); diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index a00a0a03aff4..17bc722023b2 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -11394,6 +11394,8 @@ type PrepareOnboardingOnyxDataParams = { isSelfTourViewed?: boolean; // TODO: hasCompletedGuidedSetupFlow will be required eventually. Refactor issue: https://github.com/Expensify/App/issues/66424 hasCompletedGuidedSetupFlow?: boolean; + /** All reports, passed from the React layer (useOnyx). Falls back to the deprecated module-level Onyx data while the refactor is in progress. */ + reports?: OnyxCollection; }; function prepareOnboardingOnyxData({ @@ -11409,6 +11411,7 @@ function prepareOnboardingOnyxData({ onboardingPurposeSelected, isSelfTourViewed, hasCompletedGuidedSetupFlow, + reports = deprecatedAllReports, }: PrepareOnboardingOnyxDataParams) { if (engagementChoice === CONST.ONBOARDING_CHOICES.PERSONAL_SPEND) { // eslint-disable-next-line no-param-reassign @@ -11426,9 +11429,9 @@ function prepareOnboardingOnyxData({ const shouldUseFollowupsInsteadOfTasks = engagementChoice === CONST.ONBOARDING_CHOICES.MANAGE_TEAM; // Post to #admins room when followups fire OR the existing tasks-in-admins predicate approves. const shouldPostTasksInAdminsRoom = shouldUseFollowupsInsteadOfTasks || isPostingTasksInAdminsRoom(engagementChoice); - const adminsChatReport = deprecatedAllReports?.[`${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`]; + const adminsChatReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`]; const conciergeChat = - getChatByParticipants([CONST.ACCOUNT_ID.CONCIERGE, deprecatedCurrentUserAccountID ?? CONST.DEFAULT_NUMBER_ID], deprecatedAllReports, false) ?? + getChatByParticipants([CONST.ACCOUNT_ID.CONCIERGE, deprecatedCurrentUserAccountID ?? CONST.DEFAULT_NUMBER_ID], reports, false) ?? (conciergeReportIDOnyxConnect ? {reportID: conciergeReportIDOnyxConnect} : undefined); const targetChatReport = shouldPostTasksInAdminsRoom ? (adminsChatReport ?? {reportID: adminsChatReportID, policyID: onboardingPolicyID, chatType: CONST.REPORT.CHAT_TYPE.POLICY_ADMINS}) diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index c5bfa6d6c1e6..3038b06e2f41 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -5434,6 +5434,8 @@ type CompleteOnboardingProps = { shouldWaitForRHPVariantInitialization?: boolean; introSelected: OnyxEntry; isSelfTourViewed: boolean | undefined; + /** All reports. Optional during migration; the `?` will be removed once every caller passes `reports`. Link to issue https://github.com/Expensify/App/issues/66416 */ + reports?: OnyxCollection; }; async function completeOnboarding({ @@ -5454,6 +5456,7 @@ async function completeOnboarding({ shouldWaitForRHPVariantInitialization = false, introSelected, isSelfTourViewed, + reports, }: CompleteOnboardingProps) { const onboardingData = prepareOnboardingOnyxData({ introSelected, @@ -5467,6 +5470,7 @@ async function completeOnboarding({ isInvitedAccountant, onboardingPurposeSelected, isSelfTourViewed, + reports, }); if (!onboardingData) { return; diff --git a/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx b/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx index 2dbd5c0cf89e..9f50919ebed2 100644 --- a/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx +++ b/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx @@ -52,6 +52,7 @@ function BaseOnboardingInterestedFeatures({shouldUseNativeStyles}: BaseOnboardin // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth const {onboardingIsMediumOrLargerScreenWidth, isSmallScreenWidth} = useResponsiveLayout(); const [onboardingPurposeSelected] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED); + const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); const onboardingStep = useOnboardingStepCounter(SCREENS.ONBOARDING.INTERESTED_FEATURES); const [onboardingPolicyID] = useOnyx(ONYXKEYS.ONBOARDING_POLICY_ID); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); @@ -237,6 +238,7 @@ function BaseOnboardingInterestedFeatures({shouldUseNativeStyles}: BaseOnboardin shouldWaitForRHPVariantInitialization: isSidePanelReportSupported, introSelected, isSelfTourViewed, + reports: allReports, }); // Avoid creating new WS because onboardingPolicyID is cleared before unmounting @@ -292,6 +294,7 @@ function BaseOnboardingInterestedFeatures({shouldUseNativeStyles}: BaseOnboardin hasActiveAdminPolicies, lastWorkspaceNumber, translate, + allReports, ]); // Create items for enabled features diff --git a/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx b/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx index f3ef4dcfdc95..6031365e2801 100644 --- a/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx +++ b/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx @@ -42,6 +42,7 @@ function BaseOnboardingPersonalDetails({currentUserPersonalDetails, shouldUseNat const styles = useThemeStyles(); const {translate, formatPhoneNumber} = useLocalize(); const [onboardingPurposeSelected] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED); + const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); const [onboardingPolicyID] = useOnyx(ONYXKEYS.ONBOARDING_POLICY_ID); const [onboardingAdminsChatReportID] = useOnyx(ONYXKEYS.ONBOARDING_ADMINS_CHAT_REPORT_ID); const [account] = useOnyx(ONYXKEYS.ACCOUNT); @@ -93,6 +94,7 @@ function BaseOnboardingPersonalDetails({currentUserPersonalDetails, shouldUseNat onboardingPolicyID, introSelected, isSelfTourViewed, + reports: allReports, }); setOnboardingAdminsChatReportID(); @@ -120,6 +122,7 @@ function BaseOnboardingPersonalDetails({currentUserPersonalDetails, shouldUseNat conciergeChatReportID, introSelected, isSelfTourViewed, + allReports, ], ); diff --git a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx index 014c386d2e2f..3cf06dc5de2d 100644 --- a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx +++ b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx @@ -64,6 +64,7 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, ro const {onboardingIsMediumOrLargerScreenWidth} = useResponsiveLayout(); const onboardingStep = useOnboardingStepCounter(SCREENS.ONBOARDING.PURPOSE); const [account] = useOnyx(ONYXKEYS.ACCOUNT); + const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); const {onboardingMessages} = useOnboardingMessages(); const isPrivateDomainAndHasAccessiblePolicies = !account?.isFromPublicDomain && !!account?.hasAccessibleDomainPolicies; @@ -137,6 +138,7 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, ro companySize: onboardingCompanySize, introSelected, isSelfTourViewed, + reports: allReports, }); return; diff --git a/src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx b/src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx index ad5037dee989..d499dcfbdd7d 100644 --- a/src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx +++ b/src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx @@ -47,6 +47,7 @@ function BaseOnboardingWorkspaces({route, shouldUseNativeStyles}: BaseOnboarding // We need to use isSmallScreenWidth, see navigateAfterOnboarding function comment // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth const {onboardingIsMediumOrLargerScreenWidth, isSmallScreenWidth, shouldUseNarrowLayout} = useResponsiveLayout(); + const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); const [joinablePolicies] = useOnyx(ONYXKEYS.JOINABLE_POLICIES); const [getAccessiblePoliciesAction] = useOnyx(ONYXKEYS.VALIDATE_USER_AND_GET_ACCESSIBLE_POLICIES); @@ -94,6 +95,7 @@ function BaseOnboardingWorkspaces({route, shouldUseNativeStyles}: BaseOnboarding companySize: onboardingCompanySize, introSelected, isSelfTourViewed, + reports: allReports, }); setOnboardingAdminsChatReportID(); setOnboardingPolicyID(policy.policyID); From 3c923058069c7d47cc69803b89704111c59c4270 Mon Sep 17 00:00:00 2001 From: truph01 Date: Thu, 11 Jun 2026 17:20:30 +0700 Subject: [PATCH 02/17] fix: add test --- tests/actions/ReportTest.ts | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index b25f9e3ea898..1f54cc3fe0b4 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -2831,6 +2831,44 @@ describe('actions/Report', () => { const formEntries = Object.fromEntries(body as FormData); expect(formEntries.selectedInterestedFeatures).toBe(JSON.stringify(selectedInterestedFeatures)); }); + + it('should post onboarding tasks to the existing Concierge chat', async () => { + await Onyx.set(ONYXKEYS.SESSION, {email: TEST_USER_LOGIN, accountID: TEST_USER_ACCOUNT_ID}); + await waitForBatchedUpdates(); + + // An existing 1:1 Concierge chat the onboarding tasks should be posted to + const conciergeChatReportID = '9988776655'; + const conciergeChat: OnyxTypes.Report = { + reportID: conciergeChatReportID, + type: CONST.REPORT.TYPE.CHAT, + participants: { + [CONST.ACCOUNT_ID.CONCIERGE]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, + [TEST_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, + }, + }; + const reports: OnyxCollection = { + [`${ONYXKEYS.COLLECTION.REPORT}${conciergeChatReportID}`]: conciergeChat, + }; + + // LOOKING_AROUND posts the onboarding tasks to the Concierge chat (not the #admins room) + const engagementChoice = CONST.ONBOARDING_CHOICES.LOOKING_AROUND; + const {onboardingMessages} = getOnboardingMessages(); + + const onboardingData = ReportUtils.prepareOnboardingOnyxData({ + engagementChoice, + onboardingMessage: onboardingMessages[engagementChoice], + companySize: CONST.ONBOARDING_COMPANY_SIZE.MICRO, + userReportedIntegration: null, + introSelected: {choice: engagementChoice}, + isSelfTourViewed: false, + reports, + }); + + // The onboarding optimistic data should target the existing Concierge chat + expect(onboardingData).toBeTruthy(); + const targetsConciergeChat = onboardingData?.optimisticData.some((update) => update.key.includes(conciergeChatReportID)); + expect(targetsConciergeChat).toBe(true); + }); }); describe('markAllMessagesAsRead', () => { From 6830d0219cc7756a22ada1967482c59d2a487f9a Mon Sep 17 00:00:00 2001 From: truph01 Date: Thu, 11 Jun 2026 17:39:01 +0700 Subject: [PATCH 03/17] fix: use reports instead of deprecatedAllReports --- src/libs/ReportUtils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 17bc722023b2..f683dd961283 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -11827,7 +11827,7 @@ function prepareOnboardingOnyxData({ lastVisibleActionCreated: '', hasOutstandingChildTask: false, }; - const report = deprecatedAllReports?.[`${ONYXKEYS.COLLECTION.REPORT}${targetChatReportID}`]; + const report = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${targetChatReportID}`]; const canUserPerformWriteActionVariable = canUserPerformWriteAction(report, false); const {lastMessageText = ''} = getLastVisibleMessageActionUtils(targetChatReportID, canUserPerformWriteActionVariable); if (lastMessageText) { @@ -11938,7 +11938,7 @@ function prepareOnboardingOnyxData({ (!onboardingPurposeSelected || onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.PERSONAL_SPEND || onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.TRACK_PERSONAL)) ) { const selfDMReportID = findSelfDMReportID(); - let selfDMReport = deprecatedAllReports?.[`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`]; + let selfDMReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`]; let createdAction: ReportAction; if (!selfDMReport) { const currentTime = DateUtils.getDBTime(); From 5816f8d517c17aee6341fa7a182e5f6889eb058e Mon Sep 17 00:00:00 2001 From: truph01 Date: Thu, 11 Jun 2026 18:06:10 +0700 Subject: [PATCH 04/17] fix: add test --- tests/actions/ReportTest.ts | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index 1f54cc3fe0b4..e0fdb58dcc06 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -2869,6 +2869,56 @@ describe('actions/Report', () => { const targetsConciergeChat = onboardingData?.optimisticData.some((update) => update.key.includes(conciergeChatReportID)); expect(targetsConciergeChat).toBe(true); }); + + it('should reuse the existing self-DM for a personal spend onboarding', async () => { + await Onyx.set(ONYXKEYS.SESSION, {email: TEST_USER_LOGIN, accountID: TEST_USER_ACCOUNT_ID}); + await waitForBatchedUpdates(); + + // An existing Concierge chat (the onboarding target) and an existing self-DM the personal spend + // onboarding should reuse instead of creating a new one + const conciergeChatReportID = '6677889900'; + const conciergeChat: OnyxTypes.Report = { + reportID: conciergeChatReportID, + type: CONST.REPORT.TYPE.CHAT, + participants: { + [CONST.ACCOUNT_ID.CONCIERGE]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, + [TEST_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, + }, + }; + const selfDMReportID = '5544332211'; + const selfDMReport: OnyxTypes.Report = { + reportID: selfDMReportID, + type: CONST.REPORT.TYPE.CHAT, + chatType: CONST.REPORT.CHAT_TYPE.SELF_DM, + participants: { + [TEST_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, + }, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`, selfDMReport); + await waitForBatchedUpdates(); + const reports: OnyxCollection = { + [`${ONYXKEYS.COLLECTION.REPORT}${conciergeChatReportID}`]: conciergeChat, + [`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`]: selfDMReport, + }; + + // PERSONAL_SPEND routes the onboarding to the user's self-DM + const engagementChoice = CONST.ONBOARDING_CHOICES.PERSONAL_SPEND; + const {onboardingMessages} = getOnboardingMessages(); + + const onboardingData = ReportUtils.prepareOnboardingOnyxData({ + engagementChoice, + onboardingMessage: onboardingMessages[engagementChoice], + companySize: CONST.ONBOARDING_COMPANY_SIZE.MICRO, + userReportedIntegration: null, + introSelected: {choice: engagementChoice}, + isSelfTourViewed: false, + reports, + }); + + // The existing self-DM should be reused, so no new self-DM is created + expect(onboardingData).toBeTruthy(); + expect(onboardingData?.selfDMParameters?.reportID).toBeUndefined(); + }); }); describe('markAllMessagesAsRead', () => { From 5e05fbe7d1b39883591ae8ad094f89377bdc4b25 Mon Sep 17 00:00:00 2001 From: truph01 Date: Thu, 11 Jun 2026 18:15:58 +0700 Subject: [PATCH 05/17] fix: add test --- tests/actions/ReportTest.ts | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index e0fdb58dcc06..4e7c301aedd1 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -2919,6 +2919,45 @@ describe('actions/Report', () => { expect(onboardingData).toBeTruthy(); expect(onboardingData?.selfDMParameters?.reportID).toBeUndefined(); }); + + it('should optimistically create a self-DM for a personal spend onboarding when none exists', async () => { + await Onyx.set(ONYXKEYS.SESSION, {email: TEST_USER_LOGIN, accountID: TEST_USER_ACCOUNT_ID}); + await waitForBatchedUpdates(); + + // Only a Concierge chat exists (the onboarding target); there is no self-DM yet + const conciergeChatReportID = '1122334455'; + const conciergeChat: OnyxTypes.Report = { + reportID: conciergeChatReportID, + type: CONST.REPORT.TYPE.CHAT, + participants: { + [CONST.ACCOUNT_ID.CONCIERGE]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, + [TEST_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, + }, + }; + const reports: OnyxCollection = { + [`${ONYXKEYS.COLLECTION.REPORT}${conciergeChatReportID}`]: conciergeChat, + }; + + const engagementChoice = CONST.ONBOARDING_CHOICES.PERSONAL_SPEND; + const {onboardingMessages} = getOnboardingMessages(); + + const onboardingData = ReportUtils.prepareOnboardingOnyxData({ + engagementChoice, + onboardingMessage: onboardingMessages[engagementChoice], + companySize: CONST.ONBOARDING_COMPANY_SIZE.MICRO, + userReportedIntegration: null, + introSelected: {choice: engagementChoice}, + isSelfTourViewed: false, + reports, + }); + + // A new self-DM is created and added to the optimistic data + expect(onboardingData).toBeTruthy(); + const newSelfDMReportID = onboardingData?.selfDMParameters?.reportID; + expect(newSelfDMReportID).toBeTruthy(); + const createsSelfDM = onboardingData?.optimisticData.some((update) => update.key === `${ONYXKEYS.COLLECTION.REPORT}${newSelfDMReportID}`); + expect(createsSelfDM).toBe(true); + }); }); describe('markAllMessagesAsRead', () => { From 69dd980969b5f2d6476ba049d866e8175ae10f5a Mon Sep 17 00:00:00 2001 From: truph01 Date: Tue, 16 Jun 2026 16:21:59 +0700 Subject: [PATCH 06/17] fix: don't pass entire reports data to prepareOnboardingOnyxData --- src/hooks/useAutoCreateSubmitWorkspace.ts | 14 ++++++++++--- src/hooks/useAutoCreateTrackWorkspace.ts | 10 ++++++--- src/libs/ReportUtils.ts | 21 ++++++++++++------- src/libs/actions/Report/index.ts | 16 ++++++++++---- .../BaseOnboardingInterestedFeatures.tsx | 13 +++++++++--- .../BaseOnboardingPersonalDetails.tsx | 13 +++++++++--- .../BaseOnboardingPurpose.tsx | 10 +++++++-- .../BaseOnboardingWorkspaces.tsx | 10 +++++++-- tests/actions/ReportTest.ts | 18 +++------------- 9 files changed, 83 insertions(+), 42 deletions(-) diff --git a/src/hooks/useAutoCreateSubmitWorkspace.ts b/src/hooks/useAutoCreateSubmitWorkspace.ts index bbc3937ba8d9..6a22bcf7c0f5 100644 --- a/src/hooks/useAutoCreateSubmitWorkspace.ts +++ b/src/hooks/useAutoCreateSubmitWorkspace.ts @@ -43,7 +43,11 @@ function useAutoCreateSubmitWorkspace() { [], ); const [hasEditableGroupPolicy] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {selector: groupPolicySelector}); - const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); + const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); + const [conciergeChat] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${conciergeReportID}`); + const [adminsChatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${onboardingAdminsChatReportID}`); + const [selfDMReportID] = useOnyx(ONYXKEYS.SELF_DM_REPORT_ID); + const [selfDMReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`); const autoCreateSubmitWorkspace = useCallback( (firstName: string, lastName: string) => { @@ -81,7 +85,9 @@ function useAutoCreateSubmitWorkspace() { onboardingPolicyID: newPolicyID, introSelected, isSelfTourViewed, - reports: allReports, + conciergeChat, + adminsChatReport, + selfDMReport, }); setOnboardingAdminsChatReportID(); @@ -107,7 +113,9 @@ function useAutoCreateSubmitWorkspace() { betas, hasActiveAdminPolicies, shouldUseNarrowLayout, - allReports, + conciergeChat, + adminsChatReport, + selfDMReport, ], ); diff --git a/src/hooks/useAutoCreateTrackWorkspace.ts b/src/hooks/useAutoCreateTrackWorkspace.ts index 231b0155e830..210d03599af7 100644 --- a/src/hooks/useAutoCreateTrackWorkspace.ts +++ b/src/hooks/useAutoCreateTrackWorkspace.ts @@ -51,8 +51,10 @@ function useAutoCreateTrackWorkspace() { const [hasPaidGroupAdminPolicy] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {selector: paidGroupPolicySelector}); const [conciergeChatReportID = ''] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); + const [conciergeChat] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${conciergeChatReportID}`); + const [selfDMReportID] = useOnyx(ONYXKEYS.SELF_DM_REPORT_ID); + const [selfDMReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`); const [onboardingValues] = useOnyx(ONYXKEYS.NVP_ONBOARDING); - const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); const archivedReportsIDSet = useArchivedReportsIDSet(); const {isBetaEnabled} = usePermissions(); @@ -106,7 +108,8 @@ function useAutoCreateTrackWorkspace() { personalTrackGoal: onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.TRACK_PERSONAL && !!personalTrackGoal ? personalTrackGoal : undefined, introSelected, isSelfTourViewed, - reports: allReports, + conciergeChat, + selfDMReport, }); if (isSidePanelReportSupported) { @@ -159,7 +162,8 @@ function useAutoCreateTrackWorkspace() { conciergeChatReportID, archivedReportsIDSet, mergedAccountConciergeReportID, - allReports, + conciergeChat, + selfDMReport, ], ); diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 78c8c7c00fdb..d49f1ed84d4e 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -11392,8 +11392,12 @@ type PrepareOnboardingOnyxDataParams = { isSelfTourViewed?: boolean; // TODO: hasCompletedGuidedSetupFlow will be required eventually. Refactor issue: https://github.com/Expensify/App/issues/66424 hasCompletedGuidedSetupFlow?: boolean; - /** All reports, passed from the React layer (useOnyx). Falls back to the deprecated module-level Onyx data while the refactor is in progress. */ - reports?: OnyxCollection; + /** The concierge chat report, looked up by conciergeReportID. Falls back to getChatByParticipants using the deprecated module-level Onyx data while the refactor is in progress. */ + conciergeChat?: OnyxEntry; + /** The admins chat report, looked up by adminsChatReportID. Falls back to the deprecated module-level Onyx data while the refactor is in progress. */ + adminsChatReport?: OnyxEntry; + /** The self-DM report, looked up by ONYXKEYS.SELF_DM_REPORT_ID. Falls back to the deprecated module-level Onyx data while the refactor is in progress. */ + selfDMReport?: OnyxEntry; }; function prepareOnboardingOnyxData({ @@ -11409,7 +11413,9 @@ function prepareOnboardingOnyxData({ onboardingPurposeSelected, isSelfTourViewed, hasCompletedGuidedSetupFlow, - reports = deprecatedAllReports, + conciergeChat: conciergeChatParam, + adminsChatReport: adminsChatReportParam, + selfDMReport: selfDMReportParam, }: PrepareOnboardingOnyxDataParams) { if (engagementChoice === CONST.ONBOARDING_CHOICES.PERSONAL_SPEND) { // eslint-disable-next-line no-param-reassign @@ -11427,9 +11433,10 @@ function prepareOnboardingOnyxData({ const shouldUseFollowupsInsteadOfTasks = engagementChoice === CONST.ONBOARDING_CHOICES.MANAGE_TEAM; // Post to #admins room when followups fire OR the existing tasks-in-admins predicate approves. const shouldPostTasksInAdminsRoom = shouldUseFollowupsInsteadOfTasks || isPostingTasksInAdminsRoom(engagementChoice); - const adminsChatReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`]; + const adminsChatReport = adminsChatReportParam ?? deprecatedAllReports?.[`${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`]; const conciergeChat = - getChatByParticipants([CONST.ACCOUNT_ID.CONCIERGE, deprecatedCurrentUserAccountID ?? CONST.DEFAULT_NUMBER_ID], reports, false) ?? + conciergeChatParam ?? + getChatByParticipants([CONST.ACCOUNT_ID.CONCIERGE, deprecatedCurrentUserAccountID ?? CONST.DEFAULT_NUMBER_ID], deprecatedAllReports, false) ?? (conciergeReportIDOnyxConnect ? {reportID: conciergeReportIDOnyxConnect} : undefined); const targetChatReport = shouldPostTasksInAdminsRoom ? (adminsChatReport ?? {reportID: adminsChatReportID, policyID: onboardingPolicyID, chatType: CONST.REPORT.CHAT_TYPE.POLICY_ADMINS}) @@ -11825,7 +11832,7 @@ function prepareOnboardingOnyxData({ lastVisibleActionCreated: '', hasOutstandingChildTask: false, }; - const report = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${targetChatReportID}`]; + const report = targetChatReport as OnyxEntry; const canUserPerformWriteActionVariable = canUserPerformWriteAction(report, false); const {lastMessageText = ''} = getLastVisibleMessageActionUtils(targetChatReportID, canUserPerformWriteActionVariable); if (lastMessageText) { @@ -11936,7 +11943,7 @@ function prepareOnboardingOnyxData({ (!onboardingPurposeSelected || onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.PERSONAL_SPEND || onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.TRACK_PERSONAL)) ) { const selfDMReportID = findSelfDMReportID(); - let selfDMReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`]; + let selfDMReport = selfDMReportParam ?? deprecatedAllReports?.[`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`]; let createdAction: ReportAction; if (!selfDMReport) { const currentTime = DateUtils.getDBTime(); diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index ff7f5efb4fa5..081ef130f471 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -5408,8 +5408,12 @@ type CompleteOnboardingProps = { shouldWaitForRHPVariantInitialization?: boolean; introSelected: OnyxEntry; isSelfTourViewed: boolean | undefined; - /** All reports. Optional during migration; the `?` will be removed once every caller passes `reports`. Link to issue https://github.com/Expensify/App/issues/66416 */ - reports?: OnyxCollection; + /** The concierge chat report, looked up by ONYXKEYS.CONCIERGE_REPORT_ID. */ + conciergeChat?: OnyxEntry; + /** The admins chat report, looked up by ONYXKEYS.ONBOARDING_ADMINS_CHAT_REPORT_ID. */ + adminsChatReport?: OnyxEntry; + /** The self-DM report, looked up by ONYXKEYS.SELF_DM_REPORT_ID. */ + selfDMReport?: OnyxEntry; }; async function completeOnboarding({ @@ -5430,7 +5434,9 @@ async function completeOnboarding({ shouldWaitForRHPVariantInitialization = false, introSelected, isSelfTourViewed, - reports, + conciergeChat, + adminsChatReport, + selfDMReport, }: CompleteOnboardingProps) { const onboardingData = prepareOnboardingOnyxData({ introSelected, @@ -5444,7 +5450,9 @@ async function completeOnboarding({ isInvitedAccountant, onboardingPurposeSelected, isSelfTourViewed, - reports, + conciergeChat, + adminsChatReport, + selfDMReport, }); if (!onboardingData) { return; diff --git a/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx b/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx index 2c1fee65ff1f..11f28e951660 100644 --- a/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx +++ b/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx @@ -51,7 +51,6 @@ function BaseOnboardingInterestedFeatures({shouldUseNativeStyles}: BaseOnboardin // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth const {onboardingIsMediumOrLargerScreenWidth, isSmallScreenWidth} = useResponsiveLayout(); const [onboardingPurposeSelected] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED); - const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); const onboardingStep = useOnboardingStepCounter(SCREENS.ONBOARDING.INTERESTED_FEATURES); const [onboardingPolicyID] = useOnyx(ONYXKEYS.ONBOARDING_POLICY_ID); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); @@ -66,6 +65,10 @@ function BaseOnboardingInterestedFeatures({shouldUseNativeStyles}: BaseOnboardin const {isBetaEnabled} = usePermissions(); const [session] = useOnyx(ONYXKEYS.SESSION); const [conciergeReportID = ''] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); + const [conciergeChat] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${conciergeReportID}`); + const [adminsChatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${onboardingAdminsChatReportID}`); + const [selfDMReportID] = useOnyx(ONYXKEYS.SELF_DM_REPORT_ID); + const [selfDMReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`); const archivedReportsIDSet = useArchivedReportsIDSet(); const activePolicy = useActivePolicy(); const hasActiveAdminPolicies = useHasActiveAdminPolicies(); @@ -237,7 +240,9 @@ function BaseOnboardingInterestedFeatures({shouldUseNativeStyles}: BaseOnboardin shouldWaitForRHPVariantInitialization: isSidePanelReportSupported, introSelected, isSelfTourViewed, - reports: allReports, + conciergeChat, + adminsChatReport, + selfDMReport, }); // Avoid creating new WS because onboardingPolicyID is cleared before unmounting @@ -293,7 +298,9 @@ function BaseOnboardingInterestedFeatures({shouldUseNativeStyles}: BaseOnboardin hasActiveAdminPolicies, lastWorkspaceNumber, translate, - allReports, + conciergeChat, + adminsChatReport, + selfDMReport, ]); // Create items for enabled features diff --git a/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx b/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx index 6031365e2801..7dd023701c6f 100644 --- a/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx +++ b/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx @@ -42,15 +42,18 @@ function BaseOnboardingPersonalDetails({currentUserPersonalDetails, shouldUseNat const styles = useThemeStyles(); const {translate, formatPhoneNumber} = useLocalize(); const [onboardingPurposeSelected] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED); - const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); const [onboardingPolicyID] = useOnyx(ONYXKEYS.ONBOARDING_POLICY_ID); const [onboardingAdminsChatReportID] = useOnyx(ONYXKEYS.ONBOARDING_ADMINS_CHAT_REPORT_ID); + const [adminsChatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${onboardingAdminsChatReportID}`); const [account] = useOnyx(ONYXKEYS.ACCOUNT); const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const archivedReportsIDSet = useArchivedReportsIDSet(); const [loginList] = useOnyx(ONYXKEYS.LOGINS, {selector: expensifyLoginsSelector}); const [onboardingValues] = useOnyx(ONYXKEYS.NVP_ONBOARDING); const [conciergeChatReportID = ''] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); + const [conciergeChat] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${conciergeChatReportID}`); + const [selfDMReportID] = useOnyx(ONYXKEYS.SELF_DM_REPORT_ID); + const [selfDMReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`); const {onboardingMessages} = useOnboardingMessages(); const [session] = useOnyx(ONYXKEYS.SESSION); const [onboardingPersonalDetailsForm] = useOnyx(ONYXKEYS.FORMS.ONBOARDING_PERSONAL_DETAILS_FORM); @@ -94,7 +97,9 @@ function BaseOnboardingPersonalDetails({currentUserPersonalDetails, shouldUseNat onboardingPolicyID, introSelected, isSelfTourViewed, - reports: allReports, + conciergeChat, + adminsChatReport, + selfDMReport, }); setOnboardingAdminsChatReportID(); @@ -122,7 +127,9 @@ function BaseOnboardingPersonalDetails({currentUserPersonalDetails, shouldUseNat conciergeChatReportID, introSelected, isSelfTourViewed, - allReports, + conciergeChat, + adminsChatReport, + selfDMReport, ], ); diff --git a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx index 3cf06dc5de2d..7d5b554b3aa9 100644 --- a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx +++ b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx @@ -64,7 +64,10 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, ro const {onboardingIsMediumOrLargerScreenWidth} = useResponsiveLayout(); const onboardingStep = useOnboardingStepCounter(SCREENS.ONBOARDING.PURPOSE); const [account] = useOnyx(ONYXKEYS.ACCOUNT); - const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); + const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); + const [conciergeChat] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${conciergeReportID}`); + const [selfDMReportID] = useOnyx(ONYXKEYS.SELF_DM_REPORT_ID); + const [selfDMReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`); const {onboardingMessages} = useOnboardingMessages(); const isPrivateDomainAndHasAccessiblePolicies = !account?.isFromPublicDomain && !!account?.hasAccessibleDomainPolicies; @@ -73,6 +76,7 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, ro const [onboardingErrorMessage, onboardingErrorMessageResult] = useOnyx(ONYXKEYS.ONBOARDING_ERROR_MESSAGE_TRANSLATION_KEY); const [onboardingPolicyID] = useOnyx(ONYXKEYS.ONBOARDING_POLICY_ID); const [onboardingAdminsChatReportID] = useOnyx(ONYXKEYS.ONBOARDING_ADMINS_CHAT_REPORT_ID); + const [adminsChatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${onboardingAdminsChatReportID}`); const [personalDetailsForm] = useOnyx(ONYXKEYS.FORMS.ONBOARDING_PERSONAL_DETAILS_FORM); const [onboardingCompanySize] = useOnyx(ONYXKEYS.ONBOARDING_COMPANY_SIZE); const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); @@ -138,7 +142,9 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, ro companySize: onboardingCompanySize, introSelected, isSelfTourViewed, - reports: allReports, + conciergeChat, + adminsChatReport, + selfDMReport, }); return; diff --git a/src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx b/src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx index d499dcfbdd7d..3d271aba4f97 100644 --- a/src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx +++ b/src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx @@ -47,7 +47,6 @@ function BaseOnboardingWorkspaces({route, shouldUseNativeStyles}: BaseOnboarding // We need to use isSmallScreenWidth, see navigateAfterOnboarding function comment // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth const {onboardingIsMediumOrLargerScreenWidth, isSmallScreenWidth, shouldUseNarrowLayout} = useResponsiveLayout(); - const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); const [joinablePolicies] = useOnyx(ONYXKEYS.JOINABLE_POLICIES); const [getAccessiblePoliciesAction] = useOnyx(ONYXKEYS.VALIDATE_USER_AND_GET_ACCESSIBLE_POLICIES); @@ -66,6 +65,11 @@ function BaseOnboardingWorkspaces({route, shouldUseNativeStyles}: BaseOnboarding const {isBetaEnabled} = usePermissions(); const [conciergeReportID = ''] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); + const [conciergeChat] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${conciergeReportID}`); + const [onboardingAdminsChatReportID] = useOnyx(ONYXKEYS.ONBOARDING_ADMINS_CHAT_REPORT_ID); + const [adminsChatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${onboardingAdminsChatReportID}`); + const [selfDMReportID] = useOnyx(ONYXKEYS.SELF_DM_REPORT_ID); + const [selfDMReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`); const [onboardingValues] = useOnyx(ONYXKEYS.NVP_ONBOARDING); const isVsb = onboardingValues?.signupQualifier === CONST.ONBOARDING_SIGNUP_QUALIFIERS.VSB; @@ -95,7 +99,9 @@ function BaseOnboardingWorkspaces({route, shouldUseNativeStyles}: BaseOnboarding companySize: onboardingCompanySize, introSelected, isSelfTourViewed, - reports: allReports, + conciergeChat, + adminsChatReport, + selfDMReport, }); setOnboardingAdminsChatReportID(); setOnboardingPolicyID(policy.policyID); diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index c7335b4b3da8..f58e982e2e82 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -2847,10 +2847,6 @@ describe('actions/Report', () => { [TEST_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, }, }; - const reports: OnyxCollection = { - [`${ONYXKEYS.COLLECTION.REPORT}${conciergeChatReportID}`]: conciergeChat, - }; - // LOOKING_AROUND posts the onboarding tasks to the Concierge chat (not the #admins room) const engagementChoice = CONST.ONBOARDING_CHOICES.LOOKING_AROUND; const {onboardingMessages} = getOnboardingMessages(); @@ -2862,7 +2858,7 @@ describe('actions/Report', () => { userReportedIntegration: null, introSelected: {choice: engagementChoice}, isSelfTourViewed: false, - reports, + conciergeChat, }); // The onboarding optimistic data should target the existing Concierge chat @@ -2897,10 +2893,6 @@ describe('actions/Report', () => { }; await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`, selfDMReport); await waitForBatchedUpdates(); - const reports: OnyxCollection = { - [`${ONYXKEYS.COLLECTION.REPORT}${conciergeChatReportID}`]: conciergeChat, - [`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`]: selfDMReport, - }; // PERSONAL_SPEND routes the onboarding to the user's self-DM const engagementChoice = CONST.ONBOARDING_CHOICES.PERSONAL_SPEND; @@ -2913,7 +2905,7 @@ describe('actions/Report', () => { userReportedIntegration: null, introSelected: {choice: engagementChoice}, isSelfTourViewed: false, - reports, + conciergeChat, }); // The existing self-DM should be reused, so no new self-DM is created @@ -2935,10 +2927,6 @@ describe('actions/Report', () => { [TEST_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, }, }; - const reports: OnyxCollection = { - [`${ONYXKEYS.COLLECTION.REPORT}${conciergeChatReportID}`]: conciergeChat, - }; - const engagementChoice = CONST.ONBOARDING_CHOICES.PERSONAL_SPEND; const {onboardingMessages} = getOnboardingMessages(); @@ -2949,7 +2937,7 @@ describe('actions/Report', () => { userReportedIntegration: null, introSelected: {choice: engagementChoice}, isSelfTourViewed: false, - reports, + conciergeChat, }); // A new self-DM is created and added to the optimistic data From 51a9f8ec26461c7e24ad6f584f86fe53837a544b Mon Sep 17 00:00:00 2001 From: truph01 Date: Tue, 23 Jun 2026 11:10:32 +0700 Subject: [PATCH 07/17] fix: conflicts --- src/hooks/useAutoCreateTrackWorkspace.ts | 11 +++++++++-- src/libs/actions/Policy/Policy.ts | 14 ++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/hooks/useAutoCreateTrackWorkspace.ts b/src/hooks/useAutoCreateTrackWorkspace.ts index 210d03599af7..178ec039e63d 100644 --- a/src/hooks/useAutoCreateTrackWorkspace.ts +++ b/src/hooks/useAutoCreateTrackWorkspace.ts @@ -43,6 +43,7 @@ function useAutoCreateTrackWorkspace() { shouldUseNarrowLayout, } = useOnboardingWorkspaceCreationState(); const [onboardingPersonalTrackGoal] = useOnyx(ONYXKEYS.ONBOARDING_PERSONAL_TRACK_GOAL); + const [onboardingAdminsChatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${onboardingAdminsChatReportID}`); const paidGroupPolicySelector = useMemo( () => (policies: OnyxCollection) => Object.values(policies ?? {}).some((policy) => isPaidGroupPolicy(policy) && isPolicyAdmin(policy, currentUserEmail)), @@ -70,7 +71,11 @@ function useAutoCreateTrackWorkspace() { const engagementChoice = onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.TRACK_PERSONAL ? CONST.ONBOARDING_CHOICES.TRACK_PERSONAL : CONST.ONBOARDING_CHOICES.TRACK_WORKSPACE; - const {adminsChatReportID: newAdminsChatReportID, policyID: newPolicyID} = shouldCreateWorkspace + const { + adminsChatReportID: newAdminsChatReportID, + policyID: newPolicyID, + adminsChatReport: newAdminsChatReport, + } = shouldCreateWorkspace ? createWorkspace({ policyOwnerEmail: undefined, makeMeAdmin: true, @@ -91,7 +96,7 @@ function useAutoCreateTrackWorkspace() { hasActiveAdminPolicies, personalTrackGoal: onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.TRACK_PERSONAL && !!personalTrackGoal ? personalTrackGoal : undefined, }) - : {adminsChatReportID: onboardingAdminsChatReportID, policyID: onboardingPolicyID}; + : {adminsChatReportID: onboardingAdminsChatReportID, policyID: onboardingPolicyID, adminsChatReport: onboardingAdminsChatReport}; // On mobile, hardcode trackExpensesWithConcierge since the web flow already works // with the CompleteGuidedSetup response and side panel isn't supported on native. @@ -109,6 +114,7 @@ function useAutoCreateTrackWorkspace() { introSelected, isSelfTourViewed, conciergeChat, + adminsChatReport: newAdminsChatReport, selfDMReport, }); @@ -149,6 +155,7 @@ function useAutoCreateTrackWorkspace() { onboardingPolicyID, hasPaidGroupAdminPolicy, onboardingAdminsChatReportID, + onboardingAdminsChatReport, onboardingPersonalTrackGoal, localCurrencyCode, introSelected, diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 78b1eefb665d..e3dea27807e0 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -2576,7 +2576,7 @@ function buildDefaultTitleFieldList(pendingFields?: Record & {params: CreateWorkspaceParams} { +function buildPolicyData(options: BuildPolicyDataOptions): OnyxData & {params: CreateWorkspaceParams; adminsChatData: Report} { const { policyOwnerEmail = '', makeMeAdmin = false, @@ -3076,7 +3076,7 @@ function buildPolicyData(options: BuildPolicyDataOptions): OnyxData Date: Tue, 23 Jun 2026 11:12:39 +0700 Subject: [PATCH 08/17] fix: conflicts --- Mobile-Expensify | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mobile-Expensify b/Mobile-Expensify index 9980e46fc98d..87dddff6098e 160000 --- a/Mobile-Expensify +++ b/Mobile-Expensify @@ -1 +1 @@ -Subproject commit 9980e46fc98d57b05cc73e61198727ed037ee9d8 +Subproject commit 87dddff6098e1a4c02722b2ff1f9c6c64751990f From f5bf27d23765871cda1950b9806a7b0935d17085 Mon Sep 17 00:00:00 2001 From: truph01 Date: Tue, 23 Jun 2026 14:10:51 +0700 Subject: [PATCH 09/17] fix: lint --- src/libs/ReportUtils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index af6b4333e764..60a1b091bd85 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -11988,6 +11988,7 @@ function prepareOnboardingOnyxData({ lastVisibleActionCreated: '', hasOutstandingChildTask: false, }; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- targetChatReport may be a stub with only reportID/policyID/chatType; the consumers below handle missing fields gracefully. const report = targetChatReport as OnyxEntry; const canUserPerformWriteActionVariable = canUserPerformWriteAction(report, false); const {lastMessageText = ''} = getLastVisibleMessageActionUtils(targetChatReportID, canUserPerformWriteActionVariable); From d416b104881933bcdd067be33cdf087bf43c4b64 Mon Sep 17 00:00:00 2001 From: truph01 Date: Tue, 23 Jun 2026 16:55:00 +0700 Subject: [PATCH 10/17] fix: remove redundant subscribe --- src/hooks/useAutoCreateSubmitWorkspace.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/hooks/useAutoCreateSubmitWorkspace.ts b/src/hooks/useAutoCreateSubmitWorkspace.ts index 1bd5429a00d1..10800d776ef0 100644 --- a/src/hooks/useAutoCreateSubmitWorkspace.ts +++ b/src/hooks/useAutoCreateSubmitWorkspace.ts @@ -46,9 +46,6 @@ function useAutoCreateSubmitWorkspace() { const [hasEditableGroupPolicy] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {selector: groupPolicySelector}); const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); const [conciergeChat] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${conciergeReportID}`); - const [adminsChatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${onboardingAdminsChatReportID}`); - const [selfDMReportID] = useOnyx(ONYXKEYS.SELF_DM_REPORT_ID); - const [selfDMReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`); const autoCreateSubmitWorkspace = useCallback( async (firstName: string, lastName: string) => { @@ -88,8 +85,8 @@ function useAutoCreateSubmitWorkspace() { introSelected, isSelfTourViewed, conciergeChat, - adminsChatReport, - selfDMReport, + adminsChatReport: undefined, + selfDMReport: undefined, }); } catch (error) { Log.warn('[useAutoCreateSubmitWorkspace] Error completing onboarding', {error}); @@ -119,8 +116,6 @@ function useAutoCreateSubmitWorkspace() { hasActiveAdminPolicies, shouldUseNarrowLayout, conciergeChat, - adminsChatReport, - selfDMReport, ], ); From 018c0c67da821bee6a2cc7707f905ed02d026ed8 Mon Sep 17 00:00:00 2001 From: truph01 Date: Tue, 23 Jun 2026 18:39:19 +0700 Subject: [PATCH 11/17] fix: only pass necessary report params --- src/hooks/useAutoCreateSubmitWorkspace.ts | 3 +-- src/hooks/useAutoCreateTrackWorkspace.ts | 12 +++--------- src/libs/actions/Policy/Policy.ts | 14 ++++++-------- .../BaseOnboardingInterestedFeatures.tsx | 5 +---- .../BaseOnboardingPersonalDetails.tsx | 8 +------- .../OnboardingPurpose/BaseOnboardingPurpose.tsx | 4 +--- .../BaseOnboardingWorkspaces.tsx | 7 +------ 7 files changed, 14 insertions(+), 39 deletions(-) diff --git a/src/hooks/useAutoCreateSubmitWorkspace.ts b/src/hooks/useAutoCreateSubmitWorkspace.ts index 10800d776ef0..11fd95f51686 100644 --- a/src/hooks/useAutoCreateSubmitWorkspace.ts +++ b/src/hooks/useAutoCreateSubmitWorkspace.ts @@ -75,6 +75,7 @@ function useAutoCreateSubmitWorkspace() { : {adminsChatReportID: onboardingAdminsChatReportID, policyID: onboardingPolicyID}; try { + // EMPLOYER only posts tasks to concierge — adminsChatReport and selfDMReport are not needed. await completeOnboarding({ engagementChoice: CONST.ONBOARDING_CHOICES.EMPLOYER, onboardingMessage: onboardingMessages[CONST.ONBOARDING_CHOICES.EMPLOYER], @@ -85,8 +86,6 @@ function useAutoCreateSubmitWorkspace() { introSelected, isSelfTourViewed, conciergeChat, - adminsChatReport: undefined, - selfDMReport: undefined, }); } catch (error) { Log.warn('[useAutoCreateSubmitWorkspace] Error completing onboarding', {error}); diff --git a/src/hooks/useAutoCreateTrackWorkspace.ts b/src/hooks/useAutoCreateTrackWorkspace.ts index 2d63aad6a8aa..bc047205cbd7 100644 --- a/src/hooks/useAutoCreateTrackWorkspace.ts +++ b/src/hooks/useAutoCreateTrackWorkspace.ts @@ -42,7 +42,6 @@ function useAutoCreateTrackWorkspace() { shouldUseNarrowLayout, } = useOnboardingWorkspaceCreationState(); const [onboardingPersonalTrackGoal] = useOnyx(ONYXKEYS.ONBOARDING_PERSONAL_TRACK_GOAL); - const [onboardingAdminsChatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${onboardingAdminsChatReportID}`); const paidGroupPolicySelector = useMemo( () => (policies: OnyxCollection) => Object.values(policies ?? {}).some((policy) => isPaidGroupPolicy(policy) && isPolicyAdmin(policy, currentUserEmail)), @@ -70,11 +69,7 @@ function useAutoCreateTrackWorkspace() { const engagementChoice = onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.TRACK_PERSONAL ? CONST.ONBOARDING_CHOICES.TRACK_PERSONAL : CONST.ONBOARDING_CHOICES.TRACK_WORKSPACE; - const { - adminsChatReportID: newAdminsChatReportID, - policyID: newPolicyID, - adminsChatReport: newAdminsChatReport, - } = shouldCreateWorkspace + const {adminsChatReportID: newAdminsChatReportID, policyID: newPolicyID} = shouldCreateWorkspace ? createWorkspace({ policyOwnerEmail: undefined, makeMeAdmin: true, @@ -95,12 +90,13 @@ function useAutoCreateTrackWorkspace() { hasActiveAdminPolicies, personalTrackGoal: onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.TRACK_PERSONAL && !!personalTrackGoal ? personalTrackGoal : undefined, }) - : {adminsChatReportID: onboardingAdminsChatReportID, policyID: onboardingPolicyID, adminsChatReport: onboardingAdminsChatReport}; + : {adminsChatReportID: onboardingAdminsChatReportID, policyID: onboardingPolicyID}; // On mobile, hardcode trackExpensesWithConcierge since the web flow already works // with the CompleteGuidedSetup response and side panel isn't supported on native. let rhpVariant: OnboardingRHPVariant | undefined = isSidePanelReportSupported ? undefined : CONST.ONBOARDING_RHP_VARIANT.TRACK_EXPENSES_WITH_CONCIERGE; try { + // Track/personal choices post tasks to concierge and self-DM — adminsChatReport is not needed (only used for MANAGE_TEAM). const response = await completeOnboarding({ engagementChoice, onboardingMessage: onboardingMessages[engagementChoice], @@ -113,7 +109,6 @@ function useAutoCreateTrackWorkspace() { introSelected, isSelfTourViewed, conciergeChat, - adminsChatReport: newAdminsChatReport, selfDMReport, }); @@ -154,7 +149,6 @@ function useAutoCreateTrackWorkspace() { onboardingPolicyID, hasPaidGroupAdminPolicy, onboardingAdminsChatReportID, - onboardingAdminsChatReport, onboardingPersonalTrackGoal, localCurrencyCode, introSelected, diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index f94124c53e1d..8a31c9910a76 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -2576,7 +2576,7 @@ function buildDefaultTitleFieldList(pendingFields?: Record & {params: CreateWorkspaceParams; adminsChatData: Report} { +function buildPolicyData(options: BuildPolicyDataOptions): OnyxData & {params: CreateWorkspaceParams} { const { policyOwnerEmail = '', makeMeAdmin = false, @@ -3076,7 +3076,7 @@ function buildPolicyData(options: BuildPolicyDataOptions): OnyxData Date: Mon, 29 Jun 2026 16:01:52 +0700 Subject: [PATCH 12/17] Update src/hooks/useAutoCreateSubmitWorkspace.ts Co-authored-by: DylanDylann <141406735+DylanDylann@users.noreply.github.com> --- src/hooks/useAutoCreateSubmitWorkspace.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/useAutoCreateSubmitWorkspace.ts b/src/hooks/useAutoCreateSubmitWorkspace.ts index 11fd95f51686..a35d71c41eda 100644 --- a/src/hooks/useAutoCreateSubmitWorkspace.ts +++ b/src/hooks/useAutoCreateSubmitWorkspace.ts @@ -75,7 +75,6 @@ function useAutoCreateSubmitWorkspace() { : {adminsChatReportID: onboardingAdminsChatReportID, policyID: onboardingPolicyID}; try { - // EMPLOYER only posts tasks to concierge — adminsChatReport and selfDMReport are not needed. await completeOnboarding({ engagementChoice: CONST.ONBOARDING_CHOICES.EMPLOYER, onboardingMessage: onboardingMessages[CONST.ONBOARDING_CHOICES.EMPLOYER], From c7ffa68e388672d59ee2847b95bf6b8f88dac8d5 Mon Sep 17 00:00:00 2001 From: truph01 Date: Mon, 29 Jun 2026 16:02:03 +0700 Subject: [PATCH 13/17] Update src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx Co-authored-by: DylanDylann <141406735+DylanDylann@users.noreply.github.com> --- .../BaseOnboardingInterestedFeatures.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx b/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx index 2ec1757338d8..a458eddb85f4 100644 --- a/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx +++ b/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx @@ -224,7 +224,6 @@ function BaseOnboardingInterestedFeatures({shouldUseNativeStyles}: BaseOnboardin setOnboardingPolicyID(policyID); } - // MANAGE_TEAM posts tasks to #admins room — selfDMReport is not needed (only used for personal/track choices). const response = await completeOnboarding({ engagementChoice: onboardingPurposeSelected, onboardingMessage: onboardingMessages[onboardingPurposeSelected], From 12921ee9c4e4446c9c59a88fe7566b297f6f51f1 Mon Sep 17 00:00:00 2001 From: truph01 Date: Mon, 29 Jun 2026 16:02:20 +0700 Subject: [PATCH 14/17] Update src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx Co-authored-by: DylanDylann <141406735+DylanDylann@users.noreply.github.com> --- src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx b/src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx index 6206fef061ef..2840384a4a41 100644 --- a/src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx +++ b/src/pages/OnboardingWorkspaces/BaseOnboardingWorkspaces.tsx @@ -86,7 +86,6 @@ function BaseOnboardingWorkspaces({route, shouldUseNativeStyles}: BaseOnboarding askToJoinPolicy(policy.policyID); } - // LOOKING_AROUND only posts tasks to concierge — adminsChatReport and selfDMReport are not needed. completeOnboarding({ engagementChoice: CONST.ONBOARDING_CHOICES.LOOKING_AROUND, onboardingMessage: onboardingMessages[CONST.ONBOARDING_CHOICES.LOOKING_AROUND], From 23432863aefeb86cb91b9b8491c0cd43a3642332 Mon Sep 17 00:00:00 2001 From: truph01 Date: Mon, 29 Jun 2026 16:02:34 +0700 Subject: [PATCH 15/17] Update src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx Co-authored-by: DylanDylann <141406735+DylanDylann@users.noreply.github.com> --- src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx index 316d4e6ef1e4..df28d4b7f595 100644 --- a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx +++ b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx @@ -130,7 +130,6 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, ro autoCreateTrackWorkspace(personalDetailsForm.firstName, personalDetailsForm.lastName ?? '', choice); return; } - // This path handles LOOKING_AROUND/EMPLOYER/MANAGE_TEAM — selfDMReport is not needed (only used for personal/track choices). completeOnboarding({ engagementChoice: choice, onboardingMessage: onboardingMessages[choice], From f4e82f9f4236d51bf39af837655ce4693a2336a3 Mon Sep 17 00:00:00 2001 From: truph01 Date: Mon, 29 Jun 2026 16:02:50 +0700 Subject: [PATCH 16/17] Update src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx Co-authored-by: DylanDylann <141406735+DylanDylann@users.noreply.github.com> --- .../OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx b/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx index cccc5ef2e57a..399244ae32fd 100644 --- a/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx +++ b/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx @@ -89,7 +89,6 @@ function BaseOnboardingPersonalDetails({currentUserPersonalDetails, shouldUseNat setIsLoading(true); try { - // This path handles LOOKING_AROUND/EMPLOYER which only post tasks to concierge — adminsChatReport and selfDMReport are not needed. await completeOnboardingReport({ engagementChoice: onboardingPurposeSelected, onboardingMessage: onboardingMessages[onboardingPurposeSelected], From de2754eb326108a498fcb4a8343081289986b231 Mon Sep 17 00:00:00 2001 From: truph01 Date: Mon, 29 Jun 2026 16:03:05 +0700 Subject: [PATCH 17/17] Update src/hooks/useAutoCreateTrackWorkspace.ts Co-authored-by: DylanDylann <141406735+DylanDylann@users.noreply.github.com> --- src/hooks/useAutoCreateTrackWorkspace.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/useAutoCreateTrackWorkspace.ts b/src/hooks/useAutoCreateTrackWorkspace.ts index bc047205cbd7..cb3e6439c8f8 100644 --- a/src/hooks/useAutoCreateTrackWorkspace.ts +++ b/src/hooks/useAutoCreateTrackWorkspace.ts @@ -96,7 +96,6 @@ function useAutoCreateTrackWorkspace() { // with the CompleteGuidedSetup response and side panel isn't supported on native. let rhpVariant: OnboardingRHPVariant | undefined = isSidePanelReportSupported ? undefined : CONST.ONBOARDING_RHP_VARIANT.TRACK_EXPENSES_WITH_CONCIERGE; try { - // Track/personal choices post tasks to concierge and self-DM — adminsChatReport is not needed (only used for MANAGE_TEAM). const response = await completeOnboarding({ engagementChoice, onboardingMessage: onboardingMessages[engagementChoice],