From 7dc42b67d87ebf7ce008746b5255195b5d88936c Mon Sep 17 00:00:00 2001 From: VickyStash Date: Tue, 14 Jan 2025 12:34:28 +0100 Subject: [PATCH 1/4] Set up bank-connection-complete page --- src/SCREENS.ts | 1 + src/components/DeeplinkWrapper/index.website.tsx | 3 ++- src/libs/Navigation/AppNavigator/AuthScreens.tsx | 5 +++++ src/libs/Navigation/AppNavigator/PublicScreens.tsx | 4 ++++ src/libs/Navigation/linkingConfig/config.ts | 1 + src/libs/Navigation/types.ts | 2 ++ 6 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 2359324c9b90..c204b05c90de 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -22,6 +22,7 @@ const SCREENS = { TRANSITION_BETWEEN_APPS: 'TransitionBetweenApps', VALIDATE_LOGIN: 'ValidateLogin', CONNECTION_COMPLETE: 'ConnectionComplete', + BANK_CONNECTION_COMPLETE: 'BankConnectionComplete', UNLINK_LOGIN: 'UnlinkLogin', SETTINGS_CENTRAL_PANE: 'SettingsCentralPane', TRAVEL: { diff --git a/src/components/DeeplinkWrapper/index.website.tsx b/src/components/DeeplinkWrapper/index.website.tsx index 73427f0d11aa..cdf1e4703bc6 100644 --- a/src/components/DeeplinkWrapper/index.website.tsx +++ b/src/components/DeeplinkWrapper/index.website.tsx @@ -67,7 +67,8 @@ function DeeplinkWrapper({children, isAuthenticated, autoAuthState, initialUrl}: // According to the design, we don't support unlink in Desktop app https://github.com/Expensify/App/issues/19681#issuecomment-1610353099 const routeRegex = new RegExp(CONST.REGEX.ROUTES.UNLINK_LOGIN); const isUnsupportedDeeplinkRoute = routeRegex.test(window.location.pathname); - const isConnectionCompleteRoute = window.location.pathname.replace('/', '') === ROUTES.CONNECTION_COMPLETE; + const route = window.location.pathname.replace('/', ''); + const isConnectionCompleteRoute = route === ROUTES.CONNECTION_COMPLETE || route === ROUTES.BANK_CONNECTION_COMPLETE; // Making a few checks to exit early before checking authentication status if ( diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index f0673a42c622..d8f6439f86e6 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -602,6 +602,11 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie options={defaultScreenOptions} component={ConnectionCompletePage} /> + {Object.entries(CENTRAL_PANE_SCREENS).map(([screenName, componentGetter]) => { const centralPaneName = screenName as CentralPaneName; return ( diff --git a/src/libs/Navigation/AppNavigator/PublicScreens.tsx b/src/libs/Navigation/AppNavigator/PublicScreens.tsx index dbbb11c978d5..00b9a98e78bd 100644 --- a/src/libs/Navigation/AppNavigator/PublicScreens.tsx +++ b/src/libs/Navigation/AppNavigator/PublicScreens.tsx @@ -38,6 +38,10 @@ function PublicScreens() { name={SCREENS.CONNECTION_COMPLETE} component={ConnectionCompletePage} /> + ['config'] = { [SCREENS.UNLINK_LOGIN]: ROUTES.UNLINK_LOGIN, [SCREENS.TRANSITION_BETWEEN_APPS]: ROUTES.TRANSITION_BETWEEN_APPS, [SCREENS.CONNECTION_COMPLETE]: ROUTES.CONNECTION_COMPLETE, + [SCREENS.BANK_CONNECTION_COMPLETE]: ROUTES.BANK_CONNECTION_COMPLETE, [SCREENS.CONCIERGE]: ROUTES.CONCIERGE, [SCREENS.TRACK_EXPENSE]: ROUTES.TRACK_EXPENSE, [SCREENS.SUBMIT_EXPENSE]: ROUTES.SUBMIT_EXPENSE, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 088f624c7dc3..f8a98dd909f7 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -1668,6 +1668,7 @@ type PublicScreensParamList = SharedScreensParamList & { [SCREENS.SIGN_IN_WITH_GOOGLE_DESKTOP]: undefined; [SCREENS.SAML_SIGN_IN]: undefined; [SCREENS.CONNECTION_COMPLETE]: undefined; + [SCREENS.BANK_CONNECTION_COMPLETE]: undefined; }; type AuthScreensParamList = CentralPaneScreensParamList & @@ -1715,6 +1716,7 @@ type AuthScreensParamList = CentralPaneScreensParamList & isFromReviewDuplicates?: string; }; [SCREENS.CONNECTION_COMPLETE]: undefined; + [SCREENS.BANK_CONNECTION_COMPLETE]: undefined; }; type SearchReportParamList = { From b988b8342c77fd7fde936d8a108c8a974db3ac50 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Tue, 14 Jan 2025 12:58:55 +0100 Subject: [PATCH 2/4] Fix browser window duplicate --- .../companyCards/addNew/BankConnection/index.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/companyCards/addNew/BankConnection/index.tsx b/src/pages/workspace/companyCards/addNew/BankConnection/index.tsx index e7e71d1c3785..80b66592e89c 100644 --- a/src/pages/workspace/companyCards/addNew/BankConnection/index.tsx +++ b/src/pages/workspace/companyCards/addNew/BankConnection/index.tsx @@ -1,4 +1,4 @@ -import React, {useCallback, useEffect, useMemo} from 'react'; +import React, {useCallback, useEffect, useMemo, useState} from 'react'; import {useOnyx} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import BlockingView from '@components/BlockingViews/BlockingView'; @@ -35,6 +35,7 @@ function BankConnection({policyID}: BankConnectionStepProps) { const workspaceAccountID = PolicyUtils.getWorkspaceAccountID(policyID); const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); const prevFeedsData = usePrevious(cardFeeds?.settings?.oAuthAccountDetails); + const [shouldBlockWindowOpen, setShouldBlockWindowOpen] = useState(false); const {isNewFeedConnected, newFeed} = useMemo(() => CardUtils.checkIfNewFeedConnected(prevFeedsData ?? {}, cardFeeds?.settings?.oAuthAccountDetails ?? {}), [cardFeeds, prevFeedsData]); const url = getCompanyCardBankConnection(policyID, bankName); @@ -71,6 +72,7 @@ function BankConnection({policyID}: BankConnectionStepProps) { return; } if (isNewFeedConnected) { + setShouldBlockWindowOpen(true); customWindow?.close(); if (newFeed) { Card.updateSelectedFeed(newFeed, policyID); @@ -78,7 +80,9 @@ function BankConnection({policyID}: BankConnectionStepProps) { Navigation.navigate(ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(policyID)); return; } - customWindow = openBankConnection(url); + if (!shouldBlockWindowOpen) { + customWindow = openBankConnection(url); + } }, [isNewFeedConnected, newFeed, policyID, url]); return ( From 60e7ff875a4f5dcb32676e2d4f22a4f9eacbf309 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Tue, 14 Jan 2025 15:01:44 +0100 Subject: [PATCH 3/4] Lint fixes --- .../DeeplinkWrapper/index.website.tsx | 16 +++++++------- .../addNew/BankConnection/index.tsx | 22 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/components/DeeplinkWrapper/index.website.tsx b/src/components/DeeplinkWrapper/index.website.tsx index cdf1e4703bc6..158bf43b2dfe 100644 --- a/src/components/DeeplinkWrapper/index.website.tsx +++ b/src/components/DeeplinkWrapper/index.website.tsx @@ -1,19 +1,19 @@ import {Str} from 'expensify-common'; import {useEffect, useRef, useState} from 'react'; -import * as Browser from '@libs/Browser'; +import {isMobile} from '@libs/Browser'; import Navigation from '@libs/Navigation/Navigation'; import navigationRef from '@libs/Navigation/navigationRef'; import shouldPreventDeeplinkPrompt from '@libs/Navigation/shouldPreventDeeplinkPrompt'; -import * as App from '@userActions/App'; -import * as Link from '@userActions/Link'; -import * as Session from '@userActions/Session'; +import {beginDeepLinkRedirect, beginDeepLinkRedirectAfterTransition} from '@userActions/App'; +import {getInternalNewExpensifyPath} from '@userActions/Link'; +import {isAnonymousUser} from '@userActions/Session'; import CONFIG from '@src/CONFIG'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type DeeplinkWrapperProps from './types'; function isMacOSWeb(): boolean { - return !Browser.isMobile() && typeof navigator === 'object' && typeof navigator.userAgent === 'string' && /Mac/i.test(navigator.userAgent) && !/Electron/i.test(navigator.userAgent); + return !isMobile() && typeof navigator === 'object' && typeof navigator.userAgent === 'string' && /Mac/i.test(navigator.userAgent) && !/Electron/i.test(navigator.userAgent); } function promptToOpenInDesktopApp(initialUrl = '') { @@ -27,12 +27,12 @@ function promptToOpenInDesktopApp(initialUrl = '') { if (params.get('referrer') === 'desktop') { return; } - App.beginDeepLinkRedirectAfterTransition(); + beginDeepLinkRedirectAfterTransition(); } else { // Match any magic link (/v//<6 digit code>) const isMagicLink = CONST.REGEX.ROUTES.VALIDATE_LOGIN.test(window.location.pathname); - App.beginDeepLinkRedirect(!isMagicLink, Link.getInternalNewExpensifyPath(initialUrl)); + beginDeepLinkRedirect(!isMagicLink, getInternalNewExpensifyPath(initialUrl)); } } @@ -78,7 +78,7 @@ function DeeplinkWrapper({children, isAuthenticated, autoAuthState, initialUrl}: isConnectionCompleteRoute || CONFIG.ENVIRONMENT === CONST.ENVIRONMENT.DEV || autoAuthState === CONST.AUTO_AUTH_STATE.NOT_STARTED || - Session.isAnonymousUser() + isAnonymousUser() ) { return; } diff --git a/src/pages/workspace/companyCards/addNew/BankConnection/index.tsx b/src/pages/workspace/companyCards/addNew/BankConnection/index.tsx index 80b66592e89c..e563f9020a39 100644 --- a/src/pages/workspace/companyCards/addNew/BankConnection/index.tsx +++ b/src/pages/workspace/companyCards/addNew/BankConnection/index.tsx @@ -10,11 +10,11 @@ import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import usePrevious from '@hooks/usePrevious'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as CardUtils from '@libs/CardUtils'; +import {checkIfNewFeedConnected} from '@libs/CardUtils'; import Navigation from '@libs/Navigation/Navigation'; -import * as PolicyUtils from '@libs/PolicyUtils'; -import * as Card from '@userActions/Card'; -import * as CompanyCards from '@userActions/CompanyCards'; +import {getWorkspaceAccountID} from '@libs/PolicyUtils'; +import {updateSelectedFeed} from '@userActions/Card'; +import {setAddNewCompanyCardStepAndData} from '@userActions/CompanyCards'; import getCompanyCardBankConnection from '@userActions/getCompanyCardBankConnection'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -32,11 +32,11 @@ function BankConnection({policyID}: BankConnectionStepProps) { const {translate} = useLocalize(); const [addNewCard] = useOnyx(ONYXKEYS.ADD_NEW_COMPANY_CARD); const bankName: ValueOf | undefined = addNewCard?.data?.selectedBank; - const workspaceAccountID = PolicyUtils.getWorkspaceAccountID(policyID); + const workspaceAccountID = getWorkspaceAccountID(policyID); const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); const prevFeedsData = usePrevious(cardFeeds?.settings?.oAuthAccountDetails); const [shouldBlockWindowOpen, setShouldBlockWindowOpen] = useState(false); - const {isNewFeedConnected, newFeed} = useMemo(() => CardUtils.checkIfNewFeedConnected(prevFeedsData ?? {}, cardFeeds?.settings?.oAuthAccountDetails ?? {}), [cardFeeds, prevFeedsData]); + const {isNewFeedConnected, newFeed} = useMemo(() => checkIfNewFeedConnected(prevFeedsData ?? {}, cardFeeds?.settings?.oAuthAccountDetails ?? {}), [cardFeeds, prevFeedsData]); const url = getCompanyCardBankConnection(policyID, bankName); @@ -50,14 +50,14 @@ function BankConnection({policyID}: BankConnectionStepProps) { const handleBackButtonPress = () => { customWindow?.close(); if (bankName === CONST.COMPANY_CARDS.BANKS.BREX) { - CompanyCards.setAddNewCompanyCardStepAndData({step: CONST.COMPANY_CARDS.STEP.SELECT_BANK}); + setAddNewCompanyCardStepAndData({step: CONST.COMPANY_CARDS.STEP.SELECT_BANK}); return; } if (bankName === CONST.COMPANY_CARDS.BANKS.AMEX) { - CompanyCards.setAddNewCompanyCardStepAndData({step: CONST.COMPANY_CARDS.STEP.AMEX_CUSTOM_FEED}); + setAddNewCompanyCardStepAndData({step: CONST.COMPANY_CARDS.STEP.AMEX_CUSTOM_FEED}); return; } - CompanyCards.setAddNewCompanyCardStepAndData({step: CONST.COMPANY_CARDS.STEP.SELECT_FEED_TYPE}); + setAddNewCompanyCardStepAndData({step: CONST.COMPANY_CARDS.STEP.SELECT_FEED_TYPE}); }; const CustomSubtitle = ( @@ -75,7 +75,7 @@ function BankConnection({policyID}: BankConnectionStepProps) { setShouldBlockWindowOpen(true); customWindow?.close(); if (newFeed) { - Card.updateSelectedFeed(newFeed, policyID); + updateSelectedFeed(newFeed, policyID); } Navigation.navigate(ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(policyID)); return; @@ -83,7 +83,7 @@ function BankConnection({policyID}: BankConnectionStepProps) { if (!shouldBlockWindowOpen) { customWindow = openBankConnection(url); } - }, [isNewFeedConnected, newFeed, policyID, url]); + }, [isNewFeedConnected, shouldBlockWindowOpen, newFeed, policyID, url]); return ( From 2d069c434c605c84412556c5ffc9a3c831a26899 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 15 Jan 2025 10:52:51 +0100 Subject: [PATCH 4/4] Show connection complete screens at the fullscreen --- src/libs/Navigation/AppNavigator/AuthScreens.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index d8f6439f86e6..8832a3b4287c 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -599,12 +599,12 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie /> {Object.entries(CENTRAL_PANE_SCREENS).map(([screenName, componentGetter]) => {