From 8457c495cfee0e3ff0e99402391f4998df210af8 Mon Sep 17 00:00:00 2001 From: Deny Date: Wed, 18 Oct 2023 05:45:50 +0000 Subject: [PATCH] Adding Chinese language --- frontend/src/lib/components/DeviceCard.svelte | 4 + frontend/src/lib/i18n/i18n-types.ts | 2 +- frontend/src/lib/i18n/i18n-util.async.ts | 4 +- frontend/src/lib/i18n/i18n-util.sync.ts | 6 +- frontend/src/lib/i18n/i18n-util.ts | 2 +- frontend/src/lib/i18n/zh-CN/index.ts | 8 + frontend/src/lib/i18n/zh/index.ts | 207 ++++++++++++++++++ frontend/src/routes/account/+page.svelte | 4 +- 8 files changed, 232 insertions(+), 5 deletions(-) create mode 100644 frontend/src/lib/i18n/zh-CN/index.ts create mode 100644 frontend/src/lib/i18n/zh/index.ts diff --git a/frontend/src/lib/components/DeviceCard.svelte b/frontend/src/lib/components/DeviceCard.svelte index 0b1082e1..9f4cfefa 100644 --- a/frontend/src/lib/components/DeviceCard.svelte +++ b/frontend/src/lib/components/DeviceCard.svelte @@ -79,6 +79,10 @@ case 'pt-PT': dateFnsLocale = (await import('date-fns/locale/pt/index.js')).default; break; + case 'zh': + case 'zh-CN': + dateFnsLocale = (await import('date-fns/locale/zh/index.js')).default; + break; default: dateFnsLocale = (await import('date-fns/locale/en-US/index.js')).default; break; diff --git a/frontend/src/lib/i18n/i18n-types.ts b/frontend/src/lib/i18n/i18n-types.ts index 0d415665..a651923d 100644 --- a/frontend/src/lib/i18n/i18n-types.ts +++ b/frontend/src/lib/i18n/i18n-types.ts @@ -9,7 +9,7 @@ import type { export type BaseTranslation = BaseTranslationType; export type BaseLocale = 'en'; -export type Locales = 'de' | 'de-DE' | 'en' | 'en-US' | 'fr' | 'fr-FR' | 'pt' | 'pt-PT'; +export type Locales = 'de' | 'de-DE' | 'en' | 'en-US' | 'fr' | 'fr-FR' | 'pt' | 'pt-PT' | 'zh' | 'zh-CN'; export type Translation = RootTranslation; diff --git a/frontend/src/lib/i18n/i18n-util.async.ts b/frontend/src/lib/i18n/i18n-util.async.ts index 63c44cb5..b832ae08 100644 --- a/frontend/src/lib/i18n/i18n-util.async.ts +++ b/frontend/src/lib/i18n/i18n-util.async.ts @@ -13,7 +13,9 @@ const localeTranslationLoaders = { fr: () => import('./fr'), 'fr-FR': () => import('./fr-FR'), pt: () => import('./pt'), - 'pt-PT': () => import('./pt-PT') + 'pt-PT': () => import('./pt-PT'), + zh: () => import('./zh'), + 'zh-CN': () => import('./zh-CN') }; const updateDictionary = (locale: Locales, dictionary: Partial): Translations => diff --git a/frontend/src/lib/i18n/i18n-util.sync.ts b/frontend/src/lib/i18n/i18n-util.sync.ts index 450dc25e..2ea83d13 100644 --- a/frontend/src/lib/i18n/i18n-util.sync.ts +++ b/frontend/src/lib/i18n/i18n-util.sync.ts @@ -13,6 +13,8 @@ import fr from './fr'; import fr_FR from './fr-FR'; import pt from './pt'; import pt_PT from './pt-PT'; +import zh from './zh'; +import zh_CN from './zh-CN'; const localeTranslations = { de, @@ -22,7 +24,9 @@ const localeTranslations = { fr, 'fr-FR': fr_FR, pt, - 'pt-PT': pt_PT + 'pt-PT': pt_PT, + zh, + 'zh-CN': zh_CN }; export const loadLocale = (locale: Locales): void => { diff --git a/frontend/src/lib/i18n/i18n-util.ts b/frontend/src/lib/i18n/i18n-util.ts index dbe5cf40..38ee0ecf 100644 --- a/frontend/src/lib/i18n/i18n-util.ts +++ b/frontend/src/lib/i18n/i18n-util.ts @@ -14,7 +14,7 @@ import type { Formatters, Locales, Translations, TranslationFunctions } from './ export const baseLocale: Locales = 'en'; -export const locales: Locales[] = ['de', 'de-DE', 'en', 'en-US', 'fr', 'fr-FR', 'pt', 'pt-PT']; +export const locales: Locales[] = ['de', 'de-DE', 'en', 'en-US', 'fr', 'fr-FR', 'pt', 'pt-PT', 'zh', 'zh-CN']; export const isLocale = (locale: string): locale is Locales => locales.includes(locale as Locales); diff --git a/frontend/src/lib/i18n/zh-CN/index.ts b/frontend/src/lib/i18n/zh-CN/index.ts new file mode 100644 index 00000000..771ce9ab --- /dev/null +++ b/frontend/src/lib/i18n/zh-CN/index.ts @@ -0,0 +1,8 @@ +import zh from '../zh'; +import type { Translation } from '../i18n-types'; + +const zh_CN = { + ...(zh as unknown as Translation) +} satisfies Translation; + +export default zh_CN; diff --git a/frontend/src/lib/i18n/zh/index.ts b/frontend/src/lib/i18n/zh/index.ts new file mode 100644 index 00000000..3512fc6f --- /dev/null +++ b/frontend/src/lib/i18n/zh/index.ts @@ -0,0 +1,207 @@ +import type { BaseTranslation } from '../i18n-types'; + +const zh = { + home: { + page_title: '首页', + order_groups: '分组', + order_name: '名称', + order_ip: 'IP地址', + order_tooltip: '排序', + no_devices: '还没有任何设备', + add_first_device: '添加您的第一台设备', + grant_permissions: '请联系管理员授予您相应权限.' + }, + account: { + page_title: '账户信息', + account_type_admin: '管理员', + account_type_user: '普通用户', + avatar_title: '头像', + language_title: '语言', + language_option_auto: '自动', + change_password_title: '更改密码', + change_password_body: '更改密码后, 您需要重新登录.', + change_password_label: '旧密码', + change_password_new: '新密码', + change_password_confirm: '确认密码' + }, + device: { + page_title: '新设备', + tabs: ['手动配置', '网络扫描'], + card_btn_more: '更多', + card_btn_more_edit: '编辑', + card_btn_more_sleep: 'Sleep', + card_btn_more_reboot: '重启', + card_tooltip_wake_cron: '唤醒计划', + card_tooltip_shutdown_cron: '关机计划', + card_tooltip_wake_password: '唤醒密码', + card_tooltip_last_status_change: '最近状态更新', + card_password: '密码', + card_nic_tooltip_pending: '等待中...', + card_nic_tooltip_shutdown: '关机', + card_nic_tooltip_shutdown_no_cmd: '未设置关机命令', + card_nic_tooltip_shutdown_no_permission: '没有关闭此设备的权限', + card_nic_tooltip_power: '启动', + card_nic_tooltip_power_no_permission: '没有启动此设备的权限', + general: '通用', + general_name: '名称', + general_name_placeholder: '设备名', + general_ip: 'IP', + general_mac: 'Mac', + general_netmask: '子网掩码', + general_required_field: '必填字段', + ports: '端口', + ports_desc: 'UpSnap 可以检查设备端口是否正常.', + ports_add_new: '添加端口', + ports_name: '名称', + ports_number: '端口号', + link: '链接', + link_desc: + '为您的设备名设置一个可点击的链接.', + wake: '唤醒', + wake_desc: '您可以通过计划任务来唤醒设备.', + wake_cron: '唤醒计划任务', + wake_cron_enable: '启用定时唤醒', + sol: 'Sleep-On-LAN', + sol_desc1: + '您可以使用 Sleep-On-LAN 工具让计算机进入睡眠状态. Sleep-On-LAN (SOL) 是一个外部的工具/守护程序, 它在您想要进入休眠状态的PC上运行并提供RestApi接口. 有关 Sleep-On-LAN 设置的说明, 请参阅文档 Usage 部分.', + sol_desc2: + 'SOL 配置为通过HTTP而不是UDP发送请求, 以启用认证功能并使请求更可靠', + sol_desc3: + '因此, 请确保在 SOL 配置Listeners 部分中包含HTTP:<YOURPORT>', + sol_enable: '启用 Sleep-On-LAN', + sol_port: 'SOL 端口', + sol_authorization: '认证', + sol_user: 'SOL 账号', + sol_password: 'SOL 密码', + shutdown: '关机', + shutdown_desc: + '此 shell 命令 将在您的容器内运行 (如果使用的是Docker) 或在您的主机上运行. 要验证该命令是否有效, 您可以在容器内或主机上的shell中运行该命令. 通常在 Windows 上使用 net rpc, Linux上使用 sshpass 或者针对Web请求使用 curl.', + shutdown_examples: '示例:', + shutdown_examples_windows: '关闭远程 Windows 主机:', + shutdown_examples_linux: '关闭远程 Linux 主机:', + shutdown_cmd: '关机命令', + shutdown_cron_desc: '就像设置计划任务来唤醒设备一样, 您也可以设置计划任务来关闭该设备.', + shutdown_cron: '关机计划任务', + shutdown_cron_enable: '启用定时关机', + password: '密码', + password_desc: + '一些网卡允许为 magic packets 设置密码, 也可以称之为 SecureON. 密码长度只能为0、4或6个字符.', + groups: '分组', + groups_desc: '您可以将设备添加到组, 以便在控制面板上按组对其进行排序.', + groups_placeholder: "例如: 'Basement' 或 'Office'", + network_scan_range_saved: '扫描范围已保存', + network_scan_desc: '自动扫描网络中的设备. 要实现这一点, 您需要以超级用户/管理员身份运行 UpSnap, 并在您的 $PATH 中安装和使用nmap(对于docker用户, 您不需要执行任何操作). 扫描可能需要一些时间.', + network_scan_ip_range: 'IP 范围', + network_scan_no_range: '无扫描范围', + network_scan_unsaved_changes: '未保存的更改', + network_scan_running: '扫描中', + network_scan: '扫描', + network_scan_ip: 'IP:', + network_scan_mac: 'Mac:', + network_scan_mac_vendor: 'Mac 供应商:', + network_scan_netmask: '子网掩码:', + network_scan_add_all: '添加全部设备', + network_scan_replace_netmask: '更换所有设备的子网掩码?', + network_scan_new_netmask: '新子网掩码', + network_scan_include_unknown: '包括名称为 “Unknown” 的设备' + }, + login: { + welcome: '欢迎使用', + email_label: '邮箱/用户名:', + password_label: '密码:', + btn_more: '更多', + menu_title_auth_providers: '其他身份验证提供程序', + btn_login: '登录' + }, + settings: { + page_title: '设置', + ping_interval_title: 'Ping 间隔', + ping_interval_desc1: + '设置 ping 的间隔。为空时使用默认值 @every 3s.', + ping_interval_desc2: + '有关 cron 的更多信息, 请访问Wikipedia 或参阅 cron 文档.', + lazy_ping_title: 'Lazy ping', + lazy_ping_desc: + "当开关打开时, UpSnap 只会在用户访问网站期间进行 ping 操作.", + lazy_ping_enable: '启用', + website_title_title: '网站标题', + website_title_desc: '设置在浏览器选项卡和网站中显示标题', + icon_title: '图标', + icon_desc: '设置一个自定义图标. 支持的文件类型:', + upsnap_version: 'UpSnap 版本' + }, + users: { + page_title: '用户', + allow_create_devices: '允许 {username} 创建新设备和编辑设备组', + device_permissions: '设备权限', + create_new_device: '创建新设备', + read: '查看', + update: '更新', + delete: '删除', + power: '电源', + toggle: '全选', + confirm_delete_title: '确认删除', + confirm_delete_desc: '您确定要删除 {username} 吗?', + create_new_user: '新增用户', + username: '用户名', + password: '密码', + password_confirm: '确认密码', + required_field: '必填字段' + }, + buttons: { + save: '保存', + delete: '删除', + change: '更改', + reset: '重置', + cancel: '取消', + add: '添加' + }, + welcome: { + step1_page_title: '欢迎使用 UpSnap 🥳', + step1_setup_desc: '初次使用, 请依照指示完成下列步骤.', + step1_setup_btn_next: '下一步', + step2_page_title: '创建管理员账号', + step2_label_email: '邮箱:', + step2_label_password: '密码:', + step2_label_min_chars: '请输入至少10个字符', + step2_label_password_confirm: '确认密码:', + step2_btn_create: '创建', + step3_page_title: '一切就绪! 🎉', + step3_page_desc: '继续向您的仪表板添加一些设备.', + step3_btn_done: '开始使用!', + not_expected_title: "意料之外! 🧐", + not_expected_desc: '您已经完成了设置, 无需再次设置', + not_expected_back: '返回', + progress_step1: '欢迎', + progress_step2: '创建账号', + progress_step3: '完成' + }, + toasts: { + admin_saved: '账户信息已保存', + user_saved: '账户信息已保存', + user_created: '用户 {username} 已创建', + user_deleted: '用户 {username} 已删除', + settings_saved: '设置已保存', + password_changed: '密码已修改, 请重新登录.', + passwords_missmatch: "两次输入的密码不匹配", + permissions_created: '用户 {username} 的权限已创建', + permissions_deleted: '用户 {username} 的权限已删除', + permissions_updated: '用户 {username} 的权限已更新', + permissions_updated_personal: '您的权限已更新', + no_permission: "您没有权限访问 {url}", + device_created: '已创建 {device}', + devices_created_multiple: '已创建 {count|int} 个设备', + device_updated: '已更新 {device}', + device_deleted: '已删除 {device}', + group_created: '已创建组 {group}', + group_deleted: '已删除组 {group}' + }, + navbar: { + theme: '主题', + new: '新增', + edit_account: '编辑账户', + logout: '退出' + } +} satisfies BaseTranslation; + +export default zh; diff --git a/frontend/src/routes/account/+page.svelte b/frontend/src/routes/account/+page.svelte index 7a09335a..478d809b 100644 --- a/frontend/src/routes/account/+page.svelte +++ b/frontend/src/routes/account/+page.svelte @@ -22,7 +22,9 @@ de: '🇩🇪', 'de-DE': '🇩🇪', pt: '🇵🇹', - 'pt-PT': '🇵🇹' + 'pt-PT': '🇵🇹', + zh: '🇨🇳', + 'zh-CN': '🇨🇳' }; let localStorageLang: Locales | 'auto' = 'auto'; let selectedLanguage: Locales | 'auto' = localStorageLang;