Skip to content

Commit

Permalink
Merge pull request #3711 from Expensify/marcaaron-handleDeepLink
Browse files Browse the repository at this point in the history
[No QA] Improve VBA deep link routing
  • Loading branch information
MariaHCD authored Jun 23, 2021
2 parents 35c09f6 + 20b8492 commit 7ea9941
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/ROUTES.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const REPORT = 'r';
export default {
BANK_ACCOUNT: 'bank-account/:stepToOpen?',
BANK_ACCOUNT_PERSONAL: 'bank-account/personal',
getBankAccountRoute: stepToOpen => `bank-account/${stepToOpen}`,
HOME: '',
SETTINGS: 'settings',
SETTINGS_PROFILE: 'settings/profile',
Expand Down
1 change: 1 addition & 0 deletions src/libs/Navigation/AppNavigator/AuthScreens.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ class AuthScreens extends React.Component {
options={modalScreenOptions}
component={ReimbursementAccountModalStackNavigator}
listeners={modalScreenListeners}
initialParams={{stepToOpen: CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT}}
/>
<RootStack.Screen
name="WorkspaceInvite"
Expand Down
12 changes: 11 additions & 1 deletion src/libs/actions/BankAccounts.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,10 @@ function fetchUserWallet() {

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

// If we are providing a stepToOpen via a deep link then we will always navigate to that step. This
// should be used with caution as it is possible to drop a user into a flow they can't complete e.g.
// if we drop the user into the CompanyStep, but they have no accountNumber or routing Number in
// their achData.
if (stepToOpen) {
currentStep = stepToOpen;
}

// 'error' displays any string set as an error encountered during the add Verified BBA flow.
// If we are fetching a bank account, clear the error to reset.
Onyx.merge(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {
Expand Down
54 changes: 50 additions & 4 deletions src/pages/ReimbursementAccount/ReimbursementAccountPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import CompanyStep from './CompanyStep';
import RequestorStep from './RequestorStep';
import ValidationStep from './ValidationStep';
import BeneficialOwnersStep from './BeneficialOwnersStep';
import ROUTES from '../../ROUTES';
import HeaderWithCloseButton from '../../components/HeaderWithCloseButton';

const propTypes = {
Expand Down Expand Up @@ -80,7 +81,30 @@ const defaultProps = {

class ReimbursementAccountPage extends React.Component {
componentDidMount() {
fetchFreePlanVerifiedBankAccount();
// We can specify a step to navigate to by using route params when the component mounts.
fetchFreePlanVerifiedBankAccount(this.getStepToOpenFromRouteParams());
}

componentDidUpdate(prevProps) {
const currentStep = lodashGet(
this.props,
'reimbursementAccount.achData.currentStep',
CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT,
);
const previousStep = lodashGet(
prevProps,
'reimbursementAccount.achData.currentStep',
CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT,
);

if (currentStep === previousStep) {
return;
}

// When the step changes we will navigate to update the route params. This is mostly cosmetic as we only use
// the route params when the component first mounts to jump to a specific route instead of picking up where the
// user left off in the flow.
Navigation.navigate(ROUTES.getBankAccountRoute(this.getRouteForCurrentStep(currentStep)));
}

/**
Expand All @@ -103,6 +127,26 @@ class ReimbursementAccountPage extends React.Component {
}
}

/**
* @param {String} currentStep
* @returns {String}
*/
getRouteForCurrentStep(currentStep) {
switch (currentStep) {
case CONST.BANK_ACCOUNT.STEP.COMPANY:
return 'company';
case CONST.BANK_ACCOUNT.STEP.REQUESTOR:
return 'requestor';
case CONST.BANK_ACCOUNT.STEP.ACH_CONTRACT:
return 'contract';
case CONST.BANK_ACCOUNT.STEP.VALIDATION:
return 'validate';
case CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT:
default:
return 'new';
}
}

render() {
if (!Permissions.canUseFreePlan(this.props.betas)) {
console.debug('Not showing new bank account page because user is not on free plan beta');
Expand Down Expand Up @@ -156,9 +200,11 @@ class ReimbursementAccountPage extends React.Component {
const error = lodashGet(this.props, 'reimbursementAccount.error');
const maxAttemptsReached = lodashGet(this.props, 'reimbursementAccount.maxAttemptsReached');

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

0 comments on commit 7ea9941

Please sign in to comment.