Skip to content

Commit

Permalink
feat: Russian language translation (#903)
Browse files Browse the repository at this point in the history
* feat(Russian Translation): Adds Russian Language option

* fix: Corrects Failedtofetch field in English Version

* fix: Adds missing translations on upload page
  • Loading branch information
StepanLebedevTheodo committed Aug 9, 2023
1 parent 0fed69d commit 672eec0
Show file tree
Hide file tree
Showing 19 changed files with 323 additions and 32 deletions.
25 changes: 13 additions & 12 deletions frontend/app/upload/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const requiredRolesForUpload: BrainRoleType[] = ["Editor", "Owner"];
const UploadPage = (): JSX.Element => {
const { currentBrain } = useBrainContext();
const { session } = useSupabase();
const { t } = useTranslation(["translation","upload"]);
const { t } = useTranslation(["translation", "upload"]);

if (session === null) {
redirectToLogin();
Expand All @@ -29,9 +29,11 @@ const UploadPage = (): JSX.Element => {
return (
<div className="flex justify-center items-center mt-5">
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative max-w-md">
<strong className="font-bold mr-1">Oh no!</strong>
<strong className="font-bold mr-1">
{t("ohNo", { ns: "upload" })}
</strong>
<span className="block sm:inline">
{"You need to select a brain first. 🧠💡🥲"}
{t("selectBrainFirst", { ns: "upload" })}
</span>
</div>
</div>
Expand All @@ -44,11 +46,11 @@ const UploadPage = (): JSX.Element => {
return (
<div className="flex justify-center items-center mt-5">
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative max-w-md">
<strong className="font-bold mr-1">Oh no!</strong>
<strong className="font-bold mr-1">
{t("ohNo", { ns: "upload" })}
</strong>
<span className="block sm:inline">
{
"You don't have the necessary role to upload content to the selected brain. 🧠💡🥲"
}
{t("missingNecessaryRole", { ns: "upload" })}
</span>
</div>
</div>
Expand All @@ -59,8 +61,8 @@ const UploadPage = (): JSX.Element => {
return (
<main className="pt-10">
<PageHeading
title={t("title",{"ns":"upload"})}
subtitle={t("subtitle",{"ns":"upload"})}
title={t("title", { ns: "upload" })}
subtitle={t("subtitle", { ns: "upload" })}
/>
<FileUploader />
<Divider text={t("or")} className="m-5" />
Expand All @@ -73,14 +75,13 @@ const UploadPage = (): JSX.Element => {
</Link>
</div>
</main>
);
}
);
};

return (
<Suspense fallback="Loading...">
<Upload />
</Suspense>

);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,40 @@ export type Language = {
};

export const useLanguageHook = (): {
change: (newLanguage: Language) => void;
allLanguages: Language[];
currentLanguage: Language | null;
} => {
change: (newLanguage: Language) => void;
allLanguages: Language[];
currentLanguage: Language | null;
} => {
const { i18n } = useTranslation();
const [allLanguages, setAllLanguages] = useState<Language[]>([]);
const [currentLanguage, setCurrentLanguage] = useState<Language | null>(null);
useEffect(() => {
const languages = [
{
{
id: "en",
name: 'English'
name: "English",
},
{
id: "es",
name: 'Español'
name: "Español",
},
{
id: "fr",
name: 'Français'
}
name: "Français",
},
{
id: "ru",
name: "Русский",
},
];

setAllLanguages(languages);

// get language from localStorage
const savedLanguage = localStorage.getItem('selectedLanguage');
const savedLanguage = localStorage.getItem("selectedLanguage");

if (savedLanguage != null) {
const foundLanguage = languages.find(lang => lang.id === savedLanguage);
const foundLanguage = languages.find((lang) => lang.id === savedLanguage);
if (foundLanguage) {
setCurrentLanguage(foundLanguage);
void i18n.changeLanguage(foundLanguage.id);
Expand All @@ -47,18 +51,18 @@ export const useLanguageHook = (): {

// Set language to default if no language found in localStorage
setCurrentLanguage(languages[0]);
localStorage.setItem('selectedLanguage', languages[0].id);
localStorage.setItem("selectedLanguage", languages[0].id);
}, [i18n]);

const change = (newLanguage: Language) => {
setCurrentLanguage(newLanguage);
localStorage.setItem('selectedLanguage', newLanguage.id);
localStorage.setItem("selectedLanguage", newLanguage.id);
void i18n.changeLanguage(newLanguage.id);
};

return {
change,
allLanguages,
currentLanguage
currentLanguage,
};
};
28 changes: 28 additions & 0 deletions frontend/lib/config/LocaleConfig/resources.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable max-lines */
// import all namespaces English
import brain_en from "../../../public/locales/en/brain.json";
import chat_en from "../../../public/locales/en/chat.json";
Expand Down Expand Up @@ -37,6 +38,19 @@ import translation_fr from "../../../public/locales/fr/translation.json";
import updatePassword_fr from "../../../public/locales/fr/updatePassword.json";
import upload_fr from "../../../public/locales/fr/upload.json";
import user_fr from "../../../public/locales/fr/user.json";
// import all namespaces Russian
import brain_ru from "../../../public/locales/ru/brain.json";
import chat_ru from "../../../public/locales/ru/chat.json";
import config_ru from "../../../public/locales/ru/config.json";
import delete_brain_ru from "../../../public/locales/ru/deleteBrain.json";
import explore_ru from "../../../public/locales/ru/explore.json";
import login_ru from "../../../public/locales/ru/login.json";
import logout_ru from "../../../public/locales/ru/logout.json";
import signUp_ru from "../../../public/locales/ru/signUp.json";
import translation_ru from "../../../public/locales/ru/translation.json";
import updatePassword_ru from "../../../public/locales/ru/updatePassword.json";
import upload_ru from "../../../public/locales/ru/upload.json";
import user_ru from "../../../public/locales/ru/user.json";

export const defaultNS = "translation";
export const resources = {
Expand Down Expand Up @@ -82,4 +96,18 @@ export const resources = {
user: user_fr,
delete_brain: delete_brain_fr,
},
ru: {
brain: brain_ru,
chat: chat_ru,
config: config_ru,
explore: explore_ru,
login: login_ru,
logout: logout_ru,
signUp: signUp_ru,
translation: translation_ru,
updatePassword: updatePassword_ru,
upload: upload_ru,
user: user_ru,
delete_brain: delete_brain_ru,
},
} as const;
2 changes: 1 addition & 1 deletion frontend/public/locales/en/login.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
"Invalidlogincredentials" : "Invalid login credentials",
"password.updated": "Password updated successfully!",
"new_password": "New Password",
"Failedtofetch": "Failed to Failed"
"Failedtofetch": "Failed to fetch data"
}
5 changes: 4 additions & 1 deletion frontend/public/locales/en/upload.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@
"addFiles": "Please, add files to upload",
"selectBrain": "Please, select or create a brain to upload a file",
"invalidUrl": "Invalid URL",
"crawlFailed": "Failed to crawl website: {{message}}"
"crawlFailed": "Failed to crawl website: {{message}}",
"ohNo": "Oh no!",
"selectBrainFirst": "You need to select a brain first. 🧠💡🥲",
"missingNecessaryRole": "You don't have the necessary role to upload content to the selected brain. 🧠💡🥲"
}
5 changes: 4 additions & 1 deletion frontend/public/locales/es/upload.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@
"addFiles": "Por favor, agregar archivos a subir",
"selectBrain": "Por favor, seleccione o cree un cerebro antes de subir un archivo",
"invalidUrl": "URL inválido",
"crawlFailed": "Error al rastrear sitio web: {{message}}"
"crawlFailed": "Error al rastrear sitio web: {{message}}",
"ohNo": "¡Oh no!",
"selectBrainFirst": "Primero debes seleccionar un cerebro. 🧠💡🥲",
"missingNecessaryRole": "No tienes el rol necesario para cargar contenido en el cerebro seleccionado. 🧠💡🥲"
}
5 changes: 4 additions & 1 deletion frontend/public/locales/fr/upload.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@
"addFiles": "Veuillez ajouter des fichiers à télécharger",
"selectBrain": "Veuillez sélectionner ou créer un cerveau pour télécharger un fichier",
"invalidUrl": "URL invalide",
"crawlFailed": "Échec de l'exploration du site web : {{message}}"
"crawlFailed": "Échec de l'exploration du site web : {{message}}",
"ohNo": "Oh non !",
"selectBrainFirst": "Vous devez d'abord sélectionner un cerveau. 🧠💡🥲",
"missingNecessaryRole": "Vous n'avez pas le rôle nécessaire pour télécharger du contenu dans le cerveau sélectionné. 🧠💡🥲"
}
30 changes: 30 additions & 0 deletions frontend/public/locales/ru/brain.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"searchBrain": "Поиск мозга",
"selectBrain": "Выберите мозг, пожалуйста",
"brainCreated": "Мозг успешно создан",
"newBrain": "Добавить новый мозг",
"newBrainTitle": "Добавить новый мозг",
"newBrainSubtitle": "Создайте новое пространство для ваших данных",
"brainName": "Название мозга",
"brainNamePlaceholder": "Например, Заметки по истории",
"brainDescription": "Описание",
"brainDescriptionPlaceholder": "Мой новый мозг - это...",
"shareBrain": "Поделиться мозгом {{name}}",
"shareBrainUsers": "Пользователи с доступом",
"shareBrainLink": "Нажмите, чтобы скопировать ссылку для совместного использования мозга",
"copiedToClipboard": "Скопировано в буфер обмена",
"inviteUsers": "Добавить новых пользователей",
"usersInvited": "Пользователи успешно приглашены",
"errorSendingInvitation": "Ошибка при отправке приглашений",
"brainUndefined": "Мозг не определен",
"noBrainUsers": "Нет пользователей мозга",
"errorFetchingBrainUsers": "Ошибка при получении пользователей мозга",
"usersWithAccess": "Пользователи с доступом",
"userRoleUpdated": "{{email}} обновлен до {{newRole}}",
"userRoleUpdateFailed": "Не удалось обновить {{email}} до {{newRole}}",
"userRemoved": "{{email}} удален из мозга",
"userRemoveFailed": "Не удалось удалить {{email}} из мозга",
"defaultBrain": "Мозг по умолчанию",
"setDefaultBrain": "Установить как мозг по умолчанию",
"errorCreatingBrain": "Произошла ошибка при создании мозга"
}
35 changes: 35 additions & 0 deletions frontend/public/locales/ru/chat.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"title": "Чат с {{brain}}",
"brain": "мозг",
"keyboard_shortcuts": "Сочетания клавиш",
"brains": "мозги",
"subtitle": "Общайтесь с языковой моделью о ваших загруженных данных",
"limit_reached": "Вы достигли лимита запросов, пожалуйста, попробуйте позже",
"error_occurred": "Произошла ошибка при получении ответа",
"noCurrentBrain": "Нет текущего мозга",
"errorParsingData": "Ошибка при разборе данных",
"resposeBodyNull": "Пустой ответ",
"receivedResponse": "Получен ответ. Начинается обработка потока...",
"errorCallingAPI": "Ошибка вызова API",
"ask": "Задайте вопрос или опишите задачу.",
"begin_conversation_placeholder": "Начните беседу здесь...",
"thinking": "Думаю...",
"chat": "Чат",
"errorFetching": "Произошла ошибка при получении ваших чатов",
"chatDeleted": "Чат успешно удален. Id: {{id}}",
"errorDeleting": "Ошибка при удалении чата: {{error}}",
"chatNameUpdated": "Имя чата обновлено",
"shortcut_select_brain": "@: Выберите мозг для общения",
"shortcut_select_file": "/: Выберите файл для общения",
"shortcut_choose_prompt": "#: Выберите конкретный запрос",
"shortcut_create_brain": "@+: Создайте новый мозг",
"shortcut_feed_brain": "/+: Подайте мозгу знаний",
"shortcut_create_prompt": "#+: Создайте новый пользовательский запрос",
"shortcut_manage_brains": "CMDB: Управление вашими мозгами",
"shortcut_go_to_user_page": "CMDU: Перейти на страницу пользователя",
"shortcut_go_to_shortcuts": "CMDK: Перейти к ярлыкам",
"empty_brain_title_intro": "Чат с вашими",
"empty_brain_title_prefix": "Загрузите файлы в",
"empty_brain_title_suffix": "и общайтесь с ними",
"actions_bar_placeholder": "Задайте вопрос @brains или /files и выберите ваш #prompt"
}
49 changes: 49 additions & 0 deletions frontend/public/locales/ru/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"title": "Настройки",
"subtitle": "Управление вашим мозгом",
"settings": "Настройки",
"people": "Люди",
"knowledge": "Знания",
"modelSection": "Настройки модели",
"openAiKeyLabel": "Ключ Open AI",
"openAiKeyPlaceholder": "sk-xxx",
"modelLabel": "Модель",
"anthropicKeyPlaceholder": "Ключ Anthropic API",
"anthropicKeyLabel": "Ключ Anthropic API",
"temperature": "Температура",
"maxTokens": "Максимальное количество токенов",
"accountSection": "Ваш аккаунт",
"signedInAs": "Вы вошли как",
"backendSection": "Настройки бэкенда",
"backendUrlPlaceHolder": "URL бэкенда",
"backendUrlLabel": "URL бэкенда",
"supabaseURLPlaceHolder": "URL Supabase",
"supabaseURLLabel": "URL Supabase",
"supabaseKeyPlaceHolder": "Ключ Supabase",
"supabaseKeyLabel": "Ключ Supabase",
"keepInLocal": "Сохранить локально",
"customPromptSection": "Пользовательский запрос",
"promptName": "Название запроса",
"promptNamePlaceholder": "Название моего потрясающего запроса",
"promptContent": "Содержание запроса",
"promptContentPlaceholder": "Как искусственный интеллект, ваше...",
"promptRemoved": "Запрос успешно удален",
"errorRemovingPrompt": "Ошибка при удалении запроса",
"removePrompt": "Удалить запрос",
"newAPIKey": "Создать новый ключ",
"configSaved": "Настройки сохранены",
"configReset": "Настройки сброшены",
"invalidOpenAiKey": "Недействительный ключ OpenAI",
"error.createApiKey": "Ошибка при создании API ключа",
"error.copy": "Не удалось скопировать",
"updatingBrainSettings": "Обновление настроек мозга...",
"defaultBrainSet": "Мозг успешно установлен по умолчанию",
"nameRequired": "Имя обязательно",
"promptFieldsRequired": "Название и содержание запроса обязательны",
"brainUpdated": "Мозг успешно обновлен",
"publicPrompts": "Выбрать из публичных запросов",
"roleRequired": "У вас нет необходимой роли для доступа к этой вкладке 🧠💡🥲.",
"requireAccess": "Пожалуйста, запросите доступ у владельца.",
"ohno": "О нет!",
"noUser": "Пользователь не найден"
}
6 changes: 6 additions & 0 deletions frontend/public/locales/ru/deleteBrain.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"deleteButton": "Удалить мозг",
"deleteConfirmQuestion": "Вы уверены, что хотите удалить этот мозг? Это действие нельзя отменить.",
"deleteConfirmYes": "Да, удалить этот мозг",
"returnButton": "Вернуться"
}
14 changes: 14 additions & 0 deletions frontend/public/locales/ru/explore.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"title": "Исследовать загруженные данные",
"subtitle": "Просмотрите или удалите сохраненные данные, используемые вашим мозгом",
"empty": "О нет, ваш мозг пуст.",
"noBrain": "Мозг не найден",
"sessionNotFound": "Сессия пользователя не найдена",
"deleted": "{{fileName}} удален из мозга {{brain}}",
"errorDeleting": "Ошибка при удалении {{fileName}}",
"view": "Просмотреть",
"chunkNumber": "Количество частей: {{quantity}}",
"notAvailable": "Не доступно",
"deleteConfirmTitle": "Подтвердите",
"deleteConfirmText": "Вы действительно хотите удалить?"
}
15 changes: 15 additions & 0 deletions frontend/public/locales/ru/login.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"title": "Вход",
"subtitle": "С возвращением",
"signup": "Нет аккаунта? Зарегистрируйтесь",
"forgottenPassword": "Забыли пароль",
"googleLogin": "Войти с Google",
"magicLink": "Отправить магическую ссылку",
"loginSuccess": "Успешный вход",
"errorMailMissed": "Пожалуйста, введите ваш адрес электронной почты",
"recoveryMailSended": "Восстановительное письмо будет отправлено, если адрес электронной почты распознан",
"Invalidlogincredentials": "Недопустимые учетные данные для входа",
"password.updated": "Пароль успешно обновлен!",
"new_password": "Новый пароль",
"Failedtofetch": "Не удалось получить данные"
}
8 changes: 8 additions & 0 deletions frontend/public/locales/ru/logout.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"title": "Выход",
"subtitle": "Увидимся в следующий раз",
"areYouSure": "Вы уверены, что хотите выйти?",
"cancel": "Вернуться",
"error": "Ошибка при выходе: {{errorMessage}}",
"loggedOut": "Успешный выход"
}

0 comments on commit 672eec0

Please sign in to comment.