Skip to content

Commit 7ea9941

Browse files
authored
Merge pull request #3711 from Expensify/marcaaron-handleDeepLink
[No QA] Improve VBA deep link routing
2 parents 35c09f6 + 20b8492 commit 7ea9941

File tree

4 files changed

+63
-5
lines changed

4 files changed

+63
-5
lines changed

src/ROUTES.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const REPORT = 'r';
1010
export default {
1111
BANK_ACCOUNT: 'bank-account/:stepToOpen?',
1212
BANK_ACCOUNT_PERSONAL: 'bank-account/personal',
13+
getBankAccountRoute: stepToOpen => `bank-account/${stepToOpen}`,
1314
HOME: '',
1415
SETTINGS: 'settings',
1516
SETTINGS_PROFILE: 'settings/profile',

src/libs/Navigation/AppNavigator/AuthScreens.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ class AuthScreens extends React.Component {
299299
options={modalScreenOptions}
300300
component={ReimbursementAccountModalStackNavigator}
301301
listeners={modalScreenListeners}
302+
initialParams={{stepToOpen: CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT}}
302303
/>
303304
<RootStack.Screen
304305
name="WorkspaceInvite"

src/libs/actions/BankAccounts.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,10 @@ function fetchUserWallet() {
325325

326326
/**
327327
* Fetch the bank account currently being set up by the user for the free plan if it exists.
328+
*
329+
* @param {String} [stepToOpen]
328330
*/
329-
function fetchFreePlanVerifiedBankAccount() {
331+
function fetchFreePlanVerifiedBankAccount(stepToOpen) {
330332
// We are using set here since we will rely on data from the server (not local data) to populate the VBA flow
331333
// and determine which step to navigate to.
332334
Onyx.set(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {loading: true});
@@ -461,6 +463,14 @@ function fetchFreePlanVerifiedBankAccount() {
461463
currentStep = CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT;
462464
}
463465

466+
// If we are providing a stepToOpen via a deep link then we will always navigate to that step. This
467+
// should be used with caution as it is possible to drop a user into a flow they can't complete e.g.
468+
// if we drop the user into the CompanyStep, but they have no accountNumber or routing Number in
469+
// their achData.
470+
if (stepToOpen) {
471+
currentStep = stepToOpen;
472+
}
473+
464474
// 'error' displays any string set as an error encountered during the add Verified BBA flow.
465475
// If we are fetching a bank account, clear the error to reset.
466476
Onyx.merge(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {

src/pages/ReimbursementAccount/ReimbursementAccountPage.js

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import CompanyStep from './CompanyStep';
2424
import RequestorStep from './RequestorStep';
2525
import ValidationStep from './ValidationStep';
2626
import BeneficialOwnersStep from './BeneficialOwnersStep';
27+
import ROUTES from '../../ROUTES';
2728
import HeaderWithCloseButton from '../../components/HeaderWithCloseButton';
2829

2930
const propTypes = {
@@ -80,7 +81,30 @@ const defaultProps = {
8081

8182
class ReimbursementAccountPage extends React.Component {
8283
componentDidMount() {
83-
fetchFreePlanVerifiedBankAccount();
84+
// We can specify a step to navigate to by using route params when the component mounts.
85+
fetchFreePlanVerifiedBankAccount(this.getStepToOpenFromRouteParams());
86+
}
87+
88+
componentDidUpdate(prevProps) {
89+
const currentStep = lodashGet(
90+
this.props,
91+
'reimbursementAccount.achData.currentStep',
92+
CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT,
93+
);
94+
const previousStep = lodashGet(
95+
prevProps,
96+
'reimbursementAccount.achData.currentStep',
97+
CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT,
98+
);
99+
100+
if (currentStep === previousStep) {
101+
return;
102+
}
103+
104+
// When the step changes we will navigate to update the route params. This is mostly cosmetic as we only use
105+
// the route params when the component first mounts to jump to a specific route instead of picking up where the
106+
// user left off in the flow.
107+
Navigation.navigate(ROUTES.getBankAccountRoute(this.getRouteForCurrentStep(currentStep)));
84108
}
85109

86110
/**
@@ -103,6 +127,26 @@ class ReimbursementAccountPage extends React.Component {
103127
}
104128
}
105129

130+
/**
131+
* @param {String} currentStep
132+
* @returns {String}
133+
*/
134+
getRouteForCurrentStep(currentStep) {
135+
switch (currentStep) {
136+
case CONST.BANK_ACCOUNT.STEP.COMPANY:
137+
return 'company';
138+
case CONST.BANK_ACCOUNT.STEP.REQUESTOR:
139+
return 'requestor';
140+
case CONST.BANK_ACCOUNT.STEP.ACH_CONTRACT:
141+
return 'contract';
142+
case CONST.BANK_ACCOUNT.STEP.VALIDATION:
143+
return 'validate';
144+
case CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT:
145+
default:
146+
return 'new';
147+
}
148+
}
149+
106150
render() {
107151
if (!Permissions.canUseFreePlan(this.props.betas)) {
108152
console.debug('Not showing new bank account page because user is not on free plan beta');
@@ -156,9 +200,11 @@ class ReimbursementAccountPage extends React.Component {
156200
const error = lodashGet(this.props, 'reimbursementAccount.error');
157201
const maxAttemptsReached = lodashGet(this.props, 'reimbursementAccount.maxAttemptsReached');
158202

159-
// We grab the currentStep from the achData to determine which view to display. The SetupWithdrawalAccount flow
160-
// allows us to continue the flow from various points depending on where the user left off. We can also
161-
// specify a specific step to navigate to by using route params.
203+
// The SetupWithdrawalAccount flow allows us to continue the flow from various points depending on where the
204+
// user left off. This view will refer to the achData as the single source of truth to determine which route to
205+
// display. We can also specify a specific route to navigate to via route params when the component first
206+
// mounts which will set the achData.currentStep after the account data is fetched and overwrite the logical
207+
// next step.
162208
const achData = lodashGet(this.props, 'reimbursementAccount.achData', {});
163209
const currentStep = achData.currentStep || CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT;
164210
return (

0 commit comments

Comments
 (0)