Skip to content

Commit

Permalink
fix: fall back to overall language [DHIS2-17696]
Browse files Browse the repository at this point in the history
  • Loading branch information
tomzemp committed Jul 4, 2024
1 parent 64c29a1 commit 56f49d8
Show file tree
Hide file tree
Showing 18 changed files with 187 additions and 135 deletions.
6 changes: 4 additions & 2 deletions src/components/__tests__/customizable-elements.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,16 @@ describe('ApplicationRightFooter', () => {
describe('PoweredByDHIS2', () => {
it('displays in translation', () => {
useLoginConfig.mockReturnValue({
uiLocale: 'id',
lngs: ['id', 'en'],
})
const i18Spy = jest
.spyOn(i18n, 't')
.mockReturnValue('Dipersembahkan oleh DHIS2')
render(<PoweredByDHIS2 />)
expect(i18Spy).toHaveBeenCalled()
expect(i18Spy).toHaveBeenCalledWith('Powered by DHIS2', { lng: 'id' })
expect(i18Spy).toHaveBeenCalledWith('Powered by DHIS2', {
lngs: ['id', 'en'],
})
expect(
screen.getByText('Dipersembahkan oleh DHIS2')
).toBeInTheDocument()
Expand Down
58 changes: 26 additions & 32 deletions src/components/account-creation-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,43 +46,41 @@ AccountFormSection.propTypes = {
title: PropTypes.string,
}

const RecaptchaWarning = ({ uiLocale }) => (
const RecaptchaWarning = ({ lngs }) => (
<div className={styles.recaptchaWarning}>
<IconErrorFilled24 color={colors.red500} />
<div className={styles.recaptchaWarningText}>
{i18n.t(
'Please confirm that you are not a robot by checking the checkbox.',
{ lng: uiLocale }
{ lngs }
)}
</div>
</div>
)

RecaptchaWarning.propTypes = {
uiLocale: PropTypes.string,
lngs: PropTypes.arrayOf(PropTypes.string),
}

const InnerCreateAccountForm = ({
handleSubmit,
uiLocale,
loading,
lngs,
prepopulatedFields,
emailConfigured,
recaptchaSite,
recaptchaRef,
recaptchaError,
selfRegistrationNoRecaptcha,
}) => {
const isRequired = getIsRequired(uiLocale)
const isRequired = getIsRequired(lngs?.[0])
return (
<form onSubmit={handleSubmit}>
<div>
<AccountFormSection
title={i18n.t('Log in details', { lng: uiLocale })}
>
<AccountFormSection title={i18n.t('Log in details', { lngs })}>
<ReactFinalForm.Field
name="username"
label={i18n.t('Username', { lng: uiLocale })}
label={i18n.t('Username', { lngs })}
component={InputFieldFF}
className={styles.inputField}
validate={composeValidators(isRequired, dhis2Username)}
Expand All @@ -93,7 +91,7 @@ const InnerCreateAccountForm = ({
/>
<ReactFinalForm.Field
name="password"
label={i18n.t('Password', { lng: uiLocale })}
label={i18n.t('Password', { lngs })}
component={InputFieldFF}
className={styles.inputField}
validate={composeValidators(isRequired, dhis2Password)}
Expand All @@ -105,11 +103,11 @@ const InnerCreateAccountForm = ({
/>
</AccountFormSection>
<AccountFormSection
title={i18n.t('Personal details', { lng: uiLocale })}
title={i18n.t('Personal details', { lngs })}
>
<ReactFinalForm.Field
name="firstName"
label={i18n.t('First name', { lng: uiLocale })}
label={i18n.t('First name', { lngs })}
component={InputFieldFF}
className={styles.inputField}
validate={composeValidators(
Expand All @@ -120,7 +118,7 @@ const InnerCreateAccountForm = ({
/>
<ReactFinalForm.Field
name="surname"
label={i18n.t('Last name', { lng: uiLocale })}
label={i18n.t('Last name', { lngs })}
component={InputFieldFF}
className={styles.inputField}
validate={composeValidators(
Expand All @@ -131,7 +129,7 @@ const InnerCreateAccountForm = ({
/>
<ReactFinalForm.Field
name="email"
label={i18n.t('Email', { lng: uiLocale })}
label={i18n.t('Email', { lngs })}
component={InputFieldFF}
className={styles.inputField}
validate={composeValidators(isRequired, email)}
Expand All @@ -142,7 +140,7 @@ const InnerCreateAccountForm = ({
{!emailConfigured && (
<ReactFinalForm.Field
name="phoneNumber"
label={i18n.t('Phone number', { lng: uiLocale })}
label={i18n.t('Phone number', { lngs })}
component={InputFieldFF}
className={styles.inputField}
validate={composeValidators(
Expand All @@ -158,7 +156,7 @@ const InnerCreateAccountForm = ({
<ReCAPTCHA
ref={recaptchaRef}
sitekey={recaptchaSite}
hl={uiLocale}
hl={lngs?.[0] ?? 'en'}
/>
{recaptchaError && <RecaptchaWarning />}
</AccountFormSection>
Expand All @@ -167,12 +165,10 @@ const InnerCreateAccountForm = ({
<ButtonStrip>
<Button primary type="submit" disabled={loading}>
{loading
? i18n.t('Creating...', { lng: uiLocale })
: i18n.t('Create account', { lng: uiLocale })}
? i18n.t('Creating...', { lngs })
: i18n.t('Create account', { lngs })}
</Button>
<BackToLoginButton
buttonText={i18n.t('Cancel', { lng: uiLocale })}
/>
<BackToLoginButton buttonText={i18n.t('Cancel', { lngs })} />
</ButtonStrip>
</form>
)
Expand All @@ -181,13 +177,13 @@ const InnerCreateAccountForm = ({
InnerCreateAccountForm.propTypes = {
emailConfigured: PropTypes.bool,
handleSubmit: PropTypes.func,
lngs: PropTypes.arrayOf(PropTypes.string),
loading: PropTypes.bool,
prepopulatedFields: PropTypes.object,
recaptchaError: PropTypes.bool,
recaptchaRef: PropTypes.node,
recaptchaSite: PropTypes.string,
selfRegistrationNoRecaptcha: PropTypes.bool,
uiLocale: PropTypes.string,
}

export const CreateAccountForm = ({
Expand All @@ -203,7 +199,7 @@ export const CreateAccountForm = ({
// depends on https://dhis2.atlassian.net/browse/DHIS2-14615
const {
applicationTitle,
uiLocale,
lngs,
emailConfigured,
recaptchaSite,
selfRegistrationNoRecaptcha,
Expand All @@ -225,7 +221,7 @@ export const CreateAccountForm = ({
{i18n.t(
'Enter your details below to create a {{- applicationName}} account.',
{
lng: uiLocale,
lngs,
applicationName:
removeHTMLTags(applicationTitle),
}
Expand All @@ -234,11 +230,9 @@ export const CreateAccountForm = ({
{createType === CREATE_FORM_TYPES.create && (
<p>
{i18n.t('Already have an account?', {
lng: uiLocale,
lngs,
})}{' '}
<Link to="/">
{i18n.t('Log in.', { lng: uiLocale })}
</Link>
<Link to="/">{i18n.t('Log in.', { lngs })}</Link>
</p>
)}
</FormSubtitle>
Expand All @@ -249,7 +243,7 @@ export const CreateAccountForm = ({
<FormNotice
title={i18n.t(
'Something went wrong, and we could not register your account',
{ lng: uiLocale }
{ lngs }
)}
error={true}
>
Expand All @@ -260,14 +254,14 @@ export const CreateAccountForm = ({
<>
<FormNotice
title={i18n.t('Account created successfully', {
lng: uiLocale,
lngs,
})}
valid
>
<span>
{i18n.t(
'You can use your username and password to log in.',
{ lng: uiLocale }
{ lngs }
)}
</span>
</FormNotice>
Expand All @@ -279,7 +273,7 @@ export const CreateAccountForm = ({
{({ handleSubmit }) => (
<InnerCreateAccountForm
handleSubmit={handleSubmit}
uiLocale={uiLocale}
lngs={lngs}
loading={loading}
prepopulatedFields={prepopulatedFields}
emailConfigured={emailConfigured}
Expand Down
4 changes: 2 additions & 2 deletions src/components/customizable-elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const ApplicationRightFooter = () => {
}

export const PoweredByDHIS2 = () => {
const { uiLocale } = useLoginConfig()
const { lngs } = useLoginConfig()
return (
<span>
<bdi>
Expand All @@ -69,7 +69,7 @@ export const PoweredByDHIS2 = () => {
rel="noopener noreferrer"
target="_blank"
>
{i18n.t('Powered by DHIS2', { lng: uiLocale })}
{i18n.t('Powered by DHIS2', { lngs })}
</a>
</bdi>
</span>
Expand Down
8 changes: 4 additions & 4 deletions src/components/login-links.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const LoginLinks = ({ formUserName }) => {
allowAccountRecovery,
emailConfigured,
selfRegistrationEnabled,
uiLocale,
lngs,
} = useLoginConfig()

return (
Expand All @@ -25,15 +25,15 @@ export const LoginLinks = ({ formUserName }) => {
: `/reset-password`
}
>
{i18n.t('Forgot password?', { lng: uiLocale })}
{i18n.t('Forgot password?', { lngs })}
</Link>
</span>
)}
{selfRegistrationEnabled && (
<span>
{i18n.t("Don't have an account?", { lng: uiLocale })}{' '}
{i18n.t("Don't have an account?", { lngs })}{' '}
<Link to="/create-account">
{i18n.t('Create an account', { lng: uiLocale })}
{i18n.t('Create an account', { lngs })}
</Link>
</span>
)}
Expand Down
14 changes: 7 additions & 7 deletions src/components/not-allowed-notice.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import { BackToLoginButton } from './back-to-login-button.js'
import { FormContainer } from './form-container.js'
import { FormNotice } from './form-notice.js'

export const NotAllowedNotice = ({ uiLocale }) => (
export const NotAllowedNotice = ({ lngs }) => (
<FormContainer>
<FormNotice error>
<span>
{i18n.t(
'The requested page is not configured for your system',
{ lng: uiLocale }
{ lngs }
)}
</span>
</FormNotice>
Expand All @@ -20,19 +20,19 @@ export const NotAllowedNotice = ({ uiLocale }) => (
)

NotAllowedNotice.propTypes = {
uiLocale: PropTypes.string,
lngs: PropTypes.arrayOf(PropTypes.string),
}

export const NotAllowedNoticeCreateAccount = ({ uiLocale }) => (
export const NotAllowedNoticeCreateAccount = ({ lngs }) => (
<FormContainer>
<FormNotice
error
title={i18n.t('Creating account not available', { lng: uiLocale })}
title={i18n.t('Creating account not available', { lngs })}
>
<span>
{i18n.t(
'Contact a system administrator to create an account.',
{ lng: uiLocale }
{ lngs }
)}
</span>
</FormNotice>
Expand All @@ -41,5 +41,5 @@ export const NotAllowedNoticeCreateAccount = ({ uiLocale }) => (
)

NotAllowedNoticeCreateAccount.propTypes = {
uiLocale: PropTypes.string,
lngs: PropTypes.arrayOf(PropTypes.string),
}
22 changes: 22 additions & 0 deletions src/helpers/__tests__/locales.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { parseLocale, getLngsArray } from '../locales.js'

describe('parseLocale', () => {
it('handles one _', () => {
expect(parseLocale('en_LK')).toBe('en-LK')
})
it('handles multiple _', () => {
expect(parseLocale('mn_MN_Cyrl')).toBe('mn-MN-Cyrl')
})
it('handles no _', () => {
expect(parseLocale('id')).toBe('id')
})
})

describe('getLngsArray', () => {
it('adds language from multipart locale', () => {
expect(getLngsArray('fr_CA')).toEqual(['fr_CA', 'fr'])
})
it('returns array with just language when locale is only language', () => {
expect(getLngsArray('fr')).toEqual(['fr'])
})
})
1 change: 1 addition & 0 deletions src/helpers/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { checkIsLoginFormValid, getIsRequired } from './validators.js'
export { convertHTML, removeHTMLTags, sanitizeMainHTML } from './handleHTML.js'
export { redirectTo, getRedirectString } from './redirectHelpers.js'
export { parseLocale, getLngsArray } from './locales.js'
7 changes: 7 additions & 0 deletions src/helpers/locales.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const parseLocale = (unparsedLocale) =>
unparsedLocale?.replaceAll('_', '-')

export const getLngsArray = (locale) => {
const [lng] = locale.split('_')
return lng === locale ? [locale] : [locale, lng]
}
4 changes: 2 additions & 2 deletions src/helpers/validators.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import i18n from '@dhis2/d2-i18n'

export const getIsRequired = (uiLocale) => (val) =>
val ? undefined : i18n.t('This field is required', { lng: uiLocale })
export const getIsRequired = (lng) => (val) =>
val ? undefined : i18n.t('This field is required', { lng })

export const checkIsLoginFormValid = (values) => {
const isRequired = getIsRequired('en') // 'en' because we do not need the actual translation for validation test
Expand Down
Loading

0 comments on commit 56f49d8

Please sign in to comment.