Skip to content

Commit

Permalink
Merge pull request #3409 from LiteFarmOrg/LF-4400-add-new-languages-t…
Browse files Browse the repository at this point in the history
…o-i-18-n-framework

LF-4400 Add new languages to i18n framework
  • Loading branch information
kathyavini authored Sep 5, 2024
2 parents d772da2 + 1ee10b9 commit 290546e
Show file tree
Hide file tree
Showing 18 changed files with 91 additions and 44 deletions.
4 changes: 4 additions & 0 deletions packages/api/dev.export.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ cp ../webapp/public/locales/en/crop.json src/jobs/locales/en
cp ../webapp/public/locales/es/crop.json src/jobs/locales/es
cp ../webapp/public/locales/pt/crop.json src/jobs/locales/pt
cp ../webapp/public/locales/fr/crop.json src/jobs/locales/fr
cp ../webapp/public/locales/fr/crop.json src/jobs/locales/de
cp ../webapp/public/locales/fr/crop.json src/jobs/locales/hi
cp ../webapp/public/locales/fr/crop.json src/jobs/locales/pa
cp ../webapp/public/locales/fr/crop.json src/jobs/locales/ml

# Give nodemon time to restart the API
sleep 10
Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/jobs/locales/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Backend from 'i18next-fs-backend';
i18n.use(Backend).init(
{
fallbackLng: 'en',
preload: ['en', 'es', 'pt', 'fr'],
preload: ['en', 'es', 'pt', 'fr', 'de', 'hi', 'pa', 'ml'],
ns: ['translation', 'crop'],
defaultNS: 'translation',
nsSeparator: ':',
Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/jobs/locales/i18next-parser.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ export default {
output: 'src/jobs/locales/$LOCALE/$NAMESPACE.json',
sort: true,
defaultValue: 'MISSING',
locales: ['en', 'es', 'pt', 'fr'],
locales: ['en', 'es', 'pt', 'fr', 'de', 'hi', 'pa', 'ml'],
};
2 changes: 1 addition & 1 deletion packages/api/src/templates/sendEmailTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const emailTransporter = new EmailTemplates({
root: path.join(dir, 'emails'),
},
i18n: {
locales: ['en', 'es', 'fr', 'pt'],
locales: ['en', 'es', 'fr', 'pt', 'de', 'hi', 'pa', 'ml'],
directory: path.join(dir, 'locales'),
objectNotation: true,
},
Expand Down
4 changes: 4 additions & 0 deletions packages/webapp/.storybook/preview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ export const globalTypes = {
{ value: 'es', title: 'Spanish' },
{ value: 'fr', title: 'French' },
{ value: 'pt', title: 'Portuguese' },
{ value: 'de', title: 'German' },
{ value: 'hi', title: 'Hindi' },
{ value: 'pa', title: 'Punjabi' },
{ value: 'ml', title: 'Malayalam' },
],
showName: true,
},
Expand Down
8 changes: 4 additions & 4 deletions packages/webapp/public/locales/de/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,8 @@
"BIRTH_YEAR_ERROR": "Das Geburtsjahr muss zwischen 1900 und",
"BIRTH_YEAR_TOOLTIP": "Altersangaben werden nur zu Forschungszwecken gesammelt und nur weitergegeben, wenn die persönlichen Daten entfernt wurden.",
"CREATE_BUTTON": "Konto erstellen",
"DEFAULT_LANGUAGE": "Englisch",
"DEFAULT_LANGUAGE_VALUE": "en",
"DEFAULT_LANGUAGE": "Deutsch",
"DEFAULT_LANGUAGE_VALUE": "de",
"EMAIL": "E-Mail",
"FULL_NAME": "Vollständiger Name",
"GENDER": "Geschlecht",
Expand Down Expand Up @@ -1020,8 +1020,8 @@
"BIRTH_YEAR_ERROR": "Das Geburtsjahr muss zwischen 1900 und",
"BIRTH_YEAR_TOOLTIP": "Altersangaben werden nur zu Forschungszwecken gesammelt und nur weitergegeben, wenn personenbezogene Daten entfernt wurden",
"CHOOSE_ROLE": "Rolle wählen",
"DEFAULT_LANGUAGE": "Englisch",
"DEFAULT_LANGUAGE_VALUE": "en",
"DEFAULT_LANGUAGE": "Deutsch",
"DEFAULT_LANGUAGE_VALUE": "de",
"EMAIL": "E-Mail",
"EMAIL_INFO": "Benutzer ohne E-Mail können sich nicht anmelden",
"FULL_NAME": "Vollständiger Name",
Expand Down
8 changes: 4 additions & 4 deletions packages/webapp/public/locales/hi/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,8 @@
"BIRTH_YEAR_ERROR": "जन्म वर्ष १९०० और बीच में होना चाहिए",
"BIRTH_YEAR_TOOLTIP": "आयु संबंधित जानकारी केवल अनुसंधान उद्देश्यों के लिए एकत्र की जाती है और व्यक्तिगत पहचान सूचना के बिना ही साझा की जाएगी",
"CREATE_BUTTON": "खाता बनाएं",
"DEFAULT_LANGUAGE": "अंग्रेज़ी",
"DEFAULT_LANGUAGE_VALUE": "अंग्रेज़ी",
"DEFAULT_LANGUAGE": "हिंदी",
"DEFAULT_LANGUAGE_VALUE": "hi",
"EMAIL": "ईमेल",
"FULL_NAME": "पूरा नाम",
"GENDER": "लिंग",
Expand Down Expand Up @@ -1020,8 +1020,8 @@
"BIRTH_YEAR_ERROR": "जन्म वर्ष 1900 से बीच होना चाहिए",
"BIRTH_YEAR_TOOLTIP": "आयु संबंधी जानकारी केवल अनुसंधान प्रयोजनों के लिए एकत्रित की जाती है और व्यक्तिगत पहचान सूचना हटाने के साथ ही साझा की जाएगी",
"CHOOSE_ROLE": "भूमिका चुनें",
"DEFAULT_LANGUAGE": "अंग्रेजी",
"DEFAULT_LANGUAGE_VALUE": "अंग्रेजी",
"DEFAULT_LANGUAGE": "हिंदी",
"DEFAULT_LANGUAGE_VALUE": "hi",
"EMAIL": "ईमेल",
"EMAIL_INFO": "ईमेल के बिना उपयोगकर्ता लॉग इन नहीं कर पाएंगे",
"FULL_NAME": "पूरा नाम",
Expand Down
8 changes: 4 additions & 4 deletions packages/webapp/public/locales/pa/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,8 @@
"BIRTH_YEAR_ERROR": "ਜਨਮ ਸਾਲ 1900 ਅਤੇ ਵਿਚਕਾਰ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ",
"BIRTH_YEAR_TOOLTIP": "ਉਮਰ ਦੀ ਜਾਣਕਾਰੀ ਸਿਰਫ਼ ਖੋਜ ਦੇ ਉਦੇਸ਼ਾਂ ਲਈ ਇਕੱਠੀ ਕੀਤੀ ਜਾਂਦੀ ਹੈ ਅਤੇ ਸਿਰਫ਼ ਨਿੱਜੀ ਤੌਰ 'ਤੇ ਪਛਾਣ ਕਰਨ ਵਾਲੀ ਜਾਣਕਾਰੀ ਨਾਲ ਹੀ ਸਾਂਝੀ ਕੀਤੀ ਜਾਵੇਗੀ",
"CREATE_BUTTON": "ਖਾਤਾ ਬਣਾਓ",
"DEFAULT_LANGUAGE": "ਅੰਗਰੇਜ਼ੀ",
"DEFAULT_LANGUAGE_VALUE": "ਅੰਗਰੇਜ਼ੀ",
"DEFAULT_LANGUAGE": "ਪੰਜਾਬੀ",
"DEFAULT_LANGUAGE_VALUE": "pa",
"EMAIL": "ਈਮੇਲ",
"FULL_NAME": "ਪੂਰਾ ਨਾਂਮ",
"GENDER": "ਲਿੰਗ",
Expand Down Expand Up @@ -1020,8 +1020,8 @@
"BIRTH_YEAR_ERROR": "ਜਨਮ ਸਾਲ 1900 ਅਤੇ ਵਿਚਕਾਰ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ",
"BIRTH_YEAR_TOOLTIP": "ਉਮਰ ਦੀ ਜਾਣਕਾਰੀ ਸਿਰਫ਼ ਖੋਜ ਦੇ ਉਦੇਸ਼ਾਂ ਲਈ ਇਕੱਠੀ ਕੀਤੀ ਜਾਂਦੀ ਹੈ ਅਤੇ ਸਿਰਫ਼ ਨਿੱਜੀ ਤੌਰ 'ਤੇ ਪਛਾਣ ਕਰਨ ਵਾਲੀ ਜਾਣਕਾਰੀ ਨਾਲ ਹੀ ਸਾਂਝੀ ਕੀਤੀ ਜਾਵੇਗੀ",
"CHOOSE_ROLE": "ਰੋਲ ਚੁਣੋ",
"DEFAULT_LANGUAGE": "ਅੰਗਰੇਜ਼ੀ",
"DEFAULT_LANGUAGE_VALUE": "ਅੰਗਰੇਜ਼ੀ",
"DEFAULT_LANGUAGE": "ਪੰਜਾਬੀ",
"DEFAULT_LANGUAGE_VALUE": "pa",
"EMAIL": "ਈਮੇਲ",
"EMAIL_INFO": "ਈਮੇਲ ਤੋਂ ਬਿਨਾਂ ਉਪਭੋਗਤਾ ਲੌਗਇਨ ਕਰਨ ਦੇ ਯੋਗ ਨਹੀਂ ਹੋਣਗੇ",
"FULL_NAME": "ਪੂਰਾ ਨਾਂਮ",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const getDate = (date, language = 'en') => {
return new Intl.DateTimeFormat(language, { dateStyle: 'medium' }).format(new Date(date));
};

import useLanguageOptions, { languageCodes } from '../../../hooks/useLanguageOptions';

export const PureTaskCard = ({
taskType,
status,
Expand Down Expand Up @@ -173,5 +175,5 @@ PureTaskCard.propTypes = {
onClickAssignee: PropTypes.func,
onClickCompleteOrDueDate: PropTypes.func,
selected: PropTypes.bool,
language: PropTypes.oneOf(['en', 'es', 'fr', 'pt']),
language: PropTypes.oneOf(languageCodes),
};
9 changes: 2 additions & 7 deletions packages/webapp/src/components/CreateUserAccount/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import ReactSelect from '../Form/ReactSelect';
import { useTranslation } from 'react-i18next';
import i18n from '../../locales/i18n';
import useGenderOptions from '../../hooks/useGenderOptions';
import useLanguageOptions from '../../hooks/useLanguageOptions';

export default function PureCreateUserAccount({ onSignUp, email, onGoBack, isNotSSO }) {
const {
Expand Down Expand Up @@ -41,13 +42,7 @@ export default function PureCreateUserAccount({ onSignUp, email, onGoBack, isNot
} = validatePasswordWithErrors(password);

const genderOptions = useGenderOptions();

const languageOptions = [
{ value: 'en', label: t('PROFILE.ACCOUNT.ENGLISH') },
{ value: 'es', label: t('PROFILE.ACCOUNT.SPANISH') },
{ value: 'pt', label: t('PROFILE.ACCOUNT.PORTUGUESE') },
{ value: 'fr', label: t('PROFILE.ACCOUNT.FRENCH') },
];
const languageOptions = useLanguageOptions();

const getLanguageOption = (language) => {
return languageOptions.findIndex((object) => object.value === language);
Expand Down
1 change: 1 addition & 0 deletions packages/webapp/src/components/FullYearCalendar/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getNewDate } from '../Form/InputDuration/utils';
import 'rc-year-calendar/locales/rc-year-calendar.es';
import 'rc-year-calendar/locales/rc-year-calendar.pt';
import 'rc-year-calendar/locales/rc-year-calendar.fr';
import 'rc-year-calendar/locales/rc-year-calendar.de';

function FullYearCalendarView({
seed_date,
Expand Down
9 changes: 3 additions & 6 deletions packages/webapp/src/components/InviteUser/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ReactSelect from '../Form/ReactSelect';
import { useTranslation } from 'react-i18next';
import { getFirstNameLastName } from '../../util';
import useGenderOptions from '../../hooks/useGenderOptions';
import useLanguageOptions from '../../hooks/useLanguageOptions';

export default function PureInviteUser({ onInvite, onGoBack, userFarmEmails, roleOptions = [] }) {
const {
Expand Down Expand Up @@ -41,13 +42,9 @@ export default function PureInviteUser({ onInvite, onGoBack, userFarmEmails, rol
}, [selectedRoleId]);
const { t } = useTranslation(['translation', 'common', 'gender']);
const title = t('INVITE_USER.TITLE');

const genderOptions = useGenderOptions();
const languageOptions = [
{ value: 'en', label: t('PROFILE.ACCOUNT.ENGLISH') },
{ value: 'es', label: t('PROFILE.ACCOUNT.SPANISH') },
{ value: 'pt', label: t('PROFILE.ACCOUNT.PORTUGUESE') },
{ value: 'fr', label: t('PROFILE.ACCOUNT.FRENCH') },
];
const languageOptions = useLanguageOptions();

const disabled = !isValid || !isDirty;
const onSubmit = (data) => {
Expand Down
9 changes: 2 additions & 7 deletions packages/webapp/src/components/Profile/Account/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,10 @@ import Button from '../../Form/Button';
import PropTypes from 'prop-types';
import ProfileLayout from '../ProfileLayout';
import useGenderOptions from '../../../hooks/useGenderOptions';
import useLanguageOptionsMap from '../../../hooks/useLanguageOptions';

const useLanguageOptions = (language_preference) => {
const { t } = useTranslation();
const languageOptionMap = {
en: { label: t('PROFILE.ACCOUNT.ENGLISH'), value: 'en' },
es: { label: t('PROFILE.ACCOUNT.SPANISH'), value: 'es' },
pt: { label: t('PROFILE.ACCOUNT.PORTUGUESE'), value: 'pt' },
fr: { label: t('PROFILE.ACCOUNT.FRENCH'), value: 'fr' },
};
const languageOptionMap = useLanguageOptionsMap();
const languageOptions = Object.values(languageOptionMap);
const languagePreferenceOptionRef = useRef();
languagePreferenceOptionRef.current =
Expand Down
9 changes: 3 additions & 6 deletions packages/webapp/src/components/Profile/EditUser/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Checkbox from '../../Form/Checkbox';
import { useSelector } from 'react-redux';
import { userFarmsByFarmSelector } from '../../../containers/userFarmSlice';
import useGenderOptions from '../../../hooks/useGenderOptions';
import useLanguageOptions from '../../../hooks/useLanguageOptions';

export default function PureEditUser({
userFarm,
Expand Down Expand Up @@ -43,12 +44,8 @@ export default function PureEditUser({
const adminRoles = [1, 2, 5];

const genderOptions = useGenderOptions();
const languageOptions = [
{ value: 'en', label: t('PROFILE.ACCOUNT.ENGLISH') },
{ value: 'es', label: t('PROFILE.ACCOUNT.SPANISH') },
{ value: 'pt', label: t('PROFILE.ACCOUNT.PORTUGUESE') },
{ value: 'fr', label: t('PROFILE.ACCOUNT.FRENCH') },
];
const languageOptions = useLanguageOptions();

const isPseudoUser = userFarm.role_id === 4;
const roleOptions = Object.keys(dropDownMap).map((role_id) => ({
value: role_id,
Expand Down
12 changes: 12 additions & 0 deletions packages/webapp/src/containers/Consent/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ import PortugueseOwnerConsent from './locales/pt/Owner.Consent.md';
import PortugueseWorkerConsent from './locales/pt/Worker.Consent.md';
import SpanishOwnerConsent from './locales/es/Owner.Consent.md';
import SpanishWorkerConsent from './locales/es/Worker.Consent.md';
import GermanOwnerConsent from './locales/de/Owner.Consent.md';
import GermanWorkerConsent from './locales/de/Worker.Consent.md';
import HindiOwnerConsent from './locales/hi/Owner.Consent.md';
import HindiWorkerConsent from './locales/hi/Worker.Consent.md';
import PunjabiOwnerConsent from './locales/pa/Owner.Consent.md';
import PunjabiWorkerConsent from './locales/pa/Worker.Consent.md';
import MalayalamOwnerConsent from './locales/ml/Owner.Consent.md';
import MalayalamWorkerConsent from './locales/ml/Worker.Consent.md';
import { getLanguageFromLocalStorage } from '../../util/getLanguageFromLocalStorage';
import { CONSENT_VERSION } from '../../util/constants';

Expand All @@ -21,6 +29,10 @@ const languageConsent = {
fr: { worker: <FrenchWorkerConsent />, owner: <FrenchOwnerConsent /> },
es: { worker: <SpanishWorkerConsent />, owner: <SpanishOwnerConsent /> },
pt: { worker: <PortugueseWorkerConsent />, owner: <PortugueseOwnerConsent /> },
de: { worker: <GermanWorkerConsent />, owner: <GermanOwnerConsent /> },
hi: { worker: <HindiWorkerConsent />, owner: <HindiOwnerConsent /> },
pa: { worker: <PunjabiWorkerConsent />, owner: <PunjabiOwnerConsent /> },
ml: { worker: <MalayalamWorkerConsent />, owner: <MalayalamOwnerConsent /> },
};

const getLanguageConsent = (language) => languageConsent[language] || languageConsent.en;
Expand Down
40 changes: 40 additions & 0 deletions packages/webapp/src/hooks/useLanguageOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2024 LiteFarm.org
* This file is part of LiteFarm.
*
* LiteFarm is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LiteFarm is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details, see <https://www.gnu.org/licenses/>.
*/
import { useTranslation } from 'react-i18next';

// TODO: LF-4056
const supportedLanguages = [
['en', 'PROFILE.ACCOUNT.ENGLISH'],
['de', 'PROFILE.ACCOUNT.GERMAN'],
['es', 'PROFILE.ACCOUNT.SPANISH'],
['pt', 'PROFILE.ACCOUNT.PORTUGUESE'],
['fr', 'PROFILE.ACCOUNT.FRENCH'],
['hi', 'PROFILE.ACCOUNT.HINDI'],
['pa', 'PROFILE.ACCOUNT.PUNJABI'],
['ml', 'PROFILE.ACCOUNT.MALAYALAM'],
];

const useLanguageOptions = () => {
const { t } = useTranslation();

return supportedLanguages.map(([value, text]) => ({
value,
label: t(text),
}));
};

export const languageCodes = supportedLanguages.map(([code]) => code);

export default useLanguageOptions;
2 changes: 1 addition & 1 deletion packages/webapp/src/locales/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ i18n
defaultNS: 'translation',
nsSeparator: ':',
fallbackLng: 'en',
locales: ['en', 'pt', 'es', 'fr'],
locales: ['en', 'pt', 'es', 'fr', 'de', 'hi', 'pa', 'ml'],
debug: false,
detection: {
order: ['localStorage', 'navigator', 'querystring'],
Expand Down
2 changes: 1 addition & 1 deletion packages/webapp/src/locales/i18next-parser.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ module.exports = {
output: 'public/locales/$LOCALE/$NAMESPACE.json',
sort: true,
defaultValue: 'MISSING',
locales: ['en', 'es', 'pt', 'fr'],
locales: ['en', 'es', 'pt', 'fr', 'de', 'hi', 'pa', 'ml'],
};

0 comments on commit 290546e

Please sign in to comment.