diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/App.vue | 2 | ||||
-rw-r--r-- | src/components/Global/PageTitle.vue | 8 | ||||
-rw-r--r-- | src/i18n.js | 29 | ||||
-rw-r--r-- | src/locales/en.json | 38 | ||||
-rw-r--r-- | src/locales/es.json | 38 | ||||
-rw-r--r-- | src/main.js | 2 | ||||
-rw-r--r-- | src/router/index.js | 10 | ||||
-rw-r--r-- | src/views/Login/Login.vue | 42 | ||||
-rw-r--r-- | src/views/Overview/OverviewQuickLinks.vue | 2 |
9 files changed, 146 insertions, 25 deletions
diff --git a/src/App.vue b/src/App.vue index a5a768a5..30de752b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -13,7 +13,7 @@ export default { name: 'App', watch: { $route: function(to) { - document.title = to.meta.title || 'Page is Missing Title'; + document.title = this.$t(to.meta.title) || 'Page is missing title'; } } }; diff --git a/src/components/Global/PageTitle.vue b/src/components/Global/PageTitle.vue index 5c64f0d6..59bb6a1e 100644 --- a/src/components/Global/PageTitle.vue +++ b/src/components/Global/PageTitle.vue @@ -14,10 +14,10 @@ export default { default: '' } }, - data() { - return { - title: this.$route.meta.title - }; + computed: { + title() { + return this.$t(this.$route.meta.title); + } } }; </script> diff --git a/src/i18n.js b/src/i18n.js new file mode 100644 index 00000000..09b3f4ca --- /dev/null +++ b/src/i18n.js @@ -0,0 +1,29 @@ +import Vue from 'vue'; +import VueI18n from 'vue-i18n'; + +Vue.use(VueI18n); + +function loadLocaleMessages() { + const locales = require.context( + './locales', + true, + /[A-Za-z0-9-_,\s]+\.json$/i + ); + const messages = {}; + locales.keys().forEach(key => { + const matched = key.match(/([A-Za-z0-9-_]+)\./i); + if (matched && matched.length > 1) { + const locale = matched[1]; + messages[locale] = locales(key); + } + }); + return messages; +} + +export default new VueI18n({ + // default language is English + locale: 'en', + // locale messages with a message key that doesn't exist will fallback to English + fallbackLocale: 'en', + messages: loadLocaleMessages() +}); diff --git a/src/locales/en.json b/src/locales/en.json new file mode 100644 index 00000000..8464ff43 --- /dev/null +++ b/src/locales/en.json @@ -0,0 +1,38 @@ +{ + "global": { + "formField": { + "validator": "Field required" + } + }, + "login": { + "language": { + "label": "Language" + }, + "languages": { + "select": "Select an option", + "english": "English", + "spanish": "Spanish" + }, + "logIn": { + "label": "Log in" + }, + "errorMsg": { + "title": "Invalid username or password.", + "action": "Please try again." + }, + "password": { + "label": "Password", + "validator": "@:global.formField.validator" + }, + "username": { + "label": "Username", + "validator": "@:global.formField.validator" + } + }, + "pageTitle": { + "localUserMgmt": "Local user management", + "login": "Login", + "overview": "Overview", + "unauthorized": "Unauthorized" + } +}
\ No newline at end of file diff --git a/src/locales/es.json b/src/locales/es.json new file mode 100644 index 00000000..30d1fd17 --- /dev/null +++ b/src/locales/es.json @@ -0,0 +1,38 @@ +{ + "global": { + "formField": { + "validator": "Campo requerido" + } + }, + "login": { + "language": { + "label": "Idioma" + }, + "languages": { + "select": "Seleccione una opción", + "english": "Inglés", + "spanish": "Español" + }, + "logIn": { + "label": "Iniciar sesión" + }, + "errorMsg": { + "title": "Usuario o contraseña invalido.", + "action": "Inténtalo de nuevo." + }, + "password": { + "label": "Contraseña", + "validator": "@:global.formField.validator" + }, + "username": { + "label": "Nombre de usuario", + "validator": "@:global.formField.validator" + } + }, + "pageTitle": { + "localUserMgmt": "Administración de usuarios locales", + "login": "Inicio de sesión", + "overview": "Información general", + "unauthorized": "No autorizado" + } +}
\ No newline at end of file diff --git a/src/main.js b/src/main.js index d80d2019..72167510 100644 --- a/src/main.js +++ b/src/main.js @@ -25,6 +25,7 @@ import { ToastPlugin } from 'bootstrap-vue'; import Vuelidate from 'vuelidate'; +import i18n from './i18n'; Vue.filter('date', dateFilter); @@ -59,5 +60,6 @@ Vue.use(Vuelidate); new Vue({ router, store, + i18n, render: h => h(App) }).$mount('#app'); diff --git a/src/router/index.js b/src/router/index.js index 71b90fb1..bec7f548 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -5,6 +5,8 @@ import AppLayout from '../layouts/AppLayout.vue'; Vue.use(VueRouter); +// Meta title is translated using i18n in App.vue and PageTitle.Vue +// Example meta: {title: 'pageTitle.overview'} const routes = [ { path: '/', @@ -18,7 +20,7 @@ const routes = [ path: '', component: () => import('@/views/Overview'), meta: { - title: 'Overview' + title: 'pageTitle.overview' } }, { @@ -26,7 +28,7 @@ const routes = [ name: 'local-users', component: () => import('@/views/AccessControl/LocalUserManagement'), meta: { - title: 'Local user management' + title: 'pageTitle.localUserMgmt' } }, { @@ -34,7 +36,7 @@ const routes = [ name: 'unauthorized', component: () => import('@/views/Unauthorized'), meta: { - title: 'Unauthorized' + title: 'pageTitle.unauthorized' } } ] @@ -44,7 +46,7 @@ const routes = [ name: 'login', component: () => import('@/views/Login'), meta: { - title: 'Login' + title: 'pageTitle.login' } } ]; diff --git a/src/views/Login/Login.vue b/src/views/Login/Login.vue index 35af76f2..d4fde8cb 100644 --- a/src/views/Login/Login.vue +++ b/src/views/Login/Login.vue @@ -13,17 +13,24 @@ <h1>OpenBMC</h1> </div> </b-col> - <b-col md="6"> <b-form class="login-form" novalidate @submit.prevent="login"> <b-alert class="login-error" :show="authError" variant="danger"> <p id="login-error-alert"> - <strong>{{ errorMsg.title }}</strong> - <span>{{ errorMsg.action }}</span> + <strong>{{ $t('login.errorMsg.title') }}</strong> + <span>{{ $t('login.errorMsg.action') }}</span> </p> </b-alert> <div class="login-form__section"> - <label for="username">Username</label> + <label for="language">{{ $t('login.language.label') }}</label> + <b-form-select + id="language" + v-model="$i18n.locale" + :options="languages" + ></b-form-select> + </div> + <div class="login-form__section"> + <label for="username">{{ $t('login.username.label') }}</label> <b-form-input id="username" v-model="userInfo.username" @@ -36,13 +43,12 @@ </b-form-input> <b-form-invalid-feedback role="alert"> <template v-if="!$v.userInfo.username.required"> - Field required + {{ $t('login.username.validator') }} </template> </b-form-invalid-feedback> </div> - <div class="login-form__section"> - <label for="password">Password</label> + <label for="password">{{ $t('login.password.label') }}</label> <b-form-input id="password" v-model="userInfo.password" @@ -54,18 +60,17 @@ </b-form-input> <b-form-invalid-feedback role="alert"> <template v-if="!$v.userInfo.password.required"> - Field required + {{ $t('login.password.validator') }} </template> </b-form-invalid-feedback> </div> - <b-button block class="mt-5" type="submit" variant="primary" :disabled="disableSubmitButton" - >Log in</b-button + >{{ $t('login.logIn.label') }}</b-button > </b-form> </b-col> @@ -83,15 +88,22 @@ export default { mixins: [VuelidateMixin], data() { return { - errorMsg: { - title: 'Invalid username or password.', - action: 'Please try again.' - }, userInfo: { username: null, password: null }, - disableSubmitButton: false + disableSubmitButton: false, + languages: [ + { value: null, text: this.$t('login.languages.select') }, + { + value: 'en', + text: this.$t('login.languages.english') + }, + { + value: 'es', + text: this.$t('login.languages.spanish') + } + ] }; }, computed: { diff --git a/src/views/Overview/OverviewQuickLinks.vue b/src/views/Overview/OverviewQuickLinks.vue index d9d86ca8..89253977 100644 --- a/src/views/Overview/OverviewQuickLinks.vue +++ b/src/views/Overview/OverviewQuickLinks.vue @@ -43,7 +43,7 @@ export default { }, data() { return { - serverLEDChecked: false + serverLedChecked: false }; }, computed: { |