From 4b21f934046afcbb7ad55fe0c2bf5cb609c5e789 Mon Sep 17 00:00:00 2001
From: Henrik Askjer <henrik.askjer@uib.no>
Date: Wed, 1 Sep 2021 13:59:54 +0200
Subject: [PATCH] Reimplement get_articles and enable axios cache

---
 package-lock.json                 | 84 +++++++++++++++++++++++++++++--
 package.json                      |  1 +
 src/components/Autocomplete.vue   | 19 +++----
 src/components/DictionaryView.vue | 22 ++++++--
 4 files changed, 108 insertions(+), 18 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 859b1397..4710a532 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,7 @@
         "@fortawesome/free-solid-svg-icons": "^5.15.3",
         "@fortawesome/vue-fontawesome": "^2.0.2",
         "axios": "^0.21.1",
+        "axios-cache-adapter": "^2.7.3",
         "core-js": "~3.6.5",
         "debounce": "^1.2.1",
         "inflection-table": "https://git.app.uib.no/api/v4/projects/16442/jobs/artifacts/0.2.25/raw/module.tar.gz?job=publish",
@@ -3389,6 +3390,18 @@
         "follow-redirects": "^1.10.0"
       }
     },
+    "node_modules/axios-cache-adapter": {
+      "version": "2.7.3",
+      "resolved": "https://registry.npmjs.org/axios-cache-adapter/-/axios-cache-adapter-2.7.3.tgz",
+      "integrity": "sha512-A+ZKJ9lhpjthOEp4Z3QR/a9xC4du1ALaAsejgRGrH9ef6kSDxdFrhRpulqsh9khsEnwXxGfgpUuDp1YXMNMEiQ==",
+      "dependencies": {
+        "cache-control-esm": "1.0.0",
+        "md5": "^2.2.1"
+      },
+      "peerDependencies": {
+        "axios": "~0.21.1"
+      }
+    },
     "node_modules/axios/node_modules/follow-redirects": {
       "version": "1.14.1",
       "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
@@ -3987,6 +4000,11 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/cache-control-esm": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/cache-control-esm/-/cache-control-esm-1.0.0.tgz",
+      "integrity": "sha512-Fa3UV4+eIk4EOih8FTV6EEsVKO0W5XWtNs6FC3InTfVz+EjurjPfDXY5wZDo/lxjDxg5RjNcurLyxEJBcEUx9g=="
+    },
     "node_modules/cache-loader": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-4.1.0.tgz",
@@ -4147,6 +4165,14 @@
       "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
       "dev": true
     },
+    "node_modules/charenc": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
+      "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=",
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/check-types": {
       "version": "8.0.3",
       "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz",
@@ -5119,6 +5145,14 @@
         "semver": "bin/semver"
       }
     },
+    "node_modules/crypt": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
+      "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=",
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/crypto-browserify": {
       "version": "3.12.0",
       "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
@@ -8568,8 +8602,7 @@
     "node_modules/is-buffer": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
-      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
-      "dev": true
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
     },
     "node_modules/is-callable": {
       "version": "1.2.3",
@@ -9416,6 +9449,16 @@
       "integrity": "sha512-wRJtOo1v1ch+gN8PRsj0IGJznk+kQ8mz13ds/nuhLI+Qyf/931ZlRpd92oq0IRPpZIb+bhX8pRjzIVdcPDKmiQ==",
       "dev": true
     },
+    "node_modules/md5": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
+      "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
+      "dependencies": {
+        "charenc": "0.0.2",
+        "crypt": "0.0.2",
+        "is-buffer": "~1.1.6"
+      }
+    },
     "node_modules/md5.js": {
       "version": "1.3.5",
       "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -18220,6 +18263,15 @@
         }
       }
     },
+    "axios-cache-adapter": {
+      "version": "2.7.3",
+      "resolved": "https://registry.npmjs.org/axios-cache-adapter/-/axios-cache-adapter-2.7.3.tgz",
+      "integrity": "sha512-A+ZKJ9lhpjthOEp4Z3QR/a9xC4du1ALaAsejgRGrH9ef6kSDxdFrhRpulqsh9khsEnwXxGfgpUuDp1YXMNMEiQ==",
+      "requires": {
+        "cache-control-esm": "1.0.0",
+        "md5": "^2.2.1"
+      }
+    },
     "babel-eslint": {
       "version": "10.1.0",
       "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz",
@@ -18703,6 +18755,11 @@
         "unset-value": "^1.0.0"
       }
     },
+    "cache-control-esm": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/cache-control-esm/-/cache-control-esm-1.0.0.tgz",
+      "integrity": "sha512-Fa3UV4+eIk4EOih8FTV6EEsVKO0W5XWtNs6FC3InTfVz+EjurjPfDXY5wZDo/lxjDxg5RjNcurLyxEJBcEUx9g=="
+    },
     "cache-loader": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-4.1.0.tgz",
