Skip to content

Commit 9f73a02

Browse files
authored
Merge pull request #4431 from Expensify/jasper-VBAFlowRedFieldOutlines
Handle VBA errors with red field outlines
2 parents b93e158 + 37fd8c7 commit 9f73a02

File tree

9 files changed

+222
-38
lines changed

9 files changed

+222
-38
lines changed

src/components/TextInputWithLabel.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,12 @@ const TextInputWithLabel = props => (
5454
)}
5555
</View>
5656
<TextInput
57-
style={[styles.textInput, styles.mb1, props.disabled ? styles.inputDisabled : undefined]}
57+
style={[
58+
styles.textInput,
59+
styles.mb1,
60+
props.disabled ? styles.inputDisabled : undefined,
61+
props.errorText ? styles.errorOutline : undefined,
62+
]}
5863
// eslint-disable-next-line react/jsx-props-no-spreading
5964
{..._.omit(props, ['label', 'errorText'])}
6065
/>

src/libs/ValidationUtils.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import moment from 'moment';
22
import CONST from '../CONST';
3-
import Growl from './Growl';
43
import {translateLocal} from './translate';
4+
import {showBankAccountFormValidationError} from './actions/BankAccounts';
55

66
/**
77
* Validating that this is a valid address (PO boxes are not allowed)
@@ -74,27 +74,27 @@ function isValidSSNLastFour(ssnLast4) {
7474
*/
7575
function isValidIdentity(identity) {
7676
if (!isValidAddress(identity.street)) {
77-
Growl.error(translateLocal('bankAccount.error.address'));
77+
showBankAccountFormValidationError(translateLocal('bankAccount.error.address'));
7878
return false;
7979
}
8080

8181
if (identity.state === '') {
82-
Growl.error(translateLocal('bankAccount.error.addressState'));
82+
showBankAccountFormValidationError(translateLocal('bankAccount.error.addressState'));
8383
return false;
8484
}
8585

8686
if (!isValidZipCode(identity.zipCode)) {
87-
Growl.error(translateLocal('bankAccount.error.zipCode'));
87+
showBankAccountFormValidationError(translateLocal('bankAccount.error.zipCode'));
8888
return false;
8989
}
9090

9191
if (!isValidDate(identity.dob)) {
92-
Growl.error(translateLocal('bankAccount.error.dob'));
92+
showBankAccountFormValidationError(translateLocal('bankAccount.error.dob'));
9393
return false;
9494
}
9595

9696
if (!isValidSSNLastFour(identity.ssnLast4)) {
97-
Growl.error(translateLocal('bankAccount.error.ssnLast4'));
97+
showBankAccountFormValidationError(translateLocal('bankAccount.error.ssnLast4'));
9898
return false;
9999
}
100100

src/libs/actions/BankAccounts.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,10 @@ function validateBankAccount(bankAccountID, validateCode) {
602602
});
603603
}
604604

