Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Russian language translation #903

Merged
merged 3 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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": "Успешный выход"
}
Loading