Skip to content

Commit 3b5aaec

Browse files
ZonaHexCopilot
andauthored
refactor(global): better i18n (#575)
* refactor(global): better i18n * Update src/locale/index.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * refactor: i18n --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent ae167a5 commit 3b5aaec

File tree

19 files changed

+312
-171
lines changed

19 files changed

+312
-171
lines changed

src/assets/icons.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/footer/index.vue

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,23 @@ a-layout-footer.footer
1212
img.icon(:src="getIconUrl(region.country)")
1313
.text {{ region.location }}
1414
.right
15-
StatusList(:items="statusRight")
15+
a-space(:size="10")
16+
a-select(
17+
v-if="dev"
18+
v-model="currentLocale"
19+
size="mini"
20+
:style="{ width: '112px' }"
21+
@change="onChangeLocale"
22+
)
23+
a-option(value="en-US") English
24+
a-option(value="zh-CN") 中文
25+
StatusList(:items="statusRight")
1626
</template>
1727

1828
<script lang="ts" setup>
1929
import { getIconUrl } from '@/utils'
2030
import { useStorage } from '@vueuse/core'
31+
import useLocale from '@/hooks/locale'
2132
2233
const { regionVendor, regionLocation, regionCountry, serviceName }: any = useStorage('config', {}).value
2334
const { host } = storeToRefs(useAppStore())
@@ -31,6 +42,11 @@ a-layout-footer.footer
3142
})
3243
3344
const vendorIcon = getIconUrl(region.value.vendor)
45+
46+
const { currentLocale, onChangeLocale } = useLocale()
47+
48+
// Not yet used in production
49+
const dev = import.meta.env.MODE === 'development'
3450
</script>
3551

3652
<style lang="less" scoped>

src/components/navbar/index.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,24 @@ a-layout.navbar
3838
| {{ label }}
3939
a-doption.news(@click="showNews")
4040
| {{ $t('menu.news') }}
41-
NewsModal(ref="newsModal" :news-list="newsList" :loading="isLoadingNews")
41+
NewsModal(ref="newsModal" :news-list="newsListMutable" :loading="isLoadingNews")
4242
</template>
4343

4444
<script lang="ts" setup name="NavBar">
45+
import { useI18n } from 'vue-i18n'
4546
import { listenerRouteChange } from '@/utils/route-listener'
4647
import { useNews } from '@/hooks/news'
4748
import useMenuTree from '../menu/use-menu-tree'
4849
import NewsModal from './news-modal.vue'
4950
5051
const router = useRouter()
52+
const { t } = useI18n()
5153
const { updateSettings } = useAppStore()
5254
const { menuSelectedKey, globalSettings, hideSidebar } = storeToRefs(useAppStore())
5355
const { activeTab: ingestTab } = storeToRefs(useIngestStore())
5456
const { menuTree } = useMenuTree()
5557
const { newsList, isLoadingNews } = useNews()
56-
58+
const newsListMutable = computed(() => (newsList.value ? [...newsList.value] : []))
5759
const newsModal = ref()
5860
5961
const menu = menuTree.value[0].children

src/components/time-select/index.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,15 @@ a-trigger#time-select(
4343
:class="isSingleTimeSelected(time.value) ? 'selected' : ''"
4444
@click="selectTimeLength(time.value)"
4545
) {{ time.label }}
46-
a-doption(:class="!isRelative ? 'selected' : ''" @click="rangePickerVisible = !rangePickerVisible") Custom
46+
a-doption(:class="!isRelative ? 'selected' : ''" @click="rangePickerVisible = !rangePickerVisible") {{ t('time-select.custom') }}
4747
</template>
4848