605+
function showBankAccountFormValidationError(error) {
606+
Onyx.merge(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {error}).then(() => Growl.error(error));
607+
}
608+
605609
/**
606610
* Create or update the bank account in db with the updated data.
607611
*
@@ -773,7 +777,7 @@ function setupWithdrawalAccount(data) {
773777
goToWithdrawalAccountSetupStep(nextStep, achData);
774778

775779
if (error) {
776-
Growl.error(error, 5000);
780+
showBankAccountFormValidationError(error);
777781
}
778782
})
779783
.catch((response) => {
@@ -783,7 +787,7 @@ function setupWithdrawalAccount(data) {
783787
});
784788
}
785789

786-
function hideExistingOwnersError() {
790+
function hideBankAccountErrors() {
787791
Onyx.merge(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {error: '', existingOwnersList: ''});
788792
}
789793

@@ -799,5 +803,6 @@ export {
799803
goToWithdrawalAccountSetupStep,
800804
setupWithdrawalAccount,
801805
validateBankAccount,
802-
hideExistingOwnersError,
806+
hideBankAccountErrors,
807+
showBankAccountFormValidationError,
803808
};

src/pages/ReimbursementAccount/BankAccountStep.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import Text from '../../components/Text';
2323
import ExpensiTextInput from '../../components/ExpensiTextInput';
2424
import {
2525
goToWithdrawalAccountSetupStep,
26-
hideExistingOwnersError,
26+
hideBankAccountErrors,
2727
setupWithdrawalAccount,
2828
} from '../../libs/actions/BankAccounts';
2929
import ConfirmModal from '../../components/ConfirmModal';
@@ -130,8 +130,8 @@ class BankAccountStep extends React.Component {
130130
const isFromPlaid = this.props.achData.setupType === CONST.BANK_ACCOUNT.SETUP_TYPE.PLAID;
131131
const shouldDisableInputs = Boolean(this.props.achData.bankAccountID) || isFromPlaid;
132132
const existingOwners = this.props.reimbursementAccount.existingOwners;
133-
const isExistingOwnersErrorVisible = Boolean(this.props.reimbursementAccount.error
134-
&& existingOwners);
133+
const error = this.props.reimbursementAccount.error;
134+
const isExistingOwnersErrorVisible = Boolean(error && existingOwners);
135135
return (
136136
<View style={[styles.flex1, styles.justifyContentBetween]}>
137137
<HeaderWithCloseButton
@@ -211,8 +211,15 @@ class BankAccountStep extends React.Component {
211211
placeholder={this.props.translate('bankAccount.routingNumber')}
212212
keyboardType="number-pad"
213213
value={this.state.routingNumber}
214-
onChangeText={routingNumber => this.setState({routingNumber})}
214+
onChangeText={(routingNumber) => {
215+
if (error === this.props.translate('bankAccount.error.routingNumber')) {
216+
hideBankAccountErrors();
217+
}
218+
this.setState({routingNumber});
219+
}}
215220
disabled={shouldDisableInputs}
221+
errorText={error === this.props.translate('bankAccount.error.routingNumber')
222+
? error : ''}
216223
/>
217224
<ExpensiTextInput
218225
placeholder={this.props.translate('bankAccount.accountNumber')}
@@ -250,7 +257,7 @@ class BankAccountStep extends React.Component {
250257
<ConfirmModal
251258
title={this.props.translate('bankAccount.error.existingOwners.unableToAddBankAccount')}
252259
isVisible={isExistingOwnersErrorVisible}
253-
onConfirm={hideExistingOwnersError}
260+
onConfirm={hideBankAccountErrors}
254261
shouldShowCancelButton={false}
255262
prompt={(
256263
<View>

src/pages/ReimbursementAccount/BeneficialOwnersStep.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import _ from 'underscore';
22
import React from 'react';
33
import PropTypes from 'prop-types';
44
import {ScrollView, View} from 'react-native';
5+
import {withOnyx} from 'react-native-onyx';
56
import Text from '../../components/Text';
67
import HeaderWithCloseButton from '../../components/HeaderWithCloseButton';
78
import styles from '../../styles/styles';
@@ -11,17 +12,28 @@ import Button from '../../components/Button';
1112
import IdentityForm from './IdentityForm';
1213
import FixedFooter from '../../components/FixedFooter';
1314
import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
14-
import {goToWithdrawalAccountSetupStep, setupWithdrawalAccount} from '../../libs/actions/BankAccounts';
15+
import {
16+
goToWithdrawalAccountSetupStep,
17+
setupWithdrawalAccount,
18+
} from '../../libs/actions/BankAccounts';
1519
import Navigation from '../../libs/Navigation/Navigation';
1620
import CONST from '../../CONST';
1721
import {isValidIdentity} from '../../libs/ValidationUtils';
1822
import Growl from '../../libs/Growl';
23+
import ONYXKEYS from '../../ONYXKEYS';
24+
import compose from '../../libs/compose';
1925

2026
const propTypes = {
2127
/** Name of the company */
2228
companyName: PropTypes.string.isRequired,
2329

2430
...withLocalizePropTypes,
31+
32+
/** Bank account currently in setup */
33+
reimbursementAccount: PropTypes.shape({
34+
/** Error set when handling the API response */
35+
error: PropTypes.string,
36+
}).isRequired,
2537
};
2638

2739
class BeneficialOwnersStep extends React.Component {
@@ -172,6 +184,7 @@ class BeneficialOwnersStep extends React.Component {
172184
dob: owner.dob || '',
173185
ssnLast4: owner.ssnLast4 || '',
174186
}}
187+
error={this.props.reimbursementAccount.error}
175188
/>
176189
{this.state.beneficialOwners.length > 1 && (
177190
<TextLink onPress={() => this.removeBeneficialOwner(owner)}>
@@ -230,5 +243,11 @@ class BeneficialOwnersStep extends React.Component {
230243
}
231244

232245
BeneficialOwnersStep.propTypes = propTypes;
233-
234-
export default withLocalize(BeneficialOwnersStep);
246+
export default compose(
247+
withLocalize,
248+
withOnyx({
249+
reimbursementAccount: {
250+
key: ONYXKEYS.REIMBURSEMENT_ACCOUNT,
251+
},
252+
}),
253+
)(BeneficialOwnersStep);

0 commit comments

Comments
 (0)