UNPKG

@shopgate/pwa-common-commerce

Version:

Commerce library for the Shopgate Connect PWA.

134 lines (132 loc) 4.21 kB
import { LoadingProvider } from '@shopgate/pwa-common/providers'; import { ACTION_PUSH, ACTION_REPLACE } from '@virtuous/conductor'; import { buildFetchSearchResultsParams, getProductsResult } from '@shopgate/engage/product'; import { hex2bin, router } from '@shopgate/engage/core'; import { CATEGORY_ALL_PATTERN, fetchCategory, getShowAllProductsFilters } from '@shopgate/engage/category'; import { getCurrentRoute } from '@shopgate/pwa-common/selectors/router'; import expireProductsByHash from '@shopgate/pwa-common-commerce/product/action-creators/expireProductsByHash'; import fetchSearchResults from '@shopgate/pwa-common-commerce/search/actions/fetchSearchResults'; import fetchFilters from '@shopgate/pwa-common-commerce/filter/actions/fetchFilters'; import { buildFilterParamsForFetchFiltersRequest } from '@shopgate/engage/filter/helpers'; import { categoryAllWillEnter$, categoryAllFiltersDidUpdateFromFilterPage$ } from '@shopgate/pwa-common-commerce/category/streams'; import { searchWillEnter$, searchFiltersDidUpdateFromFilterPage$, searchRequesting$, searchReceived$, searchProductsNeedUpdate$ } from "../streams"; import { SEARCH_PATTERN } from "../constants"; const searchBasedRouteWillEnter$ = searchWillEnter$.merge(categoryAllWillEnter$); const searchBasedFiltersDidUpdateFromFilterPage$ = searchFiltersDidUpdateFromFilterPage$.merge(categoryAllFiltersDidUpdateFromFilterPage$); /** * Search subscriptions. * @param {Function} subscribe The subscribe function. */ export default function search(subscribe) { subscribe(searchRequesting$, () => { LoadingProvider.setLoading(SEARCH_PATTERN); }); subscribe(searchReceived$, () => { LoadingProvider.unsetLoading(SEARCH_PATTERN); }); subscribe(searchBasedRouteWillEnter$, async ({ action, dispatch, getState }) => { if (![ACTION_PUSH, ACTION_REPLACE].includes(action?.historyAction)) { return; } let { filters } = action.route.state; let { s: searchPhrase } = action.route.query; const { sort } = action.route.query; if (action.route.pattern === CATEGORY_ALL_PATTERN) { searchPhrase = '*'; if (!filters) { const category = await dispatch(fetchCategory(hex2bin(action.route.params.categoryId))); filters = getShowAllProductsFilters(category); router.update(action.route.id, { filters, categoryName: category.name }); } } const { hash, expired } = getProductsResult(getState(), { searchPhrase, routeId: action?.route?.id, ...buildFetchSearchResultsParams() }); if (expired) { dispatch(expireProductsByHash(hash)); } dispatch(fetchSearchResults({ filters, searchPhrase, sort, ...buildFetchSearchResultsParams() })); dispatch(fetchFilters({ filters: buildFilterParamsForFetchFiltersRequest(filters) })); }); // No logic related to "show all products" necessary here, since stream only emits when // location based shopping is active. That's currently only supported when new services are // used, but the new services don't support "show all products". subscribe(searchProductsNeedUpdate$, ({ dispatch, getState }) => { const { query, state: { filters }, pattern } = getCurrentRoute(getState()); const { sort } = query; let { s: searchPhrase } = query; if (pattern === CATEGORY_ALL_PATTERN) { searchPhrase = '*'; } dispatch(fetchSearchResults({ filters, searchPhrase, sort, ...buildFetchSearchResultsParams() })); }); subscribe(searchBasedFiltersDidUpdateFromFilterPage$, ({ dispatch, action }) => { const { filters } = action.route.state; const { pattern } = action.route; const { sort } = action.route.query; let { s: searchPhrase } = action.route.query; if (pattern === CATEGORY_ALL_PATTERN) { searchPhrase = '*'; } dispatch(fetchSearchResults({ filters, searchPhrase, sort, ...buildFetchSearchResultsParams() })); }); }