mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-11 16:26:02 +00:00
Add i18n support with language selector on login page (#1410)
* feat: add i18n support with language selector on login page Co-Authored-By: Junyan Qin <Chin> <rockchinq@gmail.com> * feat: complete i18n implementation for all webui components Co-Authored-By: Junyan Qin <Chin> <rockchinq@gmail.com> * feat: complete all hardcoded text * feat: dynamic label i18n * fix: lint errors * fix: lint errors * delete sh fils * fix: edit model dialog title --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Junyan Qin <Chin> <rockchinq@gmail.com>
This commit is contained in:
committed by
GitHub
parent
91cd8cf380
commit
2bf94539bd
20
web/src/i18n/I18nProvider.tsx
Normal file
20
web/src/i18n/I18nProvider.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
'use client';
|
||||
|
||||
import { ReactNode } from 'react';
|
||||
import '@/i18n';
|
||||
import { I18nText } from '@/app/infra/entities/api';
|
||||
|
||||
interface I18nProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export default function I18nProvider({ children }: I18nProviderProps) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
export function i18nObj(i18nText: I18nText): string {
|
||||
const language = localStorage.getItem('langbot_language');
|
||||
if ((language === 'zh-Hans' && i18nText.zh_CN) || !i18nText.en_US) {
|
||||
return i18nText.zh_CN;
|
||||
}
|
||||
return i18nText.en_US;
|
||||
}
|
||||
34
web/src/i18n/index.ts
Normal file
34
web/src/i18n/index.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
'use client';
|
||||
|
||||
import i18n from 'i18next';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||
|
||||
import enUS from './locales/en-US';
|
||||
import zhHans from './locales/zh-Hans';
|
||||
|
||||
i18n
|
||||
.use(LanguageDetector)
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
resources: {
|
||||
'en-US': {
|
||||
translation: enUS,
|
||||
},
|
||||
'zh-Hans': {
|
||||
translation: zhHans,
|
||||
},
|
||||
},
|
||||
fallbackLng: 'zh-Hans',
|
||||
debug: process.env.NODE_ENV === 'development',
|
||||
interpolation: {
|
||||
escapeValue: false, // React already escapes values
|
||||
},
|
||||
detection: {
|
||||
order: ['localStorage', 'navigator'],
|
||||
lookupLocalStorage: 'langbot_language',
|
||||
caches: ['localStorage'],
|
||||
},
|
||||
});
|
||||
|
||||
export default i18n;
|
||||
174
web/src/i18n/locales/en-US.ts
Normal file
174
web/src/i18n/locales/en-US.ts
Normal file
@@ -0,0 +1,174 @@
|
||||
const enUS = {
|
||||
common: {
|
||||
login: 'Login',
|
||||
logout: 'Logout',
|
||||
email: 'Email',
|
||||
password: 'Password',
|
||||
welcome: 'Welcome back to LangBot 👋',
|
||||
continueToLogin: 'Login to continue',
|
||||
loginSuccess: 'Login successful',
|
||||
loginFailed: 'Login failed, please check your email and password',
|
||||
enterEmail: 'Enter email address',
|
||||
enterPassword: 'Enter password',
|
||||
invalidEmail: 'Please enter a valid email address',
|
||||
emptyPassword: 'Please enter your password',
|
||||
language: 'Language',
|
||||
helpDocs: 'Get Help',
|
||||
create: 'Create',
|
||||
edit: 'Edit',
|
||||
delete: 'Delete',
|
||||
add: 'Add',
|
||||
select: 'Select',
|
||||
cancel: 'Cancel',
|
||||
submit: 'Submit',
|
||||
error: 'Error',
|
||||
success: 'Success',
|
||||
save: 'Save',
|
||||
saving: 'Saving...',
|
||||
confirm: 'Confirm',
|
||||
confirmDelete: 'Confirm Delete',
|
||||
deleteConfirmation: 'Are you sure you want to delete this?',
|
||||
selectOption: 'Select an option',
|
||||
required: 'Required',
|
||||
enable: 'Enable',
|
||||
name: 'Name',
|
||||
description: 'Description',
|
||||
close: 'Close',
|
||||
deleteSuccess: 'Deleted successfully',
|
||||
deleteError: 'Delete failed: ',
|
||||
addRound: 'Add Round',
|
||||
},
|
||||
models: {
|
||||
title: 'Models',
|
||||
description: 'Configure and manage models that can be used in pipelines',
|
||||
createModel: 'Create Model',
|
||||
editModel: 'Edit Model',
|
||||
getModelListError: 'Failed to get model list: ',
|
||||
modelName: 'Model Name',
|
||||
modelProvider: 'Model Provider',
|
||||
modelBaseURL: 'Base URL',
|
||||
modelAbilities: 'Model Abilities',
|
||||
saveSuccess: 'Saved successfully',
|
||||
saveError: 'Save failed: ',
|
||||
createSuccess: 'Created successfully',
|
||||
createError: 'Creation failed: ',
|
||||
deleteSuccess: 'Deleted successfully',
|
||||
deleteError: 'Delete failed: ',
|
||||
deleteConfirmation: 'Are you sure you want to delete this model?',
|
||||
modelNameRequired: 'Model name cannot be empty',
|
||||
modelProviderRequired: 'Model provider cannot be empty',
|
||||
requestURLRequired: 'Request URL cannot be empty',
|
||||
apiKeyRequired: 'API Key cannot be empty',
|
||||
keyNameRequired: 'Key name cannot be empty',
|
||||
mustBeValidNumber: 'Must be a valid number',
|
||||
mustBeTrueOrFalse: 'Must be true or false',
|
||||
requestURL: 'Request URL',
|
||||
apiKey: 'API Key',
|
||||
abilities: 'Abilities',
|
||||
selectModelAbilities: 'Select model abilities',
|
||||
visionAbility: 'Vision Ability',
|
||||
functionCallAbility: 'Function Call',
|
||||
extraParameters: 'Extra Parameters',
|
||||
addParameter: 'Add Parameter',
|
||||
keyName: 'Key Name',
|
||||
type: 'Type',
|
||||
value: 'Value',
|
||||
string: 'String',
|
||||
number: 'Number',
|
||||
boolean: 'Boolean',
|
||||
extraParametersDescription:
|
||||
'Will be attached to the request body, such as max_tokens, temperature, top_p, etc.',
|
||||
selectModelProvider: 'Select Model Provider',
|
||||
modelProviderDescription:
|
||||
'Please fill in the model name provided by the supplier',
|
||||
selectModel: 'Select Model',
|
||||
},
|
||||
bots: {
|
||||
title: 'Bots',
|
||||
description:
|
||||
'Create and manage bots, which are the entry points for LangBot to connect with various platforms',
|
||||
createBot: 'Create Bot',
|
||||
editBot: 'Edit Bot',
|
||||
getBotListError: 'Failed to get bot list: ',
|
||||
botName: 'Bot Name',
|
||||
botDescription: 'Bot Description',
|
||||
botNameRequired: 'Bot name cannot be empty',
|
||||
botDescriptionRequired: 'Bot description cannot be empty',
|
||||
adapterRequired: 'Adapter cannot be empty',
|
||||
defaultDescription: 'A bot',
|
||||
getBotConfigError: 'Failed to get bot configuration: ',
|
||||
saveSuccess: 'Saved successfully',
|
||||
saveError: 'Save failed: ',
|
||||
createSuccess:
|
||||
'Created successfully. Please enable or modify the bound pipeline',
|
||||
createError: 'Creation failed: ',
|
||||
deleteSuccess: 'Deleted successfully',
|
||||
deleteError: 'Delete failed: ',
|
||||
deleteConfirmation: 'Are you sure you want to delete this bot?',
|
||||
platformAdapter: 'Platform/Adapter Selection',
|
||||
selectAdapter: 'Select Adapter',
|
||||
adapterConfig: 'Adapter Configuration',
|
||||
bindPipeline: 'Bind Pipeline',
|
||||
selectPipeline: 'Select Pipeline',
|
||||
},
|
||||
plugins: {
|
||||
title: 'Plugins',
|
||||
description:
|
||||
'Install and configure plugins to extend LangBot functionality',
|
||||
createPlugin: 'Create Plugin',
|
||||
editPlugin: 'Edit Plugin',
|
||||
installed: 'Installed',
|
||||
marketplace: 'Marketplace',
|
||||
arrange: 'Sort Plugins',
|
||||
install: 'Install',
|
||||
installFromGithub: 'Install Plugin from GitHub',
|
||||
onlySupportGithub: 'Currently only supports installation from GitHub',
|
||||
enterGithubLink: 'Enter GitHub link of the plugin',
|
||||
installing: 'Installing plugin...',
|
||||
installSuccess: 'Plugin installed successfully',
|
||||
installFailed: 'Plugin installation failed:',
|
||||
searchPlugin: 'Search plugins',
|
||||
sortBy: 'Sort by',
|
||||
mostStars: 'Most stars',
|
||||
recentlyAdded: 'Recently added',
|
||||
recentlyUpdated: 'Recently updated',
|
||||
noMatchingPlugins: 'No matching plugins found',
|
||||
loading: 'Loading...',
|
||||
getPluginListError: 'Failed to get plugin list:',
|
||||
noPluginInstalled: 'No plugins installed',
|
||||
pluginConfig: 'Plugin Configuration',
|
||||
pluginSort: 'Plugin Sort',
|
||||
pluginSortDescription:
|
||||
'Plugin order affects the processing order within the same event, please drag the plugin card to sort',
|
||||
pluginSortSuccess: 'Plugin sort successful',
|
||||
pluginSortError: 'Plugin sort failed: ',
|
||||
},
|
||||
pipelines: {
|
||||
title: 'Pipelines',
|
||||
description:
|
||||
'Pipelines define the processing flow for message events, used to bind to bots',
|
||||
createPipeline: 'Create Pipeline',
|
||||
editPipeline: 'Edit Pipeline',
|
||||
getPipelineListError: 'Failed to get pipeline list: ',
|
||||
daysAgo: 'days ago',
|
||||
today: 'Today',
|
||||
updateTime: 'Updated ',
|
||||
defaultBadge: 'Default',
|
||||
basicInfo: 'Basic',
|
||||
aiCapabilities: 'AI',
|
||||
triggerConditions: 'Trigger',
|
||||
safetyControls: 'Safety',
|
||||
outputProcessing: 'Output',
|
||||
nameRequired: 'Name cannot be empty',
|
||||
descriptionRequired: 'Description cannot be empty',
|
||||
createSuccess: 'Created successfully. Please edit pipeline parameters',
|
||||
createError: 'Creation failed: ',
|
||||
saveSuccess: 'Saved successfully',
|
||||
saveError: 'Save failed: ',
|
||||
deleteConfirmation:
|
||||
'Are you sure you want to delete this pipeline? Bots bound to this pipeline will not work.',
|
||||
defaultPipelineCannotDelete: 'Default pipeline cannot be deleted',
|
||||
},
|
||||
};
|
||||
|
||||
export default enUS;
|
||||
169
web/src/i18n/locales/zh-Hans.ts
Normal file
169
web/src/i18n/locales/zh-Hans.ts
Normal file
@@ -0,0 +1,169 @@
|
||||
const zhHans = {
|
||||
common: {
|
||||
login: '登录',
|
||||
logout: '退出登录',
|
||||
email: '邮箱',
|
||||
password: '密码',
|
||||
welcome: '欢迎回到 LangBot 👋',
|
||||
continueToLogin: '登录以继续',
|
||||
loginSuccess: '登录成功',
|
||||
loginFailed: '登录失败,请检查邮箱和密码是否正确',
|
||||
enterEmail: '输入邮箱地址',
|
||||
enterPassword: '输入密码',
|
||||
invalidEmail: '请输入有效的邮箱地址',
|
||||
emptyPassword: '请输入密码',
|
||||
language: '语言',
|
||||
helpDocs: '帮助文档',
|
||||
create: '创建',
|
||||
edit: '编辑',
|
||||
delete: '删除',
|
||||
add: '添加',
|
||||
select: '请选择',
|
||||
cancel: '取消',
|
||||
submit: '提交',
|
||||
error: '错误',
|
||||
success: '成功',
|
||||
save: '保存',
|
||||
saving: '保存中...',
|
||||
confirm: '确认',
|
||||
confirmDelete: '删除确认',
|
||||
deleteConfirmation: '你确定要删除这个吗?',
|
||||
selectOption: '选择一个选项',
|
||||
required: '必填',
|
||||
enable: '是否启用',
|
||||
name: '名称',
|
||||
description: '描述',
|
||||
close: '关闭',
|
||||
deleteSuccess: '删除成功',
|
||||
deleteError: '删除失败:',
|
||||
addRound: '添加回合',
|
||||
},
|
||||
models: {
|
||||
title: '模型配置',
|
||||
description: '配置和管理可在流水线中使用的模型',
|
||||
createModel: '创建模型',
|
||||
editModel: '编辑模型',
|
||||
getModelListError: '获取模型列表失败:',
|
||||
modelName: '模型名称',
|
||||
modelProvider: '模型提供商',
|
||||
modelBaseURL: '基础 URL',
|
||||
modelAbilities: '模型能力',
|
||||
saveSuccess: '保存成功',
|
||||
saveError: '保存失败:',
|
||||
createSuccess: '创建成功',
|
||||
createError: '创建失败:',
|
||||
deleteSuccess: '删除成功',
|
||||
deleteError: '删除失败:',
|
||||
deleteConfirmation: '你确定要删除这个模型吗?',
|
||||
modelNameRequired: '模型名称不能为空',
|
||||
modelProviderRequired: '模型供应商不能为空',
|
||||
requestURLRequired: '请求URL不能为空',
|
||||
apiKeyRequired: 'API Key不能为空',
|
||||
keyNameRequired: '键名不能为空',
|
||||
mustBeValidNumber: '必须是有效的数字',
|
||||
mustBeTrueOrFalse: '必须是 true 或 false',
|
||||
requestURL: '请求URL',
|
||||
apiKey: 'API Key',
|
||||
abilities: '能力',
|
||||
selectModelAbilities: '选择模型能力',
|
||||
visionAbility: '视觉能力',
|
||||
functionCallAbility: '函数调用',
|
||||
extraParameters: '额外参数',
|
||||
addParameter: '添加参数',
|
||||
keyName: '键名',
|
||||
type: '类型',
|
||||
value: '值',
|
||||
string: '字符串',
|
||||
number: '数字',
|
||||
boolean: '布尔值',
|
||||
extraParametersDescription:
|
||||
'将在请求时附加到请求体中,如 max_tokens, temperature, top_p 等',
|
||||
selectModelProvider: '选择模型供应商',
|
||||
modelProviderDescription: '请填写供应商向您提供的模型名称',
|
||||
selectModel: '请选择模型',
|
||||
},
|
||||
bots: {
|
||||
title: '机器人',
|
||||
description: '创建和管理机器人,这是 LangBot 与各个平台连接的入口',
|
||||
createBot: '创建机器人',
|
||||
editBot: '编辑机器人',
|
||||
getBotListError: '获取机器人列表失败:',
|
||||
botName: '机器人名称',
|
||||
botDescription: '机器人描述',
|
||||
botNameRequired: '机器人名称不能为空',
|
||||
botDescriptionRequired: '机器人描述不能为空',
|
||||
adapterRequired: '适配器不能为空',
|
||||
defaultDescription: '一个机器人',
|
||||
getBotConfigError: '获取机器人配置失败:',
|
||||
saveSuccess: '保存成功',
|
||||
saveError: '保存失败:',
|
||||
createSuccess: '创建成功 请启用或修改绑定流水线',
|
||||
createError: '创建失败:',
|
||||
deleteSuccess: '删除成功',
|
||||
deleteError: '删除失败:',
|
||||
deleteConfirmation: '你确定要删除这个机器人吗?',
|
||||
platformAdapter: '平台/适配器选择',
|
||||
selectAdapter: '选择适配器',
|
||||
adapterConfig: '适配器配置',
|
||||
bindPipeline: '绑定流水线',
|
||||
selectPipeline: '选择流水线',
|
||||
},
|
||||
plugins: {
|
||||
title: '插件管理',
|
||||
description: '安装和配置用于扩展 LangBot 功能的插件',
|
||||
createPlugin: '创建插件',
|
||||
editPlugin: '编辑插件',
|
||||
installed: '已安装',
|
||||
marketplace: '插件市场',
|
||||
arrange: '编排',
|
||||
install: '安装',
|
||||
installFromGithub: '从 GitHub 安装插件',
|
||||
onlySupportGithub: '目前仅支持从 GitHub 安装',
|
||||
enterGithubLink: '请输入插件的Github链接',
|
||||
installing: '正在安装插件...',
|
||||
installSuccess: '插件安装成功',
|
||||
installFailed: '插件安装失败:',
|
||||
searchPlugin: '搜索插件',
|
||||
sortBy: '排序方式',
|
||||
mostStars: '最多星标',
|
||||
recentlyAdded: '最近新增',
|
||||
recentlyUpdated: '最近更新',
|
||||
noMatchingPlugins: '没有找到匹配的插件',
|
||||
loading: '加载中...',
|
||||
getPluginListError: '获取插件列表失败:',
|
||||
pluginConfig: '插件配置',
|
||||
noPluginInstalled: '暂未安装任何插件',
|
||||
pluginSort: '插件排序',
|
||||
pluginSortDescription:
|
||||
'插件顺序会影响同一事件内的处理顺序,请拖动插件卡片排序',
|
||||
pluginSortSuccess: '插件排序成功',
|
||||
pluginSortError: '插件排序失败:',
|
||||
},
|
||||
pipelines: {
|
||||
title: '流水线',
|
||||
description: '流水线定义了对消息事件的处理流程,用于绑定到机器人',
|
||||
createPipeline: '创建流水线',
|
||||
editPipeline: '编辑流水线',
|
||||
getPipelineListError: '获取流水线列表失败:',
|
||||
daysAgo: '天前',
|
||||
today: '今天',
|
||||
updateTime: '更新于',
|
||||
defaultBadge: '默认',
|
||||
basicInfo: '基础信息',
|
||||
aiCapabilities: 'AI 能力',
|
||||
triggerConditions: '触发条件',
|
||||
safetyControls: '安全控制',
|
||||
outputProcessing: '输出处理',
|
||||
nameRequired: '名称不能为空',
|
||||
descriptionRequired: '描述不能为空',
|
||||
createSuccess: '创建成功 请编辑流水线详细参数',
|
||||
createError: '创建失败:',
|
||||
saveSuccess: '保存成功',
|
||||
saveError: '保存失败:',
|
||||
deleteConfirmation:
|
||||
'你确定要删除这个流水线吗?已绑定此流水线的机器人将无法使用。',
|
||||
defaultPipelineCannotDelete: '默认流水线不可删除',
|
||||
},
|
||||
};
|
||||
|
||||
export default zhHans;
|
||||
Reference in New Issue
Block a user