diff --git a/src/components/SearchFilter.vue b/src/components/SearchFilter.vue index c359eb8bc..ec43059ff 100644 --- a/src/components/SearchFilter.vue +++ b/src/components/SearchFilter.vue @@ -110,7 +110,7 @@ - {{ $t('submit') }} + {{ $t('submit') }} {{ $t('reset') }} @@ -151,6 +151,52 @@ function getQueryDefaults() { }; } +function getUrlParamValues() { + const searchURL = new URL(window.location); + const params = searchURL.searchParams; + const urlParams = {}; + const arrayParams = ['bbox', 'collections', 'ids']; + const allowedQueryParams = [ + 'q', + 'datetime', + 'bbox', + 'limit', + 'ids', + 'collections', + 'sortby', + 'filters', + 'itemsPerPage']; + + allowedQueryParams.forEach((allowedParam) => { + if (params.has(allowedParam)) { + if( arrayParams.includes(allowedParam)) { + urlParams[allowedParam] = params.get(allowedParam).split(','); + // bbox bust be array of numbers + if(allowedParam === 'bbox') { + urlParams[allowedParam] = urlParams[allowedParam].map(Number); + } + } else if(allowedParam === 'datetime') { + // datetime must be array of date objects + urlParams[allowedParam] = params.get(allowedParam); + const dateArray= urlParams['datetime'].split('/').map( day => new Date(day)); + urlParams[allowedParam] = dateArray; + } else { + // all others are strings + urlParams[allowedParam] = params.get(allowedParam); + } + } + }); + + const combinedQuery = { ...getQueryDefaults(), ...urlParams}; + return combinedQuery; +} + +function bboxProvided() { + const searchURL = new URL(window.location); + const hasBbox = searchURL.searchParams.has('bbox'); + return hasBbox; + } + function getDefaults() { return { sortOrder: 1, @@ -159,10 +205,60 @@ function getDefaults() { query: getQueryDefaults(), filtersAndOr: 'and', filters: [], - selectedCollections: [] + selectedCollections: [], }; } +function overwriteDefaults() { + const searchURL = new URL(window.location); + const params = searchURL.searchParams; + const permittedOverwrites = ['sortOrder', 'sortTerm', 'provideBBox']; + const numericParams=['sortOrder', 'limit']; + const defaultOverwrites = { + provideBBox: bboxProvided(), + bboxSelectionStyle: bboxProvided() ? 'text' : 'map', + }; + + + permittedOverwrites.forEach((allowedValue) => { + if(params.has(allowedValue)) { + // sortTerm is a json object, not a string + if (allowedValue === 'sortTerm') { + defaultOverwrites[allowedValue] = JSON.parse(params.get(allowedValue)); + } + else if(numericParams.includes(allowedValue)) { + defaultOverwrites[allowedValue] = parseInt(params.get(allowedValue)); + } else { + defaultOverwrites[allowedValue] = params.get(allowedValue); + } + } + }); + + return {...getDefaults(), ...defaultOverwrites}; + +} + +function updateUrlParamString(key, value) { + // remove parameters if new value is null + const searchURL = new URL(window.location); + if (value === null || value.length === 0 || value.value === null) { + searchURL.searchParams.delete(key); + window.history.pushState({}, '', searchURL); + return; + } + // sortTerm is an object + if(key === 'sortTerm') { + searchURL.searchParams.set(key, JSON.stringify(value)); + } else if(key ==='datetime') { + const dateFormattedForPicker = `${JSON.stringify(value['0'])}/${JSON.stringify(value['1'])}`; + searchURL.searchParams.set(key, dateFormattedForPicker.replaceAll('"','')); + } else { + searchURL.searchParams.set(key, value); + } + + window.history.pushState({}, '', searchURL); +} + let formId = 0; export default { @@ -202,6 +298,10 @@ export default { value: { type: Object, default: () => ({}) + }, + searchLink: { + type: Object, + default: () => ({}) } }, data() { @@ -214,7 +314,7 @@ export default { collections: [], collectionsLoadingTimer: null, additionalCollectionCount: 0 - }, getDefaults()); + }, overwriteDefaults()); }, computed: { ...mapState(['itemsPerPage', 'uiLanguage']), @@ -297,7 +397,7 @@ export default { immediate: true, deep: true, handler(value) { - let query = Object.assign(getQueryDefaults(), value); + let query = Object.assign(getUrlParamValues(), value); if (Array.isArray(query.datetime)) { query.datetime = query.datetime.map(Utils.dateFromUTC); } @@ -312,7 +412,8 @@ export default { }); } } - } + }, + $route() {}, }, beforeCreate() { formId++; @@ -341,6 +442,14 @@ export default { } Promise.all(promises).finally(() => this.loaded = true); }, + mounted() { + // submit form if loaded with url params + const searchURL = new URL(window.location); + const params = searchURL.searchParams; + if(params.size > 1) { + document.getElementById("submitBtn").click(); + } + }, methods: { resetSearchCollection() { clearTimeout(this.collectionsLoadingTimer); @@ -465,9 +574,11 @@ export default { }, sortFieldSet(value) { this.sortTerm = value; + updateUrlParamString('sortTerm', value); }, sortDirectionSet(value) { this.sortOrder = value; + updateUrlParamString('sortOrder', value); }, buildFilter() { if (this.filters.length === 0) { @@ -498,6 +609,7 @@ export default { async onReset() { Object.assign(this, getDefaults()); this.$emit('input', {}, true); + this.removeQueryParams(); }, setLimit(limit) { limit = Number.parseInt(limit, 10); @@ -508,15 +620,24 @@ export default { limit = null; } this.$set(this.query, 'limit', limit); + updateUrlParamString('limit', limit); }, addSearchTerm(term) { if (!Utils.hasText(term)) { return; } this.query.q.push(term); + updateUrlParamString('q', term); }, setSearchTerms(terms) { this.$set(this.query, 'q', terms); + updateUrlParamString('q', terms); + }, + updateBBoxArray(entry, position) { + const bbox = this.query.bbox; + bbox[position] = Number(entry); + this.$set(this.query, 'bbox', bbox); + updateUrlParamString('bbox', bbox); }, setBBox(bounds) { let bbox = null; @@ -537,6 +658,7 @@ export default { } } this.$set(this.query, 'bbox', bbox); + updateUrlParamString('bbox', bbox); }, setDateTime(datetime) { if (datetime.find(dt => dt instanceof Date)) { @@ -546,6 +668,7 @@ export default { datetime = null; } this.$set(this.query, 'datetime', datetime); + updateUrlParamString('datetime', datetime); }, addCollection(collection) { if (!this.collectionSelectOptions.taggable) { @@ -556,16 +679,20 @@ export default { this.selectedCollections.push(opt); this.collections.push(opt); this.query.collections.push(collection); + updateUrlParamString('collections', collection); }, setCollections(collections) { this.selectedCollections = collections; this.$set(this.query, 'collections', collections.map(c => c.value)); + updateUrlParamString('collections', collections.map(c => c.value)); }, addId(id) { this.query.ids.push(id); + updateUrlParamString('ids', id); }, setIds(ids) { this.$set(this.query, 'ids', ids); + updateUrlParamString('ids', ids); }, formatSort() { if (this.sortTerm && this.sortTerm.value && this.sortOrder) { @@ -575,8 +702,11 @@ export default { else { return null; } - } - } + }, + removeQueryParams() { + this.$router.replace({name: "search"}); + }, + }, };