diff --git a/sitemedia/js/components/FacetChoice.js b/sitemedia/js/components/FacetChoice.js deleted file mode 100644 index d4562ce..0000000 --- a/sitemedia/js/components/FacetChoice.js +++ /dev/null @@ -1,26 +0,0 @@ -import { mapActions } from 'vuex' - -export default Vue.component('FacetChoice', { - template: ` -
- - -
`, - props: { - facet: String, - value: String, - count: Number, - active: Boolean, - }, - methods: { - ...mapActions([ - 'toggleFacetChoice' - ]) - } -}) \ No newline at end of file diff --git a/sitemedia/js/components/SearchFacet.js b/sitemedia/js/components/SearchFacet.js index 116c9d1..8470e60 100644 --- a/sitemedia/js/components/SearchFacet.js +++ b/sitemedia/js/components/SearchFacet.js @@ -1,4 +1,4 @@ -import FacetChoice from './FacetChoice' +import { mapActions } from 'vuex' export default Vue.component('SearchFacet', { template: ` @@ -19,12 +19,21 @@ export default Vue.component('SearchFacet', {
- + > + + +
`, - components: { - FacetChoice - }, data() { return { filter: '', @@ -62,6 +68,9 @@ export default Vue.component('SearchFacet', { choices: Array }, methods: { + ...mapActions([ + 'toggleFacetChoice', + ]), /** * Utility that normalizes strings for simple comparison. * Removes special characters, trims whitespace, and uppercases. diff --git a/sitemedia/js/components/books/BooksSearch.js b/sitemedia/js/components/books/BooksSearch.js index 134cc45..33bb719 100644 --- a/sitemedia/js/components/books/BooksSearch.js +++ b/sitemedia/js/components/books/BooksSearch.js @@ -116,6 +116,7 @@ export default Vue.component('BooksSearch', { 'facetChoices', ]), ...mapGetters([ + 'activeFacets', 'activeFacetChoices', ]), }, @@ -135,10 +136,10 @@ export default Vue.component('BooksSearch', { * @param {Array} tab * @returns {String} */ - tabLabel(tab) { + tabLabel(tab, separator = ' · ') { return tab .map(facetName => this.facetConfig.find(facet => facet.name === facetName).label) - .join(' · ') - } + .join(separator) + }, }, }) diff --git a/sitemedia/js/router/index.js b/sitemedia/js/router/index.js index 803dbb4..570a1fd 100644 --- a/sitemedia/js/router/index.js +++ b/sitemedia/js/router/index.js @@ -1,9 +1,14 @@ import VueRouter from 'vue-router' +import store from '../store' import BooksSearch from '../components/books/BooksSearch' export const routes = [ - { path: '*', component: BooksSearch } // always render the books search view + { + path: '*', // always render the books search view + component: BooksSearch, + props: route => store.dispatch('setFormState', route.query) // convert any query params to form state + } ] export default new VueRouter({ diff --git a/sitemedia/js/store/actions.js b/sitemedia/js/store/actions.js index b4df82a..ed2e437 100644 --- a/sitemedia/js/store/actions.js +++ b/sitemedia/js/store/actions.js @@ -1,3 +1,5 @@ +import router from '../router' + export default { loadSearchData ({ commit }, query) { return fetch(query) @@ -17,11 +19,25 @@ export default { }) }, - toggleFacetChoice ({ commit }, choice) { + toggleFacetChoice ({ commit, getters }, choice) { commit('editFacetChoice', { choice, active: !choice.active }) + router.replace({ + query: { + ...getters.activeFacets + } + }) }, clearFacetChoices ({ commit }) { commit('clearFacetChoices') + router.replace({ + path: '/' + }) }, + + setFormState ({ commit, getters }, query) { + if (JSON.stringify(query) != JSON.stringify(getters.activeFacets)) { + commit('setFacetChoices', Object.entries(query)) + } + } } \ No newline at end of file diff --git a/sitemedia/js/store/getters.js b/sitemedia/js/store/getters.js index da57515..0b43ab0 100644 --- a/sitemedia/js/store/getters.js +++ b/sitemedia/js/store/getters.js @@ -1,5 +1,21 @@ +import { toArray } from '../utilities' + export default { activeFacetChoices (state) { return state.facetChoices.filter(choice => choice.active) }, + + activeFacets (state, getters) { + return getters.activeFacetChoices + .reduce((acc, cur) => { + if (acc[cur.facet]) { + if (!Array.isArray(acc[cur.facet])) { + acc[cur.facet] = toArray(acc[cur.facet]) + } + acc[cur.facet].push(cur.value) + } + else acc[cur.facet] = cur.value + return acc + }, {}) + } } \ No newline at end of file diff --git a/sitemedia/js/store/mutations.js b/sitemedia/js/store/mutations.js index 2a2982c..edc0281 100644 --- a/sitemedia/js/store/mutations.js +++ b/sitemedia/js/store/mutations.js @@ -1,3 +1,5 @@ +import { toArray } from '../utilities' + export default { addFacetChoice (state, choice) { state.facetChoices.push(choice) @@ -24,6 +26,15 @@ export default { state.facetChoices.forEach(choice => choice.active = false) }, + setFacetChoices (state, facets) { + state.facetChoices.forEach(choice => choice.active = false) + facets.forEach(facet => { + state.facetChoices + .filter(choice => choice.facet === facet[0] && toArray(facet[1]).includes(choice.value)) + .forEach(choice => choice.active = true) + }) + }, + setTotalResults (state, total) { state.totalResults = total }, diff --git a/sitemedia/js/utilities.js b/sitemedia/js/utilities.js new file mode 100644 index 0000000..8a827dc --- /dev/null +++ b/sitemedia/js/utilities.js @@ -0,0 +1 @@ +export const toArray = value => Array.isArray(value) ? value : value ? [value] : undefined