From 93bda14a25a4fd971cdf660deefe4975dd2da779 Mon Sep 17 00:00:00 2001
From: "Henrik.Askjer" <henrik.askjer@uib.no>
Date: Mon, 30 Aug 2021 11:47:20 +0200
Subject: [PATCH] Replace suggestion api

---
 src/components/Autocomplete.vue   | 104 ++++++++++++++++++------------
 src/components/DictionaryView.vue |  12 +++-
 2 files changed, 71 insertions(+), 45 deletions(-)

diff --git a/src/components/Autocomplete.vue b/src/components/Autocomplete.vue
index 300ec15a..4140eb89 100644
--- a/src/components/Autocomplete.vue
+++ b/src/components/Autocomplete.vue
@@ -26,7 +26,10 @@
         :dense="$vuetify.breakpoint.smAndDown"
       >
       <template v-slot:item="data">
-      <span class="search-hit">{{data.item.label}} </span> ({{data.item.lang_set ? Array.from(data.item.lang_set).sort().join(', ') : 'fritekstsøk'}})
+      <span class="search-hit">
+        {{data.item.label}} 
+      </span> 
+      ({{data.item.lang? data.item.lang[1] ? "bm, nn" : {"bob": "bm", "nob": "nn"}[data.item.lang[0]] : 'fritekstsøk'}})
       </template>
     </v-combobox>
   </div>
@@ -49,44 +52,26 @@
         suggesting: null,
         debounced: debounce(function(q, self) {
           self.loading = true
-          return axios.get(self.endpoint + 'suggest?q=' + encodeURIComponent(q))
+          return axios.get(self.endpoint + 'suggest?', { params: {q: q,
+                                                                  dict: self.$parent.lang,
+                                                                  n: 9}} )
                       .then(
                             function(response) {
-                                if (self.suggesting) {
-                                  let hits = []
-                                  if (q == self.$refs.autocomplete.searchInput)  {
+                                  if (self.$refs.autocomplete.searchInput == q & self.suggesting) {
+
+                                    let hits = []
                                     response.data.forEach((item, i) => {
-                                      let match = encodeURIComponent(item.match)
+                                      let hit = {q: q, match: item[0], label: item[0], articles: []}
+                                      hit.lang = item[1]
+                                      hits.push(hit)
 
-                                      if (! hits[0] || hits[0].word != match) {
-                                        hits.splice(0, 0, {q: encodeURIComponent(q), lang_set: new Set(), word: match, articles: []})
-                                      }
-                                      hits[0].lang_set.add(item.dictionary == 'bob' ? 'bm' : 'nn')
-                                      hits[0].articles.push(item)
-                                    });
-                                    hits.forEach(function (hit) {
-                                      if (hit.lang_set) {
-                                        hit.label = decodeURIComponent(hit.word)
-                                      }
                                     });
-                                    hits.reverse()
-                                    hits = hits.slice(0, 9)
-
-                                    hits.sort( (h1, h2) => {
-                                    let val1 = h1.label.length * 10 + (h1.label[0].toLowerCase() === h1.label[0] ? 0 : 1)
-                                    let val2 = h2.label.length * 10 + (h2.label[0].toLowerCase() === h2.label[0] ? 0 : 1)
-                                    return val1 - val2
-                                    
-                                  })
-                                  let currentSearch = self.$refs.autocomplete.searchInput
-                                  if (q == currentSearch) {
+                                    // whitespace necessary because duplicates aren't allowed in the dropdown
+                                    hits.push({q: q, label: q + ' '}) 
                                     self.items = hits
                                   }
-                                  self.items.push({currentSearch: encodeURIComponent(currentSearch), label: currentSearch + ' '})
-                                  
-                                  }
-                                }
-                                self.loading = false
+
+                                self.loading = false                          
                               })
         }, 100)
       }
@@ -101,24 +86,59 @@
       },
       select(item) {
         if (item) {
-          if (typeof item === 'string') {
-            item = {"q": encodeURIComponent(item)}
-          }
-          this.items = []
-          this.suggesting = false
+          if (typeof item != 'string') {
+            let self = this
+            if (item.articles) {
+            axios.get(self.endpoint + 'articles?', {params: {lord: item.match,
+                                                             dict: self.$parent.lang}})
+              .then(
+                function(response) {
+                    ['bob', 'nob'].forEach((dict_tag) => {
+                      response.data[dict_tag].forEach((article_id) => {
+                        let article = {}
+                        article.article_id = article_id
+                        article.dictionary = dict_tag
+                        article.match = item.match
+                        item.articles.push(article)
+                        })
+                      })
+                    }
+                  )
+              }
+              this.items = []
+              this.suggesting = false
+
+              self.$emit('submit', item)
 
-          this.$emit('submit', item)
-          let self = this
-          setTimeout(() => self.$refs.autocomplete.$refs.input.select(), 1)
+              setTimeout(() => {
+                self.$refs.autocomplete.$refs.input.select()
+                this.items = []
+                this.suggesting = false
+                }, 1)
+            
+          }
+          // If blurred
+          else {
+            this.items = []
+          }
         }
       }
     },
     methods: {
       run_query(q) {
-        this.items = []
         this.suggesting = true
+        // Put full text search in the list while processing suggestions
+        if (this.items[0]) {
+          if (this.items[0].lang) {
+          this.items.unshift({q: q, label: q})
+        }
+          else {
+            this.items[0] = {q: q, label: q}
+          }
+        }
         this.debounced(q, this)
-      }
+      },
+
     },
   }
 </script>
diff --git a/src/components/DictionaryView.vue b/src/components/DictionaryView.vue
index a4509ad4..6182d3b0 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="api_pref">
+      <Autocomplete @submit="select_result" :endpoint="oda_endpoint">
       </Autocomplete>
     </div>
     <div id="spinner" v-if="waiting">
@@ -74,6 +74,7 @@ import SearchResults from './SearchResults.vue'
 import Autocomplete from './Autocomplete.vue'
 
 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) {
@@ -188,6 +189,9 @@ export default {
     },
     api_pref: function() {
       return api_endpoint + '/' + this.lang + '/article/'
+    },
+    oda_endpoint: function() {
+      return oda_endpoint
     }
   },
   components: {
@@ -199,12 +203,14 @@ export default {
     select_result: function(event) {
       this.event = event
       if(event.articles){
-        let source = '/' + this.lang + '/w/' + event.word
+        let source = '/' + this.lang + '/w/' + event.match
         this.$router.push(source)
-        this.search_results = event.articles.sort(compare_by_hgno(decodeURIComponent(event.word))).map(a => Object.assign(a, {source: source}))
+        this.search_results = event.articles.map(a => Object.assign(a, {source: source}))
         this.article = null
         this.error = null
+        this.waiting_for_articles = true
         history.replaceState({article: this.article, search_results: this.search_results, lang: this.lang, error: this.error}, '')
+        navigate_to_word(this, event.match)
         this.$plausible.trackEvent('dropdown selection', {props: {query: event.label, match: event.match}})
       }else{
         this.waiting_for_articles = true
-- 
GitLab