diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8012987c5..ab57f6b5b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -426,14 +426,14 @@ jobs: - name: Load Docker Image run: docker load < /tmp/admin.tar ########################################################################## - # UNIT TESTS FRONTEND #################################################### + # UNIT TESTS ADMIN INTERFACE ############################################# ########################################################################## - name: Admin Interface | Unit tests run: | docker run -v ~/coverage:/app/coverage --rm gradido/admin:test yarn run test cp -r ~/coverage ./coverage ########################################################################## - # COVERAGE CHECK ADMIN INTERFACE########################################## + # COVERAGE CHECK ADMIN INTERFACE ######################################### ########################################################################## - name: Admin Interface | Coverage check uses: webcraftmedia/coverage-check-action@master @@ -441,7 +441,7 @@ jobs: report_name: Coverage Admin Interface type: lcov result_path: ./coverage/lcov.info - min_coverage: 82 + min_coverage: 65 token: ${{ github.token }} ############################################################################## diff --git a/admin/babel.config.js b/admin/babel.config.js index 5907ab074..80b148fd1 100644 --- a/admin/babel.config.js +++ b/admin/babel.config.js @@ -1,11 +1,4 @@ module.exports = { presets: ['@babel/preset-env'], - plugins: [ - [ - 'component', - { - styleLibraryName: 'theme-chalk', - }, - ], - ], + plugins: ['transform-require-context'], } diff --git a/admin/package.json b/admin/package.json index d70a077d8..2b4e33c91 100644 --- a/admin/package.json +++ b/admin/package.json @@ -36,6 +36,7 @@ "stats-webpack-plugin": "^0.7.0", "vue": "^2.6.11", "vue-apollo": "^3.0.8", + "vue-i18n": "^8.26.5", "vue-jest": "^3.0.7", "vue-router": "^3.5.3", "vuex": "^3.6.2" @@ -46,6 +47,7 @@ "@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-service": "~4.5.0", "babel-eslint": "^10.1.0", + "babel-plugin-transform-require-context": "^0.1.1", "eslint": "7.25.0", "eslint-config-prettier": "^8.3.0", "eslint-config-standard": "^16.0.3", diff --git a/admin/src/i18n.js b/admin/src/i18n.js new file mode 100644 index 000000000..7ccfec4c9 --- /dev/null +++ b/admin/src/i18n.js @@ -0,0 +1,89 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' + +Vue.use(VueI18n) + +const 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 +} + +const numberFormats = { + en: { + decimal: { + style: 'decimal', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }, + ungroupedDecimal: { + style: 'decimal', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + useGrouping: false, + }, + }, + de: { + decimal: { + style: 'decimal', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }, + ungroupedDecimal: { + style: 'decimal', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + useGrouping: false, + }, + }, +} + +const dateTimeFormats = { + en: { + short: { + year: 'numeric', + month: 'numeric', + day: 'numeric', + }, + long: { + year: 'numeric', + month: 'short', + day: 'numeric', + weekday: 'short', + hour: 'numeric', + minute: 'numeric', + }, + }, + de: { + short: { + day: 'numeric', + month: 'numeric', + year: 'numeric', + }, + long: { + day: 'numeric', + month: 'short', + year: 'numeric', + weekday: 'short', + hour: 'numeric', + minute: 'numeric', + }, + }, +} + +const i18n = new VueI18n({ + locale: 'en', + fallbackLocale: 'en', + messages: loadLocaleMessages(), + numberFormats, + dateTimeFormats, +}) + +export default i18n diff --git a/admin/src/locales/de.json b/admin/src/locales/de.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/admin/src/locales/de.json @@ -0,0 +1 @@ +{} diff --git a/admin/src/locales/en.json b/admin/src/locales/en.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/admin/src/locales/en.json @@ -0,0 +1 @@ +{} diff --git a/admin/src/main.js b/admin/src/main.js index 55d2101ab..61f65129e 100644 --- a/admin/src/main.js +++ b/admin/src/main.js @@ -6,6 +6,8 @@ import store from './store/store' import router from './router/router' import addNavigationGuards from './router/guards' +import i18n from './i18n' + import { ApolloClient, ApolloLink, InMemoryCache, HttpLink } from 'apollo-boost' import VueApollo from 'vue-apollo' @@ -52,6 +54,7 @@ addNavigationGuards(router, store) new Vue({ router, store, + i18n, apolloProvider, render: (h) => h(App), }).$mount('#app') diff --git a/admin/src/main.test.js b/admin/src/main.test.js index 198716ea8..27c8898ab 100644 --- a/admin/src/main.test.js +++ b/admin/src/main.test.js @@ -4,9 +4,11 @@ import CONFIG from './config' import Vue from 'vue' import Vuex from 'vuex' +import VueI18n from 'vue-i18n' jest.mock('vue') jest.mock('vuex') +jest.mock('vue-i18n') const storeMock = jest.fn() Vuex.Store = storeMock @@ -44,6 +46,10 @@ describe('main', () => { expect(Vue).toBeCalled() }) + it('calls VueI18n', () => { + expect(VueI18n).toBeCalled() + }) + it.skip('creates a store', () => { expect(storeMock).toBeCalled() }) diff --git a/admin/yarn.lock b/admin/yarn.lock index 04e838ec9..59a49674d 100644 --- a/admin/yarn.lock +++ b/admin/yarn.lock @@ -932,7 +932,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.0.0", "@babel/template@^7.15.4", "@babel/template@^7.3.3", "@babel/template@^7.4.0": +"@babel/template@7", "@babel/template@^7.0.0", "@babel/template@^7.15.4", "@babel/template@^7.3.3", "@babel/template@^7.4.0": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg== @@ -3343,6 +3343,13 @@ babel-plugin-transform-regenerator@^6.22.0: dependencies: regenerator-transform "^0.10.0" +babel-plugin-transform-require-context@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-require-context/-/babel-plugin-transform-require-context-0.1.1.tgz#319b545ca83080b5062776b46cc9b8b346fea9a6" + integrity sha512-4ceqYOtzgmq4/QsB8dP7pUrUOCjY/jrRYdt7YkIOWHxtGDQbcf6YZDyLCiPQf6KsEIcIbSQiTRXOsbLiuJfgNQ== + dependencies: + "@babel/template" "7" + babel-plugin-transform-strict-mode@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" @@ -12420,6 +12427,11 @@ vue-hot-reload-api@^2.3.0: resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2" integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog== +vue-i18n@^8.26.5: + version "8.26.5" + resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-8.26.5.tgz#b61e994e7ae83564c6aebd004543156bbdc7c7e9" + integrity sha512-qYqfsFd8v2QFSLDAabqXXXpwjGvkuqJtTWqRpZPXpAFO6PArGH4A9vSplnA0HLmnB8km7OB5ZSdP8lkkX0rLew== + vue-jest@^3.0.5, vue-jest@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/vue-jest/-/vue-jest-3.0.7.tgz#a6d29758a5cb4d750f5d1242212be39be4296a33"