UNPKG

@mezereon/ui-shopify

Version:

Shopify UI components for Mezereon Search & Filter

225 lines (209 loc) 6.69 kB
import { mapState, mapGetters } from 'vuex' import mz from '@mezereon/tracking' import { convertCurrency, isAbsoluteUrl } from '@/helpers' export default { data() { return { loading: true, apiUrl: mz.config.search.url, searchKey: mz.config.search.key, cookieless: mz.config.cookieless } }, computed: { ...mapState('search', [ 'pageId', 'queryId', 'segments', 'keyword', 'page', 'sort', 'pageSize', 'selections', 'filters', 'aggregations', 'hits', 'layout', 'primaryKey', 'context', 'queryParam', 'pagination', 'redirect' ]), ...mapGetters('search', ['getFacetBanners', 'getQuery']) }, async created() { const store = this.$store if (this.$bus) this.$bus.on('run-query', this.doSearch) store.dispatch('api/setApiUrl', this.apiUrl, { root: true }) store.dispatch('api/setSearchKey', this.searchKey, { root: true }) await this.$store.dispatch('search/loadConfig', {}, { root: true }) // define queryParam and register query state change handler this.$queryState.setQueryParam(this.queryParam) this.$queryState.onChange(this.queryStateChange) // run initial query this.queryStateChange(this.$queryState.parseUrl()) }, async mounted() { // initial query is executed only when #mz-app is on the page const app = document.querySelector('#mz-app') if (!app) { this.loading = false return } }, methods: { pushState(pagination) { if (pagination.current_page == 1) { return true } if ( pagination.pagingType === 'more' || pagination.pagingType == 'infinite' ) { return false } return true }, queryStateChange(state) { this.loading = true // use sort and pageSize from cookies when undefined if (!this.cookieless || !this.cookieless.sort) { state.sort = state.sort || this.$cookies.get('sort') } state.pageSize = state.pageSize || this.$cookies.get('pageSize') this.$store.dispatch('search/setState', state, { root: true }) this.runQuery(false) }, doSearch: function () { this.runQuery(true) }, runQuery: function (push) { const query = { filter: this.context.filter, pageUrl: this.context.pageUrl, pageId: this.pageId, keyword: this.keyword, page: this.page, sort: this.sort, pageSize: this.pageSize, filters: this.filters } if (this.context.handle) { query['handle'] = this.context.handle } if (this.context.currency) { query['currency'] = this.context.currency } if (this.context.country) { query['country'] = this.context.country } if (this.context.themeId) { query['themeId'] = this.context.themeId } // inject special tags e.g. not-first-page let tags = this.context.tags || [] if (this.page > 1 && !tags.includes('not-first-page')) { tags.push('not-first-page') } if (this.page == 1 && tags.includes('not-first-page')) { tags = tags.filter((tag) => tag !== 'not-first-page') } const context = { visitId: mz ? mz.getVisitId() : '', visitorId: mz ? mz.getVisitorId() : '', tags } this.$store .dispatch('search/runQuery', { query, context }, { root: true }) .then(() => { // hide loader this.loading = false // push to history if (push) { this.$queryState.push(this.getQuery()) } if (this.pushState(this.pagination)) { if (this.$scrollTo) { if (mz && mz.config && mz.config.scroll) { if (!mz.config.scroll.disabled) { this.$scrollTo( mz.config.scroll.element || 'body', mz.config.scroll.duration || 300 ) } } else { this.$scrollTo(300) } } } // update title tag if (this.context.tags && this.context.tags.includes('search')) { if (this.keyword) { document.title = `${this.keyword} - ${this.context.shopName}` } else { document.title = `${this.context.pageTitle} - ${this.context.shopName}` } } if (push) { convertCurrency('.money') // emit after-query event needed for custom handlers i.e. custom multi-currency if (this.$bus) this.$bus.emit('after-query') } else { // emit after-initial-query event needed for custom handlers i.e. custom multi-currency if (this.$bus) this.$bus.emit('after-initial-query') } if (this.$bus) this.$bus.emit('lazy-load-reset') const self = this this.$nextTick(() => { if (self.$bus) self.$bus.emit('after-update') // trigger quick view update (qikify) if (document) { document.dispatchEvent(new CustomEvent('qview-grid-updated')) } }) if (mz && mz.track && this.hits) { // retrieve top 10 unique ids from results for ML const uids = [] for (let i = 0; i < 10 && i < this.hits.items.length; i++) { uids.push(this.hits.items[i].item[this.hits.primaryKey]) } const banners = [] if (this.hits.banners) { for (const [k, v] of Object.entries(this.hits.banners)) { if (v === null) { continue } banners.push({ zone: k, id: v.id }) } } mz.track('query', { queryId: this.queryId, query: query, segments: this.segments, context: context, total: this.hits.total, banners: banners, uids: uids, redirect: this.redirect }) } if (this.redirect) { let redirect = this.redirect if (isAbsoluteUrl(redirect)) { window.location.replace(redirect) return } if (mz && mz.context && mz.context.root) { redirect = `${mz.context.root}${redirect}` } window.location.replace(redirect) return } }) .catch(() => { this.loading = false }) } } }