Browse Source

fix: i18n client caching

Nick 5 years ago
parent
commit
d74683b5fd

+ 32 - 7
client/components/admin/admin-utilities-content.vue

@@ -3,11 +3,30 @@
     v-toolbar(flat, color='primary', dark, dense)
       .subheading {{ $t('admin:utilities.contentTitle') }}
     v-card-text
-      v-subheader.pl-0.primary--text Migrate all pages to base language
+      v-subheader.pl-0.primary--text Migrate all pages to target locale
       .body-1 If you created content before selecting a different locale and activating the namespacing capabilities, you may want to transfer all content to the base locale.
       .body-1.red--text: strong This operation is destructive and cannot be reversed! Make sure you have proper backups!
-      .body-1.mt-3 Based on your current configuration, all pages will be migrated to the locale #[v-chip(label, small): strong {{currentLocale.toUpperCase()}}]
-      .body-1.mt-3 Pages that are already in the target locale will not be touched. If a page already exists at the target, the source page will not be modified as it would create a conflict. If you want to overwrite the target content, you must first delete that page.
+      v-toolbar.radius-7.mt-3.wiki-form(flat, color='grey lighten-4', height='80')
+        v-select(
+          label='Source Locale'
+          outline
+          hide-details
+          :items='locales'
+          item-text='name'
+          item-value='code'
+          v-model='sourceLocale'
+        )
+        v-icon.mx-3(large) arrow_forward
+        v-select(
+          label='Target Locale'
+          outline
+          hide-details
+          :items='locales'
+          item-text='name'
+          item-value='code'
+          v-model='targetLocale'
+        )
+      .body-1.mt-3 Pages that are already in the target locale will not be touched. If a page already exists at the target, the source page will not be modified as it would create a conflict. If you want to overwrite the target page, you must first delete it.
       v-btn(outline, color='primary', @click='migrateToLocale', :disabled='loading').ml-0.mt-3
         v-icon(left) build
         span Proceed
@@ -17,17 +36,22 @@
 import _ from 'lodash'
 import utilityContentMigrateLocaleMutation from 'gql/admin/utilities/utilities-mutation-content-migratelocale.gql'
 
