Skip to content

Commit

Permalink
Merge pull request #30073 from tienifr/fix/29712
Browse files Browse the repository at this point in the history
Fix: Missing translation for server errors
  • Loading branch information
marcaaron authored Feb 8, 2024
2 parents b7ba49b + 7f14df6 commit 067bfa8
Show file tree
Hide file tree
Showing 69 changed files with 188 additions and 123 deletions.
2 changes: 1 addition & 1 deletion src/components/AddressForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function AddressForm({city, country, formID, onAddressChanged, onSubmit, shouldS
const styles = useThemeStyles();
const {translate} = useLocalize();
const zipSampleFormat = lodashGet(CONST.COUNTRY_ZIP_REGEX_DATA, [country, 'samples'], '');
const zipFormat = translate('common.zipCodeExampleFormat', {zipSampleFormat});
const zipFormat = ['common.zipCodeExampleFormat', {zipSampleFormat}];
const isUSAForm = country === CONST.COUNTRY.US;

/**
Expand Down
3 changes: 2 additions & 1 deletion src/components/AddressSearch/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {RefObject} from 'react';
import type {NativeSyntheticEvent, StyleProp, TextInputFocusEventData, View, ViewStyle} from 'react-native';
import type {Place} from 'react-native-google-places-autocomplete';
import type {MaybePhraseKey} from '@libs/Localize';
import type Locale from '@src/types/onyx/Locale';

type CurrentLocationButtonProps = {
Expand Down Expand Up @@ -43,7 +44,7 @@ type AddressSearchProps = {
onBlur?: () => void;

/** Error text to display */
errorText?: string;
errorText?: MaybePhraseKey;

/** Hint text to display */
hint?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/components/AvatarWithImagePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ function AvatarWithImagePicker({
{errorData.validationError && (
<DotIndicatorMessage
style={[styles.mt6]}
messages={{0: translate(errorData.validationError, errorData.phraseParam)}}
messages={{0: [errorData.validationError, errorData.phraseParam]}}
type="error"
/>
)}
Expand Down
3 changes: 2 additions & 1 deletion src/components/CheckboxWithLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, {useState} from 'react';
import type {StyleProp, ViewStyle} from 'react-native';
import {View} from 'react-native';
import useThemeStyles from '@hooks/useThemeStyles';
import type {MaybePhraseKey} from '@libs/Localize';
import variables from '@styles/variables';
import Checkbox from './Checkbox';
import FormHelpMessage from './FormHelpMessage';
Expand Down Expand Up @@ -40,7 +41,7 @@ type CheckboxWithLabelProps = RequiredLabelProps & {
style?: StyleProp<ViewStyle>;

/** Error text to display */
errorText?: string;
errorText?: MaybePhraseKey;

/** Value for checkbox. This prop is intended to be set by FormProvider only */
value?: boolean;
Expand Down
3 changes: 2 additions & 1 deletion src/components/CountrySelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {ForwardedRef} from 'react';
import {View} from 'react-native';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import type {MaybePhraseKey} from '@libs/Localize';
import Navigation from '@libs/Navigation/Navigation';
import type {Country} from '@src/CONST';
import ROUTES from '@src/ROUTES';
Expand All @@ -11,7 +12,7 @@ import MenuItemWithTopDescription from './MenuItemWithTopDescription';

type CountrySelectorProps = {
/** Form error text. e.g when no country is selected */
errorText?: string;
errorText?: MaybePhraseKey;

/** Callback called when the country changes. */
onInputChange: (value?: string) => void;
Expand Down
2 changes: 1 addition & 1 deletion src/components/DistanceRequest/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ function DistanceRequest({transactionID, report, transaction, route, isEditingRe
}

if (_.size(validatedWaypoints) < 2) {
return {0: translate('iou.error.atLeastTwoDifferentWaypoints')};
return {0: 'iou.error.atLeastTwoDifferentWaypoints'};
}
};

Expand Down
6 changes: 3 additions & 3 deletions src/components/DotIndicatorMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ type DotIndicatorMessageProps = {
};

/** Check if the error includes a receipt. */
function isReceiptError(message: string | ReceiptError): message is ReceiptError {
if (typeof message === 'string') {
function isReceiptError(message: Localize.MaybePhraseKey | ReceiptError): message is ReceiptError {
if (typeof message === 'string' || Array.isArray(message)) {
return false;
}
return (message?.error ?? '') === CONST.IOU.RECEIPT_ERROR;
Expand All @@ -57,7 +57,7 @@ function DotIndicatorMessage({messages = {}, style, type, textStyles}: DotIndica
.map((key) => messages[key]);

// Removing duplicates using Set and transforming the result into an array
const uniqueMessages = [...new Set(sortedMessages)].map((message) => Localize.translateIfPhraseKey(message));
const uniqueMessages = [...new Set(sortedMessages)].map((message) => (isReceiptError(message) ? message : Localize.translateIfPhraseKey(message)));

const isErrorMessage = type === 'error';

Expand Down
3 changes: 2 additions & 1 deletion src/components/FormAlertWithSubmitButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import React from 'react';
import type {StyleProp, ViewStyle} from 'react-native';
import {View} from 'react-native';
import useThemeStyles from '@hooks/useThemeStyles';
import type {MaybePhraseKey} from '@libs/Localize';
import Button from './Button';
import FormAlertWrapper from './FormAlertWrapper';

type FormAlertWithSubmitButtonProps = {
/** Error message to display above button */
message?: string | null;
message?: MaybePhraseKey;

/** Whether the button is disabled */
isDisabled?: boolean;
Expand Down
5 changes: 3 additions & 2 deletions src/components/FormAlertWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {StyleProp, ViewStyle} from 'react-native';
import {View} from 'react-native';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import type {MaybePhraseKey} from '@libs/Localize';
import type Network from '@src/types/onyx/Network';
import FormHelpMessage from './FormHelpMessage';
import {withNetwork} from './OnyxProvider';
Expand All @@ -28,7 +29,7 @@ type FormAlertWrapperProps = {
isMessageHtml?: boolean;

/** Error message to display above button */
message?: string | null;
message?: MaybePhraseKey;

/** Props to detect online status */
network: Network;
Expand Down Expand Up @@ -68,7 +69,7 @@ function FormAlertWrapper({
{` ${translate('common.inTheFormBeforeContinuing')}.`}
</Text>
);
} else if (isMessageHtml) {
} else if (isMessageHtml && typeof message === 'string') {
content = <RenderHTML html={`<alert-text>${message}</alert-text>`} />;
}

Expand Down
3 changes: 2 additions & 1 deletion src/components/MagicCodeInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import useNetwork from '@hooks/useNetwork';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Browser from '@libs/Browser';
import type {MaybePhraseKey} from '@libs/Localize';
import * as ValidationUtils from '@libs/ValidationUtils';
import CONST from '@src/CONST';
import FormHelpMessage from './FormHelpMessage';
Expand All @@ -32,7 +33,7 @@ type MagicCodeInputProps = {
shouldDelayFocus?: boolean;

/** Error text to display */
errorText?: string;
errorText?: MaybePhraseKey;

/** Specifies autocomplete hints for the system, so it can provide autofill */
autoComplete: AutoCompleteVariant;
Expand Down
3 changes: 2 additions & 1 deletion src/components/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import ControlSelection from '@libs/ControlSelection';
import convertToLTR from '@libs/convertToLTR';
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
import getButtonState from '@libs/getButtonState';
import type {MaybePhraseKey} from '@libs/Localize';
import type {AvatarSource} from '@libs/UserUtils';
import variables from '@styles/variables';
import * as Session from '@userActions/Session';
Expand Down Expand Up @@ -136,7 +137,7 @@ type MenuItemProps = (IconProps | AvatarProps | NoIcon) & {
error?: string;

/** Error to display at the bottom of the component */
errorText?: string;
errorText?: MaybePhraseKey;

/** A boolean flag that gives the icon a green fill if true */
success?: boolean;
Expand Down
3 changes: 1 addition & 2 deletions src/components/MoneyRequestConfirmationList.js
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ function MoneyRequestConfirmationList(props) {
<FormHelpMessage
style={[styles.ph1, styles.mb2]}
isError
message={translate(formError)}
message={formError}
/>
)}
{button}
Expand All @@ -586,7 +586,6 @@ function MoneyRequestConfirmationList(props) {
formError,
styles.ph1,
styles.mb2,
translate,
]);

const {image: receiptImage, thumbnail: receiptThumbnail} =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,13 +616,13 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
<FormHelpMessage
style={[styles.ph1, styles.mb2]}
isError
message={translate(formError)}
message={formError}
/>
)}
{button}
</>
);
}, [isReadOnly, iouType, selectedParticipants.length, confirm, bankAccountRoute, iouCurrencyCode, policyID, splitOrRequestOptions, formError, styles.ph1, styles.mb2, translate]);
}, [isReadOnly, iouType, selectedParticipants.length, confirm, bankAccountRoute, iouCurrencyCode, policyID, splitOrRequestOptions, formError, styles.ph1, styles.mb2]);

const {image: receiptImage, thumbnail: receiptThumbnail} = receiptPath && receiptFilename ? ReceiptUtils.getThumbnailAndImageURIs(transaction, receiptPath, receiptFilename) : {};
return (
Expand Down
11 changes: 9 additions & 2 deletions src/components/OfflineWithFeedback.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import {mapValues} from 'lodash';
import React, {useCallback} from 'react';
import type {ImageStyle, StyleProp, TextStyle, ViewStyle} from 'react-native';
import {View} from 'react-native';
import useNetwork from '@hooks/useNetwork';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ErrorUtils from '@libs/ErrorUtils';
import type {MaybePhraseKey} from '@libs/Localize';
import mapChildrenFlat from '@libs/mapChildrenFlat';
import shouldRenderOffscreen from '@libs/shouldRenderOffscreen';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -59,6 +62,10 @@ type OfflineWithFeedbackProps = ChildrenProps & {

type StrikethroughProps = Partial<ChildrenProps> & {style: Array<ViewStyle | TextStyle | ImageStyle>};

function isMaybePhraseKeyType(message: unknown): message is MaybePhraseKey {
return typeof message === 'string' || Array.isArray(message);
}

function OfflineWithFeedback({
pendingAction,
canDismissError = true,
Expand All @@ -82,8 +89,8 @@ function OfflineWithFeedback({

// Some errors have a null message. This is used to apply opacity only and to avoid showing redundant messages.
const errorEntries = Object.entries(errors ?? {});
const filteredErrorEntries = errorEntries.filter((errorEntry): errorEntry is [string, string | ReceiptError] => errorEntry[1] !== null);
const errorMessages = Object.fromEntries(filteredErrorEntries);
const filteredErrorEntries = errorEntries.filter((errorEntry): errorEntry is [string, MaybePhraseKey | ReceiptError] => errorEntry[1] !== null);
const errorMessages = mapValues(Object.fromEntries(filteredErrorEntries), (error) => (isMaybePhraseKeyType(error) ? ErrorUtils.getErrorMessageWithTranslationData(error) : error));

const hasErrorMessages = !isEmptyObject(errorMessages);
const isOfflinePendingAction = !!isOffline && !!pendingAction;
Expand Down
2 changes: 1 addition & 1 deletion src/components/OptionsSelector/BaseOptionsSelector.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ class BaseOptionsSelector extends Component {
updateSearchValue(value) {
this.setState({
paginationPage: 1,
errorMessage: value.length > this.props.maxLength ? this.props.translate('common.error.characterLimitExceedCounter', {length: value.length, limit: this.props.maxLength}) : '',
errorMessage: value.length > this.props.maxLength ? ['common.error.characterLimitExceedCounter', {length: value.length, limit: this.props.maxLength}] : '',
value,
});

Expand Down
6 changes: 3 additions & 3 deletions src/components/PDFView/PDFPasswordForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ function PDFPasswordForm({isFocused, isPasswordInvalid, shouldShowLoadingIndicat

const errorText = useMemo(() => {
if (isPasswordInvalid) {
return translate('attachmentView.passwordIncorrect');
return 'attachmentView.passwordIncorrect';
}
if (!_.isEmpty(validationErrorText)) {
return translate(validationErrorText);
return validationErrorText;
}
return '';
}, [isPasswordInvalid, translate, validationErrorText]);
}, [isPasswordInvalid, validationErrorText]);

useEffect(() => {
if (!isFocused) {
Expand Down
3 changes: 2 additions & 1 deletion src/components/Picker/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {ChangeEvent, Component, ReactElement} from 'react';
import type {MeasureLayoutOnSuccessCallback, NativeMethods, StyleProp, ViewStyle} from 'react-native';
import type {MaybePhraseKey} from '@libs/Localize';

type MeasureLayoutOnFailCallback = () => void;

Expand Down Expand Up @@ -58,7 +59,7 @@ type BasePickerProps<TPickerValue> = {
placeholder?: PickerPlaceholder;

/** Error text to display */
errorText?: string;
errorText?: MaybePhraseKey;

/** Customize the BasePicker container */
containerStyles?: StyleProp<ViewStyle>;
Expand Down
3 changes: 2 additions & 1 deletion src/components/RadioButtonWithLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from 'react';
import type {StyleProp, ViewStyle} from 'react-native';
import {View} from 'react-native';
import useThemeStyles from '@hooks/useThemeStyles';
import type {MaybePhraseKey} from '@libs/Localize';
import FormHelpMessage from './FormHelpMessage';
import * as Pressables from './Pressable';
import RadioButton from './RadioButton';
Expand All @@ -28,7 +29,7 @@ type RadioButtonWithLabelProps = {
hasError?: boolean;

/** Error text to display */
errorText?: string;
errorText?: MaybePhraseKey;
};

const PressableWithFeedback = Pressables.PressableWithFeedback;
Expand Down
3 changes: 2 additions & 1 deletion src/components/RoomNameInput/roomNameInputPropTypes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import PropTypes from 'prop-types';
import refPropTypes from '@components/refPropTypes';
import {translatableTextPropTypes} from '@libs/Localize';

const propTypes = {
/** Callback to execute when the text input is modified correctly */
Expand All @@ -12,7 +13,7 @@ const propTypes = {
disabled: PropTypes.bool,

/** Error text to show */
errorText: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))]),
errorText: translatableTextPropTypes,

/** A ref forwarded to the TextInput */
forwardedRef: refPropTypes,
Expand Down
3 changes: 2 additions & 1 deletion src/components/StatePicker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import FormHelpMessage from '@components/FormHelpMessage';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import type {MaybePhraseKey} from '@libs/Localize';
import type {CountryData} from '@libs/searchCountryOptions';
import StateSelectorModal from './StateSelectorModal';
import type {State} from './StateSelectorModal';

type StatePickerProps = {
/** Error text to display */
errorText?: string;
errorText?: MaybePhraseKey;

/** State to display */
value?: State;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import PropTypes from 'prop-types';
import sourcePropTypes from '@components/Image/sourcePropTypes';
import {translatableTextPropTypes} from '@libs/Localize';

const propTypes = {
/** Input label */
Expand All @@ -18,7 +19,7 @@ const propTypes = {
placeholder: PropTypes.string,

/** Error text to display */
errorText: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))]),
errorText: translatableTextPropTypes,

/** Icon to display in right side of text input */
icon: sourcePropTypes,
Expand Down Expand Up @@ -68,7 +69,7 @@ const propTypes = {
maxLength: PropTypes.number,

/** Hint text to display below the TextInput */
hint: PropTypes.string,
hint: translatableTextPropTypes,

/** Prefix character */
prefixCharacter: PropTypes.string,
Expand Down
2 changes: 1 addition & 1 deletion src/components/TextInput/BaseTextInput/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ type CustomBaseTextInputProps = {
hideFocusedState?: boolean;

/** Hint text to display below the TextInput */
hint?: string;
hint?: MaybePhraseKey;

/** Prefix character */
prefixCharacter?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/components/TimePicker/TimePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ function TimePicker({forwardedRef, defaultValue, onSubmit, onInputChange}) {
{isError ? (
<FormHelpMessage
isError={isError}
message={translate('common.error.invalidTimeShouldBeFuture')}
message="common.error.invalidTimeShouldBeFuture"
style={styles.pl5}
/>
) : (
Expand Down
3 changes: 2 additions & 1 deletion src/components/ValuePicker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import refPropTypes from '@components/refPropTypes';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import {translatableTextPropTypes} from '@libs/Localize';
import variables from '@styles/variables';
import ValueSelectorModal from './ValueSelectorModal';

const propTypes = {
/** Form Error description */
errorText: PropTypes.string,
errorText: translatableTextPropTypes,

/** Item to display */
value: PropTypes.string,
Expand Down
Loading

0 comments on commit 067bfa8

Please sign in to comment.