UNPKG

@mezereon/bigcommerce-stencil

Version:

BigCommerce UI components for Mezereon Xperience

226 lines (214 loc) 6.56 kB
import { isAbsoluteUrl, isEmpty } from '@/helpers' import mz from '@mezereon/tracking' import { mapGetters, mapState } from 'vuex' export default { data() { return { loading: true, apiUrl: mz.config.search.url, searchKey: mz.config.search.key } }, computed: { ...mapState('search', [ 'pageId', 'queryId', 'segments', 'keyword', 'page', 'sort', 'pageSize', 'selections', 'filters', 'aggregations', 'hits', 'primaryKey', 'context', 'fallbackMode', 'queryParam', 'pagination', 'redirect' ]), ...mapGetters('search', ['getFacetBanners', 'getQuery']) }, created() { const store = this.$store store.dispatch('api/setApiUrl', this.apiUrl, { root: true }) store.dispatch('api/setSearchKey', this.searchKey, { root: true }) if (this.$bus) this.$bus.on('run-query', this.doSearch) }, mounted() { // initial query is executed only when mz-context is on the page if (this.$refs.context === undefined) { this.loading = false this.showResults() return } if (this.fallbackMode) { this.loading = false this.turnOnFallbackMode() return } // 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()) }, methods: { pushState(pagination) { if (pagination.current_page == 1) { return true } if ( pagination.pagingType === 'more' || pagination.pagingType == 'infinite' ) { return false } return true }, showResults() { // hide aggregations div const hideAggs = isEmpty(this.getFacetBanners) && this.aggregations.length === 0 const aggs = document.querySelectorAll('.mz-aggs') if (aggs) { aggs.forEach((item) => { item.style.display = hideAggs ? 'none' : 'block' }) } }, turnOnFallbackMode() { // show fallback content const app = document.querySelector('#mz-app') if (app) { app.style.setProperty('display', 'none', 'important') } const autocomplete = document.querySelector('#mz-autocomplete') if (autocomplete) { autocomplete.style.setProperty('display', 'none', 'important') } // remove mz-fallback class to make original controls visible const fallback = document.querySelectorAll('.mz-fallback') if (fallback) { fallback.forEach((item) => { item.classList.remove('mz-fallback') }) } window.mz.enabled = false }, queryStateChange(state) { this.loading = true // use sort and pageSize from cookies when undefined 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() { this.runQuery(true) }, runQuery(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, currency: this.context.currency } if (this.context.categoryId) { query['categoryId'] = this.context.categoryId } const context = { visitId: mz ? mz.getVisitId() : '', visitorId: mz ? mz.getVisitorId() : '', tags: this.context.tags, narrow: this.context.narrow } this.$store .dispatch('search/runQuery', { query, context }, { root: true }) .then(() => { // hide loader this.loading = false if (this.pushState(this.pagination)) { // push to history if (push) { this.$queryState.push(this.getQuery()) } 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) } } } this.showResults() const event = { query, context, result: this.hits } if (push) { // emit after-query event needed for custom handlers if (this.$bus) this.$bus.emit('after-query', event) } else { // emit after-initial-query event needed for custom handlers if (this.$bus) this.$bus.emit('after-initial-query', event) } const self = this this.$nextTick(() => { if (self.$bus) self.$bus.emit('after-update', event) }) 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, segments: this.segments, context, total: this.hits.total, banners, 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 this.turnOnFallbackMode() }) } } }