Skip to content

Commit

Permalink
feat: add i18n support for the web ui
Browse files Browse the repository at this point in the history
  • Loading branch information
LinuxSuRen committed Aug 26, 2023
1 parent 37700ec commit 699cc4d
Show file tree
Hide file tree
Showing 11 changed files with 285 additions and 31 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ embed-ui:
cp console/atest-ui/dist/assets/*.js cmd/data/index.js
cp console/atest-ui/dist/assets/*.css cmd/data/index.css
clean-embed-ui:
echo -n '' > cmd/data/index.html
echo -n '' > cmd/data/index.js
echo -n '' > cmd/data/index.css
git checkout cmd/data/index.html
git checkout cmd/data/index.js
git checkout cmd/data/index.css
build-embed-ui: embed-ui
GOOS=${OS} go build -ldflags "-w -s -X github.com/linuxsuren/api-testing/pkg/version.version=$(shell git rev-parse --short HEAD)" -o bin/${BINARY} main.go
make clean-embed-ui
Expand Down
132 changes: 129 additions & 3 deletions console/atest-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions console/atest-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"element-plus": "^2.3.7",
"intro.js": "^7.0.1",
"vue": "^3.3.4",
"vue-i18n": "^9.2.2",
"vue-json-viewer": "^3.0.4",
"vue-router": "^4.2.2"
},
Expand Down
11 changes: 7 additions & 4 deletions console/atest-ui/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import { ElTree } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import { Edit, Share } from '@element-plus/icons-vue'
import type { Suite } from './types'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
interface Tree {
id: string
Expand Down Expand Up @@ -255,10 +258,10 @@ const viewName = ref('')
<el-aside width="200px">
<el-button type="primary" @click="openTestSuiteCreateDialog"
data-intro="Click here to create a new test suite"
test-id="open-new-suite-dialog" :icon="Edit">New</el-button>
test-id="open-new-suite-dialog" :icon="Edit">{{ t('button.new') }}</el-button>
<el-button type="primary" @click="openTestSuiteImportDialog"
data-intro="Click here to import from Postman"
test-id="open-import-suite-dialog">Import</el-button>
test-id="open-import-suite-dialog">{{ t('button.import') }}</el-button>
<el-input v-model="filterText" placeholder="Filter keyword" test-id="search" />

<el-tree
Expand Down Expand Up @@ -337,7 +340,7 @@ const viewName = ref('')
@click="submitForm(suiteFormRef)"
:loading="suiteCreatingLoading"
test-id="suite-form-submit"
>Submit</el-button
>{{ t('button.submit') }}</el-button
>
</el-form-item>
</el-form>
Expand Down Expand Up @@ -376,7 +379,7 @@ const viewName = ref('')
type="primary"
@click="importSuiteFormSubmit(importSuiteFormRef)"
test-id="suite-import-submit"
>Import</el-button
>{{ t('button.import') }}</el-button
>
</el-form-item>
</el-form>
Expand Down
69 changes: 69 additions & 0 deletions console/atest-ui/src/i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { nextTick, isRef } from 'vue'
import { createI18n } from 'vue-i18n'

import type {
I18n,
I18nOptions,
Locale,
VueI18n,
Composer,
I18nMode
} from 'vue-i18n'

export const SUPPORT_LOCALES = ['en', 'ja']

function isComposer(
instance: VueI18n | Composer,
mode: I18nMode
): instance is Composer {
return mode === 'composition' && isRef(instance.locale)
}

export function getLocale(i18n: I18n): string {
if (isComposer(i18n.global, i18n.mode)) {
return i18n.global.locale.value
} else {
return i18n.global.locale
}
}

export function setLocale(i18n: I18n, locale: Locale): void {
if (isComposer(i18n.global, i18n.mode)) {
i18n.global.locale.value = locale
} else {
i18n.global.locale = locale
}
}

export function setupI18n(options: I18nOptions = { locale: 'en' }): I18n {
const i18n = createI18n(options)
setI18nLanguage(i18n, options.locale!)
return i18n
}

export function setI18nLanguage(i18n: I18n, locale: Locale): void {
setLocale(i18n, locale)
/**
* NOTE:
* If you need to specify the language setting for headers, such as the `fetch` API, set it here.
* The following is an example for axios.
*
* axios.defaults.headers.common['Accept-Language'] = locale
*/
document.querySelector('html')!.setAttribute('lang', locale)
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const getResourceMessages = (r: any) => r.default || r

export async function loadLocaleMessages(i18n: I18n, locale: Locale) {
// load locale messages
const messages = await import(
/* @vite-ignore */ `./locales/${locale}.json`
).then(getResourceMessages)

// set locale and locale message
i18n.global.setLocaleMessage(locale, messages)

return nextTick()
}
19 changes: 19 additions & 0 deletions console/atest-ui/src/locales/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"button": {
"import": "Import",
"export": "Export",
"new": "New",
"submit": "Submit",
"save": "Save",
"delete": "Delete",
"send": "Send",
"toolbox": "Tool Box",
"newtestcase": "New TestCase"
},
"tip": {
"filter": "Filter Keyword"
},
"field": {
"name": "Name"
}
}
19 changes: 19 additions & 0 deletions console/atest-ui/src/locales/zh.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"button": {
"import": "导入",
"export": "导出",
"new": "新建",
"submit": "提交",
"save": "保存",
"delete": "删除",
"send": "发送",
"toolbox": "工具箱",
"newtestcase": "新建测试用例"
},
"tip": {
"filter": "过滤"
},
"field": {
"name": "名称"
}
}
21 changes: 18 additions & 3 deletions console/atest-ui/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,34 @@ import './assets/main.css'

import { createApp } from 'vue'
import App from './App.vue'
// import router from './router'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import enUS from 'element-plus/dist/locale/en.mjs'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import introJs from 'intro.js'
import 'intro.js/introjs.css'
import { setupI18n } from './i18n'
import en from './locales/en.json'
import zh from './locales/zh.json'

const app = createApp(App)

const language = window.navigator.userLanguage || window.navigator.language;
const lang = language.split('-')[0]

const i18n = setupI18n({
legacy: false,
locale: lang,
fallbackLocale: 'en',
messages: {
en, zh
}
})

app.use(ElementPlus, {
locale: zhCn
locale: lang === 'zh' ? zhCn : enUS
})
// app.use(router)
app.use(i18n)

app.mount('#app')

Expand Down
Loading

0 comments on commit 699cc4d

Please sign in to comment.