-/* global siteLang */
+/* global siteLangs, siteConfig */
 
 export default {
   data: () => {
     return {
-      loading: false
+      loading: false,
+      sourceLocale: '',
+      targetLocale: ''
     }
   },
   computed: {
-    currentLocale() {
+    currentLocale () {
       return siteConfig.lang
+    },
+    locales () {
+      return siteLangs
     }
   },
   methods: {
@@ -39,7 +63,8 @@ export default {
         const respRaw = await this.$apollo.mutate({
           mutation: utilityContentMigrateLocaleMutation,
           variables: {
-            targetLocale: siteConfig.lang
+            sourceLocale: this.sourceLocale,
+            targetLocale: this.targetLocale
           }
         })
         const resp = _.get(respRaw, 'data.pages.migrateToLocale.responseResult', {})

+ 2 - 2
client/graph/admin/utilities/utilities-mutation-content-migratelocale.gql

@@ -1,6 +1,6 @@
-mutation {
+mutation($sourceLocale: String!, $targetLocale: String!) {
   pages {
-    migrateToLocale {
+    migrateToLocale(sourceLocale: $sourceLocale, targetLocale: $targetLocale) {
       responseResult {
         succeeded
         errorCode

+ 35 - 28
client/modules/localization.js

@@ -1,6 +1,7 @@
 import i18next from 'i18next'
+import Backend from 'i18next-chained-backend'
+import LocalStorageBackend from 'i18next-localstorage-backend'
 import i18nextXHR from 'i18next-xhr-backend'
-import i18nextCache from 'i18next-localstorage-cache'
 import VueI18Next from '@panter/vue-i18next'
 import _ from 'lodash'
 
@@ -12,37 +13,43 @@ export default {
   VueI18Next,
   init() {
     i18next
-      .use(i18nextXHR)
-      .use(i18nextCache)
+      .use(Backend)
       .init({
         backend: {
-          loadPath: '{{lng}}/{{ns}}',
-          parse: (data) => data,
-          ajax: (url, opts, cb, data) => {
-            let langParams = url.split('/')
-            graphQL.query({
-              query: localeQuery,
-              variables: {
-                locale: langParams[0],
-                namespace: langParams[1]
-              }
-            }).then(resp => {
-              let ns = {}
-              if (_.get(resp, 'data.localization.translations', []).length > 0) {
-                resp.data.localization.translations.forEach(entry => {
-                  _.set(ns, entry.key, entry.value)
+          backends: [
+            LocalStorageBackend,
+            i18nextXHR
+          ],
+          backendOptions: [
+            {
+              expirationTime: 1000*60*60*24 // 24h
+            },
+            {
+              loadPath: '{{lng}}/{{ns}}',
+              parse: (data) => data,
+              ajax: (url, opts, cb, data) => {
+                let langParams = url.split('/')
+                graphQL.query({
+                  query: localeQuery,
+                  variables: {
+                    locale: langParams[0],
+                    namespace: langParams[1]
+                  }
+                }).then(resp => {
+                  let ns = {}
+                  if (_.get(resp, 'data.localization.translations', []).length > 0) {
+                    resp.data.localization.translations.forEach(entry => {
+                      _.set(ns, entry.key, entry.value)
+                    })
+                  }
+                  return cb(ns, {status: '200'})
+                }).catch(err => {
+                  console.error(err)
+                  return cb(null, {status: '404'})
                 })
               }
-              return cb(ns, {status: '200'})
-            }).catch(err => {
-              console.error(err)
-              return cb(null, {status: '404'})
-            })
-          }
-        },
-        cache: {
-          enabled: true,
-          expiration: 60 * 60 * 1000
+            }
+          ]
         },
         defaultNS: 'common',
         lng: siteConfig.lang,

+ 2 - 1
package.json

@@ -79,7 +79,6 @@
     "highlight.js": "9.15.8",
     "i18next": "17.0.4",
     "i18next-express-middleware": "1.8.0",
-    "i18next-localstorage-cache": "1.1.1",
     "i18next-node-fs-backend": "2.1.3",
     "image-size": "0.7.4",
     "js-base64": "2.5.1",
@@ -231,6 +230,8 @@
     "hammerjs": "2.0.8",
     "html-webpack-plugin": "3.2.0",
     "html-webpack-pug-plugin": "2.0.0",
+    "i18next-chained-backend": "2.0.0",
+    "i18next-localstorage-backend": "3.0.0",
     "i18next-xhr-backend": "3.0.0",
     "ignore-loader": "0.1.2",
     "js-cookie": "2.2.0",

+ 4 - 1
server/graph/schemas/page.graphql

@@ -74,7 +74,10 @@ type PageMutation {
 
   flushCache: DefaultResponse @auth(requires: ["manage:system"])
 
-  migrateToLocale: DefaultResponse @auth(requires: ["manage:system"])
+  migrateToLocale(
+    sourceLocale: String!
+    targetLocale: String!
+  ): DefaultResponse @auth(requires: ["manage:system"])
 }
 
 # -----------------------------------------------

+ 13 - 4
yarn.lock

@@ -7056,6 +7056,13 @@ hyphenate-style-name@^1.0.2:
   resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz#097bb7fa0b8f1a9cf0bd5c734cf95899981a9b48"
   integrity sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ==
 
+i18next-chained-backend@2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/i18next-chained-backend/-/i18next-chained-backend-2.0.0.tgz#faf2e8b5f081a01e74fbec1fe580c184bc64e25b"
+  integrity sha512-NAwfxzNUojtYc3nTCFIyNUYsxT+RFpfWc75dHbv7BsYxfbpKV1NISiFGU77D4u0wtq5IqM87YSINX/2miH9qvg==
+  dependencies:
+    "@babel/runtime" "^7.4.5"
+
 i18next-express-middleware@1.8.0:
   version "1.8.0"
   resolved "https://registry.yarnpkg.com/i18next-express-middleware/-/i18next-express-middleware-1.8.0.tgz#8ef73a56036b404b162d81d4aec23cfa0ab2a609"
@@ -7063,10 +7070,12 @@ i18next-express-middleware@1.8.0:
   dependencies:
     cookies "0.7.1"
 
-i18next-localstorage-cache@1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/i18next-localstorage-cache/-/i18next-localstorage-cache-1.1.1.tgz#575256cc35e8cb2d88148f754766fdd2d24bb1b7"
-  integrity sha1-V1JWzDXoyy2IFI91R2b90tJLsbc=
+i18next-localstorage-backend@3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/i18next-localstorage-backend/-/i18next-localstorage-backend-3.0.0.tgz#19b4e836e9a79e564631b88b8ba1c738375e636f"
+  integrity sha512-jOvnvVYP7VlA87aO0wgNeXRoj/vQHqO56UB/R6DlglWn/Ipz4rNGZUyzejJVLFaypZTZ6rpqNsB/pjSVtZm4YQ==
+  dependencies:
+    "@babel/runtime" "^7.4.5"
 
 i18next-node-fs-backend@2.1.3:
   version "2.1.3"