4949
<script lang="ts" setup name="TimeSelect">
5050
import type { OptionsType } from '@/types/global'
5151
import dayjs from 'dayjs'
52+
import { useI18n } from 'vue-i18n'
53+
54+
const { t } = useI18n()
5255
5356
const props = defineProps({
5457
timeLength: {

src/hooks/locale.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
import { computed } from 'vue'
2-
import { useI18n } from 'vue-i18n'
31
import { Message } from '@arco-design/web-vue'
2+
import { useLocalStorage } from '@vueuse/core'
3+
import { useI18n } from 'vue-i18n'
44

55
export default function useLocale() {
6-
const i18 = useI18n()
7-
const currentLocale = computed(() => {
8-
return i18.locale.value
6+
const { t, locale } = useI18n()
7+
8+
const STORAGE_KEY = 'greptime-locale'
9+
10+
const currentLocale = useLocalStorage(STORAGE_KEY, 'en-US')
11+
12+
watch(currentLocale, (val) => {
13+
locale.value = val
914
})
10-
const changeLocale = (value: string) => {
11-
i18.locale.value = value
12-
localStorage.setItem('arco-locale', value)
13-
Message.success(i18.t('navbar.action.locale'))
14-
}
15-
return {
16-
currentLocale,
17-
changeLocale,
15+
16+
const onChangeLocale = () => {
17+
Message.success(t('navbar.action.locale'))
1818
}
19+
return { currentLocale, onChangeLocale }
1920
}

src/locale/en-US.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,55 @@ import settings from './en-US/settings'
33
import menu from './en-US/menu'
44
import playground from './en-US/playground'
55
import logsQuery from './en-US/logs-query'
6+
import flow from './en-US/flow'
67

78
export default {
8-
'navbar.action.locale': 'Switch to English',
9-
'navbar.docs': 'Docs',
9+
'copy': 'Copy',
1010
'copied': 'Copied',
1111
'guide.confirm': 'Confirm',
1212
'guide.welcome': 'Welcome!',
13+
'navbar.action.locale': 'Switch to English',
14+
'navbar.docs': 'Docs',
15+
'navbar.newQuery': 'New Query',
1316
'news.seeAll': 'See all news',
17+
'common.retry': 'Retry',
18+
'common.cancel': 'Cancel',
19+
'common.edit': 'Edit',
20+
'common.delete': 'Delete',
21+
'common.refresh': 'Refresh',
22+
'common.save': 'Save',
23+
'common.usage': 'Usage',
24+
'common.search': 'Search',
25+
'common.clearFilter': 'Clear Filter',
26+
'common.export': 'Export',
27+
'common.limit': 'Limit',
28+
'common.time': 'Time',
29+
'common.cost': 'Cost',
30+
'common.level': 'Level',
31+
'common.message': 'Message',
32+
'common.autoRefresh': 'Auto Refresh',
33+
'common.stop': 'Stop',
34+
'common.all': 'All',
35+
'common.pleaseInput': 'Please input...',
36+
'time-select.custom': 'Custom',
37+
'logs.copyQuery': 'Copy Query',
38+
'logs.explainQuery': 'Explain Query',
39+
'time-select.last1Minute': 'Last 1 minute',
40+
'time-select.last10Minutes': 'Last 10 minutes',
41+
'time-select.last30Minutes': 'Last 30 minutes',
42+
'time-select.last1Hour': 'Last 1 hour',
43+
'time-select.last3Hours': 'Last 3 hours',
44+
'time-select.last6Hours': 'Last 6 hours',
45+
'time-select.last12Hours': 'Last 12 hours',
46+
'time-select.last24Hours': 'Last 24 hours',
47+
'time-select.last2Days': 'Last 2 days',
48+
'time-select.last7Days': 'Last 7 days',
49+
'time-select.last3Days': 'Last 3 days',
50+
'time-select.anyTime': 'Any time',
1451
...dashboard,
1552
...settings,
1653
...menu,
1754
...playground,
1855
...logsQuery,
56+
...flow,
1957
}

src/locale/en-US/dashboard.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ export default {
5555
'dashboard.step': 'step',
5656
'dashboard.supportedDurations': 'Supported Durations',
5757
'dashboard.table': 'Table',
58-
'dashboard.tableTree': 'TABLES',
5958
'dashboard.total': 'Total: {time} ms',
6059
'dashboard.xType': 'X-Axis Type',
6160
'dashboard.yType': 'Y-Axis Types',
@@ -77,9 +76,9 @@ export default {
7776
'dashboard.importExplain': 'Import Result JSON',
7877
'dashboard.exportCSV': 'Export Result as CSV',
7978
'dashboard.wrapLines': 'Wrap Lines',
80-
'dashboard.copy': 'Copy',
8179
'dashboard.hideSidebar': 'Hide sidebar',
8280
'dashboard.rerunQuery': 'Rerun Query',
8381
'dashboard.clearResults': 'Clear results?',
8482
'dashboard.timeAssistance': 'Time Input Assistance',
83+
'dashboard.fetchingDatabases': 'Fetching databases...',
8584
}

src/locale/en-US/flow.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export default {
2+
'flow.header.readMore': "GreptimeDB's Flow engine enables real-time computation of data streams, read more",
3+
'flow.createSql': 'Flow Create SQL',
4+
'flow.save': 'Save',
5+
'flow.props': 'Flow Props',
6+
'flow.confirmDelete': 'Are you sure you want to delete?',
7+
'flow.delete': 'Delete',
8+
'flow.sinkData': 'Sink Table Data',
9+
'flow.createTitle': 'Create Flow',
10+
}

src/locale/en-US/menu.ts

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,27 @@
11
export default {
2+
'menu.dashboard': 'Dashboard',
3+
'menu.settings': 'Settings',
24
'menu.dashboard.playground': 'Playground',
35
'menu.dashboard.query': 'Query',
46
'menu.dashboard.metrics': 'Metrics Query',
57
'menu.dashboard.tables': 'Tables',
68
'menu.dashboard.scripts': 'Scripts',
9+
'menu.dashboard.deployment': 'Deployment',
710
'menu.dashboard.status': 'Status',
811
'menu.dashboard.ingest': 'Ingest',
912
'menu.dashboard.influxdb': 'InfluxDB Line Protocol',
1013
'menu.dashboard.write': 'Write',
1114
'menu.dashboard.upload': 'Upload',
1215
'menu.dashboard.input': 'Input',
13-
'menu.dashboard': 'Dashboard',
14-
'menu.exception': 'Exception',
15-
'menu.faq': 'FAQ',
16-
'menu.form': 'Form',
17-
'menu.list': 'List',
18-
'menu.profile': 'Profile',
19-
'menu.result': 'Result',
20-
'menu.server.dashboard': 'Dashboard-Server',
21-
'menu.server.monitor': 'Monitor-Server',
22-
'menu.server.workplace': 'Workplace-Server',
23-
'menu.user': 'User Center',
24-
'menu.visualization': 'Data Visualization',
25-
'menu.newQuery': 'New Query',
26-
'menu.tour.query':
27-
'Check full list of tables and their metadata of your instance. Place SQL and PromQL query in our query editor.',
28-
'menu.tour.tables': 'Full list of tables and their metadata of your instance.',
29-
'menu.tour.ingest': 'Ingest time-series data from the Ingest UI.',
30-
'menu.tour.workbench': 'Build advanced dashboard using UI builder and YAML based configuration, all managed by git.',
16+
'menu.dashboard.management': 'Management',
17+
'menu.dashboard.log-ingestion': 'Log Ingestion',
3118
'menu.dashboard.logsQuery': 'Logs Query',
3219
'menu.dashboard.logPipeline': 'Logs Pipelines',
33-
'menu.traces.list': 'Traces Query',
34-
'menu.dashboard.log-ingestion': 'Log Ingestion',
35-
'menu.news': 'Latest News',
3620
'menu.dashboard.flow': 'Flow',
3721
'menu.dashboard.traces': 'Traces Query',
22+
'menu.tour.query':
23+
'Check full list of tables and their metadata of your instance. Place SQL and PromQL query in our query editor.',
24+
'menu.tour.ingest': 'Ingest time-series data from the Ingest UI.',
25+
'menu.news': 'Latest News',
26+
'menu.feedback': 'Send Feedback',
3827
}

src/locale/index.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,32 @@ export const LOCALE_OPTIONS = [
66
{ label: '中文', value: 'zh-CN' },
77
{ label: 'English', value: 'en-US' },
88
]
9-
const defaultLocale = localStorage.getItem('arco-locale') || import.meta.env.VITE_LANG || 'en-US'
9+
10+
const STORAGE_KEY = 'greptime-locale'
11+
12+
function detectLocale(): string {
13+
// 1) explicit storage
14+
const stored = localStorage.getItem(STORAGE_KEY)
15+
if (stored) return stored
16+
17+
// 2) env default
18+
const envLang = import.meta.env.VITE_LANG
19+
if (envLang) return envLang
20+
21+
// 3) enterprise and browser
22+
const appName = import.meta.env.VITE_APP_NAME
23+
if (appName === 'enterprise') {
24+
const navLang = (navigator.language || navigator.languages?.[0] || '').toLowerCase()
25+
if (navLang.startsWith('zh')) return 'zh-CN'
26+
return 'en-US'
27+
}
28+
29+
// 4) default to en-US
30+
return 'en-US'
31+
}
1032

1133
const i18n = createI18n({
12-
locale: defaultLocale,
34+
locale: detectLocale(),
1335
fallbackLocale: 'en-US',
1436
allowComposition: true,
1537
messages: {

0 commit comments

Comments
 (0)