mirror of https://github.com/nocodb/nocodb
44 changed files with 12901 additions and 284 deletions
@ -0,0 +1,44 @@ |
|||||||
|
name: "Publish : noco-i18n" |
||||||
|
|
||||||
|
on: |
||||||
|
push: |
||||||
|
branches: [ master ] |
||||||
|
release: |
||||||
|
types: [ published ] |
||||||
|
|
||||||
|
jobs: |
||||||
|
copy-file: |
||||||
|
runs-on: ubuntu-latest |
||||||
|
steps: |
||||||
|
- name: Checkout |
||||||
|
uses: actions/checkout@v2 |
||||||
|
with: |
||||||
|
fetch-depth: 0 |
||||||
|
- name: Check for update |
||||||
|
run: | |
||||||
|
echo "CHANGED=$([[ $(lerna ls --since ${{github.event.before}} | grep noco-i18n) = noco-i18n ]] && echo 'OK')" >> $GITHUB_ENV |
||||||
|
|
||||||
|
- uses: actions/setup-node@v2 |
||||||
|
if: ${{ env.CHANGED == 'OK' }} |
||||||
|
with: |
||||||
|
node-version: 14 |
||||||
|
- name: Build noco-i18n |
||||||
|
if: ${{ env.CHANGED == 'OK' || github.event_name == 'release' }} |
||||||
|
run: | |
||||||
|
cd packages/noco-i18n |
||||||
|
npm install |
||||||
|
npm run generate |
||||||
|
|
||||||
|
|
||||||
|
- name: Pushes generated output |
||||||
|
if: ${{ env.CHANGED == 'OK' || github.event_name == 'release' }} |
||||||
|
uses: dmnemec/copy_file_to_another_repo_action@main |
||||||
|
env: |
||||||
|
API_TOKEN_GITHUB: ${{ secrets.GH_TOKEN }} |
||||||
|
with: |
||||||
|
source_file: 'packages/noco-i18n/dist/' |
||||||
|
destination_repo: 'nocodb/noco-i18n' |
||||||
|
destination_folder: 'docs' |
||||||
|
user_email: 'oof1lab@gmail.com' |
||||||
|
user_name: 'o1lab' |
||||||
|
commit_message: 'Autorelease from github.com/nocodb/nocodb/packages/noco-i18n' |
@ -1,247 +0,0 @@ |
|||||||
{ |
|
||||||
"projects": { |
|
||||||
"my_projects": "我的项目", |
|
||||||
"reload_projects_tooltip": "刷新项目", |
|
||||||
"create_new_project_button": { |
|
||||||
"text": "新项目", |
|
||||||
"subtext_1": "创建", |
|
||||||
"subtext_1_tooltip": "创建一个新项目", |
|
||||||
"subtext_2": "通过连接为外部数据库创建", |
|
||||||
"subtext_2_tooltip": "支持MySQL,PostgreSQL,SQL Server和SQLite" |
|
||||||
}, |
|
||||||
"search_project": "搜索项目", |
|
||||||
"import_metadata": "导入元数据", |
|
||||||
"export_metadata": "导出元数据", |
|
||||||
"clear_metadata": "清除元数据", |
|
||||||
"stop_project": "停止项目", |
|
||||||
"start_project": "启动项目", |
|
||||||
"restart_project": "重新启动项目", |
|
||||||
"delete_project": "删除项目", |
|
||||||
"project_api_type_tooltip_graphql": "通过GraphQL API访问", |
|
||||||
"project_api_type_tooltip_rest": "通过REST API可访问", |
|
||||||
"project_empty_message": "通过创建一个新项目开始", |
|
||||||
"import_button": { |
|
||||||
"text": "通过上传元数据zip文件导入NoCodb项目" |
|
||||||
}, |
|
||||||
"show_community_star": "星星", |
|
||||||
"show_community_us_on_Github": "我们在github上", |
|
||||||
"show_community_book_a_free_demo": "预订一个免费的演示", |
|
||||||
"show_community_get_your_questions_answered": "收到您的问题", |
|
||||||
"show_community_join_discord": "加入不和谐", |
|
||||||
"show_community_follow_nocodb": "关注Nocodb.", |
|
||||||
"search": { |
|
||||||
"your_search_found_no_results": "您的搜索{search}找不到结果" |
|
||||||
}, |
|
||||||
"ext_db": { |
|
||||||
"title": { |
|
||||||
"edit": "编辑项目", |
|
||||||
"create": "创建项目" |
|
||||||
}, |
|
||||||
"project_name": "输入项目名称", |
|
||||||
"project_type": "访问项目通过", |
|
||||||
"button": { |
|
||||||
"save_project": "保存项目", |
|
||||||
"update_and_restart": "更新并重新启动", |
|
||||||
"cancel": "取消", |
|
||||||
"cancel_tooltip": "取消并返回" |
|
||||||
}, |
|
||||||
"credentials": { |
|
||||||
"title": "数据库凭据", |
|
||||||
"db_type": "数据库类型", |
|
||||||
"sqlite_file": "sqlite文件", |
|
||||||
"host_address": "主机地址", |
|
||||||
"port": "端口号码", |
|
||||||
"username": "用户名", |
|
||||||
"password": "密码", |
|
||||||
"db_create_if_not_exists": "数据库:创建如果不存在", |
|
||||||
"button": { |
|
||||||
"test_db_conn": "测试数据库连接", |
|
||||||
"remove_db_from_env": "从环境中删除数据库" |
|
||||||
}, |
|
||||||
"advanced": { |
|
||||||
"title": "SSL和高级参数", |
|
||||||
"ssl": { |
|
||||||
"client_key": { |
|
||||||
"title": "客户钥匙", |
|
||||||
"toolip": "选择.key文件" |
|
||||||
}, |
|
||||||
"client_cert": { |
|
||||||
"title": "客户证书", |
|
||||||
"toolip": "选择.cert文件" |
|
||||||
}, |
|
||||||
"server_ca": { |
|
||||||
"title": "服务器CA.", |
|
||||||
"toolip": "选择CA File." |
|
||||||
}, |
|
||||||
"preferred": "首选", |
|
||||||
"usage": { |
|
||||||
"no": "不", |
|
||||||
"preferred": "首选", |
|
||||||
"required": "必需的", |
|
||||||
"requried_ca": "必填卡", |
|
||||||
"requried_identity": "必要的身份" |
|
||||||
} |
|
||||||
}, |
|
||||||
"inflection": { |
|
||||||
"table_name": "拐点 - 表名", |
|
||||||
"column_name": "拐点 - 列名称" |
|
||||||
}, |
|
||||||
"button": { |
|
||||||
"edit_conn_json": "编辑连接JSON." |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
"error": { |
|
||||||
"invalid_char_in_folder_path": "文件夹路径中的字符无效。", |
|
||||||
"invalid_db_credentials": "数据库凭据无效。", |
|
||||||
"unable_to_connect_to_db": "无法连接数据库,请检查您的数据库已启动。", |
|
||||||
"user_doesnt_ve_sufficient_permission": "用户不存在或具有足够的权限来创建架构。" |
|
||||||
}, |
|
||||||
"head": { |
|
||||||
"title": "创建项目| Nocodb." |
|
||||||
}, |
|
||||||
"dialog": { |
|
||||||
"success": "连接成功了", |
|
||||||
"failure": "连接失败:" |
|
||||||
} |
|
||||||
}, |
|
||||||
"notifications": { |
|
||||||
"no_new": "没有新的通知", |
|
||||||
"clear": "清除" |
|
||||||
} |
|
||||||
}, |
|
||||||
"signin": { |
|
||||||
"title": "登入", |
|
||||||
"enter_your_work_email": "输入您的工作电子邮件", |
|
||||||
"enter_your_password": "输入您的密码", |
|
||||||
"forget_password": "忘记密码了吗 ?", |
|
||||||
"dont_ve_an_account": "没有帐户?", |
|
||||||
"sign_up": "报名", |
|
||||||
"form": { |
|
||||||
"rules": { |
|
||||||
"email_is_reqd": "电子邮件是必需的", |
|
||||||
"email_must_be_valid": "电子邮件必须有效", |
|
||||||
"passwd_required": "密码是必需的", |
|
||||||
"passwd_must_be_8_chars": "您的密码必须至少为8个字符" |
|
||||||
} |
|
||||||
}, |
|
||||||
"head": { |
|
||||||
"title": "登录| Nocodb.", |
|
||||||
"meta": { |
|
||||||
"hid": "登录NoCodb", |
|
||||||
"name": "登录NoCodb", |
|
||||||
"content": "登录NoCodb" |
|
||||||
} |
|
||||||
}, |
|
||||||
"password": { |
|
||||||
"recovery": { |
|
||||||
"title": "重置您的密码", |
|
||||||
"message_1": "请提供您注册时使用的电子邮件地址。", |
|
||||||
"message_2": "我们会向您发送一封带有链接以重置密码的电子邮件。", |
|
||||||
"success": "请检查您的电子邮件以重置密码", |
|
||||||
"button": "发电子邮件" |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
"signup": { |
|
||||||
"title": "报名", |
|
||||||
"you_will_be_the_super_admin": "你将是'超级管理'", |
|
||||||
"already_ve_an_account": "已经有一个帐户?" |
|
||||||
}, |
|
||||||
"treeview": { |
|
||||||
"settings": { |
|
||||||
"title": "设置", |
|
||||||
"tooltip": "仅对创造者可见" |
|
||||||
}, |
|
||||||
"app_store": "应用商店", |
|
||||||
"team_n_auth": { |
|
||||||
"title": "团队&auth", |
|
||||||
"tooltip": "角色和用户管理" |
|
||||||
}, |
|
||||||
"project_metadata": { |
|
||||||
"title": "项目元数据", |
|
||||||
"tooltip": "元管理" |
|
||||||
}, |
|
||||||
"preview_as": "预览", |
|
||||||
"reset_review": "重置预览" |
|
||||||
}, |
|
||||||
"nav_drawer": { |
|
||||||
"title": "意见", |
|
||||||
"virtual_views": { |
|
||||||
"action": { |
|
||||||
"copy": "复制视图", |
|
||||||
"rename": "重命名视图", |
|
||||||
"delete": "删除视图" |
|
||||||
}, |
|
||||||
"title": "创建一个视图", |
|
||||||
"caption": "仅对创造者可见", |
|
||||||
"grid": { |
|
||||||
"title": "网格", |
|
||||||
"create": "添加网格视图" |
|
||||||
}, |
|
||||||
"gallery": { |
|
||||||
"title": "画廊", |
|
||||||
"create": "添加图库视图" |
|
||||||
}, |
|
||||||
"calendar": { |
|
||||||
"title": "日历", |
|
||||||
"create": "添加日历视图" |
|
||||||
}, |
|
||||||
"kanban": { |
|
||||||
"title": "卡班", |
|
||||||
"create": "添加Kanban View." |
|
||||||
}, |
|
||||||
"form": { |
|
||||||
"title": "形式", |
|
||||||
"create": "添加表单视图" |
|
||||||
} |
|
||||||
}, |
|
||||||
"advanced": { |
|
||||||
"title1": "分享视图", |
|
||||||
"views_list": "观点列表", |
|
||||||
"copy_api_url": "复制API URL." |
|
||||||
}, |
|
||||||
"share_view": { |
|
||||||
"title": "此视图通过私人链接共享", |
|
||||||
"body": "具有私有链接的人只能看到此视图中可见的细胞", |
|
||||||
"toggle": { |
|
||||||
"option1": "限制密码访问权限", |
|
||||||
"option2": "访问是受限制的密码" |
|
||||||
}, |
|
||||||
"password": { |
|
||||||
"caption": "输入密码", |
|
||||||
"button": "保存密码" |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
"management": { |
|
||||||
"tabs": { |
|
||||||
"user": "用户管理", |
|
||||||
"api": "API令牌管理", |
|
||||||
"roles": "角色管理" |
|
||||||
}, |
|
||||||
"meta": { |
|
||||||
"title": "元数据操作", |
|
||||||
"export_to_file": { |
|
||||||
"title": "导出到文件", |
|
||||||
"desc": "将所有元数据从元表导出到Meta目录。" |
|
||||||
}, |
|
||||||
"import": { |
|
||||||
"title": "进口", |
|
||||||
"desc": "将所有元数据从Meta目录导入元表。" |
|
||||||
}, |
|
||||||
"export_to_zip": { |
|
||||||
"title": "出口邮编", |
|
||||||
"desc": "将项目元导出到zip文件和下载。" |
|
||||||
}, |
|
||||||
"import_zip": { |
|
||||||
"title": "进口邮编", |
|
||||||
"desc": "导入项目元拉链文件并重新启动。" |
|
||||||
}, |
|
||||||
"reset": { |
|
||||||
"title": "重启", |
|
||||||
"desc": "清除元表中的所有元数据。" |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,23 @@ |
|||||||
|
.DS_Store |
||||||
|
node_modules |
||||||
|
/dist |
||||||
|
|
||||||
|
|
||||||
|
# local env files |
||||||
|
.env.local |
||||||
|
.env.*.local |
||||||
|
|
||||||
|
# Log files |
||||||
|
npm-debug.log* |
||||||
|
yarn-debug.log* |
||||||
|
yarn-error.log* |
||||||
|
pnpm-debug.log* |
||||||
|
|
||||||
|
# Editor directories and files |
||||||
|
.idea |
||||||
|
.vscode |
||||||
|
*.suo |
||||||
|
*.ntvs* |
||||||
|
*.njsproj |
||||||
|
*.sln |
||||||
|
*.sw? |
@ -0,0 +1,62 @@ |
|||||||
|
# NocoDB : i18n Contribution Guide |
||||||
|
|
||||||
|
We 've made it simple to accept new translations |
||||||
|
|
||||||
|
1. Our i18n translations are in google spreadsheet |
||||||
|
- Make a [copy of it](https://docs.google.com/spreadsheets/d/1kGp92yLwhs1l7lwwgeor3oN1dFl7JZWuQOa4WSeZ0TE/edit?usp=sharing). ( file > make a copy ) |
||||||
|
- Create a shareable link from your spreadsheet. ( share > get link > change to anyone with link ) |
||||||
|
|
||||||
|
2. Make necessary changes for the required language column (eg. fr) |
||||||
|
|
||||||
|
3. Download the sheet as .csv file ( file > download > csv ) |
||||||
|
|
||||||
|
4. Visit [https://i18n.nocodb.com/](https://i18n.nocodb.com/) |
||||||
|
|
||||||
|
5. Upload the CSV file (from step 3). |
||||||
|
|
||||||
|
6. Select the language for which you are translating (same as in step 2) |
||||||
|
|
||||||
|
https://i18n.nocodb.com will |
||||||
|
|
||||||
|
- Automatically copy the translated values to clipboard. |
||||||
|
- Automatically show the respective file to open and edit in our github. Example: [fr.json](https://github.com/nocodb/nocodb/edit/master/packages/nc-gui/lang/fr.json). |
||||||
|
- Github will ask you to fork the repo - please do so if you haven't forked the repository and then paste the values from clipboard to the file. Alternatively you can just paste the updated JSON value to corresponding files |
||||||
|
|
||||||
|
7. Submit PR with a link to your spreadsheet (from step 1) |
||||||
|
|
||||||
|
- - - - |
||||||
|
|
||||||
|
### Sample screenshot of https://i18n.nocodb.com |
||||||
|
|
||||||
|
![image](https://user-images.githubusercontent.com/35857179/136654196-162a316c-adde-431b-8316-139168298278.png) |
||||||
|
|
||||||
|
- - - - |
||||||
|
|
||||||
|
# Development setup |
||||||
|
|
||||||
|
You need vue cli in order to start the application |
||||||
|
|
||||||
|
``` |
||||||
|
npm install -g @vue/cli |
||||||
|
``` |
||||||
|
|
||||||
|
## Project setup |
||||||
|
``` |
||||||
|
npm install |
||||||
|
``` |
||||||
|
|
||||||
|
### Compiles and hot-reloads for development |
||||||
|
``` |
||||||
|
npm run serve |
||||||
|
``` |
||||||
|
|
||||||
|
### Compiles and minifies for production |
||||||
|
``` |
||||||
|
npm run build |
||||||
|
``` |
||||||
|
|
||||||
|
### Lints and fixes files |
||||||
|
``` |
||||||
|
npm run lint |
||||||
|
``` |
||||||
|
|
@ -0,0 +1,5 @@ |
|||||||
|
module.exports = { |
||||||
|
presets: [ |
||||||
|
'@vue/cli-plugin-babel/preset' |
||||||
|
] |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,43 @@ |
|||||||
|
{ |
||||||
|
"name": "noco-i18n", |
||||||
|
"version": "1.0.0", |
||||||
|
"scripts": { |
||||||
|
"serve": "vue-cli-service serve", |
||||||
|
"build": "vue-cli-service build", |
||||||
|
"lint": "vue-cli-service lint" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"core-js": "^3.6.5", |
||||||
|
"csv-parser": "^3.0.0", |
||||||
|
"papaparse": "^5.3.1", |
||||||
|
"vue": "^3.0.0" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@vue/cli-plugin-babel": "~4.5.0", |
||||||
|
"@vue/cli-plugin-eslint": "~4.5.0", |
||||||
|
"@vue/cli-service": "~4.5.0", |
||||||
|
"@vue/compiler-sfc": "^3.0.0", |
||||||
|
"babel-eslint": "^10.1.0", |
||||||
|
"eslint": "^6.7.2", |
||||||
|
"eslint-plugin-vue": "^7.0.0" |
||||||
|
}, |
||||||
|
"eslintConfig": { |
||||||
|
"root": true, |
||||||
|
"env": { |
||||||
|
"node": true |
||||||
|
}, |
||||||
|
"extends": [ |
||||||
|
"plugin:vue/vue3-essential", |
||||||
|
"eslint:recommended" |
||||||
|
], |
||||||
|
"parserOptions": { |
||||||
|
"parser": "babel-eslint" |
||||||
|
}, |
||||||
|
"rules": {} |
||||||
|
}, |
||||||
|
"browserslist": [ |
||||||
|
"> 1%", |
||||||
|
"last 2 versions", |
||||||
|
"not dead" |
||||||
|
] |
||||||
|
} |
After Width: | Height: | Size: 4.2 KiB |
@ -0,0 +1,17 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang=""> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0"> |
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
||||||
|
<title><%= htmlWebpackPlugin.options.title %></title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<noscript> |
||||||
|
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> |
||||||
|
</noscript> |
||||||
|
<div id="app"></div> |
||||||
|
<!-- built files will be auto injected --> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,26 @@ |
|||||||
|
<template> |
||||||
|
<img alt="Vue logo" src="./assets/logo.png"> |
||||||
|
<Landing /> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Landing from './components/Landing.vue' |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'App', |
||||||
|
components: { |
||||||
|
Landing |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style> |
||||||
|
#app { |
||||||
|
font-family: Avenir, Helvetica, Arial, sans-serif; |
||||||
|
-webkit-font-smoothing: antialiased; |
||||||
|
-moz-osx-font-smoothing: grayscale; |
||||||
|
text-align: center; |
||||||
|
color: #2c3e50; |
||||||
|
margin-top: 60px; |
||||||
|
} |
||||||
|
</style> |
After Width: | Height: | Size: 2.3 KiB |
@ -0,0 +1,68 @@ |
|||||||
|
module.exports = async (csvDatas, targetLanguage) => { |
||||||
|
// function for mapping nested property
|
||||||
|
const mapPropToObject = (obj, prop, val) => { |
||||||
|
const keys = prop.split('.'); |
||||||
|
for (let i = 0, prev = obj; i < keys.length; i++) { |
||||||
|
// if last keys assign or overwrite value
|
||||||
|
if (i === keys.length - 1) { |
||||||
|
prev[keys[i]] = val |
||||||
|
} else { |
||||||
|
// define or re-assign prev value
|
||||||
|
prev = prev[keys[i]] = prev[keys[i]] || {} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// const downloadJson = (exportObj, exportName) => {
|
||||||
|
// var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportObj, null, 2))
|
||||||
|
// var downloadAnchorNode = document.createElement('a')
|
||||||
|
// downloadAnchorNode.setAttribute("href", dataStr)
|
||||||
|
// downloadAnchorNode.setAttribute("download", exportName + ".json")
|
||||||
|
// document.body.appendChild(downloadAnchorNode)
|
||||||
|
// downloadAnchorNode.click()
|
||||||
|
// downloadAnchorNode.remove()
|
||||||
|
// }
|
||||||
|
|
||||||
|
const copyJsonToClipboard = (str, targetLanguage) => { |
||||||
|
var el = document.createElement('textarea') |
||||||
|
el.value = str |
||||||
|
el.setAttribute('readonly', '') |
||||||
|
el.style = {position: 'absolute', left: '-9999px'} |
||||||
|
document.body.appendChild(el) |
||||||
|
el.select() |
||||||
|
document.execCommand('copy') |
||||||
|
document.body.removeChild(el) |
||||||
|
// alert("The target JSON has been copied to your clipboard")
|
||||||
|
popEditPage(targetLanguage) |
||||||
|
} |
||||||
|
|
||||||
|
const popEditPage = (targetLanguage) => { |
||||||
|
var editAnchorNode = document.createElement('a') |
||||||
|
editAnchorNode.setAttribute("href", `https://github.com/nocodb/nocodb/edit/master/packages/nc-gui/lang/${targetLanguage}.json`) |
||||||
|
editAnchorNode.setAttribute("target", "_blank") |
||||||
|
document.body.appendChild(editAnchorNode) |
||||||
|
editAnchorNode.click() |
||||||
|
editAnchorNode.remove() |
||||||
|
} |
||||||
|
|
||||||
|
if (!csvDatas.length) throw new Error('Empty csv') |
||||||
|
|
||||||
|
const languageObjs = {}; |
||||||
|
const languages = Object.keys(csvDatas[0]).filter(k => k !== 'String Key' && k !== 'String'); |
||||||
|
|
||||||
|
for (const data of csvDatas) { |
||||||
|
for (const lan of languages) { |
||||||
|
languageObjs[lan] = languageObjs[lan] || {}; |
||||||
|
mapPropToObject(languageObjs[lan], data[0], data[lan]) |
||||||
|
} |
||||||
|
}
|
||||||
|
|
||||||
|
for (const [ln, obj] of Object.entries(languageObjs)) { |
||||||
|
if(languageObjs[ln]['String Key'] == targetLanguage) { |
||||||
|
delete languageObjs[ln]['String Key']; |
||||||
|
// downloadJson(obj, targetLanguage)
|
||||||
|
copyJsonToClipboard(JSON.stringify(obj, null, 2), targetLanguage) |
||||||
|
return |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
import { createApp } from 'vue' |
||||||
|
import App from './App.vue' |
||||||
|
|
||||||
|
createApp(App).mount('#app') |
Loading…
Reference in new issue