feat: use vue-i18n 9 for vue3

This commit is contained in:
Dominik Pschenitschni 2021-08-20 15:38:16 +02:00
parent 3d6aca3510
commit 7c3c2945f8
Signed by: dpschen
GPG Key ID: B257AC0149F43A77
19 changed files with 123 additions and 71 deletions

View File

@ -33,7 +33,7 @@
"vue-drag-resize": "1.5.4",
"vue-easymde": "1.4.0",
"vue-flatpickr-component": "9.0.4",
"vue-i18n": "8.26.3",
"vue-i18n": "9.2.0-beta.6",
"vue-router": "4.0.11",
"vue-shortkey": "3.1.7",
"vuedraggable": "2.24.3",

View File

@ -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({

View File

@ -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: {

View File

@ -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.

View File

@ -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>

View File

@ -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: {

View File

@ -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>

View File

@ -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>

View File

@ -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
}

View File

@ -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
}

View File

@ -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})
}

View File

@ -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,
},

View File

@ -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,
},
})

View File

@ -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,

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -1060,6 +1060,44 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf"
integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==
"@intlify/core-base@9.2.0-beta.6":
version "9.2.0-beta.6"
resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.2.0-beta.6.tgz#84a219277de66942bcea42cc6bca8b41c1a76414"
integrity sha512-sT/wE3erC/xRPEC1AYWBPfISHTEmtHDiILaBKk2EYL0pEP5Uo1XO7NUGcAuDrEpZTV7q7L1lbmm904YlGqSmxw==
dependencies:
"@intlify/devtools-if" "9.2.0-beta.6"
"@intlify/message-compiler" "9.2.0-beta.6"
"@intlify/shared" "9.2.0-beta.6"
"@intlify/vue-devtools" "9.2.0-beta.6"
"@intlify/devtools-if@9.2.0-beta.6":
version "9.2.0-beta.6"
resolved "https://registry.yarnpkg.com/@intlify/devtools-if/-/devtools-if-9.2.0-beta.6.tgz#ce080281c8c4e1366c13dbd12e0b1de979ec495f"
integrity sha512-1pkz5T2F4OyT6NK37RJiK+eebI07TaQRR4ZZRhN2Pal8j8c5Og2EVPomPCcoQAuxydLXxVro85NWdL8XQEanNA==
dependencies:
"@intlify/shared" "9.2.0-beta.6"
"@intlify/message-compiler@9.2.0-beta.6":
version "9.2.0-beta.6"
resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.2.0-beta.6.tgz#4680ccd32dfaf9fd99aecefb530dc26584acb887"
integrity sha512-xln6CEf7ZoEcwvu6vziQBUVOASByDtfnPIgq7ACsLLfFoYf4NPnZjGqdpWwt72PzxxI0UfrQygeQ/xoXYtDE6A==
dependencies:
"@intlify/shared" "9.2.0-beta.6"
source-map "0.6.1"
"@intlify/shared@9.2.0-beta.6":
version "9.2.0-beta.6"
resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.2.0-beta.6.tgz#4fcb148ae936dc3ca036a022f3307fd431cb17a5"
integrity sha512-k7EVVvIx7xi9LqnlGCT0sxCDILdWSmq9Y/5Rctd5Qup6D/BVLwpUYnkbuysBr0UV+wxI45w1bkasj4XDXSHYqg==
"@intlify/vue-devtools@9.2.0-beta.6":
version "9.2.0-beta.6"
resolved "https://registry.yarnpkg.com/@intlify/vue-devtools/-/vue-devtools-9.2.0-beta.6.tgz#187c5bc8a160bf4102e37b8db40f36d20656c87a"
integrity sha512-4BnlzDziBO9j4JxQO/1vjaBUIPiLXxB99CM87lBDKqa224K84kUFCT4Ez2hDvwdYQbej145rfzqxyGrL2MMELQ==
dependencies:
"@intlify/core-base" "9.2.0-beta.6"
"@intlify/shared" "9.2.0-beta.6"
"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
@ -1790,6 +1828,11 @@
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.0.0-beta.15.tgz#ad7cb384e062f165bcf9c83732125bffbc2ad83d"
integrity sha512-quBx4Jjpexo6KDiNUGFr/zF/2A4srKM9S9v2uHgMXSU//hjgq1eGzqkIFql8T9gfX5ZaVOUzYBP3jIdIR3PKIA==
"@vue/devtools-api@^6.0.0-beta.13":
version "6.0.0-beta.17"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.0.0-beta.17.tgz#d4b9eb02c670d39a4532f4bb3c8517abce3fcb82"
integrity sha512-hwGY4Xxc2nl34OyNH7l2VO8/ja3R78B8bcbaBQnZljSju5Z0Bm9HTt+/fQao+TUrs3gfNrrQrY3euWqiaG8chw==
"@vue/eslint-config-typescript@7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@vue/eslint-config-typescript/-/eslint-config-typescript-7.0.0.tgz#220c70c2edf7a253e739298525f4d401b8ef0038"
@ -6194,16 +6237,16 @@ source-map-url@^0.4.0:
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.5.0:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.7.3, source-map@~0.7.2:
version "0.7.3"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
@ -6908,10 +6951,15 @@ vue-flatpickr-component@9.0.4:
dependencies:
flatpickr "^4.6.9"
vue-i18n@8.26.3:
version "8.26.3"
resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-8.26.3.tgz#2609b66961df3c2d348ec606a059426a99c1710e"
integrity sha512-VQPG9bSoksimmETzaNvGa33waGr28cghvUBq8p1nT0volQcMR8Y3do08TY+MGmI1B/iokSdSPnxxj8nNxAS0Jw==
vue-i18n@9.2.0-beta.6:
version "9.2.0-beta.6"
resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-9.2.0-beta.6.tgz#c71f6538b43f66619ad33e7e1297bc5c97c1b6ff"
integrity sha512-NrtdgqI+BVgxYaOjMnIxJJgKpwMPmKakHCDyPR59DXALb6oorsOVEb/wKtqI4nBJv1nWXtqoGxUF8O8yZ/tZ4g==
dependencies:
"@intlify/core-base" "9.2.0-beta.6"
"@intlify/shared" "9.2.0-beta.6"
"@intlify/vue-devtools" "9.2.0-beta.6"
"@vue/devtools-api" "^6.0.0-beta.13"
vue-notification@1.3.20:
version "1.3.20"