From d421933e44cf0643c20eccb497ada14d1d689a86 Mon Sep 17 00:00:00 2001 From: "Henrik.Askjer" <henrik.askjer@uib.no> Date: Thu, 3 Feb 2022 13:03:36 +0000 Subject: [PATCH] Dev --- .env.dev_server | 4 +- .env.local | 4 +- .env.production | 5 +- src/components/Autocomplete.vue | 5 +- src/components/DictionaryView.vue | 216 ++++++++++++++++-------------- 5 files changed, 127 insertions(+), 107 deletions(-) diff --git a/.env.dev_server b/.env.dev_server index bc9b15ea..de9b0ec6 100644 --- a/.env.dev_server +++ b/.env.dev_server @@ -1,4 +1,4 @@ NODE_ENV=production -VUE_APP_ARTICLE_ENDPOINT='https://oda.uib.no/opal/dev/' -VUE_APP_SEARCH_ENDPOINT='https://oda.uib.no/opal/dev/api/' +VUE_APP_ENDPOINT='https://oda.uib.no/opal/dev/' +VUE_APP_FALLBACK_ENDPOINT='https://odd.uib.no/opal/dev/' VUE_APP_VERSION_LABEL=DEVELOPMENT diff --git a/.env.local b/.env.local index 53d6b6d7..a853ca78 100644 --- a/.env.local +++ b/.env.local @@ -1,4 +1,4 @@ -VUE_APP_ARTICLE_ENDPOINT='https://oda.uib.no/opal/dev/' -VUE_APP_SEARCH_ENDPOINT='https://oda.uib.no/opal/dev/api/' +VUE_APP_ENDPOINT='https://oda.uib.no/opal/dev/' +VUE_APP_FALLBACK_ENDPOINT='https://odd.uib.no/opal/dev/' VUE_APP_VERSION_LABEL=LOCAL VUE_APP_RELEASE=test diff --git a/.env.production b/.env.production index e67c7aae..8babb079 100644 --- a/.env.production +++ b/.env.production @@ -1,4 +1,5 @@ NODE_ENV=production VUE_APP_VERSION_LABEL=Beta -VUE_APP_ARTICLE_ENDPOINT='https://oda.uib.no/opal/prod/' -VUE_APP_SEARCH_ENDPOINT='https://oda.uib.no/opal/prod/api/' +VUE_APP_ENDPOINT='https://oda.uib.no/opal/prod/' +VUE_APP_FALLBACK_ENDPOINT='https://odd.uib.no/opal/prod/' + diff --git a/src/components/Autocomplete.vue b/src/components/Autocomplete.vue index 202ca88f..9145eba2 100644 --- a/src/components/Autocomplete.vue +++ b/src/components/Autocomplete.vue @@ -87,9 +87,6 @@ <script> export default { - props: { - api: Function, - }, data: function() { return { loading: false, @@ -157,7 +154,7 @@ let self = this let params = {q, dict: self.get_lang(), n: 6, dform: 'int', meta: 'n', include: "e", wc: self.$parent.pos_selected} - self.api.get('suggest?', {params}) + this.$parent.api.get('api/suggest?', {params}) .then(async (response) => { if (self.$refs.autocomplete.searchInput == q & self.suggesting) { let suggestions = [] diff --git a/src/components/DictionaryView.vue b/src/components/DictionaryView.vue index a52e3727..b2e1a204 100644 --- a/src/components/DictionaryView.vue +++ b/src/components/DictionaryView.vue @@ -2,7 +2,6 @@ <main> <div class="search_container"> <Autocomplete v-on:submit="select_result" - :api="get_search_endpoint" v-on:update-lang-form="update_lang_form"> </Autocomplete> <SearchToolbar @updatePos="update_pos" @@ -135,7 +134,7 @@ articleLookup/> </div> <div class="welcome" - v-show="$route.name=='/' || !$route.name"> + v-show="!error && ($route.name=='/' || !$route.name)"> <div class="monthly" :class="$vuetify.breakpoint.name"> <div> @@ -172,9 +171,9 @@ import SearchResults from './SearchResults.vue' import Autocomplete from './Autocomplete.vue' import SearchToolbar from './SearchToolbar.vue' -const SEARCH_ENDPOINT = process.env.VUE_APP_SEARCH_ENDPOINT -const ARTICLE_ENDPOINT= process.env.VUE_APP_ARTICLE_ENDPOINT -const api = axios.create({baseURL: SEARCH_ENDPOINT}) +const ENDPOINT = process.env.VUE_APP_ENDPOINT +const FALLBACK_ENDPOINT = process.env.VUE_APP_FALLBACK_ENDPOINT + function navigate_to_article(self, origin) { self.article = null @@ -182,14 +181,14 @@ function navigate_to_article(self, origin) { const lang = self.$route.params.lang - axios.get(ARTICLE_ENDPOINT + lang + '/article/' + self.$route.params.id + ".json") - //axios.get('https://httpstat.us/502') + self.api.get(lang + '/article/' + self.$route.params.id + ".json") + //self.api.get("https://httpstat.us/502") .then(function(response){ self.article = Object.assign(response.data, {'dictionary': lang, results: self.search_results}) self.error = null }) .catch(function(error){ - self.handle_error(error, true) + self.handle_error(error, {retry: navigate_to_article, arg: origin, article: true}) }) .then(function(response){ self.waiting_for_articles = false @@ -217,8 +216,9 @@ async function load_articles(self, query, offset, n, dict) { article_IDs = article_IDs.slice(offset, offset + n) return Promise.all(article_IDs.map((article_id) => { - return axios.get(`${ARTICLE_ENDPOINT}${dict}/article/${article_id}.json`) - //return axios.get('https://httpstat.us/502') + return self.api.get(`${dict}/article/${article_id}.json`) + //return self.api.get(`https://httpstat.us/502`) + })) .then((response) => { @@ -231,7 +231,7 @@ async function load_articles(self, query, offset, n, dict) { self.search_results[dict] = results }) .catch(error => { - self.handle_error(error) + self.handle_error(error, {}) }) } else { @@ -266,12 +266,12 @@ function navigate_to_query(self, word, keep_page) { // Get inflections if (!advanced_search) { let params = {q, dict: self.lang, dform: 'int', include: "i", meta: 'n', wc: self.pos_selected} - api.get('suggest?', {params}) - //axios.get('https://httpstat.us/502') + self.api.get('api/suggest?', {params}) + //self.api.get('https://httpstat.us/502') .then((response) => { self.inflection_suggestions = response.data.a.inflect }).catch(error =>{ - self.handle_error(error) + self.handle_error(error, {retry: navigate_to_query, arg: q}) self.replace_history() }) } @@ -283,8 +283,9 @@ function navigate_to_query(self, word, keep_page) { offset = self.perPage * (self.page -1) } if (self.pos_selected) params.wc = self.pos_selected - api.get('articles?', {params}).then((response) => { - //axios.get('https://httpstat.us/502').then((response) => { + self.api.get('api/articles?', {params}).then((response) => { + //self.api.get('https://httpstat.us/502', {params}).then((response) => { + self.article_info = response.data self.search_results = {} @@ -301,13 +302,13 @@ function navigate_to_query(self, word, keep_page) { dict = bm_length == 0? 'bm' : 'nn' } let params = {q, dict, dform: 'int', include: "s", wc: self.pos_selected} - api.get('suggest?', {params}) + self.api.get('api/suggest?', {params}) //axios.get('https://httpstat.us/502') .then((response) => { self.similar = response.data.a.similar self.replace_history() }).catch(error => { - self.handle_error(error) + self.handle_error(error, {retry: navigate_to_query, arg: q}) self.replace_history() }) } else { @@ -320,19 +321,19 @@ function navigate_to_query(self, word, keep_page) { self.no_results = true if (!self.scope.includes('f')) { let params = {q, dict, n: 1, dform: 'int', include: 'f', wc: self.pos_selected} - api.get('suggest?', {params}).then((response) => { + self.api.get('api/suggest?', {params}).then((response) => { self.suggest_fulltext = response.data.cnt > 0 }).catch(error => { - self.handle_error(error) + self.handle_error(error, {retry: navigate_to_query, arg: q}) self.replace_history() }) } if (dict != 'bm,nn') { let params = {q, n: 1, dict: dict=='bm'?'nn':'bm', dform: 'int', include: 'e', wc: self.pos_selected} - api.get('suggest?', {params}).then((response) => { + self.api.get('api/suggest?', {params}).then((response) => { self.suggest_other_dict = response.data.cnt > 0 && response.data.a.exact[0][0] == q }).catch(error => { - self.handle_error(error) + self.handle_error(error, {retry: navigate_to_query, arg: q}) self.replace_history() }) } @@ -351,7 +352,7 @@ function navigate_to_query(self, word, keep_page) { }) } }).catch(error =>{ - self.handle_error(error) + self.handle_error(error, {retry: navigate_to_query, arg: q}) self.replace_history() }) } @@ -360,6 +361,8 @@ export default { name: 'DictionaryView', data: function() { return { + api: null, + fallback: false, article_key: 0, search_results: {}, lang: this.$store.state.defaultDict, @@ -381,15 +384,11 @@ export default { selected: null, suggest_fulltext: false, suggest_other_dict: false - } }, computed: { waiting: function() { return (this.waiting_for_articles || this.waiting_for_metadata) && this.$route.name != 'root' - }, - get_search_endpoint: function() { - return api } }, metaInfo() { @@ -419,6 +418,55 @@ export default { SearchToolbar }, methods: { + load_welcome_and_metadata: function() { + let self = this + Promise.all([ + self.api.get('bm/concepts.json').then(function(response){ + let concepts = response.data.concepts + entities.bm = concepts + }), + self.api.get('nn/concepts.json').then(function(response){ + let concepts = response.data.concepts + entities.nn = concepts + }) + ]).then(function(_) { + self.waiting_for_metadata = false + if (self.$route.name == 'search') { + navigate_to_query(self, self.$route.query.q, true) + } + else if(self.$route.name == 'lookup'){ + navigate_to_article(self, self.$route.path) + } + else { + self.waiting_for_articles = false + self.replace_history() + self.load_monthly_bm() + self.load_monthly_nn() + + } + }).catch(function(error){ + if (self.fallback) { + if (error.response) { + self.error = {title: self.$t('error.server.title'), description: self.$t('error.server.description', {code: error.response.status})} + } + else if (error.message == "Network Error") { + self.error = {title: self.$t('error.network.title'), description: self.$t('error.network.description')} + } + else { + self.error = {title: self.$t('error.generic.title'), description: self.$t('error.generic.description')} + } + self.waiting_for_metadata = false + self.waiting_for_articles = false + } + else { + self.fallback = true + self.api = axios.create({baseURL: FALLBACK_ENDPOINT}) + self.load_welcome_and_metadata() + } + + }) + }, + replace_history: function() { history.replaceState({article: this.article, search_results: this.search_results, @@ -452,17 +500,17 @@ export default { }, load_monthly_bm: function() { let self = this - axios.get(ARTICLE_ENDPOINT + 'bm/article/120608.json').then(function(response){ + this.api.get('bm/article/120608.json').then(function(response){ self.monthly_bm = Object.assign(response.data, {dictionary: 'bm'}) }) }, load_monthly_nn: function() { let self = this - axios.get(ARTICLE_ENDPOINT + 'nn/article/44621.json').then(function(response){ + this.api.get('nn/article/44621.json').then(function(response){ self.monthly_nn = Object.assign(response.data, {dictionary: 'nn'}) }) }, - handle_error: function(error, article) { + handle_error: function(error, retry_params) { this.waiting_for_articles = false this.no_results = false this.search_results = {} @@ -470,31 +518,40 @@ export default { this.similar = [] this.suggest_fulltext = false this.suggest_other_dict = false - if (error.response) { - if (error.response.status == 404) { - if (article) { - this.error = {title: this.$t('error.404.title'), description: this.$t('error.no_article', {id: this.$route.params.id}), article: true} + this.api = axios.create({baseURL: FALLBACK_ENDPOINT}) + if (this.fallback || !retry_params.retry) { + this.fallback = true + if (error.response) { + if (error.response.status == 404) { + if (retry_params.article) { + this.error = {title: this.$t('error.404.title'), description: this.$t('error.no_article', {id: this.$route.params.id}), article: true} + } + else { + this.error = {title: this.$t('error.404.title'), description: this.$t('error.404.description'), article: retry_params.article} + } + } + else if (error.response.status == 503) { + this.error = {title: this.$t('error.503.title'), description: this.$t('error.503.description'), article: retry_params.article} + } + else if (String(error.response.status)[0] == "5") { + this.error = {title: this.$t('error.server.title'), description: this.$t('error.server.description', {code: error.response.status}), article: retry_params.article} } else { - this.error = {title: this.$t('error.404.title'), description: this.$t('error.404.description'), article} + this.error = {title: this.$t('error.generic_code.title'), description: this.$t('error.generic_code.description', {code: error.response.status}), article: retry_params.article} } - } - else if (error.response.status == 503) { - this.error = {title: this.$t('error.503.title'), description: this.$t('error.503.description'), article} - } - else if (String(error.response.status)[0] == "5") { - this.error = {title: this.$t('error.server.title'), description: this.$t('error.server.description', {code: error.response.status}), article} + } else if (error.message == "Network Error") { + this.error = {title: this.$t('error.network.title'), description: this.$t('error.network.description'), article: retry_params.article} } else { - this.error = {title: this.$t('error.generic_code.title'), description: this.$t('error.generic_code.description', {code: error.response.status}), article} + this.error = {title: this.$t('error.generic.title'), description: this.$t('error.generic.description'), article: retry_params.article} } - } else if (error.message == "Network Error") { - this.error = {title: this.$t('error.network.title'), description: this.$t('error.network.description'), article} - } - else { - this.error = {title: this.$t('error.generic.title'), description: this.$t('error.generic.description'), article} + } else { + this.fallback = true + retry_params.retry(this, retry_params.arg) } + }, + inflection_link: function (word) { this.$plausible.trackEvent('inflection link', {props: {lang: this.previous.params.lang, from: this.previous.query.q, to: word}}) this.event = null @@ -658,61 +715,26 @@ export default { } }, mounted: function(){ - let self = this - self.lang = self.$route.params.lang || this.$store.state.defaultDict || 'bm,nn' - if (self.$route.query.pos) { - self.pos_selected = self.$route.query.pos.toUpperCase() - } else self.pos_selected = null - - if (self.$route.query.scope) { - self.scope = self.$route.query.scope - self.set_fulltext_highlight() + this.api = axios.create({baseURL: ENDPOINT}) + + this.lang = this.$route.params.lang || this.$store.state.defaultDict || 'bm,nn' + if (this.$route.query.pos) { + this.pos_selected = this.$route.query.pos.toUpperCase() + } else this.pos_selected = null + + if (this.$route.query.scope) { + this.scope = this.$route.query.scope + this.set_fulltext_highlight() } - if (self.$route.query.page) self.page = parseInt(self.$route.query.page) - if (self.$route.query.perPage) { - self.perPage = parseInt(self.$route.query.perPage) + if (this.$route.query.page) this.page = parseInt(this.$route.query.page) + if (this.$route.query.perPage) { + this.perPage = parseInt(this.$route.query.perPage) } else { - self.perPage = parseInt(self.$store.state.perPage) + this.perPage = parseInt(this.$store.state.perPage) } - Promise.all([ - axios.get(ARTICLE_ENDPOINT + 'bm/concepts.json').then(function(response){ - let concepts = response.data.concepts - entities.bm = concepts - }), - axios.get(ARTICLE_ENDPOINT + 'nn/concepts.json').then(function(response){ - let concepts = response.data.concepts - entities.nn = concepts - }) - ]).then(function(_) { - self.waiting_for_metadata = false - if (self.$route.name == 'search') { - navigate_to_query(self, self.$route.query.q, true) - } - else if(self.$route.name == 'lookup'){ - navigate_to_article(self, self.$route.path) - } - else { - self.waiting_for_articles = false - self.replace_history() - self.load_monthly_bm() - self.load_monthly_nn() - - } - }).catch(function(error){ - if (error.message == "Network Error") { - self.error = self.$t('error.network') - } - else if (error.response) { - self.error = self.$t('error.server', {code: error.response.status}) - } - else { - self.error = self.$t('error.generic') - } - self.waiting_for_metadata = false - self.waiting_for_articles = false - }) + this.load_welcome_and_metadata() }, watch: { $route(to, from) { -- GitLab