From 1b4abf0bfcbdf96663e1b39095a5ee00a74436a5 Mon Sep 17 00:00:00 2001 From: Andrew Redden Date: Sun, 18 Oct 2020 08:03:22 -0300 Subject: [PATCH 1/4] URL params are being extracted correctly and loaded into the instruction set to searches --- app/assets/v2/js/shared.js | 68 ++++ app/assets/v2/js/users-elastic.js | 353 +++++------------- .../templates/dashboard/users-elastic.html | 11 +- 3 files changed, 173 insertions(+), 259 deletions(-) diff --git a/app/assets/v2/js/shared.js b/app/assets/v2/js/shared.js index ae3c299219e..a7ecc49b1d2 100644 --- a/app/assets/v2/js/shared.js +++ b/app/assets/v2/js/shared.js @@ -1010,6 +1010,74 @@ function shuffleArray(array) { return array; } + +const getAllUrlParams = () => { + + // get query string from url (optional) or window + var queryString = window.location.search.slice(1); + + // we'll store the parameters here + var obj = {}; + + // if query string exists + if (queryString) { + + // stuff after # is not part of query string, so get rid of it + queryString = queryString.split('#')[0]; + + // split our query string into its component parts + var arr = queryString.split('&'); + + for (var i = 0; i < arr.length; i++) { + // separate the keys and the values + var a = arr[i].split('='); + + // set parameter name and value (use 'true' if empty) + var paramName = a[0]; + var paramValue = typeof (a[1]) === 'undefined' ? true : a[1]; + + // (optional) keep case consistent + paramName = paramName.toLowerCase(); + if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase(); + + // if the paramName ends with square brackets, e.g. colors[] or colors[2] + if (paramName.match(/\[(\d+)?\]$/)) { + + // create key if it doesn't exist + var key = paramName.replace(/\[(\d+)?\]/, ''); + + if (!obj[key]) obj[key] = []; + + // if it's an indexed array e.g. colors[2] + if (paramName.match(/\[\d+\]$/)) { + // get the index value and add the entry at the appropriate position + var index = (/\[(\d+)\]/).exec(paramName)[1]; + + obj[key][index] = paramValue; + } else { + // otherwise add the value to the end of the array + obj[key].push(paramValue); + } + } else { + // we're dealing with a string + if (!obj[paramName]) { + // if it doesn't exist, create property + obj[paramName] = paramValue; + } else if (obj[paramName] && typeof obj[paramName] === 'string') { + // if property does exist and it's a string, convert it to an array + obj[paramName] = [obj[paramName]]; + obj[paramName].push(paramValue); + } else { + // otherwise add the property + obj[paramName].push(paramValue); + } + } + } + } + + return obj; +}; + const getURLParams = (k) => { var p = {}; diff --git a/app/assets/v2/js/users-elastic.js b/app/assets/v2/js/users-elastic.js index 2dba731d39e..1ba26c5b854 100644 --- a/app/assets/v2/js/users-elastic.js +++ b/app/assets/v2/js/users-elastic.js @@ -221,18 +221,36 @@ Vue.mixin({ }, extractURLFilters: function() { let vm = this; - let params = getURLParams(); + const params = getAllUrlParams(); - vm.users = []; + if (Object.values(params).length > 0) { + // eslint-disable-next-line guard-for-in + for (let prop in params) { - if (params) { - for (var prop in params) { - if (prop === 'skills') { - vm.$set(vm.params, prop, params[prop].split(',')); - } else { - vm.$set(vm.params, prop, params[prop]); + // eslint-disable-next-line guard-for-in + for (let key in params[prop]) { + + let value = params[prop][key]; + const columnMeta = $.extend({}, vm.esColumns[prop]); + + if (!columnMeta) { + continue; + } + columnMeta['key'] = prop; + columnMeta['value'] = value; + + let _instruction = { + fun: 'orFilter', + args: [ 'term', `${columnMeta.key}_exact`, columnMeta.value ] + }; + + this.addInstruction(_instruction); } } + debugger; + vm.params = params; + this.mount(); + this.fetch(this); } }, joinTribe: function(user, event) { @@ -264,257 +282,88 @@ Vue = Vue.extend({ }); -Vue.component('directory-card', { - name: 'DirectoryCard', - delimiters: [ '[[', ']]' ], - props: [ 'user', 'funderBounties' ] -}); -Vue.use(innerSearch.default); -Vue.component('autocomplete', { - props: [ 'options', 'value' ], - template: '#select2-template', - methods: { - formatMapping: function(item) { - console.log(item); - return item.name; - }, - formatMappingSelection: function(filter) { - return ''; - } - }, - mounted() { - let count = 0; - let vm = this; - let mappedFilters = {}; - let data = $.map(this.options, function(obj, key) { - - if (key.indexOf('_exact') === -1) - return; - let newKey = key.replace('_exact', ''); - - if (mappedFilters[newKey]) - return; - obj.id = count++; - obj.text = newKey; - obj.key = key; - - mappedFilters[newKey] = true; - mappedFilters[key] = true; - return obj; - }); - - - $(vm.$el).select2({ - data: data, - multiple: true, - allowClear: true, - placeholder: 'Search for another filter to add', - minimumInputLength: 1, - escapeMarkup: function(markup) { - return markup; - } - }) - .on('change', function() { - console.log('changed'); - let val = $(vm.$el).val(); - - let changeData = $.map(val, function(filter) { - return data[filter]; - }); +if (document.getElementById('gc-users-elastic')) { - vm.$emit('input', changeData); - }); + Vue.component('directory-card', { + name: 'DirectoryCard', + delimiters: [ '[[', ']]' ], + props: [ 'user', 'funderBounties' ] + }); - // fix for wrong position on select open - var select2Instance = $(vm.$el).data('select2'); - - select2Instance.on('results:message', function(params) { - this.dropdown._resizeDropdown(); - this.dropdown._positionDropdown(); - }); - }, - destroyed: function() { - $(this.$el).off().select2('destroy'); - this.$emit('destroyed'); - } -}); -Vue.component('user-directory', { - delimiters: [ '[[', ']]' ], - props: [ 'tribe', 'is_my_org' ], - data: function() { - return { - orgOwner: this.is_my_org || false, - userFilter: { - options: [ - {text: 'All', value: 'all'}, - {text: 'Tribe Owners', value: 'owners'}, - {text: 'Tribe Members', value: 'members'}, - {text: 'Tribe Hackers', value: 'hackers'} - ] - }, - tribeFilter: this.tribe || '', - users, - usersPage, - hackathonId, - usersNumPages, - usersHasNext, - numUsers, - media_url, - chatURL: document.chatURL || 'https://chat.gitcoin.co/', - searchTerm: null, - bottom: false, - params: { - 'user_filter': 'all' + Vue.use(innerSearch.default); + Vue.component('autocomplete', { + props: [ 'options', 'value' ], + template: '#select2-template', + methods: { + formatMapping: function(item) { + console.log(item); + return item.name; }, - funderBounties: [], - currentBounty: undefined, - contributorInvite: undefined, - isFunder: false, - bountySelected: null, - userSelected: [], - showModal: false, - showFilters: true, - skills: document.keywords, - selectedSkills: [], - noResults: false, - isLoading: true, - gitcoinIssueUrl: '', - issueDetails: undefined, - errorIssueDetails: undefined, - showBanner: undefined, - persona: undefined, - hideFilterButton: !!document.getElementById('explore_tribes'), - expandFilter: true - }; - }, - - mounted() { - this.fetchUsers(); - this.tribeFilter = this.tribe; - this.$watch('params', function(newVal, oldVal) { - this.searchUsers(); - }, { - deep: true - }); - }, - created() { - if (document.contxt.github_handle && this.is_my_org) { - this.fetchBounties(); - } - this.inviteOnMount(); - this.extractURLFilters(); - }, - beforeMount() { - if (this.isMobile) { - this.showFilters = false; - } - window.addEventListener('scroll', () => { - this.bottom = this.bottomVisible(); - }, false); - }, - beforeDestroy() { - window.removeEventListener('scroll', () => { - this.bottom = this.bottomVisible(); - }); - } -}); -Vue.component('user-directory-elastic', { - delimiters: [ '[[', ']]' ], - data: function() { - return { - filters: [], - esColumns: [], - filterLoaded: false, - users, - usersPage, - usersNumPages, - usersHasNext, - numUsers, - media_url, - chatURL: document.chatURL || 'https://chat.gitcoin.co/', - searchTerm: null, - bottom: false, - params: {}, - funderBounties: [], - currentBounty: undefined, - contributorInvite: undefined, - isFunder: false, - bountySelected: null, - userSelected: [], - showModal: false, - showFilters: !document.getElementById('explore_tribes'), - skills: document.keywords, - selectedSkills: [], - noResults: false, - isLoading: true, - gitcoinIssueUrl: '', - issueDetails: undefined, - errorIssueDetails: undefined, - showBanner: undefined, - persona: undefined, - hideFilterButton: !!document.getElementById('explore_tribes') - }; - }, - methods: { - autoCompleteDestroyed: function() { - this.filters = []; - }, - autoCompleteChange: function(filters) { - this.filters = filters; - }, - outputToCSV: function() { - let url = '/api/v0.1/users_csv/'; - - $.get(url, this.body).then(resp => resp.json()).then(json => { - _alert(json.message); - }).catch(() => _alert('There was an issue processing your request')); + formatMappingSelection: function(filter) { + return ''; + } }, - fetchMappings: function() { + mounted() { + let count = 0; let vm = this; + let mappedFilters = {}; + let data = $.map(this.options, function(obj, key) { + + if (key.indexOf('_exact') === -1) + return; + let newKey = key.replace('_exact', ''); + + if (mappedFilters[newKey]) + return; + obj.id = count++; + obj.text = newKey; + obj.key = key; + + mappedFilters[newKey] = true; + mappedFilters[key] = true; + return obj; + }); + + + $(vm.$el).select2({ + data: data, + multiple: true, + allowClear: true, + placeholder: 'Search for another filter to add', + minimumInputLength: 1, + escapeMarkup: function(markup) { + return markup; + } + }) + .on('change', function() { + console.log('changed'); + let val = $(vm.$el).val(); - $.when(vm.header.client.indices.getMapping()) - .then(response => { - vm.esColumns = response[vm.header.index]['mappings'][vm.header.type]['properties']; - vm.filterLoaded = true; + let changeData = $.map(val, function(filter) { + return data[filter]; + }); + + vm.$emit('input', changeData); }); - } - }, - mounted() { - this.fetchMappings(); - // this.fetchUsers(); - this.$watch('params', function(newVal, oldVal) { - this.searchUsers(); - }, { - deep: true - }); - }, - created() { - this.setHost(document.contxt.search_url); - this.setIndex('haystack'); - this.setType('modelresult'); - this.fetchBounties(); - this.inviteOnMount(); - this.extractURLFilters(); - }, - beforeMount() { - window.addEventListener('scroll', () => { - this.bottom = this.bottomVisible(); - }, false); - }, - beforeDestroy() { - window.removeEventListener('scroll', () => { - this.bottom = this.bottomVisible(); - }); - } -}); -if (document.getElementById('gc-users-elastic')) { + // fix for wrong position on select open + var select2Instance = $(vm.$el).data('select2'); + + select2Instance.on('results:message', function(params) { + this.dropdown._resizeDropdown(); + this.dropdown._positionDropdown(); + }); + }, + destroyed: function() { + $(this.$el).off().select2('destroy'); + this.$emit('destroyed'); + } + }); window.UserDirectory = new Vue({ delimiters: [ '[[', ']]' ], el: '#gc-users-elastic', data: { csrf: document.csrf, - filters: [], esColumns: [], filterLoaded: false, users, @@ -527,6 +376,7 @@ if (document.getElementById('gc-users-elastic')) { searchTerm: null, bottom: false, params: {}, + filters: [], funderBounties: [], currentBounty: undefined, contributorInvite: undefined, @@ -574,24 +424,19 @@ if (document.getElementById('gc-users-elastic')) { .then(response => { vm.esColumns = response[vm.header.index]['mappings'][vm.header.type]['properties']; vm.filterLoaded = true; + this.extractURLFilters(); + this.fetch(this); + }); } }, mounted() { this.fetchMappings(); - this.fetch(this); - this.$watch('params', function(newVal, oldVal) { - this.searchUsers(); - }, { - deep: true - }); }, created() { this.setHost(document.contxt.search_url); this.setIndex('haystack'); this.setType('modelresult'); - - // this.extractURLFilters(); }, beforeMount() { window.addEventListener('scroll', () => { diff --git a/app/dashboard/templates/dashboard/users-elastic.html b/app/dashboard/templates/dashboard/users-elastic.html index 473b3cb00ed..6a054f83596 100644 --- a/app/dashboard/templates/dashboard/users-elastic.html +++ b/app/dashboard/templates/dashboard/users-elastic.html @@ -43,9 +43,9 @@ @@ -63,10 +63,11 @@

[[ filter.text ]] :

- + @@ -55,7 +55,10 @@