Add a dropdown list in setting to allow change language. (#726)

* init localization

* Update defaul to en

* Fix merge issue and import path.

* Set default to en

* Change jsx to tsx

* Update the password max length string.

* Remove languageContext as using the recoil instead.

* Add localization to component endpoints pages

* Revert default to en after testing.

* Update LoginForm.tsx

* Fix translation.

* Make lint happy

* Merge (#1)

* Create deploy.yml

* Add localization support for endpoint pages components  (#667)

* init localization

* Update defaul to en

* Fix merge issue and import path.

* Set default to en

* Change jsx to tsx

* Update the password max length string.

* Remove languageContext as using the recoil instead.

* Add localization to component endpoints pages

* Revert default to en after testing.

* Update LoginForm.tsx

* Fix translation.

* Make lint happy

* Add a restart to melisearch in docker-compose.yml (#684)

* Oauth fixes for Cognito (#686)

* Add a restart to melisearch in docker-compose.yml

* Oauth fixes for Cognito

* Use the username or email for full name from oath if not provided

---------

Co-authored-by: Donavan <snark@hey.com>

* Italian localization support for endpoint (#687)

---------

Co-authored-by: Danny Avila <110412045+danny-avila@users.noreply.github.com>
Co-authored-by: Donavan Stanley <donavan.stanley@gmail.com>
Co-authored-by: Donavan <snark@hey.com>
Co-authored-by: Marco Beretta <81851188+Berry-13@users.noreply.github.com>

* Translate Nav pages

* Fix npm test

* Add setting dropdown to change the language

* Fix unit test

* Use useRecoilState

---------

Co-authored-by: Danny Avila <110412045+danny-avila@users.noreply.github.com>
Co-authored-by: Donavan Stanley <donavan.stanley@gmail.com>
Co-authored-by: Donavan <snark@hey.com>
Co-authored-by: Marco Beretta <81851188+Berry-13@users.noreply.github.com>
This commit is contained in:
Abner Chou 2023-07-31 11:47:14 -04:00 committed by GitHub
parent 41ed33e792
commit 2faeebfae2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 314 additions and 242 deletions

View file

@ -31,15 +31,7 @@
{
"name": "planet",
"type": "string",
"enum": [
"Saturn",
"Jupiter",
"Mars",
"Sun",
"Venus",
"Mercury",
"Moon"
],
"enum": ["Saturn", "Jupiter", "Mars", "Sun", "Venus", "Mercury", "Moon"],
"required": true,
"description": "The planet name to use the corresponding Kamea matrix."
}

View file

@ -3,7 +3,7 @@ import { CheckIcon } from 'lucide-react';
import { ThemeContext } from '~/hooks/ThemeContext';
import React, { useState, useContext, useEffect, useCallback } from 'react';
import { useClearConversationsMutation } from 'librechat-data-provider';
import { useRecoilValue } from 'recoil';
import { useRecoilValue, useRecoilState } from 'recoil';
import store from '~/store';
import { localize } from '~/localization/Translation';
@ -66,10 +66,38 @@ export const ClearChatsButton = ({
);
};
export const LangSelector = ({
langcode,
onChange,
}: {
langcode: string;
onChange: (value: string) => void;
}) => {
const lang = useRecoilValue(store.lang);
return (
<div className="flex items-center justify-between">
<div>{localize(lang, 'com_nav_language')}</div>
<select
className="w-24 rounded border border-black/10 bg-transparent text-sm dark:border-white/20 dark:bg-gray-900"
onChange={(e) => onChange(e.target.value)}
value={langcode}
>
<option value="en">{localize(lang, 'com_nav_lang_english')}</option>
<option value="cn">{localize(lang, 'com_nav_lang_chinese')}</option>
<option value="it">{localize(lang, 'com_nav_lang_italian')}</option>
<option value="br">{localize(lang, 'com_nav_lang_brazilian_portuguese')}</option>
<option value="es">{localize(lang, 'com_nav_lang_spanish')}</option>
</select>
</div>
);
};
function General() {
const { theme, setTheme } = useContext(ThemeContext);
const clearConvosMutation = useClearConversationsMutation();
const [confirmClear, setConfirmClear] = useState(false);
const [langcode, setLangcode] = useRecoilState(store.lang);
const { newConversation } = store.useConversation();
const { refreshConversations } = store.useConversations();
@ -97,12 +125,22 @@ function General() {
[setTheme],
);
const changeLang = useCallback(
(value: string) => {
setLangcode(value);
},
[setLangcode],
);
return (
<Tabs.Content value="general" role="tabpanel" className="w-full md:min-h-[300px]">
<div className="flex flex-col gap-3 text-sm text-gray-600 dark:text-gray-300">
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
<ThemeSelector theme={theme} onChange={changeTheme} />
</div>
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
<LangSelector langcode={langcode} onChange={changeLang} />
</div>
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
<ClearChatsButton confirmClear={confirmClear} onClick={clearConvos} showText={true} />
</div>

View file

@ -0,0 +1,36 @@
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { LangSelector } from './General';
import { RecoilRoot } from 'recoil';
describe('LangSelector', () => {
let mockOnChange;
beforeEach(() => {
mockOnChange = jest.fn();
});
it('renders correctly', () => {
const { getByText, getByDisplayValue } = render(
<RecoilRoot>
<LangSelector langcode="en" onChange={mockOnChange} />
</RecoilRoot>,
);
expect(getByText('Language')).toBeInTheDocument();
expect(getByDisplayValue('English')).toBeInTheDocument();
});
it('calls onChange when the select value changes', () => {
const { getByDisplayValue } = render(
<RecoilRoot>
<LangSelector langcode="en" onChange={mockOnChange} />
</RecoilRoot>,
);
fireEvent.change(getByDisplayValue('English'), { target: { value: 'it' } });
expect(mockOnChange).toHaveBeenCalledWith('it');
});
});

View file

@ -32,10 +32,10 @@ export const getTranslations = (langCode: string) => {
if (langCode === 'it') {
return Italy;
}
if (langCode === 'Br') {
if (langCode === 'br') {
return Portuguese;
}
if (langCode === 'Es') {
if (langCode === 'es') {
return Spanish;
}
// === add conditionals here for additional languages here === //

View file

@ -183,4 +183,10 @@ export default {
com_nav_settings: 'Settings',
com_nav_search_placeholder: 'Search messages',
com_nav_setting_general: 'General',
com_nav_language: 'Language',
com_nav_lang_english: 'English',
com_nav_lang_chinese: '中文',
com_nav_lang_italian: 'Italiano',
com_nav_lang_brazilian_portuguese: 'Português Brasileiro',
com_nav_lang_spanish: 'Español',
};