diff --git a/contributingGuides/FORMS.md b/contributingGuides/FORMS.md index b8aac1e38baa..01f145dafbc6 100644 --- a/contributingGuides/FORMS.md +++ b/contributingGuides/FORMS.md @@ -114,10 +114,10 @@ Here's an example for a form that has two inputs, `routingNumber` and `accountNu function validate(values) { const errors = {}; if (!values.routingNumber) { - errors.routingNumber = props.translate(CONST.ERRORS.ROUTING_NUMBER); + errors.routingNumber = CONST.ERRORS.ROUTING_NUMBER; } if (!values.accountNumber) { - errors.accountNumber = props.translate(CONST.ERRORS.ACCOUNT_NUMBER); + errors.accountNumber = CONST.ERRORS.ACCOUNT_NUMBER; } return errors; } @@ -130,15 +130,15 @@ function validate(values) { let errors = {}; if (!ValidationUtils.isValidDisplayName(values.firstName)) { - errors = ErrorUtils.addErrorMessage(errors, 'firstName', props.translate('personalDetails.error.hasInvalidCharacter')); + errors = ErrorUtils.addErrorMessage(errors, 'firstName', 'personalDetails.error.hasInvalidCharacter'); } if (ValidationUtils.doesContainReservedWord(values.firstName, CONST.DISPLAY_NAME.RESERVED_FIRST_NAMES)) { - errors = ErrorUtils.addErrorMessage(errors, 'firstName', props.translate('personalDetails.error.containsReservedWord')); + errors = ErrorUtils.addErrorMessage(errors, 'firstName', 'personalDetails.error.containsReservedWord'); } if (!ValidationUtils.isValidDisplayName(values.lastName)) { - errors.lastName = props.translate('personalDetails.error.hasInvalidCharacter'); + errors.lastName = 'personalDetails.error.hasInvalidCharacter'; } return errors; diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index 197c111c0ee3..ac550f34de3f 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -17,7 +17,7 @@ const propTypes = { * timestamp: 'message', * } */ - messages: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.array, PropTypes.string])), + messages: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))])), // The type of message, 'error' shows a red dot, 'success' shows a green dot type: PropTypes.oneOf(['error', 'success']).isRequired, diff --git a/src/components/Form.js b/src/components/Form.js index afc50d24763c..9191979ac671 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -96,7 +96,7 @@ function Form(props) { const inputRefs = useRef({}); const touchedInputs = useRef({}); - const {validate, translate, onSubmit, children} = props; + const {validate, onSubmit, children} = props; /** * @param {Object} values - An object containing the value of each inputID, e.g. {inputID1: value1, inputID2: value2} @@ -127,7 +127,7 @@ function Form(props) { } // Add a validation error here because it is a string value that contains HTML characters - validationErrors[inputID] = translate('common.error.invalidCharacter'); + validationErrors[inputID] = 'common.error.invalidCharacter'; }); if (!_.isObject(validationErrors)) { @@ -142,7 +142,7 @@ function Form(props) { return touchedInputErrors; }, - [errors, touchedInputs, props.formID, validate, translate], + [errors, touchedInputs, props.formID, validate], ); useEffect(() => { diff --git a/src/components/FormHelpMessage.js b/src/components/FormHelpMessage.js index 24d78267766b..df8befe5af30 100644 --- a/src/components/FormHelpMessage.js +++ b/src/components/FormHelpMessage.js @@ -12,7 +12,7 @@ import * as Localize from '../libs/Localize'; const propTypes = { /** Error or hint text. Ignored when children is not empty */ - message: PropTypes.oneOfType([PropTypes.string, PropTypes.array]), + message: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))]), /** Children to render next to dot indicator */ children: PropTypes.node, diff --git a/src/components/RoomNameInput/roomNameInputPropTypes.js b/src/components/RoomNameInput/roomNameInputPropTypes.js index 2f4af1ae2e92..de233b8d96d6 100644 --- a/src/components/RoomNameInput/roomNameInputPropTypes.js +++ b/src/components/RoomNameInput/roomNameInputPropTypes.js @@ -12,7 +12,7 @@ const propTypes = { disabled: PropTypes.bool, /** Error text to show */ - errorText: PropTypes.string, + errorText: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))]), ...withLocalizePropTypes, diff --git a/src/components/TextInput/baseTextInputPropTypes.js b/src/components/TextInput/baseTextInputPropTypes.js index 45720ceb8c47..2e278bab5d69 100644 --- a/src/components/TextInput/baseTextInputPropTypes.js +++ b/src/components/TextInput/baseTextInputPropTypes.js @@ -17,7 +17,7 @@ const propTypes = { placeholder: PropTypes.string, /** Error text to display */ - errorText: PropTypes.string, + errorText: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))]), /** Icon to display in right side of text input */ icon: PropTypes.func, diff --git a/src/libs/ErrorUtils.js b/src/libs/ErrorUtils.js index 03a26d8fa14c..fdeae7809f58 100644 --- a/src/libs/ErrorUtils.js +++ b/src/libs/ErrorUtils.js @@ -2,6 +2,7 @@ import _ from 'underscore'; import lodashGet from 'lodash/get'; import CONST from '../CONST'; import DateUtils from './DateUtils'; +import * as Localize from './Localize'; /** * @param {Object} response @@ -91,18 +92,23 @@ function getLatestErrorField(onyxData, fieldName) { * Method used to generate error message for given inputID * @param {Object} errors - An object containing current errors in the form * @param {String} inputID - * @param {String} message - Message to assign to the inputID errors + * @param {String|Array} message - Message to assign to the inputID errors * */ function addErrorMessage(errors, inputID, message) { - const errorList = errors; if (!message || !inputID) { return; } + + const errorList = errors; + const translatedMessage = Localize.translateIfPhraseKey(message); + if (_.isEmpty(errorList[inputID])) { - errorList[inputID] = message; + errorList[inputID] = [translatedMessage, {isTranslated: true}]; + } else if (_.isString(errorList[inputID])) { + errorList[inputID] = [`${errorList[inputID]}\n${translatedMessage}`, {isTranslated: true}]; } else { - errorList[inputID] = `${errorList[inputID]}\n${message}`; + errorList[inputID][0] = `${errorList[inputID][0]}\n${translatedMessage}`; } } diff --git a/src/libs/Localize/index.js b/src/libs/Localize/index.js index acbedc4b586f..9878873377b8 100644 --- a/src/libs/Localize/index.js +++ b/src/libs/Localize/index.js @@ -98,9 +98,20 @@ function translateLocal(phrase, variables) { * @returns {String} */ function translateIfPhraseKey(message) { + if (_.isEmpty(message)) { + return ''; + } + try { // check if error message has a variable parameter const [phrase, variables] = _.isArray(message) ? message : [message]; + + // This condition checks if the error is already translated. For example, if there are multiple errors per input, we handle translation in ErrorUtils.addErrorMessage due to the inability to concatenate error keys. + + if (variables && variables.isTranslated) { + return phrase; + } + return translateLocal(phrase, variables); } catch (error) { return message; diff --git a/src/libs/ValidationUtils.js b/src/libs/ValidationUtils.js index 7cefd11ec799..4778669840a8 100644 --- a/src/libs/ValidationUtils.js +++ b/src/libs/ValidationUtils.js @@ -5,7 +5,6 @@ import {parsePhoneNumber} from 'awesome-phonenumber'; import CONST from '../CONST'; import * as CardUtils from './CardUtils'; import * as LoginUtils from './LoginUtils'; -import * as Localize from './Localize'; /** * Implements the Luhn Algorithm, a checksum formula used to validate credit card @@ -225,22 +224,22 @@ function meetsMaximumAgeRequirement(date) { * @param {String} date * @param {Number} minimumAge * @param {Number} maximumAge - * @returns {String} + * @returns {String|Array} */ function getAgeRequirementError(date, minimumAge, maximumAge) { const recentDate = moment().startOf('day').subtract(minimumAge, 'years'); const longAgoDate = moment().startOf('day').subtract(maximumAge, 'years'); const testDate = moment(date); if (!testDate.isValid()) { - return Localize.translateLocal('common.error.dateInvalid'); + return 'common.error.dateInvalid'; } if (testDate.isBetween(longAgoDate, recentDate, undefined, '[]')) { return ''; } if (testDate.isSameOrAfter(recentDate)) { - return Localize.translateLocal('privatePersonalDetails.error.dateShouldBeBefore', {dateString: recentDate.format(CONST.DATE.MOMENT_FORMAT_STRING)}); + return ['privatePersonalDetails.error.dateShouldBeBefore', {dateString: recentDate.format(CONST.DATE.MOMENT_FORMAT_STRING)}]; } - return Localize.translateLocal('privatePersonalDetails.error.dateShouldBeAfter', {dateString: longAgoDate.format(CONST.DATE.MOMENT_FORMAT_STRING)}); + return ['privatePersonalDetails.error.dateShouldBeAfter', {dateString: longAgoDate.format(CONST.DATE.MOMENT_FORMAT_STRING)}]; } /** diff --git a/src/pages/EnablePayments/AdditionalDetailsStep.js b/src/pages/EnablePayments/AdditionalDetailsStep.js index 22dd50e2ab4a..ac3d2ed43ea7 100644 --- a/src/pages/EnablePayments/AdditionalDetailsStep.js +++ b/src/pages/EnablePayments/AdditionalDetailsStep.js @@ -123,47 +123,47 @@ class AdditionalDetailsStep extends React.Component { const errors = {}; if (_.isEmpty(values[INPUT_IDS.LEGAL_FIRST_NAME])) { - errors[INPUT_IDS.LEGAL_FIRST_NAME] = this.props.translate(this.errorTranslationKeys.legalFirstName); + errors[INPUT_IDS.LEGAL_FIRST_NAME] = this.errorTranslationKeys.legalFirstName; } if (_.isEmpty(values[INPUT_IDS.LEGAL_LAST_NAME])) { - errors[INPUT_IDS.LEGAL_LAST_NAME] = this.props.translate(this.errorTranslationKeys.legalLastName); + errors[INPUT_IDS.LEGAL_LAST_NAME] = this.errorTranslationKeys.legalLastName; } if (!ValidationUtils.isValidPastDate(values[INPUT_IDS.DOB]) || !ValidationUtils.meetsMaximumAgeRequirement(values[INPUT_IDS.DOB])) { - ErrorUtils.addErrorMessage(errors, INPUT_IDS.DOB, this.props.translate(this.errorTranslationKeys.dob)); + ErrorUtils.addErrorMessage(errors, INPUT_IDS.DOB, this.errorTranslationKeys.dob); } else if (!ValidationUtils.meetsMinimumAgeRequirement(values[INPUT_IDS.DOB])) { - ErrorUtils.addErrorMessage(errors, INPUT_IDS.DOB, this.props.translate(this.errorTranslationKeys.age)); + ErrorUtils.addErrorMessage(errors, INPUT_IDS.DOB, this.errorTranslationKeys.age); } if (!ValidationUtils.isValidAddress(values[INPUT_IDS.ADDRESS.street]) || _.isEmpty(values[INPUT_IDS.ADDRESS.street])) { - errors[INPUT_IDS.ADDRESS.street] = this.props.translate('bankAccount.error.addressStreet'); + errors[INPUT_IDS.ADDRESS.street] = 'bankAccount.error.addressStreet'; } if (_.isEmpty(values[INPUT_IDS.ADDRESS.city])) { - errors[INPUT_IDS.ADDRESS.city] = this.props.translate('bankAccount.error.addressCity'); + errors[INPUT_IDS.ADDRESS.city] = 'bankAccount.error.addressCity'; } if (_.isEmpty(values[INPUT_IDS.ADDRESS.state])) { - errors[INPUT_IDS.ADDRESS.state] = this.props.translate('bankAccount.error.addressState'); + errors[INPUT_IDS.ADDRESS.state] = 'bankAccount.error.addressState'; } if (!ValidationUtils.isValidZipCode(values[INPUT_IDS.ADDRESS.zipCode])) { - errors[INPUT_IDS.ADDRESS.zipCode] = this.props.translate('bankAccount.error.zipCode'); + errors[INPUT_IDS.ADDRESS.zipCode] = 'bankAccount.error.zipCode'; } if (!ValidationUtils.isValidUSPhone(values[INPUT_IDS.PHONE_NUMBER], true)) { - errors[INPUT_IDS.PHONE_NUMBER] = this.props.translate(this.errorTranslationKeys.phoneNumber); + errors[INPUT_IDS.PHONE_NUMBER] = this.errorTranslationKeys.phoneNumber; } // this.props.walletAdditionalDetails stores errors returned by the server. If the server returns an SSN error // then the user needs to provide the full 9 digit SSN. if (this.props.walletAdditionalDetails.errorCode === CONST.WALLET.ERROR.SSN) { if (!ValidationUtils.isValidSSNFullNine(values[INPUT_IDS.SSN])) { - errors[INPUT_IDS.SSN] = this.props.translate(this.errorTranslationKeys.ssnFull9); + errors[INPUT_IDS.SSN] = this.errorTranslationKeys.ssnFull9; } } else if (!ValidationUtils.isValidSSNLastFour(values[INPUT_IDS.SSN])) { - errors[INPUT_IDS.SSN] = this.props.translate(this.errorTranslationKeys.ssn); + errors[INPUT_IDS.SSN] = this.errorTranslationKeys.ssn; } return errors; diff --git a/src/pages/ReimbursementAccount/ACHContractStep.js b/src/pages/ReimbursementAccount/ACHContractStep.js index c0d0f2c1af85..2e0979b00253 100644 --- a/src/pages/ReimbursementAccount/ACHContractStep.js +++ b/src/pages/ReimbursementAccount/ACHContractStep.js @@ -51,38 +51,38 @@ function ACHContractStep(props) { _.each(requiredFields, (inputKey) => { if (!ValidationUtils.isRequiredFulfilled(values[`beneficialOwner_${ownerKey}_${inputKey}`])) { const errorKey = errorKeys[inputKey] || inputKey; - errors[`beneficialOwner_${ownerKey}_${inputKey}`] = props.translate(`bankAccount.error.${errorKey}`); + errors[`beneficialOwner_${ownerKey}_${inputKey}`] = `bankAccount.error.${errorKey}`; } }); if (values[`beneficialOwner_${ownerKey}_dob`]) { if (!ValidationUtils.meetsMinimumAgeRequirement(values[`beneficialOwner_${ownerKey}_dob`])) { - errors[`beneficialOwner_${ownerKey}_dob`] = props.translate('bankAccount.error.age'); + errors[`beneficialOwner_${ownerKey}_dob`] = 'bankAccount.error.age'; } else if (!ValidationUtils.meetsMaximumAgeRequirement(values[`beneficialOwner_${ownerKey}_dob`])) { - errors[`beneficialOwner_${ownerKey}_dob`] = props.translate('bankAccount.error.dob'); + errors[`beneficialOwner_${ownerKey}_dob`] = 'bankAccount.error.dob'; } } if (values[`beneficialOwner_${ownerKey}_ssnLast4`] && !ValidationUtils.isValidSSNLastFour(values[`beneficialOwner_${ownerKey}_ssnLast4`])) { - errors[`beneficialOwner_${ownerKey}_ssnLast4`] = props.translate('bankAccount.error.ssnLast4'); + errors[`beneficialOwner_${ownerKey}_ssnLast4`] = 'bankAccount.error.ssnLast4'; } if (values[`beneficialOwner_${ownerKey}_street`] && !ValidationUtils.isValidAddress(values[`beneficialOwner_${ownerKey}_street`])) { - errors[`beneficialOwner_${ownerKey}_street`] = props.translate('bankAccount.error.addressStreet'); + errors[`beneficialOwner_${ownerKey}_street`] = 'bankAccount.error.addressStreet'; } if (values[`beneficialOwner_${ownerKey}_zipCode`] && !ValidationUtils.isValidZipCode(values[`beneficialOwner_${ownerKey}_zipCode`])) { - errors[`beneficialOwner_${ownerKey}_zipCode`] = props.translate('bankAccount.error.zipCode'); + errors[`beneficialOwner_${ownerKey}_zipCode`] = 'bankAccount.error.zipCode'; } }); } if (!ValidationUtils.isRequiredFulfilled(values.acceptTermsAndConditions)) { - errors.acceptTermsAndConditions = props.translate('common.error.acceptTerms'); + errors.acceptTermsAndConditions = 'common.error.acceptTerms'; } if (!ValidationUtils.isRequiredFulfilled(values.certifyTrueInformation)) { - errors.certifyTrueInformation = props.translate('beneficialOwnersStep.error.certify'); + errors.certifyTrueInformation = 'beneficialOwnersStep.error.certify'; } return errors; diff --git a/src/pages/ReimbursementAccount/BankAccountManualStep.js b/src/pages/ReimbursementAccount/BankAccountManualStep.js index f8eeb6628495..5e8f46be00e5 100644 --- a/src/pages/ReimbursementAccount/BankAccountManualStep.js +++ b/src/pages/ReimbursementAccount/BankAccountManualStep.js @@ -41,13 +41,13 @@ class BankAccountManualStep extends React.Component { !values.accountNumber || (!CONST.BANK_ACCOUNT.REGEX.US_ACCOUNT_NUMBER.test(values.accountNumber.trim()) && !CONST.BANK_ACCOUNT.REGEX.MASKED_US_ACCOUNT_NUMBER.test(values.accountNumber.trim())) ) { - errorFields.accountNumber = this.props.translate('bankAccount.error.accountNumber'); + errorFields.accountNumber = 'bankAccount.error.accountNumber'; } if (!routingNumber || !CONST.BANK_ACCOUNT.REGEX.SWIFT_BIC.test(routingNumber) || !ValidationUtils.isValidRoutingNumber(routingNumber)) { - errorFields.routingNumber = this.props.translate('bankAccount.error.routingNumber'); + errorFields.routingNumber = 'bankAccount.error.routingNumber'; } if (!values.acceptTerms) { - errorFields.acceptTerms = this.props.translate('common.error.acceptTerms'); + errorFields.acceptTerms = 'common.error.acceptTerms'; } return errorFields; diff --git a/src/pages/ReimbursementAccount/BankAccountPlaidStep.js b/src/pages/ReimbursementAccount/BankAccountPlaidStep.js index 3af673084976..707828436d91 100644 --- a/src/pages/ReimbursementAccount/BankAccountPlaidStep.js +++ b/src/pages/ReimbursementAccount/BankAccountPlaidStep.js @@ -49,7 +49,7 @@ class BankAccountPlaidStep extends React.Component { validate(values) { const errorFields = {}; if (!values.acceptTerms) { - errorFields.acceptTerms = this.props.translate('common.error.acceptTerms'); + errorFields.acceptTerms = 'common.error.acceptTerms'; } return errorFields; diff --git a/src/pages/ReimbursementAccount/CompanyStep.js b/src/pages/ReimbursementAccount/CompanyStep.js index 1265469abd26..e44d0562b58e 100644 --- a/src/pages/ReimbursementAccount/CompanyStep.js +++ b/src/pages/ReimbursementAccount/CompanyStep.js @@ -83,53 +83,53 @@ class CompanyStep extends React.Component { const errors = {}; if (!values.companyName) { - errors.companyName = this.props.translate('bankAccount.error.companyName'); + errors.companyName = 'bankAccount.error.companyName'; } if (!values.addressStreet || !ValidationUtils.isValidAddress(values.addressStreet)) { - errors.addressStreet = this.props.translate('bankAccount.error.addressStreet'); + errors.addressStreet = 'bankAccount.error.addressStreet'; } if (!values.addressZipCode || !ValidationUtils.isValidZipCode(values.addressZipCode)) { - errors.addressZipCode = this.props.translate('bankAccount.error.zipCode'); + errors.addressZipCode = 'bankAccount.error.zipCode'; } if (!values.addressCity) { - errors.addressCity = this.props.translate('bankAccount.error.addressCity'); + errors.addressCity = 'bankAccount.error.addressCity'; } if (!values.addressState) { - errors.addressState = this.props.translate('bankAccount.error.addressState'); + errors.addressState = 'bankAccount.error.addressState'; } if (!values.companyPhone || !ValidationUtils.isValidUSPhone(values.companyPhone, true)) { - errors.companyPhone = this.props.translate('bankAccount.error.phoneNumber'); + errors.companyPhone = 'bankAccount.error.phoneNumber'; } if (!values.website || !ValidationUtils.isValidWebsite(values.website)) { - errors.website = this.props.translate('bankAccount.error.website'); + errors.website = 'bankAccount.error.website'; } if (!values.companyTaxID || !ValidationUtils.isValidTaxID(values.companyTaxID)) { - errors.companyTaxID = this.props.translate('bankAccount.error.taxID'); + errors.companyTaxID = 'bankAccount.error.taxID'; } if (!values.incorporationType) { - errors.incorporationType = this.props.translate('bankAccount.error.companyType'); + errors.incorporationType = 'bankAccount.error.companyType'; } if (!values.incorporationDate || !ValidationUtils.isValidDate(values.incorporationDate)) { - errors.incorporationDate = this.props.translate('common.error.dateInvalid'); + errors.incorporationDate = 'common.error.dateInvalid'; } else if (!values.incorporationDate || !ValidationUtils.isValidPastDate(values.incorporationDate)) { - errors.incorporationDate = this.props.translate('bankAccount.error.incorporationDateFuture'); + errors.incorporationDate = 'bankAccount.error.incorporationDateFuture'; } if (!values.incorporationState) { - errors.incorporationState = this.props.translate('bankAccount.error.incorporationState'); + errors.incorporationState = 'bankAccount.error.incorporationState'; } if (!values.hasNoConnectionToCannabis) { - errors.hasNoConnectionToCannabis = this.props.translate('bankAccount.error.restrictedBusiness'); + errors.hasNoConnectionToCannabis = 'bankAccount.error.restrictedBusiness'; } return errors; diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index b69067550848..c6496db73adc 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -41,51 +41,51 @@ class RequestorStep extends React.Component { const errors = {}; if (!ValidationUtils.isRequiredFulfilled(values.firstName)) { - errors.firstName = this.props.translate('bankAccount.error.firstName'); + errors.firstName = 'bankAccount.error.firstName'; } if (!ValidationUtils.isRequiredFulfilled(values.lastName)) { - errors.lastName = this.props.translate('bankAccount.error.lastName'); + errors.lastName = 'bankAccount.error.lastName'; } if (!ValidationUtils.isRequiredFulfilled(values.dob)) { - errors.dob = this.props.translate('bankAccount.error.dob'); + errors.dob = 'bankAccount.error.dob'; } if (values.dob) { if (!ValidationUtils.meetsMinimumAgeRequirement(values.dob)) { - errors.dob = this.props.translate('bankAccount.error.age'); + errors.dob = 'bankAccount.error.age'; } else if (!ValidationUtils.meetsMaximumAgeRequirement(values.dob)) { - errors.dob = this.props.translate('bankAccount.error.dob'); + errors.dob = 'bankAccount.error.dob'; } } if (!ValidationUtils.isRequiredFulfilled(values.ssnLast4) || !ValidationUtils.isValidSSNLastFour(values.ssnLast4)) { - errors.ssnLast4 = this.props.translate('bankAccount.error.ssnLast4'); + errors.ssnLast4 = 'bankAccount.error.ssnLast4'; } if (!ValidationUtils.isRequiredFulfilled(values.requestorAddressStreet)) { - errors.requestorAddressStreet = this.props.translate('bankAccount.error.address'); + errors.requestorAddressStreet = 'bankAccount.error.address'; } if (values.requestorAddressStreet && !ValidationUtils.isValidAddress(values.requestorAddressStreet)) { - errors.requestorAddressStreet = this.props.translate('bankAccount.error.addressStreet'); + errors.requestorAddressStreet = 'bankAccount.error.addressStreet'; } if (!ValidationUtils.isRequiredFulfilled(values.requestorAddressCity)) { - errors.requestorAddressCity = this.props.translate('bankAccount.error.addressCity'); + errors.requestorAddressCity = 'bankAccount.error.addressCity'; } if (!ValidationUtils.isRequiredFulfilled(values.requestorAddressState)) { - errors.requestorAddressState = this.props.translate('bankAccount.error.addressState'); + errors.requestorAddressState = 'bankAccount.error.addressState'; } if (!ValidationUtils.isRequiredFulfilled(values.requestorAddressZipCode) || !ValidationUtils.isValidZipCode(values.requestorAddressZipCode)) { - errors.requestorAddressZipCode = this.props.translate('bankAccount.error.zipCode'); + errors.requestorAddressZipCode = 'bankAccount.error.zipCode'; } if (!ValidationUtils.isRequiredFulfilled(values.isControllingOfficer)) { - errors.isControllingOfficer = this.props.translate('requestorStep.isControllingOfficerError'); + errors.isControllingOfficer = 'requestorStep.isControllingOfficerError'; } return errors; diff --git a/src/pages/ReimbursementAccount/ValidationStep.js b/src/pages/ReimbursementAccount/ValidationStep.js index e8dfeae77be7..d07f23d50843 100644 --- a/src/pages/ReimbursementAccount/ValidationStep.js +++ b/src/pages/ReimbursementAccount/ValidationStep.js @@ -71,7 +71,7 @@ class ValidationStep extends React.Component { if (ValidationUtils.isRequiredFulfilled(filteredValue)) { return; } - errors[key] = this.props.translate('common.error.invalidAmount'); + errors[key] = 'common.error.invalidAmount'; }); return errors; diff --git a/src/pages/settings/PasswordPage.js b/src/pages/settings/PasswordPage.js index f987cabb3c65..ab352851c76b 100755 --- a/src/pages/settings/PasswordPage.js +++ b/src/pages/settings/PasswordPage.js @@ -78,10 +78,7 @@ class PasswordPage extends Component { * @returns {String} */ getErrorText(field) { - if (this.state.errors[field]) { - return this.props.translate(this.errorKeysMap[field]); - } - return ''; + return this.state.errors[field] ? this.errorKeysMap[field] : ''; } /** diff --git a/src/pages/settings/Payments/AddDebitCardPage.js b/src/pages/settings/Payments/AddDebitCardPage.js index 7c174c58dbc2..77b7089fd2ef 100644 --- a/src/pages/settings/Payments/AddDebitCardPage.js +++ b/src/pages/settings/Payments/AddDebitCardPage.js @@ -74,39 +74,39 @@ class DebitCardPage extends Component { const errors = {}; if (!values.nameOnCard || !ValidationUtils.isValidCardName(values.nameOnCard)) { - errors.nameOnCard = this.props.translate('addDebitCardPage.error.invalidName'); + errors.nameOnCard = 'addDebitCardPage.error.invalidName'; } if (!values.cardNumber || !ValidationUtils.isValidDebitCard(values.cardNumber.replace(/ /g, ''))) { - errors.cardNumber = this.props.translate('addDebitCardPage.error.debitCardNumber'); + errors.cardNumber = 'addDebitCardPage.error.debitCardNumber'; } if (!values.expirationDate || !ValidationUtils.isValidExpirationDate(values.expirationDate)) { - errors.expirationDate = this.props.translate('addDebitCardPage.error.expirationDate'); + errors.expirationDate = 'addDebitCardPage.error.expirationDate'; } if (!values.securityCode || !ValidationUtils.isValidSecurityCode(values.securityCode)) { - errors.securityCode = this.props.translate('addDebitCardPage.error.securityCode'); + errors.securityCode = 'addDebitCardPage.error.securityCode'; } if (!values.addressStreet || !ValidationUtils.isValidAddress(values.addressStreet)) { - errors.addressStreet = this.props.translate('addDebitCardPage.error.addressStreet'); + errors.addressStreet = 'addDebitCardPage.error.addressStreet'; } if (!values.addressZipCode || !ValidationUtils.isValidZipCode(values.addressZipCode)) { - errors.addressZipCode = this.props.translate('addDebitCardPage.error.addressZipCode'); + errors.addressZipCode = 'addDebitCardPage.error.addressZipCode'; } if (!values.addressState || !values.addressState) { - errors.addressState = this.props.translate('addDebitCardPage.error.addressState'); + errors.addressState = 'addDebitCardPage.error.addressState'; } if (!Permissions.canUsePasswordlessLogins(this.props.betas) && (!values.password || _.isEmpty(values.password.trim()))) { - errors.password = this.props.translate('addDebitCardPage.error.password'); + errors.password = 'addDebitCardPage.error.password'; } if (!values.acceptTerms) { - errors.acceptTerms = this.props.translate('common.error.acceptTerms'); + errors.acceptTerms = 'common.error.acceptTerms'; } return errors; diff --git a/src/pages/settings/Profile/Contacts/NewContactMethodPage.js b/src/pages/settings/Profile/Contacts/NewContactMethodPage.js index a0ffcb293b8b..af339132d192 100644 --- a/src/pages/settings/Profile/Contacts/NewContactMethodPage.js +++ b/src/pages/settings/Profile/Contacts/NewContactMethodPage.js @@ -82,19 +82,19 @@ function NewContactMethodPage(props) { const errors = {}; if (_.isEmpty(values.phoneOrEmail)) { - ErrorUtils.addErrorMessage(errors, 'phoneOrEmail', props.translate('contacts.genericFailureMessages.contactMethodRequired')); + ErrorUtils.addErrorMessage(errors, 'phoneOrEmail', 'contacts.genericFailureMessages.contactMethodRequired'); } if (!_.isEmpty(values.phoneOrEmail) && !(parsePhoneNumber(phoneLogin).possible || Str.isValidEmail(values.phoneOrEmail))) { - ErrorUtils.addErrorMessage(errors, 'phoneOrEmail', props.translate('contacts.genericFailureMessages.invalidContactMethod')); + ErrorUtils.addErrorMessage(errors, 'phoneOrEmail', 'contacts.genericFailureMessages.invalidContactMethod'); } if (!_.isEmpty(values.phoneOrEmail) && lodashGet(props.loginList, validateIfnumber || values.phoneOrEmail.toLowerCase())) { - ErrorUtils.addErrorMessage(errors, 'phoneOrEmail', props.translate('contacts.genericFailureMessages.enteredMethodIsAlreadySubmited')); + ErrorUtils.addErrorMessage(errors, 'phoneOrEmail', 'contacts.genericFailureMessages.enteredMethodIsAlreadySubmited'); } if (!Permissions.canUsePasswordlessLogins(props.betas) && _.isEmpty(values.password)) { - errors.password = props.translate('contacts.genericFailureMessages.passwordRequired'); + errors.password = 'contacts.genericFailureMessages.passwordRequired'; } return errors; diff --git a/src/pages/settings/Profile/DisplayNamePage.js b/src/pages/settings/Profile/DisplayNamePage.js index 5e676a570e33..b44910290c92 100644 --- a/src/pages/settings/Profile/DisplayNamePage.js +++ b/src/pages/settings/Profile/DisplayNamePage.js @@ -51,15 +51,15 @@ function DisplayNamePage(props) { // First we validate the first name field if (!ValidationUtils.isValidDisplayName(values.firstName)) { - ErrorUtils.addErrorMessage(errors, 'firstName', props.translate('personalDetails.error.hasInvalidCharacter')); + ErrorUtils.addErrorMessage(errors, 'firstName', 'personalDetails.error.hasInvalidCharacter'); } if (ValidationUtils.doesContainReservedWord(values.firstName, CONST.DISPLAY_NAME.RESERVED_FIRST_NAMES)) { - ErrorUtils.addErrorMessage(errors, 'firstName', props.translate('personalDetails.error.containsReservedWord')); + ErrorUtils.addErrorMessage(errors, 'firstName', 'personalDetails.error.containsReservedWord'); } // Then we validate the last name field if (!ValidationUtils.isValidDisplayName(values.lastName)) { - errors.lastName = props.translate('personalDetails.error.hasInvalidCharacter'); + errors.lastName = 'personalDetails.error.hasInvalidCharacter'; } return errors; diff --git a/src/pages/settings/Profile/PersonalDetails/AddressPage.js b/src/pages/settings/Profile/PersonalDetails/AddressPage.js index 60e873125728..17c91cf133a3 100644 --- a/src/pages/settings/Profile/PersonalDetails/AddressPage.js +++ b/src/pages/settings/Profile/PersonalDetails/AddressPage.js @@ -85,7 +85,7 @@ function AddressPage(props) { // Check "State" dropdown is a valid state if selected Country is USA. if (isUSAForm && !COMMON_CONST.STATES[values.state]) { - errors.state = translate('common.error.fieldRequired'); + errors.state = 'common.error.fieldRequired'; } // Add "Field required" errors if any required field is empty @@ -93,7 +93,7 @@ function AddressPage(props) { if (ValidationUtils.isRequiredFulfilled(values[fieldKey])) { return; } - errors[fieldKey] = translate('common.error.fieldRequired'); + errors[fieldKey] = 'common.error.fieldRequired'; }); // If no country is selected, default value is an empty string and there's no related regex data so we default to an empty object @@ -106,18 +106,18 @@ function AddressPage(props) { if (countrySpecificZipRegex) { if (!countrySpecificZipRegex.test(values.zipPostCode.trim())) { if (ValidationUtils.isRequiredFulfilled(values.zipPostCode.trim())) { - errors.zipPostCode = translate('privatePersonalDetails.error.incorrectZipFormat', {zipFormat: countryZipFormat}); + errors.zipPostCode = ['privatePersonalDetails.error.incorrectZipFormat', {zipFormat: countryZipFormat}]; } else { - errors.zipPostCode = translate('common.error.fieldRequired'); + errors.zipPostCode = 'common.error.fieldRequired'; } } } else if (!CONST.GENERIC_ZIP_CODE_REGEX.test(values.zipPostCode.trim())) { - errors.zipPostCode = translate('privatePersonalDetails.error.incorrectZipFormat'); + errors.zipPostCode = 'privatePersonalDetails.error.incorrectZipFormat'; } return errors; }, - [translate, isUSAForm], + [isUSAForm], ); return ( diff --git a/src/pages/settings/Profile/PersonalDetails/DateOfBirthPage.js b/src/pages/settings/Profile/PersonalDetails/DateOfBirthPage.js index 77413ae1e596..a0a6d2394314 100644 --- a/src/pages/settings/Profile/PersonalDetails/DateOfBirthPage.js +++ b/src/pages/settings/Profile/PersonalDetails/DateOfBirthPage.js @@ -49,24 +49,21 @@ function DateOfBirthPage({translate, route, privatePersonalDetails}) { * @param {String} values.dob - date of birth * @returns {Object} - An object containing the errors for each inputID */ - const validate = useCallback( - (values) => { - const errors = {}; - const minimumAge = CONST.DATE_BIRTH.MIN_AGE; - const maximumAge = CONST.DATE_BIRTH.MAX_AGE; + const validate = useCallback((values) => { + const errors = {}; + const minimumAge = CONST.DATE_BIRTH.MIN_AGE; + const maximumAge = CONST.DATE_BIRTH.MAX_AGE; - if (!values.dob || !ValidationUtils.isValidDate(values.dob)) { - errors.dob = translate('common.error.fieldRequired'); - } - const dateError = ValidationUtils.getAgeRequirementError(values.dob, minimumAge, maximumAge); - if (dateError) { - errors.dob = dateError; - } + if (!values.dob || !ValidationUtils.isValidDate(values.dob)) { + errors.dob = 'common.error.fieldRequired'; + } + const dateError = ValidationUtils.getAgeRequirementError(values.dob, minimumAge, maximumAge); + if (dateError) { + errors.dob = dateError; + } - return errors; - }, - [translate], - ); + return errors; + }, []); return ( diff --git a/src/pages/settings/Profile/PersonalDetails/LegalNamePage.js b/src/pages/settings/Profile/PersonalDetails/LegalNamePage.js index 41139e74bcb7..d743aa0cd983 100644 --- a/src/pages/settings/Profile/PersonalDetails/LegalNamePage.js +++ b/src/pages/settings/Profile/PersonalDetails/LegalNamePage.js @@ -44,28 +44,24 @@ const updateLegalName = (values) => { function LegalNamePage(props) { const legalFirstName = lodashGet(props.privatePersonalDetails, 'legalFirstName', ''); const legalLastName = lodashGet(props.privatePersonalDetails, 'legalLastName', ''); - const translate = props.translate; - const validate = useCallback( - (values) => { - const errors = {}; + const validate = useCallback((values) => { + const errors = {}; - if (!ValidationUtils.isValidLegalName(values.legalFirstName)) { - errors.legalFirstName = translate('privatePersonalDetails.error.hasInvalidCharacter'); - } else if (_.isEmpty(values.legalFirstName)) { - errors.legalFirstName = translate('common.error.fieldRequired'); - } + if (!ValidationUtils.isValidLegalName(values.legalFirstName)) { + errors.legalFirstName = 'privatePersonalDetails.error.hasInvalidCharacter'; + } else if (_.isEmpty(values.legalFirstName)) { + errors.legalFirstName = 'common.error.fieldRequired'; + } - if (!ValidationUtils.isValidLegalName(values.legalLastName)) { - errors.legalLastName = translate('privatePersonalDetails.error.hasInvalidCharacter'); - } else if (_.isEmpty(values.legalLastName)) { - errors.legalLastName = translate('common.error.fieldRequired'); - } + if (!ValidationUtils.isValidLegalName(values.legalLastName)) { + errors.legalLastName = 'privatePersonalDetails.error.hasInvalidCharacter'; + } else if (_.isEmpty(values.legalLastName)) { + errors.legalLastName = 'common.error.fieldRequired'; + } - return errors; - }, - [translate], - ); + return errors; + }, []); return ( diff --git a/src/pages/settings/Report/RoomNamePage.js b/src/pages/settings/Report/RoomNamePage.js index b4bf1d0c5566..011a65d4cb76 100644 --- a/src/pages/settings/Report/RoomNamePage.js +++ b/src/pages/settings/Report/RoomNamePage.js @@ -48,21 +48,21 @@ function RoomNamePage(props) { if (!values.roomName || values.roomName === CONST.POLICY.ROOM_PREFIX) { // We error if the user doesn't enter a room name or left blank - ErrorUtils.addErrorMessage(errors, 'roomName', translate('newRoomPage.pleaseEnterRoomName')); + ErrorUtils.addErrorMessage(errors, 'roomName', 'newRoomPage.pleaseEnterRoomName'); } else if (!ValidationUtils.isValidRoomName(values.roomName)) { // We error if the room name has invalid characters - ErrorUtils.addErrorMessage(errors, 'roomName', translate('newRoomPage.roomNameInvalidError')); + ErrorUtils.addErrorMessage(errors, 'roomName', 'newRoomPage.roomNameInvalidError'); } else if (ValidationUtils.isReservedRoomName(values.roomName)) { // Certain names are reserved for default rooms and should not be used for policy rooms. - ErrorUtils.addErrorMessage(errors, 'roomName', translate('newRoomPage.roomNameReservedError', {reservedName: values.roomName})); + ErrorUtils.addErrorMessage(errors, 'roomName', ['newRoomPage.roomNameReservedError', {reservedName: values.roomName}]); } else if (ValidationUtils.isExistingRoomName(values.roomName, reports, report.policyID)) { // The room name can't be set to one that already exists on the policy - ErrorUtils.addErrorMessage(errors, 'roomName', translate('newRoomPage.roomAlreadyExistsError')); + ErrorUtils.addErrorMessage(errors, 'roomName', 'newRoomPage.roomAlreadyExistsError'); } return errors; }, - [report, reports, translate], + [report, reports], ); return ( diff --git a/src/pages/settings/Security/CloseAccountPage.js b/src/pages/settings/Security/CloseAccountPage.js index c5189727a3b7..3789804acc73 100644 --- a/src/pages/settings/Security/CloseAccountPage.js +++ b/src/pages/settings/Security/CloseAccountPage.js @@ -78,7 +78,7 @@ class CloseAccountPage extends Component { const errors = {}; if (_.isEmpty(values.phoneOrEmail) || userEmailOrPhone.toLowerCase() !== values.phoneOrEmail.toLowerCase()) { - errors.phoneOrEmail = this.props.translate('closeAccountPage.enterYourDefaultContactMethod'); + errors.phoneOrEmail = 'closeAccountPage.enterYourDefaultContactMethod'; } return errors; } diff --git a/src/pages/tasks/NewTaskDetailsPage.js b/src/pages/tasks/NewTaskDetailsPage.js index eaad83fd4a84..5b9773270048 100644 --- a/src/pages/tasks/NewTaskDetailsPage.js +++ b/src/pages/tasks/NewTaskDetailsPage.js @@ -53,7 +53,7 @@ function NewTaskPage(props) { if (!values.taskTitle) { // We error if the user doesn't enter a task name - ErrorUtils.addErrorMessage(errors, 'taskTitle', props.translate('newTaskPage.pleaseEnterTaskName')); + ErrorUtils.addErrorMessage(errors, 'taskTitle', 'newTaskPage.pleaseEnterTaskName'); } return errors; diff --git a/src/pages/tasks/NewTaskTitlePage.js b/src/pages/tasks/NewTaskTitlePage.js index 1e232b637de3..b1e7b689f85d 100644 --- a/src/pages/tasks/NewTaskTitlePage.js +++ b/src/pages/tasks/NewTaskTitlePage.js @@ -48,7 +48,7 @@ function NewTaskTitlePage(props) { if (!values.taskTitle) { // We error if the user doesn't enter a task name - ErrorUtils.addErrorMessage(errors, 'taskTitle', props.translate('newTaskPage.pleaseEnterTaskName')); + ErrorUtils.addErrorMessage(errors, 'taskTitle', 'newTaskPage.pleaseEnterTaskName'); } return errors; diff --git a/src/pages/tasks/TaskTitlePage.js b/src/pages/tasks/TaskTitlePage.js index 046294ec95fb..c8ac41c87c88 100644 --- a/src/pages/tasks/TaskTitlePage.js +++ b/src/pages/tasks/TaskTitlePage.js @@ -41,18 +41,15 @@ function TaskTitlePage(props) { * @param {String} values.title * @returns {Object} - An object containing the errors for each inputID */ - const validate = useCallback( - (values) => { - const errors = {}; + const validate = useCallback((values) => { + const errors = {}; - if (_.isEmpty(values.title)) { - errors.title = props.translate('newTaskPage.pleaseEnterTaskName'); - } + if (_.isEmpty(values.title)) { + errors.title = 'newTaskPage.pleaseEnterTaskName'; + } - return errors; - }, - [props], - ); + return errors; + }, []); const submit = useCallback( (values) => { diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.js b/src/pages/workspace/WorkspaceInviteMessagePage.js index bfabfc274a99..4debb088a43a 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.js +++ b/src/pages/workspace/WorkspaceInviteMessagePage.js @@ -142,7 +142,7 @@ class WorkspaceInviteMessagePage extends React.Component { validate() { const errorFields = {}; if (_.isEmpty(this.props.invitedMembersDraft)) { - errorFields.welcomeMessage = this.props.translate('workspace.inviteMessage.inviteNoMembersError'); + errorFields.welcomeMessage = 'workspace.inviteMessage.inviteNoMembersError'; } return errorFields; } diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index dc67745b3427..0c1116db2ee4 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -291,7 +291,7 @@ class WorkspaceMembersPage extends React.Component { return; } - errors[member] = this.props.translate('workspace.people.error.cannotRemove'); + errors[member] = 'workspace.people.error.cannotRemove'; }); this.setState({errors}); diff --git a/src/pages/workspace/WorkspaceNewRoomPage.js b/src/pages/workspace/WorkspaceNewRoomPage.js index 60583cbc95e8..fd91d1b43214 100644 --- a/src/pages/workspace/WorkspaceNewRoomPage.js +++ b/src/pages/workspace/WorkspaceNewRoomPage.js @@ -101,20 +101,20 @@ class WorkspaceNewRoomPage extends React.Component { if (!values.roomName || values.roomName === CONST.POLICY.ROOM_PREFIX) { // We error if the user doesn't enter a room name or left blank - ErrorUtils.addErrorMessage(errors, 'roomName', this.props.translate('newRoomPage.pleaseEnterRoomName')); + ErrorUtils.addErrorMessage(errors, 'roomName', 'newRoomPage.pleaseEnterRoomName'); } else if (values.roomName !== CONST.POLICY.ROOM_PREFIX && !ValidationUtils.isValidRoomName(values.roomName)) { // We error if the room name has invalid characters - ErrorUtils.addErrorMessage(errors, 'roomName', this.props.translate('newRoomPage.roomNameInvalidError')); + ErrorUtils.addErrorMessage(errors, 'roomName', 'newRoomPage.roomNameInvalidError'); } else if (ValidationUtils.isReservedRoomName(values.roomName)) { // Certain names are reserved for default rooms and should not be used for policy rooms. - ErrorUtils.addErrorMessage(errors, 'roomName', this.props.translate('newRoomPage.roomNameReservedError', {reservedName: values.roomName})); + ErrorUtils.addErrorMessage(errors, 'roomName', ['newRoomPage.roomNameReservedError', {reservedName: values.roomName}]); } else if (ValidationUtils.isExistingRoomName(values.roomName, this.props.reports, values.policyID)) { // Certain names are reserved for default rooms and should not be used for policy rooms. - ErrorUtils.addErrorMessage(errors, 'roomName', this.props.translate('newRoomPage.roomAlreadyExistsError')); + ErrorUtils.addErrorMessage(errors, 'roomName', 'newRoomPage.roomAlreadyExistsError'); } if (!values.policyID) { - errors.policyID = this.props.translate('newRoomPage.pleaseSelectWorkspace'); + errors.policyID = 'newRoomPage.pleaseSelectWorkspace'; } return errors; diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index 333e7fb87076..6abde456f40b 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -44,9 +44,6 @@ const defaultProps = { }; function WorkspaceSettingsPage(props) { - const nameIsRequiredError = props.translate('workspace.editor.nameIsRequiredError'); - const nameIsTooLongError = props.translate('workspace.editor.nameIsTooLongError'); - const currencyItems = useMemo(() => { const currencyListKeys = _.keys(props.currencyList); return _.map(currencyListKeys, (currencyCode) => ({ @@ -68,23 +65,20 @@ function WorkspaceSettingsPage(props) { [props.policy.id, props.policy.isPolicyUpdating], ); - const validate = useCallback( - (values) => { - const errors = {}; - const name = values.name.trim(); + const validate = useCallback((values) => { + const errors = {}; + const name = values.name.trim(); - if (!name || !name.length) { - errors.name = nameIsRequiredError; - } else if ([...name].length > CONST.WORKSPACE_NAME_CHARACTER_LIMIT) { - // Uses the spread syntax to count the number of Unicode code points instead of the number of UTF-16 - // code units. - errors.name = nameIsTooLongError; - } + if (!name || !name.length) { + errors.name = 'workspace.editor.nameIsRequiredError'; + } else if ([...name].length > CONST.WORKSPACE_NAME_CHARACTER_LIMIT) { + // Uses the spread syntax to count the number of Unicode code points instead of the number of UTF-16 + // code units. + errors.name = 'workspace.editor.nameIsTooLongError'; + } - return errors; - }, - [nameIsRequiredError, nameIsTooLongError], - ); + return errors; + }, []); const policyName = lodashGet(props.policy, 'name', ''); diff --git a/src/pages/workspace/reimburse/WorkspaceRateAndUnitPage.js b/src/pages/workspace/reimburse/WorkspaceRateAndUnitPage.js index a13385665196..2150beca2441 100644 --- a/src/pages/workspace/reimburse/WorkspaceRateAndUnitPage.js +++ b/src/pages/workspace/reimburse/WorkspaceRateAndUnitPage.js @@ -95,7 +95,7 @@ class WorkspaceRateAndUnitPage extends React.Component { const decimalSeparator = this.props.toLocaleDigit('.'); const rateValueRegex = RegExp(String.raw`^\d{1,8}([${getPermittedDecimalSeparator(decimalSeparator)}]\d{1,3})?$`, 'i'); if (!rateValueRegex.test(values.rate)) { - errors.rate = this.props.translate('workspace.reimburse.invalidRateError'); + errors.rate = 'workspace.reimburse.invalidRateError'; } return errors; } diff --git a/tests/unit/ErrorUtilsTest.js b/tests/unit/ErrorUtilsTest.js index b1bc3e6cdf25..7a46c71a1aa1 100644 --- a/tests/unit/ErrorUtilsTest.js +++ b/tests/unit/ErrorUtilsTest.js @@ -5,21 +5,21 @@ describe('ErrorUtils', () => { const errors = {}; ErrorUtils.addErrorMessage(errors, 'username', 'Username cannot be empty'); - expect(errors).toEqual({username: 'Username cannot be empty'}); + expect(errors).toEqual({username: ['Username cannot be empty', {isTranslated: true}]}); }); test('should append an error message to an existing error message for a given inputID', () => { const errors = {username: 'Username cannot be empty'}; ErrorUtils.addErrorMessage(errors, 'username', 'Username must be at least 6 characters long'); - expect(errors).toEqual({username: 'Username cannot be empty\nUsername must be at least 6 characters long'}); + expect(errors).toEqual({username: ['Username cannot be empty\nUsername must be at least 6 characters long', {isTranslated: true}]}); }); test('should add an error to input which does not contain any errors yet', () => { const errors = {username: 'Username cannot be empty'}; ErrorUtils.addErrorMessage(errors, 'password', 'Password cannot be empty'); - expect(errors).toEqual({username: 'Username cannot be empty', password: 'Password cannot be empty'}); + expect(errors).toEqual({username: 'Username cannot be empty', password: ['Password cannot be empty', {isTranslated: true}]}); }); test('should not mutate the errors object when message is empty', () => { @@ -49,7 +49,7 @@ describe('ErrorUtils', () => { ErrorUtils.addErrorMessage(errors, 'username', 'Username must be at least 6 characters long'); ErrorUtils.addErrorMessage(errors, 'username', 'Username must contain at least one letter'); - expect(errors).toEqual({username: 'Username cannot be empty\nUsername must be at least 6 characters long\nUsername must contain at least one letter'}); + expect(errors).toEqual({username: ['Username cannot be empty\nUsername must be at least 6 characters long\nUsername must contain at least one letter', {isTranslated: true}]}); }); test('should append multiple error messages to an existing error message for the same inputID', () => { @@ -58,7 +58,10 @@ describe('ErrorUtils', () => { ErrorUtils.addErrorMessage(errors, 'username', 'Username must not contain special characters'); expect(errors).toEqual({ - username: 'Username cannot be empty\nUsername must be at least 6 characters long\nUsername must contain at least one letter\nUsername must not contain special characters', + username: [ + 'Username cannot be empty\nUsername must be at least 6 characters long\nUsername must contain at least one letter\nUsername must not contain special characters', + {isTranslated: true}, + ], }); }); });