diff --git a/paimon-web-ui-new/auto-imports.d.ts b/paimon-web-ui-new/auto-imports.d.ts index 6c5160a88..e380cf019 100644 --- a/paimon-web-ui-new/auto-imports.d.ts +++ b/paimon-web-ui-new/auto-imports.d.ts @@ -41,6 +41,7 @@ declare global { const isReactive: typeof import('vue')['isReactive'] const isReadonly: typeof import('vue')['isReadonly'] const isRef: typeof import('vue')['isRef'] + const locales: typeof import('./src/composables/locales')['default'] const mapActions: typeof import('pinia')['mapActions'] const mapGetters: typeof import('pinia')['mapGetters'] const mapState: typeof import('pinia')['mapState'] @@ -56,6 +57,7 @@ declare global { const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] const onDeactivated: typeof import('vue')['onDeactivated'] const onErrorCaptured: typeof import('vue')['onErrorCaptured'] + const onLogin: typeof import('./src/api/models/login')['onLogin'] const onMounted: typeof import('vue')['onMounted'] const onRenderTracked: typeof import('vue')['onRenderTracked'] const onRenderTriggered: typeof import('vue')['onRenderTriggered'] @@ -67,6 +69,7 @@ declare global { const reactive: typeof import('vue')['reactive'] const readonly: typeof import('vue')['readonly'] const ref: typeof import('vue')['ref'] + const request: typeof import('./src/api/request')['default'] const resolveComponent: typeof import('vue')['resolveComponent'] const setActivePinia: typeof import('pinia')['setActivePinia'] const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] @@ -79,6 +82,7 @@ declare global { const toRefs: typeof import('vue')['toRefs'] const toValue: typeof import('vue')['toValue'] const triggerRef: typeof import('vue')['triggerRef'] + const types: typeof import('./src/api/types')['default'] const unref: typeof import('vue')['unref'] const useAttrs: typeof import('vue')['useAttrs'] const useCssModule: typeof import('vue')['useCssModule'] @@ -86,6 +90,7 @@ declare global { const useDialog: typeof import('naive-ui')['useDialog'] const useLink: typeof import('vue-router')['useLink'] const useLoadingBar: typeof import('naive-ui')['useLoadingBar'] + const useLocaleHooks: typeof import('./src/composables/locales')['useLocaleHooks'] const useMessage: typeof import('naive-ui')['useMessage'] const useNotification: typeof import('naive-ui')['useNotification'] const useRoute: typeof import('vue-router')['useRoute'] diff --git a/paimon-web-ui-new/src/composables/locales.ts b/paimon-web-ui-new/src/composables/locales.ts index 059c3e4ba..5bdd0dbb4 100644 --- a/paimon-web-ui-new/src/composables/locales.ts +++ b/paimon-web-ui-new/src/composables/locales.ts @@ -15,12 +15,25 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import { useI18n } from 'vue-i18n' +import {type UseI18nOptions } from 'vue-i18n' -export const useLocaleHooks = () => { - const { t } = useI18n() +import i18n, { LANGUAGES } from '@/locales' + +type LocaleType = Pick & { + setLanguage(locale: UseI18nOptions['locale']): void +} + +export const useLocaleHooks = (): LocaleType => { + const { t, d, n, locale } = i18n.global + + const setLanguage = (newLanguage: LANGUAGES) => { + locale.value = newLanguage + } return { - t + t, + n, + d, + setLanguage } } diff --git a/paimon-web-ui-new/src/layouts/content/components/menubar/index.tsx b/paimon-web-ui-new/src/layouts/content/components/menubar/index.tsx index cb1034eb5..00f7e5326 100644 --- a/paimon-web-ui-new/src/layouts/content/components/menubar/index.tsx +++ b/paimon-web-ui-new/src/layouts/content/components/menubar/index.tsx @@ -15,40 +15,29 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import i18n from '@/locales' -import { useConfigStore } from '@/store/config' - export default defineComponent({ name: 'MenuBar', setup() { - const configStore = useConfigStore() - - const menuOptions = ref([] as any[]) + const { t } = useLocaleHooks() - watch( - () => configStore.getCurrentLocale, - () => { - menuOptions.value = [ - { - label: i18n.global.t('layout.playground'), - key: 'playground', - }, - { - label: i18n.global.t('layout.metadata'), - key: 'metadata', - }, - { - label: i18n.global.t('layout.cdc_ingestion'), - key: 'cdc_ingestion', - }, - { - label: i18n.global.t('layout.system'), - key: 'system', - }, - ] + const menuOptions = computed(() => ([ + { + label: t('layout.playground'), + key: 'playground', }, - { immediate: true } - ) + { + label: t('layout.metadata'), + key: 'metadata', + }, + { + label: t('layout.cdc_ingestion'), + key: 'cdc_ingestion', + }, + { + label: t('layout.system'), + key: 'system', + }, + ])) return { activeKey: ref('playground'), diff --git a/paimon-web-ui-new/src/layouts/content/components/toolbar/index.tsx b/paimon-web-ui-new/src/layouts/content/components/toolbar/index.tsx index a436959f4..77c4630a3 100644 --- a/paimon-web-ui-new/src/layouts/content/components/toolbar/index.tsx +++ b/paimon-web-ui-new/src/layouts/content/components/toolbar/index.tsx @@ -15,13 +15,16 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import i18n from '@/locales' +import { LANGUAGES } from '@/locales' import { useConfigStore } from '@/store/config' import { LogoGithub, Moon, SunnyOutline, Language } from '@vicons/ionicons5' +// ts-ignore export default defineComponent({ name: 'ToolBar', setup() { + const { t, setLanguage } = useLocaleHooks() + const handleLink = () => { window.open('https://github.com/apache/incubator-paimon-webui') } @@ -34,11 +37,14 @@ export default defineComponent({ } const handleLanguage = () => { - configStore.setCurrentLocale(configStore.getCurrentLocale === 'zh' ? 'en' : 'zh') - i18n.global.locale.value = configStore.getCurrentLocale === 'zh' ? 'en' : 'zh' + const lang = configStore.getCurrentLocale === LANGUAGES.ZH ? LANGUAGES.EN : LANGUAGES.ZH + + configStore.setCurrentLocale(lang) + setLanguage(lang) } - + return { + t, handleLink, handleTheme, handleLanguage, @@ -46,7 +52,7 @@ export default defineComponent({ active: ref(false) } }, - render () { + render() { return ( ) }} - > - {i18n.global.t('layout.' + String(this.configStore.getCurrentTheme === 'light' ? 'dark' : 'light'))} + > + {this.t('layout.' + String(this.configStore.getCurrentTheme === 'light' ? 'dark' : 'light'))} diff --git a/paimon-web-ui-new/src/locales/index.ts b/paimon-web-ui-new/src/locales/index.ts index 0ee3fb72e..1d9adf9cb 100644 --- a/paimon-web-ui-new/src/locales/index.ts +++ b/paimon-web-ui-new/src/locales/index.ts @@ -19,14 +19,19 @@ import { createI18n } from 'vue-i18n' import en from './en' import zh from './zh' +export enum LANGUAGES { + EN = 'en', + ZH = 'zh' +} + const i18n = createI18n({ - locale: 'en', + locale: LANGUAGES.ZH, legacy: false, - fallbackLocale: 'zh', + fallbackLocale: LANGUAGES.ZH, messages: { en, zh } }) -export default i18n \ No newline at end of file +export default i18n diff --git a/paimon-web-ui-new/src/store/config/index.ts b/paimon-web-ui-new/src/store/config/index.ts index dac0a6c9a..0b7e99c42 100644 --- a/paimon-web-ui-new/src/store/config/index.ts +++ b/paimon-web-ui-new/src/store/config/index.ts @@ -15,18 +15,19 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +import { LANGUAGES } from "@/locales" + type Theme = 'dark' | 'light' -type Locale = 'en' | 'zh' export const useConfigStore = defineStore({ id: 'config', - state: (): { theme: Theme, locale: Locale } => ({ + state: (): { theme: Theme, locale: LANGUAGES } => ({ theme: 'light', - locale: 'zh' + locale: LANGUAGES.ZH }), persist: true, getters: { - getCurrentLocale(): Locale { + getCurrentLocale(): LANGUAGES { return this.locale }, getCurrentTheme(): Theme { @@ -34,7 +35,7 @@ export const useConfigStore = defineStore({ } }, actions: { - setCurrentLocale(locale: Locale): void { + setCurrentLocale(locale: LANGUAGES): void { this.locale = locale }, setCurrentTheme(theme: Theme): void { diff --git a/paimon-web-ui-new/src/views/login/index.tsx b/paimon-web-ui-new/src/views/login/index.tsx index 82ceff188..3640de4be 100644 --- a/paimon-web-ui-new/src/views/login/index.tsx +++ b/paimon-web-ui-new/src/views/login/index.tsx @@ -17,24 +17,28 @@ under the License. */ import { useForm } from './use-form' import { useConfigStore } from '@/store/config' -import i18n from '@/locales' +import { LANGUAGES } from '@/locales' import logoImage from '@/assets/logo.svg' import styles from './index.module.scss' export default defineComponent({ name: 'LoginPage', setup() { + const { t, setLanguage } = useLocaleHooks() const { state, handleLogin } = useForm() const configStore = useConfigStore() const handleLocale = () => { - configStore.setCurrentLocale(configStore.getCurrentLocale === 'zh' ? 'en' : 'zh') - i18n.global.locale.value = configStore.getCurrentLocale === 'zh' ? 'en' : 'zh' + const lang = configStore.getCurrentLocale === LANGUAGES.ZH ? LANGUAGES.EN : LANGUAGES.ZH + + configStore.setCurrentLocale(lang) + setLanguage(lang) } return { configStore, + t, handleLogin, handleLocale, ...toRefs(state) @@ -56,26 +60,26 @@ export default defineComponent({ style={{marginTop: '50px'}} > @@ -86,7 +90,7 @@ export default defineComponent({ style={{ width: '100%' }} onClick={this.handleLogin} > - {i18n.global.t('login.login')} + {this.t('login.login')} @@ -98,7 +102,7 @@ export default defineComponent({ this.configStore.getCurrentTheme === 'light' ? 'dark' : 'light' )} > - {i18n.global.t('login.' + String(this.configStore.getCurrentTheme === 'light' ? 'dark' : 'light'))} + {this.t('login.' + String(this.configStore.getCurrentTheme === 'light' ? 'dark' : 'light'))}