feat: use vue-i18n 9 for vue3
This commit is contained in:
@ -34,7 +34,7 @@ import TopNavigation from './components/home/topNavigation'
|
||||
import ContentAuth from './components/home/contentAuth'
|
||||
import ContentLinkShare from './components/home/contentLinkShare'
|
||||
import ContentNoAuth from './components/home/contentNoAuth'
|
||||
import {setLanguage} from './i18n/setup'
|
||||
import {setLanguage} from './i18n'
|
||||
import AccountDeleteService from '@/services/accountDelete'
|
||||
|
||||
export default defineComponent({
|
||||
|
@ -112,6 +112,7 @@
|
||||
<script>
|
||||
import flatPickr from 'vue-flatpickr-component'
|
||||
import 'flatpickr/dist/flatpickr.css'
|
||||
import { i18n } from '@/i18n'
|
||||
|
||||
import {format} from 'date-fns'
|
||||
import {calculateDayInterval} from '@/helpers/time/calculateDayInterval'
|
||||
@ -142,7 +143,7 @@ export default {
|
||||
chooseDateLabel: {
|
||||
type: String,
|
||||
default() {
|
||||
return this.$t('input.datepicker.chooseDate')
|
||||
return i18n.global.t('input.datepicker.chooseDate')
|
||||
},
|
||||
},
|
||||
disabled: {
|
||||
|
@ -81,6 +81,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { i18n } from '@/i18n'
|
||||
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
|
||||
|
||||
export default {
|
||||
@ -141,14 +142,14 @@ export default {
|
||||
createPlaceholder: {
|
||||
type: String,
|
||||
default() {
|
||||
return this.$t('input.multiselect.createPlaceholder')
|
||||
return i18n.global.t('input.multiselect.createPlaceholder')
|
||||
},
|
||||
},
|
||||
// The text shown next to an option.
|
||||
selectPlaceholder: {
|
||||
type: String,
|
||||
default() {
|
||||
return this.$t('input.multiselect.selectPlaceholder')
|
||||
return i18n.global.t('input.multiselect.selectPlaceholder')
|
||||
},
|
||||
},
|
||||
// If true, allows for selecting multiple items. v-model will be an array with all selected values in that case.
|
||||
|
@ -23,9 +23,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="api-url-info" v-else>
|
||||
<i18n path="apiConfig.signInOn">
|
||||
<i18n-t keypath="apiConfig.signInOn">
|
||||
<span class="url" v-tooltip="apiUrl"> {{ apiDomain }} </span>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
<br />
|
||||
<a @click="() => (configureApi = true)">{{ $t('apiConfig.change') }}</a>
|
||||
</div>
|
||||
|
@ -43,6 +43,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { i18n } from '@/i18n'
|
||||
|
||||
export default {
|
||||
name: 'create-edit',
|
||||
props: {
|
||||
@ -53,7 +55,7 @@ export default {
|
||||
primaryLabel: {
|
||||
type: String,
|
||||
default() {
|
||||
return this.$t('misc.create')
|
||||
return i18n.global.t('misc.create')
|
||||
},
|
||||
},
|
||||
primaryIcon: {
|
||||
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="notification is-danger">
|
||||
<i18n path="loadingError.failed">
|
||||
<i18n-t keypath="loadingError.failed">
|
||||
<a @click="() => location.reload()">{{ $t('loadingError.tryAgain') }}</a>
|
||||
<a href="https://vikunja.io/contact/" rel="noreferrer noopener nofollow" target="_blank">{{ $t('loadingError.contact') }}</a>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
<div class="filename">{{ a.file.name }}</div>
|
||||
<div class="info">
|
||||
<p class="collapses">
|
||||
<i18n path="task.attachment.createdBy">
|
||||
<i18n-t keypath="task.attachment.createdBy">
|
||||
<span v-tooltip="formatDate(a.created)">
|
||||
{{ formatDateSince(a.created) }}
|
||||
</span>
|
||||
@ -44,7 +44,7 @@
|
||||
:user="a.createdBy"
|
||||
:is-inline="true"
|
||||
/>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
<span>
|
||||
{{ a.file.getHumanSize() }}
|
||||
</span>
|
||||
|
@ -1,6 +1,8 @@
|
||||
export const getListTitle = (l, $t) => {
|
||||
import {i18n} from '@/i18n'
|
||||
|
||||
export const getListTitle = (l) => {
|
||||
if (l.id === -1) {
|
||||
return $t('list.pseudo.favorites.title')
|
||||
return i18n.global.t('list.pseudo.favorites.title')
|
||||
}
|
||||
return l.title
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
export const getNamespaceTitle = (n, $t) => {
|
||||
import {i18n} from '@/i18n'
|
||||
|
||||
export const getNamespaceTitle = (n) => {
|
||||
if (n.id === -1) {
|
||||
return $t('namespace.pseudo.sharedLists.title')
|
||||
return i18n.global.t('namespace.pseudo.sharedLists.title')
|
||||
}
|
||||
if (n.id === -2) {
|
||||
return $t('namespace.pseudo.favorites.title')
|
||||
return i18n.global.t('namespace.pseudo.favorites.title')
|
||||
}
|
||||
if (n.id === -3) {
|
||||
return $t('namespace.pseudo.savedFilters.title')
|
||||
return i18n.global.t('namespace.pseudo.savedFilters.title')
|
||||
}
|
||||
return n.title
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ import {createDateFromString} from '@/helpers/time/createDateFromString'
|
||||
import {format, formatDistance} from 'date-fns'
|
||||
import {enGB, de, fr, ru} from 'date-fns/locale'
|
||||
|
||||
import {i18n} from '@/i18n'
|
||||
|
||||
const locales = {en: enGB, de, ch: de, fr, ru}
|
||||
|
||||
const dateIsValid = date => {
|
||||
@ -12,7 +14,7 @@ const dateIsValid = date => {
|
||||
return date instanceof Date && !isNaN(date)
|
||||
}
|
||||
|
||||
export const formatDate = (date, f, locale) => {
|
||||
export const formatDate = (date, f, locale = i18n.global.t('date.locale')) => {
|
||||
if (!dateIsValid(date)) {
|
||||
return ''
|
||||
}
|
||||
@ -22,7 +24,15 @@ export const formatDate = (date, f, locale) => {
|
||||
return date ? format(date, f, {locale: locales[locale]}) : ''
|
||||
}
|
||||
|
||||
export const formatDateSince = (date, $t) => {
|
||||
export function formatDateLong(date) {
|
||||
return formatDate(date, 'PPPPpppp')
|
||||
}
|
||||
|
||||
export function formatDateShort(date) {
|
||||
return formatDate(date, 'PPpp')
|
||||
}
|
||||
|
||||
export const formatDateSince = (date) => {
|
||||
if (!dateIsValid(date)) {
|
||||
return ''
|
||||
}
|
||||
@ -30,11 +40,11 @@ export const formatDateSince = (date, $t) => {
|
||||
date = createDateFromString(date)
|
||||
|
||||
const currentDate = new Date()
|
||||
const distance = formatDistance(date, currentDate, {locale: locales[$t('date.locale')]})
|
||||
const distance = formatDistance(date, currentDate, {locale: locales[i18n.global.t('date.locale')]})
|
||||
|
||||
if (date > currentDate) {
|
||||
return $t('date.in', {date: distance})
|
||||
return i18n.global.t('date.in', {date: distance})
|
||||
}
|
||||
|
||||
return $t('date.ago', {date: distance})
|
||||
return i18n.global.t('date.ago', {date: distance})
|
||||
}
|
||||
|
@ -1,12 +1,10 @@
|
||||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import langEN from './lang/en.json'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
export const i18n = new VueI18n({
|
||||
export const i18n = createI18n({
|
||||
locale: 'en', // set locale
|
||||
fallbackLocale: 'en',
|
||||
globalInjection: true,
|
||||
messages: {
|
||||
en: langEN,
|
||||
},
|
30
src/main.ts
30
src/main.ts
@ -11,7 +11,7 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
import {formatDate, formatDateSince} from '@/helpers/time/formatDate'
|
||||
import {formatDateShort, formatDateLong, formatDateSince} from '@/helpers/time/formatDate'
|
||||
// @ts-ignore
|
||||
import {VERSION} from './version.json'
|
||||
|
||||
@ -28,8 +28,7 @@ import vueShortkey from 'vue-shortkey'
|
||||
// Vuex
|
||||
import {store} from './store'
|
||||
// i18n
|
||||
import VueI18n from 'vue-i18n' // types
|
||||
import {i18n} from './i18n/setup'
|
||||
import {i18n} from './i18n'
|
||||
|
||||
console.info(`Vikunja frontend version ${VERSION}`)
|
||||
|
||||
@ -77,30 +76,19 @@ app.component('modal', Modal)
|
||||
app.component('card', Card)
|
||||
|
||||
// Mixins
|
||||
import message from './message'
|
||||
import {getNamespaceTitle} from './helpers/getNamespaceTitle'
|
||||
import {getListTitle} from './helpers/getListTitle'
|
||||
import {colorIsDark} from './helpers/color/colorIsDark'
|
||||
import {setTitle} from './helpers/setTitle'
|
||||
app.mixin({
|
||||
methods: {
|
||||
formatDateSince(date) {
|
||||
return formatDateSince(date, (p: VueI18n.Path, params?: VueI18n.Values) => this.$t(p, params))
|
||||
},
|
||||
formatDate(date) {
|
||||
return formatDate(date, 'PPPPpppp', this.$t('date.locale'))
|
||||
},
|
||||
formatDateShort(date) {
|
||||
return formatDate(date, 'PPpp', this.$t('date.locale'))
|
||||
},
|
||||
getNamespaceTitle(n) {
|
||||
return getNamespaceTitle(n, (p: VueI18n.Path) => this.$t(p))
|
||||
},
|
||||
getListTitle(l) {
|
||||
return getListTitle(l, (p: VueI18n.Path) => this.$t(p))
|
||||
},
|
||||
colorIsDark: colorIsDark,
|
||||
setTitle: setTitle,
|
||||
formatDateSince,
|
||||
formatDate: formatDateLong,
|
||||
formatDateShort: formatDateShort,
|
||||
getNamespaceTitle,
|
||||
getListTitle,
|
||||
colorIsDark,
|
||||
setTitle,
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
import {i18n} from '@/i18n/setup'
|
||||
import {i18n} from '@/i18n'
|
||||
|
||||
export const getErrorText = (r) => {
|
||||
|
||||
if (r.response && r.response.data) {
|
||||
if(r.response.data.code) {
|
||||
const path = `error.${r.response.data.code}`
|
||||
const message = i18n.t(path)
|
||||
const message = i18n.global.t(path)
|
||||
|
||||
// If message and path are equal no translation exists for that error code
|
||||
if (path !== message) {
|
||||
@ -30,7 +30,7 @@ export const getErrorText = (r) => {
|
||||
export function error(e, context, actions = []) {
|
||||
context.$notify({
|
||||
type: 'error',
|
||||
title: i18n.t('error.error'),
|
||||
title: i18n.global.t('error.error'),
|
||||
text: getErrorText(e),
|
||||
actions: actions,
|
||||
})
|
||||
@ -40,7 +40,7 @@ export function error(e, context, actions = []) {
|
||||
export function success(e, context, actions = []) {
|
||||
context.$notify({
|
||||
type: 'success',
|
||||
title: i18n.t('error.success'),
|
||||
title: i18n.global.t('error.success'),
|
||||
text: getErrorText(e),
|
||||
data: {
|
||||
actions: actions,
|
||||
|
@ -381,22 +381,22 @@
|
||||
|
||||
<!-- Created / Updated [by] -->
|
||||
<p class="created">
|
||||
<i18n path="task.detail.created">
|
||||
<i18n-t keypath="task.detail.created">
|
||||
<span v-tooltip="formatDate(task.created)">{{ formatDateSince(task.created) }}</span>
|
||||
{{ task.createdBy.getDisplayName() }}
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
<template v-if="+new Date(task.created) !== +new Date(task.updated)">
|
||||
<br/>
|
||||
<!-- Computed properties to show the actual date every time it gets updated -->
|
||||
<i18n path="task.detail.updated">
|
||||
<i18n-t keypath="task.detail.updated">
|
||||
<span v-tooltip="updatedFormatted">{{ updatedSince }}</span>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
</template>
|
||||
<template v-if="task.done">
|
||||
<br/>
|
||||
<i18n path="task.detail.doneAt">
|
||||
<i18n-t keypath="task.detail.doneAt">
|
||||
<span v-tooltip="doneFormatted">{{ doneSince }}</span>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
</template>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -201,7 +201,7 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
const err = getErrorText(e, p => this.$t(p))
|
||||
const err = getErrorText(e)
|
||||
if (typeof err[1] !== 'undefined') {
|
||||
this.$store.commit(ERROR_MESSAGE, err[1])
|
||||
return
|
||||
|
@ -66,7 +66,7 @@ export default {
|
||||
this.$router.push({name: 'home'})
|
||||
})
|
||||
.catch(e => {
|
||||
const err = getErrorText(e, p => this.$t(p))
|
||||
const err = getErrorText(e)
|
||||
if (typeof err[1] !== 'undefined') {
|
||||
this.$store.commit(ERROR_MESSAGE, err[1])
|
||||
return
|
||||
|
@ -300,7 +300,7 @@ import TotpService from '../../services/totp'
|
||||
import UserSettingsService from '../../services/userSettings'
|
||||
import UserSettingsModel from '../../models/userSettings'
|
||||
import {playSoundWhenDoneKey} from '@/helpers/playPop'
|
||||
import {availableLanguages, saveLanguage, getCurrentLanguage} from '../../i18n/setup'
|
||||
import {availableLanguages, saveLanguage, getCurrentLanguage} from '@/i18n'
|
||||
import {getQuickAddMagicMode, setQuickAddMagicMode} from '../../helpers/quickAddMagicMode'
|
||||
import {PrefixMode} from '../../modules/parseTaskText'
|
||||
|
||||
|
Reference in New Issue
Block a user