Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Refactor catalog module #2890

Merged
merged 90 commits into from
Jul 1, 2019
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
5d2827c
prepare module draft
patzick May 8, 2019
3889092
add default values
patzick May 9, 2019
9d2462a
init module actions
patzick May 9, 2019
16ca33e
move helper from old module
patzick May 9, 2019
0207857
getting available filters
patzick May 9, 2019
087d45e
invoke search with current filters
patzick May 9, 2019
e834b21
current category from getter
patzick May 9, 2019
d372696
default value as string
patzick May 9, 2019
59f2130
add todo for multiple filters
patzick May 9, 2019
8a9d28d
switching search filters
patzick May 9, 2019
d2b4664
switching filters query
patzick May 9, 2019
23e70d7
multiple dilters draft and reseting filters
patzick May 9, 2019
c60508d
migrate filter components
patzick May 9, 2019
54a231b
migrate category page
patzick May 9, 2019
f45fe5b
filters and currentCategory as getters
patzick May 10, 2019
d027a4c
active filters
patzick May 10, 2019
8e71fdf
recomputing getters
patzick May 10, 2019
8f9e795
ui active filters
patzick May 10, 2019
f5cdd82
add sorty by property
patzick May 10, 2019
0a9f7d5
system filters not visible on search filters
patzick May 13, 2019
f979051
get turned off by default
patzick May 13, 2019
fece9d5
add category breadcrumbs
patzick May 13, 2019
fb380e7
stop using of sidebar mixin
patzick May 13, 2019
bd32c8c
add multiple filters support
patzick May 15, 2019
9084808
merge develop
patzick May 15, 2019
487a847
moved filter logic to mixin
patzick May 15, 2019
a819f6f
refactor calculate getters
patzick May 15, 2019
25eabd7
move logic to getters
patzick May 16, 2019
652afe0
move logic to directory
patzick May 16, 2019
767aa6d
change loadCategory invocation
patzick May 16, 2019
4ee0279
change router as separate action
patzick May 19, 2019
97e0981
add category service
patzick May 19, 2019
adc60ad
loading categories
patzick May 19, 2019
d97b2a1
change filter method with tests
patzick May 19, 2019
eab2243
extract getFiltersFromQuery with tests
patzick May 19, 2019
8fd4f42
add support for multiple prices with tests
patzick May 20, 2019
af8db3a
Merge branch 'develop' into magento-catalog
patzick May 20, 2019
98034ef
Merge branch 'magento-catalog' of https://github.com/patzick/vue-stor…
patzick May 20, 2019
35293e3
add support for filters as query and path params
patzick May 20, 2019
b47b34b
filters per category
patzick May 20, 2019
7d4633b
refactor -magento to -next
patzick May 22, 2019
e7bdcf2
merge develop
patzick May 29, 2019
93d2588
support finding configurable child with multiple filters
patzick May 30, 2019
771d734
configure fetched products
patzick May 30, 2019
fa52a84
load category filters before picking filters
patzick May 30, 2019
f0a7259
Merge branch 'develop' into magento-catalog
patzick May 30, 2019
738ddce
test caching on server
patzick Jun 3, 2019
6208010
improve service worker catalog cache
patzick Jun 3, 2019
4a687c5
use filters on product page
patzick Jun 4, 2019
abfa197
cleaning code and dependencies
patzick Jun 7, 2019
ed6492f
Merge branch 'magento-catalog' of https://github.com/patzick/vue-stor…
patzick Jun 7, 2019
0549431
merge develop
patzick Jun 11, 2019
447130b
Merge branch 'develop' into magento-catalog
patzick Jun 13, 2019
6867930
linter errors
patzick Jun 14, 2019
c648c3c
correct getter
patzick Jun 14, 2019
e4665e0
default argument
patzick Jun 17, 2019
2e9e140
filter event
patzick Jun 17, 2019
541add0
Merge branch 'develop' into magento-catalog
patzick Jun 19, 2019
c908fdb
cleanup and add types to category service
patzick Jun 22, 2019
02f542a
linter and category interface
patzick Jun 22, 2019
07a52d1
categories as map
patzick Jun 22, 2019
9d6909e
add missing translation
patzick Jun 24, 2019
bce5a2d
cleanup
patzick Jun 24, 2019
d1ca817
recurrent breadcrumbs
patzick Jun 24, 2019
67087ea
mock configuration for configureProductAsync
patzick Jun 24, 2019
867f582
additional test to check buildProductsQuery
patzick Jun 24, 2019
37aca5e
categories hierarchy map and loading categories to breadcrumbs by one…
patzick Jun 24, 2019
64aeff6
Change caegoryFilters to object
patzick Jun 25, 2019
0fc7b6d
breadcrumbs from categories hierarchy map
patzick Jun 25, 2019
ba9f93b
do no t duplicate optionLabel helper
patzick Jun 25, 2019
94e5d23
composition function for proper SSR/CSR caching
patzick Jun 25, 2019
3da38c0
code cleanup
patzick Jun 25, 2019
35638d3
add default breadcrumb value
patzick Jun 25, 2019
7329923
improve filters reactivity on product page
patzick Jun 25, 2019
097eebb
fix problem with available options
patzick Jun 25, 2019
cfafe84
merge develop
patzick Jun 25, 2019
b868176
sorting filters
patzick Jun 25, 2019
dee2ead
lnter
patzick Jun 25, 2019
e345a04
Merge branch 'develop' into magento-catalog
patzick Jun 26, 2019
a0e993d
add infinite scroll pagination
patzick Jun 26, 2019
9659e6f
categoryHierarchyMap
patzick Jun 26, 2019
0f61390
Merge branch 'develop' into magento-catalog
patzick Jun 26, 2019
aa41c09
remove hierarchyMap - build from specific category
patzick Jun 27, 2019
8545d57
Fix problem with products caching on SSR
patzick Jun 27, 2019
52e8854
refactor category page getters names
patzick Jun 27, 2019
61ae322
Merge branch 'develop' into magento-catalog
patzick Jun 28, 2019
6153d69
remove unused hook
patzick Jun 28, 2019
779ce67
fix for product option values incomplete
patzick Jul 1, 2019
f31ac67
prefetch stock for cached products
patzick Jul 1, 2019
ddc3cde
Merge branch 'develop' into magento-catalog
patzick Jul 1, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@
"setupVariantByAttributeCode": true,
"endpoint": "/api/product",
"defaultFilters": ["color", "size", "price", "erin_recommends"],
"routerFiltersSource": "query",
"filterFieldMapping": {
"category.name": "category.name.keyword"
},
Expand Down
8 changes: 5 additions & 3 deletions core/build/webpack.prod.sw.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@ module.exports = merge(base, {
{
urlPattern: '/img/(.*)',
handler: 'fastest'
}, {
urlPattern: '/api/catalog/*',
},
{
urlPattern: /(http[s]?:\/\/)?(\/)?([^\/\s]+\/)?(api\/catalog\/)(.*)/g, // eslint-disable-line no-useless-escape
handler: 'networkFirst'
}, {
},
{
urlPattern: '/api/*',
handler: 'networkFirst'
}, {
Expand Down
2 changes: 1 addition & 1 deletion core/compatibility/components/blocks/Category/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default {
return this.getActiveCategoryFilters
},
availableFilters () {
return pickBy(this.filters, (filter) => { return (filter.length) })
return pickBy(this.filters, (filter, filterType) => { return (filter.length && !this.$store.getters['category-next/getSystemFilterNames'].includes(filterType)) })
},
hasActiveFilters () {
return Object.keys(this.activeFilters).length !== 0
Expand Down
74 changes: 74 additions & 0 deletions core/data-resolver/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { SearchRequest } from '@vue-storefront/core/types/search/SearchRequest';
import { quickSearchByQuery } from '@vue-storefront/core/lib/search';
import SearchQuery from '@vue-storefront/core/lib/search/searchQuery';
import config from 'config';

export interface Product {
id: number,
name: any
}

const getProduct = async (): Promise<Product> => {
const product: Product = {
id: 1,
name: 'sample'
}
return product
}

function getProducts (): Product[] {
return [{
id: 1,
name: 'sample1'
}, {
id: 2,
name: 'sample2'
}
]
}

const getCategories = async ({parent = null, key = null, value = null, level = null, onlyActive = true, onlyNotEmpty = false, size = 4000, start = 0, sort = 'position:asc', includeFields = config.entities.optimize ? config.entities.category.includeFields : null, excludeFields = config.entities.optimize ? config.entities.category.excludeFields : null} = {}) => {
let searchQuery = new SearchQuery()
if (parent) {
searchQuery = searchQuery.applyFilter({key: 'parent_id', value: {'eq': parent.id ? parent.id : parent}})
}
if (level) {
searchQuery = searchQuery.applyFilter({key: 'level', value: {'eq': level}})
}

if (key) {
if (Array.isArray(value)) {
searchQuery = searchQuery.applyFilter({key: key, value: {'in': value}})
} else {
searchQuery = searchQuery.applyFilter({key: key, value: {'eq': value}})
}
}

if (onlyActive === true) {
searchQuery = searchQuery.applyFilter({key: 'is_active', value: {'eq': true}})
}

if (onlyNotEmpty === true) {
searchQuery = searchQuery.applyFilter({key: 'product_count', value: {'gt': 0}})
}
const response = await quickSearchByQuery({ entityType: 'category', query: searchQuery, sort: sort, size: size, start: start, includeFields: includeFields, excludeFields: excludeFields })
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the url/registerMapping call is skipped and the method is called without the filter parameters even when the config.entities.categoriesDynamicPrefetch is set to true

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return response.items
}

interface ProductResolver {
getProduct: (searchRequest: SearchRequest) => Promise<Product>,
getProducts: () => Product[]
}

interface CategoryService {
getCategories: (searchRequest?: any) => Promise<any>
}

export const ProductResolver: ProductResolver = {
getProduct,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be both services or both resolvers?

getProducts
}

export const CategoryService: CategoryService = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put export at the bottom of file, it's easier to read

getCategories
}
23 changes: 13 additions & 10 deletions core/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,24 +124,27 @@ export function baseFilterProductsQuery (parentCategory, filters = []) { // TODO
return searchProductQuery
}

export function buildFilterProductsQuery (currentCategory, chosenFilters, defaultFilters = null) {
export function buildFilterProductsQuery (currentCategory, chosenFilters = {}, defaultFilters = null) {
let filterQr = baseFilterProductsQuery(currentCategory, defaultFilters == null ? config.products.defaultFilters : defaultFilters)

// add choosedn filters
for (let code of Object.keys(chosenFilters)) {
const filter = chosenFilters[code]
const attributeCode = Array.isArray(filter) ? filter[0].attribute_code : filter.attribute_code

if (filter.attribute_code !== 'price') {
filterQr = filterQr.applyFilter({key: filter.attribute_code, value: {'eq': filter.id}, scope: 'catalog'})
if (Array.isArray(filter) && attributeCode !== 'price') {
const values = filter.map(filter => filter.id)
filterQr = filterQr.applyFilter({key: attributeCode, value: {'in': values}, scope: 'catalog'})
} else if (attributeCode !== 'price') {
filterQr = filterQr.applyFilter({key: attributeCode, value: {'eq': filter.id}, scope: 'catalog'})
} else { // multi should be possible filter here?
const rangeqr = {}
if (filter.from) {
rangeqr['gte'] = filter.from
}
if (filter.to) {
rangeqr['lte'] = filter.to
}
filterQr = filterQr.applyFilter({key: filter.attribute_code, value: rangeqr, scope: 'catalog'})
const filterValues = Array.isArray(filter) ? filter : [filter]
filterValues.forEach(singleFilter => {
if (singleFilter.from) rangeqr['gte'] = singleFilter.from
if (singleFilter.to) rangeqr['lte'] = singleFilter.to
})
filterQr = filterQr.applyFilter({key: attributeCode, value: rangeqr, scope: 'catalog'})
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/lib/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function isOnline (): boolean {
* @param {Int} size page size
* @return {Promise}
*/
export const quickSearchByQuery = async ({ query, start = 0, size = 50, entityType = 'product', sort = '', storeCode = null, excludeFields = null, includeFields = null }): Promise<SearchResponse> => {
export const quickSearchByQuery = async ({ query = {}, start = 0, size = 50, entityType = 'product', sort = '', storeCode = null, excludeFields = null, includeFields = null } = {}): Promise<SearchResponse> => {
const searchAdapter = await getSearchAdapter()
if (size <= 0) size = 50
if (start < 0) start = 0
Expand Down
22 changes: 22 additions & 0 deletions core/modules/catalog-next/helpers/categoryHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { parseCategoryPath } from '@vue-storefront/core/modules/breadcrumbs/helpers'

export const compareByLabel = (a, b) => {
if (a.label < b.label) {
return -1
}
if (a.label > b.label) {
return 1
}
return 0
}

export const calculateBreadcrumbs = (categories, id, list = []) => {
const category = categories.find(category => category.id === id)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is wrong assumption - that we have all the categories loaded when the https://docs.vuestorefront.io/guide/basics/configuration.html#dynamic-categories-prefetching is on. However, we can optimize - and in the Category.vue:asyncData load the root category (by slug) and then - by just single request - load all the categories used in the breadcrumb path. But please don't assume you have all the categories loaded.

Even as we don't have it in the state (so if even it's not outputed to the __INITIAL_STATE__ in large scale eCommerces categories collection can be really in MBs - which means, each SSR request will require a lot of RAM to process + it will kill the performance (parsing few MBs of JSON from elasticsearch is always a bad idea :D )

if (!category) return parseCategoryPath(list).reverse()
const result = [...list, category]

if (category.level > 1 && category.parent_id) {
return calculateBreadcrumbs(categories, category.parent_id, result)
}
return parseCategoryPath(result).reverse()
}
54 changes: 54 additions & 0 deletions core/modules/catalog-next/helpers/filterHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import FilterVariant from 'core/modules/catalog-next/types/FilterVariant';

export const getSystemFilterNames: string[] = ['sort']

/**
* Creates new filtersQuery (based on currentQuery) by modifying specific filter variant.
*/
export const changeFilterQuery = ({currentQuery = {}, filterVariant}: {currentQuery?: any, filterVariant?: FilterVariant} = {}) => {
const newQuery = JSON.parse(JSON.stringify(currentQuery))
if (!filterVariant) return newQuery
if (getSystemFilterNames.includes(filterVariant.type)) {
if (newQuery[filterVariant.type] && newQuery[filterVariant.type] === filterVariant.id) {
delete newQuery[filterVariant.type]
} else {
newQuery[filterVariant.type] = filterVariant.id
}
} else {
let queryFilter = newQuery[filterVariant.type] || []
if (!Array.isArray(queryFilter)) queryFilter = [queryFilter]
if (queryFilter.includes(filterVariant.id)) {
queryFilter = queryFilter.filter(value => value !== filterVariant.id)
} else {
queryFilter.push(filterVariant.id)
}
newQuery[filterVariant.type] = queryFilter
}
return newQuery
}

export const getFiltersFromQuery = ({filtersQuery = {}, availableFilters = {}} = {}) => {
const searchQuery = {
filters: {}
}
Object.keys(filtersQuery).forEach(filterKey => {
const filter = availableFilters[filterKey]
const queryValue = filtersQuery[filterKey]
if (!filter) return
if (getSystemFilterNames.includes(filterKey)) {
searchQuery[filterKey] = queryValue
} else if (Array.isArray(queryValue)) {
queryValue.map(singleValue => {
const variant = filter.find(filterVariant => filterVariant.id === singleValue)
if (!variant) return
if (!searchQuery.filters[filterKey] || !Array.isArray(searchQuery.filters[filterKey])) searchQuery.filters[filterKey] = []
searchQuery.filters[filterKey].push({...variant, attribute_code: filterKey})
})
} else {
const variant = filter.find(filterVariant => filterVariant.id === queryValue)
if (!variant) return
searchQuery.filters[filterKey] = {...variant, attribute_code: filterKey}
}
})
return searchQuery
}
39 changes: 39 additions & 0 deletions core/modules/catalog-next/helpers/optionLabel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Helper method for getting attribute name - TODO: to be moved to external/shared helper
*
* @param {String} attributeCode
* @param {String} optionId - value to get label for
*/
import toString from 'lodash-es/toString'

export function optionLabel (state, { attributeKey, searchBy = 'code', optionId }) {
let attrCache = state.labels[attributeKey]

if (attrCache) {
let label = attrCache[optionId]

if (label) {
return label
}
}
let attr = state['list_by_' + searchBy][attributeKey]
if (attr) {
let opt = attr.options.find((op) => { // TODO: cache it in memory
if (toString(op.value) === toString(optionId)) {
return op
}
}) // TODO: i18n support with multi-website attribute names

if (opt) {
if (!state.labels[attributeKey]) {
state.labels[attributeKey] = {}
}
state.labels[attributeKey][optionId] = opt.label
return opt ? opt.label : optionId
} else {
return optionId
}
} else {
return optionId
}
}
15 changes: 15 additions & 0 deletions core/modules/catalog-next/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// import { productModule } from './store/product'
// import { attributeModule } from './store/attribute'
// import { stockModule } from './store/stock'
// import { taxModule } from './store/tax'
import { categoryModule } from './store/category'
import { createModule } from '@vue-storefront/core/lib/module'
// import { beforeRegistration } from './hooks/beforeRegistration'

export const KEY = 'catalog-next'
export default createModule({
key: KEY,
store: { modules: [
{ key: 'category-next', module: categoryModule }
] }
})
5 changes: 5 additions & 0 deletions core/modules/catalog-next/store/category/CategoryState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default interface CategoryState {
categories: any,
availableFilters: any,
products: any
}
90 changes: 90 additions & 0 deletions core/modules/catalog-next/store/category/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// import Vue from 'vue'
import { ActionTree } from 'vuex'
import * as types from './mutation-types'
import RootState from '@vue-storefront/core/types/RootState'
import CategoryState from './CategoryState'
import { quickSearchByQuery } from '@vue-storefront/core/lib/search'
import { buildFilterProductsQuery } from '@vue-storefront/core/helpers'
import { router } from '@vue-storefront/core/app'
import FilterVariant from '../../types/FilterVariant'
import { CategoryService } from '@vue-storefront/core/data-resolver'
import { changeFilterQuery } from '../../helpers/filterHelpers'
import { products } from 'config'
import { configureProductAsync } from '@vue-storefront/core/modules/catalog/helpers'

const actions: ActionTree<CategoryState, RootState> = {
/**
* Initialise category module.
* - gets available categories
* - gets available filters for current category
*/
async initCategoryModule ({ getters, dispatch }) {
if (!getters.getCategories.length) {
await dispatch('loadCategories')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure but it seems like your approach is to load all the categories. Please remember that the category tree can be as big as up to few mega bytes (take the https://wonect.com). From VS 1.7 categories are dynamically loaded (only the root level - then after clicking in the SubBtn next level is loaded etc). Therefore the Category page need to load only the currently selected category by the category slug (category/single was used for this purpose before)

}
},
async loadCategoryProducts ({ commit, getters, dispatch }, { route } = {}) {
await dispatch('initCategoryModule')
const searchCategory = getters.getCategoryFrom(route.path)
await dispatch('loadCategoryFilters', searchCategory)
const searchQuery = getters.getCurrentFiltersFrom(route[products.routerFiltersSource])
let filterQr = buildFilterProductsQuery(searchCategory, searchQuery.filters)
const searchResult = await quickSearchByQuery({ query: filterQr, sort: searchQuery.sort })
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if'we re using the config.entites.products.includeFields ... as it was done with the progressive caching approach: https://github.com/DivanteLtd/vue-storefront/blob/70543b3cfa379971220f6514348fe0386a108878/core/modules/catalog/store/category/actions.ts#L240

It seems like not. Moreover, we're not running these 2 calls with the doublecheck (if it gains the performance) as it was originally done. It should work exact the same way

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moreover, the stock prefetching mechanism is also not ported to this refactored version: https://github.com/DivanteLtd/vue-storefront/blob/70543b3cfa379971220f6514348fe0386a108878/core/modules/catalog/store/category/actions.ts#L267

Without prefetching the stocks - when the config.products. filterUnavailableVariants is set to true - it will take forever to fetch the stocks on demand on the product page

let configuredProducts = searchResult.items.map(product => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is still a progressive caching feature missing plus the stock info prefetching - also missing - comparing to category/products.

Not sure why we don’t use product/list here but just wuickSearchByQuery. produxt/list also supports the caching by sku plus group products prefetching plus “syncPricesOver” feature which is pretty popular among our users.

What’s the plan to have these features still supported @patzick?

const configuredProductVariant = configureProductAsync({}, {product, configuration: searchQuery.filters, selectDefaultVariant: false, fallbackToDefaultWhenNoAvailable: true, setProductErorrs: false})
return Object.assign(product, configuredProductVariant)
})
commit(types.CATEGORY_SET_PRODUCTS, configuredProducts)
// await dispatch('loadAvailableFiltersFrom', searchResult)

return searchResult.items
},
async cacheProducts ({ commit, getters, dispatch }, { route } = {}) {
const searchCategory = getters.getCategoryFrom(route.path)
const searchQuery = getters.getCurrentFiltersFrom(route[products.routerFiltersSource])
let filterQr = buildFilterProductsQuery(searchCategory, searchQuery.filters)

console.error('CACHE 2 step...')
const xx = await dispatch('product/list', {
query: filterQr,
sort: searchQuery.sort,
updateState: false // not update the product listing - this request is only for caching
}, { root: true })
console.error('RETURNED PRODUCTS', xx)

// return searchResult.items
},
async findCategories () {
return CategoryService.getCategories()
},
async loadCategories ({ commit }) {
const categories = await CategoryService.getCategories()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're not registergin the urlMappings for loaded categories which will end up with poor performance (server query per each category route). This code from the original category/list does it: https://github.com/DivanteLtd/vue-storefront/blob/70543b3cfa379971220f6514348fe0386a108878/core/modules/catalog/store/category/actions.ts#L72

commit(types.CATEGORY_SET_CATEGORIES, categories)
return categories
},
/**
* Fetch and process filters from current category and sets them in available filters.
*/
async loadCategoryFilters ({ dispatch, getters }, category) {
const searchCategory = category || getters.getCurrentCategory
let filterQr = buildFilterProductsQuery(searchCategory)
const searchResult = await quickSearchByQuery({ query: filterQr })
await dispatch('loadAvailableFiltersFrom', searchResult)
},
async loadAvailableFiltersFrom ({ commit, getters }, {aggregations}) {
const filters = getters.getAvailableFiltersFrom(aggregations)
commit(types.CATEGORY_SET_AVAILABLE_FILTERS, filters)
},
async switchSearchFilter ({ dispatch }, filterVariant: FilterVariant) {
const newQuery = changeFilterQuery({currentQuery: router.currentRoute[products.routerFiltersSource], filterVariant})
await dispatch('changeRouterFilterParameters', newQuery)
},
async resetFilters ({dispatch}) {
await dispatch('changeRouterFilterParameters', {})
},
async changeRouterFilterParameters (context, query) {
router.push({[products.routerFiltersSource]: query})
}
}

export default actions
Loading