@@ -18826,6 +18883,11 @@
       "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
       "dev": true
     },
+    "charenc": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
+      "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
+    },
     "check-types": {
       "version": "8.0.3",
       "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz",
@@ -19621,6 +19683,11 @@
         }
       }
     },
+    "crypt": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
+      "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
+    },
     "crypto-browserify": {
       "version": "3.12.0",
       "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
@@ -22356,8 +22423,7 @@
     "is-buffer": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
-      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
-      "dev": true
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
     },
     "is-callable": {
       "version": "1.2.3",
@@ -23012,6 +23078,16 @@
       "integrity": "sha512-wRJtOo1v1ch+gN8PRsj0IGJznk+kQ8mz13ds/nuhLI+Qyf/931ZlRpd92oq0IRPpZIb+bhX8pRjzIVdcPDKmiQ==",
       "dev": true
     },
+    "md5": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
+      "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
+      "requires": {
+        "charenc": "0.0.2",
+        "crypt": "0.0.2",
+        "is-buffer": "~1.1.6"
+      }
+    },
     "md5.js": {
       "version": "1.3.5",
       "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
diff --git a/package.json b/package.json
index 8e515604..9b7689c3 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
     "@fortawesome/free-solid-svg-icons": "^5.15.3",
     "@fortawesome/vue-fontawesome": "^2.0.2",
     "axios": "^0.21.1",
+    "axios-cache-adapter": "^2.7.3",
     "core-js": "~3.6.5",
     "debounce": "^1.2.1",
     "inflection-table": "https://git.app.uib.no/api/v4/projects/16442/jobs/artifacts/0.2.25/raw/module.tar.gz?job=publish",
diff --git a/src/components/Autocomplete.vue b/src/components/Autocomplete.vue
index 4218bb39..c8d7b067 100644
--- a/src/components/Autocomplete.vue
+++ b/src/components/Autocomplete.vue
@@ -36,11 +36,10 @@
 </template>
 
 <script>
-  import axios from "axios"
 
   export default {
     props: {
-      endpoint: String,
+      api: Function,
     },
     data: function() {
       return {
@@ -94,16 +93,17 @@
           }
         }
         let self = this
-        axios.get(self.endpoint + 'suggest?', { params: {q: q,
-                                                         dict: self.$parent.lang,
-                                                         n: 9}} )
-            .then(
-                  function(response) {
+        self.api.get('suggest?', {params: {q: q, dict: self.$parent.lang, n: 9}})
+            .then((response) => {
                         if (self.$refs.autocomplete.searchInput == q & self.suggesting) {
 
                           let hits = []
                           response.data.forEach((item, i) => {
-                            let hit = {q: q, match: item[0], label: item[0], article_promise: self.get_articles(item[0])}
+                            let match = item[0]
+                            let hit = {q: q, match: match, label: match}
+
+                            hit.article_promise = self.get_articles(match)
+                            
                             hit.lang = item[1]
                             hits.push(hit)
 
@@ -118,9 +118,10 @@
       },
       get_articles(match) {
           let self = this
-          return axios.get(self.endpoint + 'articles?', {params: {lord: match, dict: self.$parent.lang}})
+          return self.api.get('articles?', {params: {lord: match, dict: self.$parent.lang}})
       },
       submit(item) {
+          
           this.$emit('submit', item)
           let self = this
 
diff --git a/src/components/DictionaryView.vue b/src/components/DictionaryView.vue
index 91fbd67b..24de9672 100644
--- a/src/components/DictionaryView.vue
+++ b/src/components/DictionaryView.vue
@@ -29,7 +29,7 @@
           </v-radio>
         </v-radio-group>
       </div>
-      <Autocomplete @submit="select_result" :endpoint="oda_endpoint">
+      <Autocomplete @submit="select_result" :api="get_oda_api">
       </Autocomplete>
     </div>
     <div id="spinner" v-if="waiting">
@@ -73,8 +73,20 @@ import Article from './Article.vue'
 import SearchResults from './SearchResults.vue'
 import Autocomplete from './Autocomplete.vue'
 
+import { setup } from 'axios-cache-adapter'
+
+const oda_api = setup({
+  baseURL: 'https://oda.uib.no/opal-api/',
+  cache: {
+    maxAge: 15 * 60 * 1000,
+    exclude: {
+      query: false
+    }
+  }
+})
+
+
 var api_endpoint = process.env.VUE_APP_API_PREFIX + '/api/dict'
-const oda_endpoint = 'https://oda.uib.no/opal-api/'
 
 function compare_by_hgno(lemma_text) {
   return function(art1, art2) {
@@ -190,9 +202,9 @@ export default {
     api_pref: function() {
       return api_endpoint + '/' + this.lang + '/article/'
     },
-    oda_endpoint: function() {
-      return oda_endpoint
-    }
+    get_oda_api: function() {
+      return oda_api
+    },
   },
   components: {
     Article,
-- 
GitLab