diff --git a/src/libs/actions/BankAccounts.ts b/src/libs/actions/BankAccounts.ts index 6e718b1bde343..a7b4f6703f8fc 100644 --- a/src/libs/actions/BankAccounts.ts +++ b/src/libs/actions/BankAccounts.ts @@ -22,7 +22,7 @@ import type {Route} from '@src/ROUTES'; import type {PersonalBankAccountForm} from '@src/types/form'; import type {ACHContractStepProps, BeneficialOwnersStepProps, CompanyStepProps, RequestorStepProps} from '@src/types/form/ReimbursementAccountForm'; import type PlaidBankAccount from '@src/types/onyx/PlaidBankAccount'; -import type {BankAccountStep, BankAccountSubStep} from '@src/types/onyx/ReimbursementAccount'; +import type {BankAccountStep, ReimbursementAccountStep, ReimbursementAccountSubStep} from '@src/types/onyx/ReimbursementAccount'; import type {OnyxData} from '@src/types/onyx/Request'; import * as ReimbursementAccount from './ReimbursementAccount'; @@ -40,10 +40,6 @@ export { export {openPlaidBankAccountSelector, openPlaidBankLogin} from './Plaid'; export {openOnfidoFlow, answerQuestionsForWallet, verifyIdentity, acceptWalletTerms} from './Wallet'; -type ReimbursementAccountStep = BankAccountStep | ''; - -type ReimbursementAccountSubStep = BankAccountSubStep | ''; - type AccountFormValues = typeof ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT_FORM | typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM; type BusinessAddress = { diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 753428e4a6df0..b14e5d0ae3ce4 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -2591,6 +2591,26 @@ function createWorkspaceFromIOUPayment(iouReport: OnyxEntry): WorkspaceF value: {[movedReportAction.reportActionID]: null}, }); + // We know that this new workspace has no BankAccount yet, so we can set + // the reimbursement account to be immediately in the setup state for a new bank account: + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}`, + value: { + isLoading: false, + achData: { + currentStep: CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT, + policyID, + subStep: '', + }, + }, + }); + failureData.push({ + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}`, + value: CONST.REIMBURSEMENT_ACCOUNT.DEFAULT_DATA, + }); + const params: CreateWorkspaceFromIOUPaymentParams = { policyID, announceChatReportID, diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx b/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx index 9bbe9f5adbc48..4b42aff1fc1d5 100644 --- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx +++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx @@ -31,7 +31,7 @@ import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {InputID} from '@src/types/form/ReimbursementAccountForm'; import type * as OnyxTypes from '@src/types/onyx'; -import type {ACHData, BankAccountStep as TBankAccountStep} from '@src/types/onyx/ReimbursementAccount'; +import type {ACHDataReimbursementAccount, BankAccountStep as TBankAccountStep} from '@src/types/onyx/ReimbursementAccount'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import ACHContractStep from './ACHContractStep'; import BankAccountStep from './BankAccountStep'; @@ -144,7 +144,7 @@ function ReimbursementAccountPage({ */ const achData = reimbursementAccount?.achData; - function getBankAccountFields(fieldNames: T[]): Pick { + function getBankAccountFields(fieldNames: T[]): Pick { return { ...lodashPick(reimbursementAccount?.achData, ...fieldNames), }; @@ -199,14 +199,20 @@ function ReimbursementAccountPage({ /** When this page is first opened, `reimbursementAccount` prop might not yet be fully loaded from Onyx. Calculating `shouldShowContinueSetupButton` immediately on initial render doesn't make sense as - it relies on complete data. Thus, we should wait to calculate it until we have received + it relies on incomplete data. Thus, we should wait to calculate it until we have received the full `reimbursementAccount` data from the server. This logic is handled within the useEffect hook, which acts similarly to `componentDidUpdate` when the `reimbursementAccount` dependency changes. */ const [hasACHDataBeenLoaded, setHasACHDataBeenLoaded] = useState(reimbursementAccount !== CONST.REIMBURSEMENT_ACCOUNT.DEFAULT_DATA); const [shouldShowContinueSetupButton, setShouldShowContinueSetupButton] = useState(hasACHDataBeenLoaded ? getShouldShowContinueSetupButtonInitialValue() : false); - const [isReimbursementAccountLoading, setIsReimbursementAccountLoading] = useState(true); + const [isReimbursementAccountLoading, setIsReimbursementAccountLoading] = useState(() => { + // By default return true (loading), if there are already loaded data we can skip the loading state + if (hasACHDataBeenLoaded && typeof reimbursementAccount?.isLoading === 'boolean' && !reimbursementAccount?.isLoading) { + return false; + } + return true; + }); // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const currentStep = achData?.currentStep || CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT; @@ -238,6 +244,10 @@ function ReimbursementAccountPage({ } useEffect(() => { + if (!isReimbursementAccountLoading) { + return; + } + // If the step to open is empty, we want to clear the sub step, so the connect option view is shown to the user const isStepToOpenEmpty = getStepToOpenFromRouteParams(route) === ''; if (isStepToOpenEmpty) { diff --git a/src/types/onyx/ReimbursementAccount.ts b/src/types/onyx/ReimbursementAccount.ts index 2322f6faab179..186b3e6ad05bf 100644 --- a/src/types/onyx/ReimbursementAccount.ts +++ b/src/types/onyx/ReimbursementAccount.ts @@ -49,6 +49,21 @@ type ACHData = Partial & { + /** Step of the setup flow that we are on. Determines which view is presented. */ + currentStep?: ReimbursementAccountStep; + + /** Optional subStep we would like the user to start back on */ + subStep?: ReimbursementAccountSubStep; +}; + /** Model of reimbursement account data */ type ReimbursementAccount = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** Whether we are loading the data via the API */ @@ -58,7 +73,7 @@ type ReimbursementAccount = OnyxCommon.OnyxValueWithOfflineFeedback<{ throttledDate?: string; /** Additional data for the account in setup */ - achData?: ACHData; + achData?: ACHDataReimbursementAccount; /** Disable validation button if max attempts exceeded */ maxAttemptsReached?: boolean; @@ -80,4 +95,4 @@ type ReimbursementAccount = OnyxCommon.OnyxValueWithOfflineFeedback<{ }>; export default ReimbursementAccount; -export type {BankAccountStep, BankAccountSubStep, ACHData}; +export type {BankAccountStep, BankAccountSubStep, ACHData, ReimbursementAccountStep, ReimbursementAccountSubStep, ACHDataReimbursementAccount};