@shopgate/pwa-common-commerce 7.30.0-alpha.6 → 7.30.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cart/action-creators/addCouponsToCart.js +9 -2
- package/cart/action-creators/addProductsToCart.js +9 -2
- package/cart/action-creators/deleteCouponsFromCart.js +9 -2
- package/cart/action-creators/deleteProductsFromCart.js +9 -2
- package/cart/action-creators/errorAddCouponsToCart.js +10 -2
- package/cart/action-creators/errorAddProductsToCart.js +10 -2
- package/cart/action-creators/errorCart.js +8 -2
- package/cart/action-creators/errorDeleteCouponsFromCart.js +10 -2
- package/cart/action-creators/errorDeleteProductsFromCart.js +10 -2
- package/cart/action-creators/errorUpdateProductsInCart.js +10 -2
- package/cart/action-creators/receiveCart.js +9 -2
- package/cart/action-creators/requestCart.js +8 -2
- package/cart/action-creators/setCartProductPendingCount.js +9 -2
- package/cart/action-creators/setCouponFieldError.js +9 -2
- package/cart/action-creators/setCouponFieldValue.js +9 -2
- package/cart/action-creators/setFulfillmentSlot.js +9 -2
- package/cart/action-creators/successAddCouponsToCart.js +10 -2
- package/cart/action-creators/successAddProductsToCart.js +8 -2
- package/cart/action-creators/successDeleteCouponsFromCart.js +8 -2
- package/cart/action-creators/successDeleteProductsFromCart.js +8 -2
- package/cart/action-creators/successUpdateProductsInCart.js +8 -2
- package/cart/action-creators/updateProductsInCart.js +9 -2
- package/cart/actions/addCouponsToCart.js +52 -8
- package/cart/actions/addProductsToCart.js +80 -11
- package/cart/actions/deleteCouponsFromCart.js +39 -6
- package/cart/actions/deleteProductsFromCart.js +38 -6
- package/cart/actions/fetchCart.js +52 -8
- package/cart/actions/updateProductsInCart.js +44 -6
- package/cart/constants/PipelineErrors.js +6 -1
- package/cart/constants/Pipelines.js +6 -1
- package/cart/constants/Portals.js +85 -1
- package/cart/constants/index.js +39 -2
- package/cart/helpers/config.js +47 -2
- package/cart/helpers/createPipelineErrorList.js +30 -4
- package/cart/helpers/fulfillmentSlots.js +37 -4
- package/cart/helpers/index.js +14 -3
- package/cart/helpers/quantity.js +23 -4
- package/cart/helpers/shipping.js +57 -2
- package/cart/helpers/tax.js +26 -2
- package/cart/index.js +25 -5
- package/cart/mock.js +130 -1
- package/cart/reducers/couponField.js +30 -2
- package/cart/reducers/data.js +98 -6
- package/cart/reducers/index.js +7 -1
- package/cart/selectors/index.js +181 -31
- package/cart/selectors/spec.js +189 -2
- package/cart/streams/index.js +176 -29
- package/cart/subscriptions/index.js +307 -30
- package/category/action-creators/errorCategory.js +10 -2
- package/category/action-creators/errorCategoryChildren.js +9 -2
- package/category/action-creators/errorRootCategories.js +8 -2
- package/category/action-creators/receiveCategory.js +12 -2
- package/category/action-creators/receiveCategoryChildren.js +10 -2
- package/category/action-creators/receiveRootCategories.js +9 -2
- package/category/action-creators/requestCategory.js +9 -2
- package/category/action-creators/requestCategoryChildren.js +9 -2
- package/category/action-creators/requestRootCategories.js +8 -2
- package/category/actions/fetchCategory.js +47 -5
- package/category/actions/fetchCategoryChildren.js +30 -2
- package/category/actions/fetchCategoryOrRootCategories.js +16 -2
- package/category/actions/fetchCategoryProducts.js +36 -2
- package/category/actions/fetchRootCategories.js +31 -2
- package/category/actions/getCategory.js +10 -2
- package/category/constants/Pipelines.js +3 -1
- package/category/constants/Portals.js +56 -3
- package/category/constants/index.js +17 -2
- package/category/helpers/index.js +27 -3
- package/category/index.js +19 -5
- package/category/mock.js +176 -1
- package/category/reducers/categoriesById.js +65 -3
- package/category/reducers/childrenByCategoryId.js +55 -4
- package/category/reducers/helpers/handleCategoryCollection.js +24 -3
- package/category/reducers/helpers/handleReceivedCategories.js +3 -1
- package/category/reducers/index.js +12 -2
- package/category/reducers/rootCategories.js +31 -2
- package/category/selectors/index.js +115 -16
- package/category/streams/index.js +82 -4
- package/category/subscriptions/index.js +96 -3
- package/checkout/action-creators/successCheckout.js +9 -2
- package/checkout/actions/fetchCheckoutUrl.js +28 -3
- package/checkout/constants/Pipelines.js +1 -1
- package/checkout/constants/index.js +3 -2
- package/checkout/index.js +11 -4
- package/checkout/selectors/index.js +7 -2
- package/checkout/streams/index.js +8 -2
- package/checkout/subscriptions/index.js +35 -6
- package/favorites/action-creators/index.js +206 -24
- package/favorites/actions/addFavorites.js +41 -3
- package/favorites/actions/addFavoritesList.js +27 -2
- package/favorites/actions/fetchFavoriteIds.js +49 -5
- package/favorites/actions/fetchFavorites.js +60 -5
- package/favorites/actions/fetchFavoritesList.js +47 -3
- package/favorites/actions/fetchFavoritesListsWithItems.js +32 -3
- package/favorites/actions/getFavorites.js +6 -2
- package/favorites/actions/removeFavorites.js +32 -3
- package/favorites/actions/removeFavoritesList.js +24 -2
- package/favorites/actions/toggleFavorites.js +68 -10
- package/favorites/actions/updateFavorites.js +39 -3
- package/favorites/actions/updateFavoritesList.js +26 -2
- package/favorites/constants/Pipelines.js +9 -1
- package/favorites/constants/Portals.js +32 -4
- package/favorites/constants/index.js +37 -5
- package/favorites/index.js +14 -4
- package/favorites/mock.js +89 -4
- package/favorites/reducers/index.js +7 -1
- package/favorites/reducers/lists.js +74 -2
- package/favorites/reducers/products.js +231 -24
- package/favorites/selectors/index.js +188 -24
- package/favorites/streams/index.js +135 -23
- package/favorites/streams/spec.js +517 -8
- package/favorites/subscriptions/index.js +260 -25
- package/favorites/subscriptions/spec.js +701 -28
- package/filter/action-creators/errorFilters.js +9 -2
- package/filter/action-creators/index.js +4 -1
- package/filter/action-creators/receiveFilters.js +10 -2
- package/filter/action-creators/requestFilters.js +9 -2
- package/filter/action-creators/updateFilters.js +8 -2
- package/filter/actions/fetchFilters.js +46 -3
- package/filter/actions/getFilters.js +6 -2
- package/filter/actions/helpers/buildFilterParams.js +34 -2
- package/filter/actions/helpers/buildRequestFilters.js +35 -2
- package/filter/actions/helpers/processFilters.js +10 -2
- package/filter/actions/helpers/processParams.js +26 -2
- package/filter/constants/Pipelines.js +1 -1
- package/filter/constants/Portals.js +39 -3
- package/filter/constants/index.js +8 -1
- package/filter/index.js +12 -4
- package/filter/reducers/helpers/enrichFilters.js +11 -3
- package/filter/reducers/index.js +5 -1
- package/filter/reducers/resultsByHash.js +43 -3
- package/filter/selectors/index.js +47 -6
- package/filter/streams/index.js +30 -1
- package/filter/subscriptions/index.js +34 -2
- package/market/constants/Portals.js +22 -4
- package/market/constants/index.js +2 -1
- package/market/helpers/showReturnPolicy.js +3 -1
- package/market/helpers/showTaxDisclaimer.js +3 -1
- package/market/index.js +6 -2
- package/orders/constants.js +2 -1
- package/package.json +3 -3
- package/product/action-creators/deleteProductsByIds.js +10 -2
- package/product/action-creators/errorProduct.js +10 -2
- package/product/action-creators/errorProductDescription.js +10 -2
- package/product/action-creators/errorProductImages.js +10 -2
- package/product/action-creators/errorProductMedia.js +10 -2
- package/product/action-creators/errorProductOptions.js +10 -2
- package/product/action-creators/errorProductProperties.js +10 -2
- package/product/action-creators/errorProductRelations.js +9 -2
- package/product/action-creators/errorProductShipping.js +10 -2
- package/product/action-creators/errorProductVariants.js +10 -2
- package/product/action-creators/errorProducts.js +9 -2
- package/product/action-creators/expireProductById.js +10 -2
- package/product/action-creators/expireProductData.js +11 -2
- package/product/action-creators/expireProductsByHash.js +9 -2
- package/product/action-creators/productNotAvailable.js +10 -2
- package/product/action-creators/provideProduct.js +9 -2
- package/product/action-creators/receiveProduct.js +10 -2
- package/product/action-creators/receiveProductCached.js +9 -2
- package/product/action-creators/receiveProductDescription.js +10 -2
- package/product/action-creators/receiveProductImages.js +10 -2
- package/product/action-creators/receiveProductMedia.js +10 -2
- package/product/action-creators/receiveProductOptions.js +10 -2
- package/product/action-creators/receiveProductProperties.js +10 -2
- package/product/action-creators/receiveProductRelations.js +12 -2
- package/product/action-creators/receiveProductShipping.js +10 -2
- package/product/action-creators/receiveProductVariants.js +10 -2
- package/product/action-creators/receiveProducts.js +16 -2
- package/product/action-creators/receiveProductsCached.js +9 -2
- package/product/action-creators/refreshExpiredPDPData.js +8 -2
- package/product/action-creators/requestProduct.js +10 -2
- package/product/action-creators/requestProductDescription.js +9 -2
- package/product/action-creators/requestProductImages.js +9 -2
- package/product/action-creators/requestProductMedia.js +9 -2
- package/product/action-creators/requestProductOptions.js +9 -2
- package/product/action-creators/requestProductProperties.js +9 -2
- package/product/action-creators/requestProductRelations.js +10 -2
- package/product/action-creators/requestProductShipping.js +9 -2
- package/product/action-creators/requestProductVariants.js +9 -2
- package/product/action-creators/requestProducts.js +9 -2
- package/product/action-creators/setProductId.js +9 -2
- package/product/action-creators/setProductQuantity.js +9 -2
- package/product/action-creators/setProductVariantId.js +9 -2
- package/product/actions/changeSortOrder.js +21 -2
- package/product/actions/fetchHighlightProducts.js +18 -2
- package/product/actions/fetchLiveshoppingProducts.js +14 -2
- package/product/actions/fetchProduct.js +52 -3
- package/product/actions/fetchProductDescription.js +30 -2
- package/product/actions/fetchProductImages.js +31 -2
- package/product/actions/fetchProductMedia.js +35 -2
- package/product/actions/fetchProductOptions.js +31 -2
- package/product/actions/fetchProductProperties.js +30 -2
- package/product/actions/fetchProductRelations.js +63 -2
- package/product/actions/fetchProductShipping.js +31 -2
- package/product/actions/fetchProductVariants.js +31 -2
- package/product/actions/fetchProducts.js +189 -17
- package/product/actions/fetchProductsById.js +68 -8
- package/product/actions/fetchProductsByQuery.js +102 -18
- package/product/actions/getHighlightProducts.js +6 -2
- package/product/actions/getLiveshoppingProducts.js +6 -2
- package/product/actions/getProduct.js +6 -2
- package/product/actions/getProductDescription.js +6 -2
- package/product/actions/getProductImages.js +6 -2
- package/product/actions/getProductOptions.js +6 -2
- package/product/actions/getProductProperties.js +6 -2
- package/product/actions/getProductRelations.js +6 -2
- package/product/actions/getProductShipping.js +6 -2
- package/product/actions/getProductVariants.js +6 -2
- package/product/actions/getProducts.js +6 -2
- package/product/actions/getProductsById.js +6 -2
- package/product/actions/getProductsByQuery.js +6 -2
- package/product/actions/processProductFlags.js +35 -3
- package/product/actions/updateMetadata.js +17 -2
- package/product/collections/ProductImageFormats.js +48 -8
- package/product/collections/index.js +1 -1
- package/product/constants/Pipelines.js +12 -1
- package/product/constants/Portals.js +200 -33
- package/product/constants/index.js +90 -18
- package/product/helpers/index.js +61 -8
- package/product/index.js +36 -6
- package/product/mock.js +1002 -2
- package/product/reducers/descriptionsByProductId.js +54 -5
- package/product/reducers/helpers/formatOptions.js +17 -2
- package/product/reducers/helpers/handleProductCollection.js +19 -2
- package/product/reducers/imagesByProductId.js +51 -4
- package/product/reducers/index.js +23 -1
- package/product/reducers/mediaByProductId.js +55 -3
- package/product/reducers/optionsByProductId.js +41 -2
- package/product/reducers/productRelationsByHash.js +43 -2
- package/product/reducers/productsById.js +122 -7
- package/product/reducers/propertiesByProductId.js +48 -2
- package/product/reducers/resultsByHash.js +125 -9
- package/product/reducers/shippingByProductId.js +37 -2
- package/product/reducers/variantsByProductId.js +56 -2
- package/product/selectors/options.js +90 -13
- package/product/selectors/page.js +62 -13
- package/product/selectors/price.js +81 -18
- package/product/selectors/product.js +549 -59
- package/product/selectors/product.mock.js +327 -12
- package/product/selectors/relations.js +35 -5
- package/product/selectors/variants.js +91 -15
- package/product/streams/index.js +167 -13
- package/product/subscriptions/index.js +210 -4
- package/reviews/action-creators/errorProductReviews.js +9 -2
- package/reviews/action-creators/errorReviews.js +9 -2
- package/reviews/action-creators/errorSubmitReview.js +9 -2
- package/reviews/action-creators/errorUserReview.js +9 -2
- package/reviews/action-creators/flushUserReview.js +8 -2
- package/reviews/action-creators/receiveProductReviews.js +11 -2
- package/reviews/action-creators/receiveReviews.js +12 -2
- package/reviews/action-creators/receiveSubmitReview.js +9 -2
- package/reviews/action-creators/receiveUserReview.js +10 -2
- package/reviews/action-creators/requestProductReviews.js +10 -2
- package/reviews/action-creators/requestReviews.js +9 -2
- package/reviews/action-creators/requestSubmitReview.js +9 -2
- package/reviews/action-creators/requestUserReview.js +9 -2
- package/reviews/action-creators/resetSubmittedReview.js +9 -2
- package/reviews/action-creators/spec.js +40 -1
- package/reviews/actions/fetchProductReviews.js +37 -2
- package/reviews/actions/fetchReviews.js +38 -2
- package/reviews/actions/fetchUserReview.js +31 -2
- package/reviews/actions/flushUserReview.js +5 -1
- package/reviews/actions/getProductReviews.js +6 -2
- package/reviews/actions/getUserReview.js +6 -2
- package/reviews/actions/spec.js +241 -4
- package/reviews/actions/submitReview.js +63 -3
- package/reviews/constants/Pipelines.js +4 -1
- package/reviews/constants/Portals.js +4 -1
- package/reviews/constants/index.js +26 -7
- package/reviews/index.js +15 -4
- package/reviews/mock.js +172 -11
- package/reviews/reducers/index.js +11 -1
- package/reviews/reducers/mock.js +14 -2
- package/reviews/reducers/reviewsByHash.js +52 -6
- package/reviews/reducers/reviewsById.js +27 -2
- package/reviews/reducers/reviewsByProductId.js +47 -2
- package/reviews/reducers/spec.js +211 -2
- package/reviews/reducers/userReviewsByProductId.js +68 -2
- package/reviews/selectors/index.js +123 -19
- package/reviews/selectors/mock.js +100 -1
- package/reviews/selectors/spec.js +100 -1
- package/reviews/streams/index.js +37 -5
- package/reviews/streams/spec.js +25 -1
- package/reviews/subscriptions/index.js +27 -2
- package/scanner/action-creators/errorHandleScanner.js +11 -2
- package/scanner/action-creators/scannerFinished.js +11 -2
- package/scanner/action-creators/startScanner.js +8 -2
- package/scanner/action-creators/successHandleScanner.js +11 -2
- package/scanner/actions/handleBarCode.js +22 -2
- package/scanner/actions/handleNoResults.js +23 -2
- package/scanner/actions/handleQrCode.js +116 -6
- package/scanner/actions/handleSearch.js +33 -2
- package/scanner/constants/Portals.js +22 -1
- package/scanner/constants/index.js +17 -1
- package/scanner/helpers/index.js +115 -5
- package/scanner/index.js +19 -5
- package/scanner/streams/index.js +36 -1
- package/scanner/subscriptions/index.js +78 -8
- package/search/action-creators/errorSearchResults.js +10 -2
- package/search/action-creators/receiveSearchResults.js +11 -2
- package/search/action-creators/receiveSearchSuggestions.js +10 -2
- package/search/action-creators/requestSearchResults.js +10 -2
- package/search/action-creators/requestSearchSuggestions.js +9 -2
- package/search/actions/fetchSearchResults.js +66 -8
- package/search/actions/fetchSearchSuggestions.js +36 -2
- package/search/constants/Pipelines.js +1 -1
- package/search/constants/Portals.js +9 -2
- package/search/constants/index.js +10 -2
- package/search/helpers/index.js +5 -2
- package/search/helpers/removeHighlightingPlaceholders.js +4 -1
- package/search/helpers/spec.js +19 -1
- package/search/index.js +17 -5
- package/search/reducers/index.js +38 -2
- package/search/selectors/index.js +23 -4
- package/search/streams/index.js +51 -3
- package/search/subscriptions/index.js +132 -5
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import{RECEIVE_SEARCH_RESULTS}from"../constants"
|
|
1
|
+
import { RECEIVE_SEARCH_RESULTS } from "../constants";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Creates the dispatched RECEIVE_SEARCH_RESULTS action object.
|
|
3
5
|
* @param {string} searchPhrase The search phrase.
|
|
4
6
|
* @param {number} offset The result offset.
|
|
5
7
|
* @param {Object} results The search results.
|
|
6
8
|
* @return {Object} The RECEIVE_SEARCH_RESULTS action.
|
|
7
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
const receiveSearchResults = (searchPhrase, offset, results) => ({
|
|
11
|
+
type: RECEIVE_SEARCH_RESULTS,
|
|
12
|
+
searchPhrase,
|
|
13
|
+
offset,
|
|
14
|
+
results
|
|
15
|
+
});
|
|
16
|
+
export default receiveSearchResults;
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import{RECEIVE_SEARCH_SUGGESTIONS}from"../constants"
|
|
1
|
+
import { RECEIVE_SEARCH_SUGGESTIONS } from "../constants";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Creates the dispatched RECEIVE_SEARCH_SUGGESTIONS action object.
|
|
3
5
|
* @param {string} searchPhrase The search phrase.
|
|
4
6
|
* @param {Array} suggestions Array of strings. The suggestions for the search phrase.
|
|
5
7
|
* @return {Object} The RECEIVE_SEARCH_SUGGESTIONS action.
|
|
6
|
-
*/
|
|
8
|
+
*/
|
|
9
|
+
const receiveSearchSuggestions = (searchPhrase, suggestions) => ({
|
|
10
|
+
type: RECEIVE_SEARCH_SUGGESTIONS,
|
|
11
|
+
searchPhrase,
|
|
12
|
+
suggestions
|
|
13
|
+
});
|
|
14
|
+
export default receiveSearchSuggestions;
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import{REQUEST_SEARCH_RESULTS}from"../constants"
|
|
1
|
+
import { REQUEST_SEARCH_RESULTS } from "../constants";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Creates the dispatched REQUEST_SEARCH_RESULTS action object.
|
|
3
5
|
* @param {string} searchPhrase The search phrase.
|
|
4
6
|
* @param {number} offset The result offset.
|
|
5
7
|
* @return {Object} The REQUEST_SEARCH_RESULTS action.
|
|
6
|
-
*/
|
|
8
|
+
*/
|
|
9
|
+
const requestSearchResults = (searchPhrase, offset) => ({
|
|
10
|
+
type: REQUEST_SEARCH_RESULTS,
|
|
11
|
+
searchPhrase,
|
|
12
|
+
offset
|
|
13
|
+
});
|
|
14
|
+
export default requestSearchResults;
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import{REQUEST_SEARCH_SUGGESTIONS}from"../constants"
|
|
1
|
+
import { REQUEST_SEARCH_SUGGESTIONS } from "../constants";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Creates the dispatched REQUEST_SEARCH_SUGGESTIONS action object.
|
|
3
5
|
* @param {string} searchPhrase The search phrase.
|
|
4
6
|
* @return {Object} The REQUEST_SEARCH_SUGGESTIONS action.
|
|
5
|
-
*/
|
|
7
|
+
*/
|
|
8
|
+
const requestSearchSuggestions = searchPhrase => ({
|
|
9
|
+
type: REQUEST_SEARCH_SUGGESTIONS,
|
|
10
|
+
searchPhrase
|
|
11
|
+
});
|
|
12
|
+
export default requestSearchSuggestions;
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import { ITEMS_PER_LOAD } from '@shopgate/pwa-common/constants/DisplayOptions';
|
|
2
|
+
import { mutable } from '@shopgate/pwa-common/helpers/redux';
|
|
3
|
+
import { makeGetDefaultSortOrder } from '@shopgate/engage/filter/selectors';
|
|
4
|
+
import fetchProducts from "../../product/actions/fetchProducts";
|
|
5
|
+
import requestSearchResults from "../action-creators/requestSearchResults";
|
|
6
|
+
import receiveSearchResults from "../action-creators/receiveSearchResults";
|
|
7
|
+
import errorSearchResults from "../action-creators/errorSearchResults";
|
|
8
|
+
const getDefaultSortOrder = makeGetDefaultSortOrder();
|
|
9
|
+
|
|
10
|
+
/**
|
|
2
11
|
* Retrieves products for a certain search query.
|
|
3
12
|
* @param {Object} params The params for the search products to request.
|
|
4
13
|
* @param {string} params.searchPhrase Search phrase for the request
|
|
@@ -11,13 +20,62 @@ function _extends(){_extends=Object.assign||function(target){for(var i=1;i<argum
|
|
|
11
20
|
* @param {boolean} [params.resolveCachedProducts=false] Whether to resolve with products even
|
|
12
21
|
* when no actual request was done due to cached data.
|
|
13
22
|
* @return {Function} The dispatched action.
|
|
14
|
-
*/
|
|
15
|
-
dispatch
|
|
23
|
+
*/
|
|
24
|
+
const fetchSearchResults = params => (dispatch, getState) => {
|
|
25
|
+
const defaultSortOrder = getDefaultSortOrder(getState(), {
|
|
26
|
+
searchPhrase: params.searchPhrase
|
|
27
|
+
});
|
|
28
|
+
const {
|
|
29
|
+
offset = 0,
|
|
30
|
+
searchPhrase,
|
|
31
|
+
limit = ITEMS_PER_LOAD,
|
|
32
|
+
sort = defaultSortOrder,
|
|
33
|
+
filters = null,
|
|
34
|
+
params: searchParams = null,
|
|
35
|
+
cachedTime = null,
|
|
36
|
+
resolveCachedProducts = false
|
|
37
|
+
} = params;
|
|
38
|
+
if (!searchPhrase) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const promise = dispatch(fetchProducts({
|
|
42
|
+
cachedTime,
|
|
43
|
+
params: {
|
|
44
|
+
searchPhrase,
|
|
45
|
+
offset,
|
|
46
|
+
limit,
|
|
47
|
+
sort,
|
|
48
|
+
...searchParams
|
|
49
|
+
},
|
|
50
|
+
filters,
|
|
51
|
+
resolveCachedProducts,
|
|
52
|
+
onBeforeDispatch: () => {
|
|
53
|
+
// Dispatch the request action before the related pipeline request is executed.
|
|
54
|
+
dispatch(requestSearchResults(searchPhrase, offset));
|
|
55
|
+
}
|
|
56
|
+
}));
|
|
57
|
+
|
|
58
|
+
/**
|
|
16
59
|
* Whenever fetchProducts is able to deliver product data
|
|
17
60
|
* - either via a request or from the cache -
|
|
18
61
|
* it returns a promise which will be resolved with the response data.
|
|
19
|
-
*/
|
|
20
|
-
if(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
62
|
+
*/
|
|
63
|
+
if (promise instanceof Promise) {
|
|
64
|
+
promise.then(response => {
|
|
65
|
+
// Inspect the response object to determine, if it represents a search result, or an error.
|
|
66
|
+
if (response && response.products && Array.isArray(response.products)) {
|
|
67
|
+
// Dispatch the receive action when the response contains valid data.s
|
|
68
|
+
dispatch(receiveSearchResults(searchPhrase, offset, response));
|
|
69
|
+
} else {
|
|
70
|
+
// If no valid data is delivered within the response the error action is dispatched.
|
|
71
|
+
dispatch(errorSearchResults(searchPhrase, offset));
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// eslint-disable-next-line consistent-return
|
|
77
|
+
return promise;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/** @mixes {MutableFunction} */
|
|
81
|
+
export default mutable(fetchSearchResults);
|
|
@@ -1,5 +1,39 @@
|
|
|
1
|
-
import PipelineRequest from'@shopgate/pwa-core/classes/PipelineRequest';
|
|
1
|
+
import PipelineRequest from '@shopgate/pwa-core/classes/PipelineRequest';
|
|
2
|
+
import { mutable } from '@shopgate/pwa-common/helpers/redux';
|
|
3
|
+
import { SHOPGATE_CATALOG_GET_SEARCH_SUGGESTIONS } from "../constants/Pipelines";
|
|
4
|
+
import requestSearchSuggestions from "../action-creators/requestSearchSuggestions";
|
|
5
|
+
import receiveSearchSuggestions from "../action-creators/receiveSearchSuggestions";
|
|
6
|
+
import { getSuggestionsState } from "../selectors";
|
|
7
|
+
import removeHighlightingPlaceholders from "../helpers/removeHighlightingPlaceholders";
|
|
8
|
+
|
|
9
|
+
/**
|
|
2
10
|
* Get suggestions from cache or pipeline.
|
|
3
11
|
* @param {string} searchPhrase The search phrase.
|
|
4
12
|
* @returns {Function} A redux thunk.
|
|
5
|
-
*/
|
|
13
|
+
*/
|
|
14
|
+
function fetchSearchSuggestions(searchPhrase) {
|
|
15
|
+
return (dispatch, getState) => {
|
|
16
|
+
if (searchPhrase.length < 3) {
|
|
17
|
+
return Promise.resolve(null);
|
|
18
|
+
}
|
|
19
|
+
const cached = getSuggestionsState(getState())[searchPhrase];
|
|
20
|
+
if (cached && (cached.isFetching || cached.expires >= Date.now())) {
|
|
21
|
+
return Promise.resolve(null);
|
|
22
|
+
}
|
|
23
|
+
dispatch(requestSearchSuggestions(searchPhrase));
|
|
24
|
+
const request = new PipelineRequest(SHOPGATE_CATALOG_GET_SEARCH_SUGGESTIONS).setInput({
|
|
25
|
+
searchPhrase
|
|
26
|
+
}).dispatch();
|
|
27
|
+
request.then(result => {
|
|
28
|
+
const {
|
|
29
|
+
suggestions
|
|
30
|
+
} = result;
|
|
31
|
+
const suggestionsWithoutPlaceholders = removeHighlightingPlaceholders(suggestions);
|
|
32
|
+
dispatch(receiveSearchSuggestions(searchPhrase, suggestionsWithoutPlaceholders));
|
|
33
|
+
});
|
|
34
|
+
return request;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** @mixes {MutableFunction} */
|
|
39
|
+
export default mutable(fetchSearchSuggestions);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export const SHOPGATE_CATALOG_GET_SEARCH_SUGGESTIONS = 'shopgate.catalog.getSearchSuggestions';
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
// FEATURES
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
const SEARCH = 'search';
|
|
3
|
+
|
|
4
|
+
// CONTENTS
|
|
5
|
+
const SUGGESTIONS = 'suggestions';
|
|
6
|
+
const SUGGESTION_ITEM = 'suggestion-item';
|
|
7
|
+
const SUGGESTION_ITEM_CONTENT = 'suggestion-item-content';
|
|
8
|
+
export const SEARCH_SUGGESTIONS = `${SEARCH}.${SUGGESTIONS}`;
|
|
9
|
+
export const SEARCH_SUGGESTION_ITEM = `${SEARCH}.${SUGGESTION_ITEM}`;
|
|
10
|
+
export const SEARCH_SUGGESTION_ITEM_CONTENT = `${SEARCH}.${SUGGESTION_ITEM_CONTENT}`;
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
1
|
+
export const SEARCH_PATH = '/search';
|
|
2
|
+
export const SEARCH_PATTERN = SEARCH_PATH;
|
|
3
|
+
export const SEARCH_FILTER_PATTERN = `${SEARCH_PATH}/filter`;
|
|
4
|
+
export const SEARCH_SUGGESTIONS_LIFETIME = 86400000; // 24 hours in milliseconds
|
|
5
|
+
|
|
6
|
+
export const REQUEST_SEARCH_RESULTS = 'REQUEST_SEARCH_RESULTS';
|
|
7
|
+
export const RECEIVE_SEARCH_RESULTS = 'RECEIVE_SEARCH_RESULTS';
|
|
8
|
+
export const ERROR_SEARCH_RESULTS = 'ERROR_SEARCH_RESULTS';
|
|
9
|
+
export const REQUEST_SEARCH_SUGGESTIONS = 'REQUEST_SEARCH_SUGGESTIONS';
|
|
10
|
+
export const RECEIVE_SEARCH_SUGGESTIONS = 'RECEIVE_SEARCH_SUGGESTIONS';
|
package/search/helpers/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import{SEARCH_PATH}from"../constants"
|
|
1
|
+
import { SEARCH_PATH } from "../constants";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Generate product route for navigation.
|
|
3
5
|
* @param {string} query search term
|
|
4
6
|
* @returns {string}
|
|
5
|
-
*/
|
|
7
|
+
*/
|
|
8
|
+
export const getSearchRoute = query => `${SEARCH_PATH}?s=${encodeURIComponent(query)}`;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import "core-js/modules/es.string.replace.js";
|
|
1
2
|
/**
|
|
2
3
|
* Pipeline call adds $start$ and $end$ placeholders for higlighting purposes.
|
|
3
4
|
*
|
|
@@ -6,4 +7,6 @@
|
|
|
6
7
|
*
|
|
7
8
|
* @param {Array} suggestions An array of strings.
|
|
8
9
|
* @returns {Array}
|
|
9
|
-
*/
|
|
10
|
+
*/
|
|
11
|
+
const removeHighlightingPlaceholers = suggestions => suggestions.map(item => item.replace(/\$start\$|\$end\$/g, ''));
|
|
12
|
+
export default removeHighlightingPlaceholers;
|
package/search/helpers/spec.js
CHANGED
|
@@ -1 +1,19 @@
|
|
|
1
|
-
import removeHighlightingPlaceholders from"./removeHighlightingPlaceholders";
|
|
1
|
+
import removeHighlightingPlaceholders from "./removeHighlightingPlaceholders";
|
|
2
|
+
describe('search/helpers', () => {
|
|
3
|
+
describe('removeHighlightingPlaceholers test', () => {
|
|
4
|
+
it('should not change string without placeholders', () => {
|
|
5
|
+
const result = removeHighlightingPlaceholders(['foo', 'bar']);
|
|
6
|
+
expect(result[0]).toBe('foo');
|
|
7
|
+
});
|
|
8
|
+
it('should remove $start$ and $end$', () => {
|
|
9
|
+
const testArray = ['$start$foo$end$', '$start$$end$', '$end$$start$', '$start$foo$end$'];
|
|
10
|
+
const result = removeHighlightingPlaceholders(testArray);
|
|
11
|
+
result.forEach((item, key) => {
|
|
12
|
+
expect(item.indexOf('start')).toBe(-1);
|
|
13
|
+
expect(item.indexOf('end')).toBe(-1);
|
|
14
|
+
expect(item.indexOf('$')).toBe(-1);
|
|
15
|
+
expect(item.length).toBe(Math.max(testArray[key].length - 12, 0));
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
});
|
package/search/index.js
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
// ACTIONS
|
|
2
|
-
export{default as fetchSearchResults}from"./actions/fetchSearchResults";
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export*from"./
|
|
2
|
+
export { default as fetchSearchResults } from "./actions/fetchSearchResults";
|
|
3
|
+
export { default as fetchSearchSuggestions } from "./actions/fetchSearchSuggestions";
|
|
4
|
+
|
|
5
|
+
// CONSTANTS
|
|
6
|
+
export * from "./constants/index";
|
|
7
|
+
export * from "./constants/Pipelines";
|
|
8
|
+
export * from "./constants/Portals";
|
|
9
|
+
|
|
10
|
+
// HELPERS
|
|
11
|
+
export { default as removeHighlightingPlaceholers } from "./helpers/removeHighlightingPlaceholders";
|
|
12
|
+
export * from "./helpers";
|
|
13
|
+
|
|
14
|
+
// SELECTORS
|
|
15
|
+
export * from "./selectors";
|
|
16
|
+
|
|
17
|
+
// STREAMS
|
|
18
|
+
export * from "./streams";
|
package/search/reducers/index.js
CHANGED
|
@@ -1,6 +1,42 @@
|
|
|
1
|
-
|
|
1
|
+
import { REQUEST_SEARCH_SUGGESTIONS, RECEIVE_SEARCH_SUGGESTIONS, SEARCH_SUGGESTIONS_LIFETIME } from "../constants";
|
|
2
|
+
const initialState = {
|
|
3
|
+
suggestions: {}
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* The search suggestions reducer.
|
|
3
8
|
* @param {Object} [state={}] The current search suggestions state.
|
|
4
9
|
* @param {Object} action The action object.
|
|
5
10
|
* @return {Object} The updated search suggestions data.
|
|
6
|
-
*/
|
|
11
|
+
*/
|
|
12
|
+
const search = (state = initialState, action) => {
|
|
13
|
+
switch (action.type) {
|
|
14
|
+
case REQUEST_SEARCH_SUGGESTIONS:
|
|
15
|
+
return {
|
|
16
|
+
...state,
|
|
17
|
+
suggestions: {
|
|
18
|
+
...state.suggestions,
|
|
19
|
+
[action.searchPhrase]: {
|
|
20
|
+
isFetching: true,
|
|
21
|
+
suggestions: [],
|
|
22
|
+
expires: 0
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
case RECEIVE_SEARCH_SUGGESTIONS:
|
|
27
|
+
return {
|
|
28
|
+
...state,
|
|
29
|
+
suggestions: {
|
|
30
|
+
...state.suggestions,
|
|
31
|
+
[action.searchPhrase]: {
|
|
32
|
+
isFetching: false,
|
|
33
|
+
suggestions: action.suggestions,
|
|
34
|
+
expires: Date.now() + SEARCH_SUGGESTIONS_LIFETIME
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
default:
|
|
39
|
+
return state;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
export default search;
|
|
@@ -1,14 +1,33 @@
|
|
|
1
|
-
import{createSelector}from'reselect'
|
|
1
|
+
import { createSelector } from 'reselect';
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* @param {Object} state The appllication state.
|
|
3
5
|
* @return {Object}
|
|
4
|
-
*/
|
|
6
|
+
*/
|
|
7
|
+
export const getSuggestionsState = state => state.search.suggestions;
|
|
8
|
+
|
|
9
|
+
/**
|
|
5
10
|
* Retrieves the search suggestions for a passed search phrase.
|
|
6
11
|
* @param {Object} state The application state.
|
|
7
12
|
* @param {Object} props The component props.
|
|
8
13
|
* @returns {Object|null} The suggestions
|
|
9
|
-
*/
|
|
14
|
+
*/
|
|
15
|
+
export const getSuggestions = createSelector(getSuggestionsState, (state, props) => props.searchPhrase, (suggestions, phrase) => {
|
|
16
|
+
if (!phrase || !suggestions[phrase]) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return suggestions[phrase].suggestions;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
/**
|
|
10
23
|
* Detects if suggestions for a passed search phrase are currently fetching.
|
|
11
24
|
* @param {Object} state The application state.
|
|
12
25
|
* @param {Object} props The component props.
|
|
13
26
|
* @returns {boolean}
|
|
14
|
-
*/
|
|
27
|
+
*/
|
|
28
|
+
export const getSuggestionsFetchingState = createSelector(getSuggestionsState, (state, props) => props.searchPhrase, (suggestions, phrase) => {
|
|
29
|
+
if (!phrase || !suggestions[phrase]) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
return suggestions[phrase].isFetching;
|
|
33
|
+
});
|
package/search/streams/index.js
CHANGED
|
@@ -1,7 +1,55 @@
|
|
|
1
|
-
import{ACTION_REPLACE}from'@virtuous/conductor';
|
|
1
|
+
import { ACTION_REPLACE } from '@virtuous/conductor';
|
|
2
|
+
import { main$ } from '@shopgate/pwa-common/streams/main';
|
|
3
|
+
import { routeWillEnter$, routeDidEnter$, routeWillLeave$, routeDidUpdate$ } from '@shopgate/pwa-common/streams/router';
|
|
4
|
+
import { HISTORY_POP_ACTION } from '@shopgate/pwa-common/constants/ActionTypes';
|
|
5
|
+
import { filtersDidUpdate$ } from '@shopgate/pwa-common-commerce/filter/streams';
|
|
6
|
+
import { SEARCH_PATH } from '@shopgate/pwa-common-commerce/search/constants';
|
|
7
|
+
import { getCurrentRoute } from '@shopgate/pwa-common/selectors/router';
|
|
8
|
+
import { preferredLocationDidUpdate$, preferredLocationDidUpdateGlobalNotOnSearch$, preferredLocationDidUpdateGlobalOnSearch$ } from '@shopgate/engage/locations/locations.streams';
|
|
9
|
+
import { CATEGORY_ALL_PATTERN } from '@shopgate/pwa-common-commerce/category/constants';
|
|
10
|
+
import { filterWillLeave$ } from "../../filter/streams";
|
|
11
|
+
import { REQUEST_SEARCH_RESULTS, RECEIVE_SEARCH_RESULTS, ERROR_SEARCH_RESULTS, SEARCH_PATTERN } from "../constants";
|
|
12
|
+
|
|
13
|
+
/**
|
|
2
14
|
* Gets triggered when search results are requested.
|
|
3
15
|
* @type {Observable}
|
|
4
|
-
*/
|
|
16
|
+
*/
|
|
17
|
+
export const searchRequesting$ = main$.filter(({
|
|
18
|
+
action
|
|
19
|
+
}) => action.type === REQUEST_SEARCH_RESULTS);
|
|
20
|
+
|
|
21
|
+
/**
|
|
5
22
|
* Gets triggered when search results are received.
|
|
6
23
|
* @type {Observable}
|
|
7
|
-
*/
|
|
24
|
+
*/
|
|
25
|
+
export const searchReceived$ = main$.filter(({
|
|
26
|
+
action
|
|
27
|
+
}) => action.type === RECEIVE_SEARCH_RESULTS || action.type === ERROR_SEARCH_RESULTS);
|
|
28
|
+
export const searchWillEnter$ = routeWillEnter$.filter(({
|
|
29
|
+
action
|
|
30
|
+
}) => action.route.pattern === SEARCH_PATTERN);
|
|
31
|
+
export const searchDidEnter$ = routeDidEnter$.filter(({
|
|
32
|
+
action
|
|
33
|
+
}) => action.route.pattern === SEARCH_PATTERN);
|
|
34
|
+
export const searchWillLeave$ = routeWillLeave$.filter(({
|
|
35
|
+
action
|
|
36
|
+
}) => action.route.pattern === SEARCH_PATTERN);
|
|
37
|
+
export const searchWillUpdate$ = routeWillEnter$.filter(({
|
|
38
|
+
action
|
|
39
|
+
}) => action.route.pattern === SEARCH_PATTERN && action.historyAction === ACTION_REPLACE);
|
|
40
|
+
export const searchDidBackEntered$ = searchDidEnter$.filter(({
|
|
41
|
+
action
|
|
42
|
+
}) => action.historyAction === HISTORY_POP_ACTION);
|
|
43
|
+
export const searchFiltersDidUpdate$ = filtersDidUpdate$.filter(({
|
|
44
|
+
getState
|
|
45
|
+
}) => {
|
|
46
|
+
const {
|
|
47
|
+
pattern
|
|
48
|
+
} = getCurrentRoute(getState());
|
|
49
|
+
return pattern === SEARCH_PATH || pattern === CATEGORY_ALL_PATTERN;
|
|
50
|
+
});
|
|
51
|
+
export const searchProductsNeedUpdate$ = preferredLocationDidUpdate$.merge(preferredLocationDidUpdateGlobalNotOnSearch$).switchMap(() => searchDidBackEntered$.first()).merge(searchFiltersDidUpdate$).merge(preferredLocationDidUpdateGlobalOnSearch$);
|
|
52
|
+
export const searchDidUpdate$ = routeDidUpdate$.filter(({
|
|
53
|
+
action
|
|
54
|
+
}) => action?.route?.pattern === SEARCH_PATTERN);
|
|
55
|
+
export const searchFiltersDidUpdateFromFilterPage$ = searchDidUpdate$.switchMap(() => filterWillLeave$.first()).switchMap(() => searchWillEnter$.first());
|
|
@@ -1,7 +1,134 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { LoadingProvider } from '@shopgate/pwa-common/providers';
|
|
2
|
+
import { ACTION_PUSH, ACTION_REPLACE } from '@virtuous/conductor';
|
|
3
|
+
import { buildFetchSearchResultsParams, getProductsResult } from '@shopgate/engage/product';
|
|
4
|
+
import { hex2bin, router } from '@shopgate/engage/core';
|
|
5
|
+
import { CATEGORY_ALL_PATTERN, fetchCategory, getShowAllProductsFilters } from '@shopgate/engage/category';
|
|
6
|
+
import { getCurrentRoute } from '@shopgate/pwa-common/selectors/router';
|
|
7
|
+
import expireProductsByHash from '@shopgate/pwa-common-commerce/product/action-creators/expireProductsByHash';
|
|
8
|
+
import fetchSearchResults from '@shopgate/pwa-common-commerce/search/actions/fetchSearchResults';
|
|
9
|
+
import fetchFilters from '@shopgate/pwa-common-commerce/filter/actions/fetchFilters';
|
|
10
|
+
import { buildFilterParamsForFetchFiltersRequest } from '@shopgate/engage/filter/helpers';
|
|
11
|
+
import { categoryAllWillEnter$, categoryAllFiltersDidUpdateFromFilterPage$ } from '@shopgate/pwa-common-commerce/category/streams';
|
|
12
|
+
import { searchWillEnter$, searchFiltersDidUpdateFromFilterPage$, searchRequesting$, searchReceived$, searchProductsNeedUpdate$ } from "../streams";
|
|
13
|
+
import { SEARCH_PATTERN } from "../constants";
|
|
14
|
+
const searchBasedRouteWillEnter$ = searchWillEnter$.merge(categoryAllWillEnter$);
|
|
15
|
+
const searchBasedFiltersDidUpdateFromFilterPage$ = searchFiltersDidUpdateFromFilterPage$.merge(categoryAllFiltersDidUpdateFromFilterPage$);
|
|
16
|
+
|
|
17
|
+
/**
|
|
2
18
|
* Search subscriptions.
|
|
3
19
|
* @param {Function} subscribe The subscribe function.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
20
|
+
*/
|
|
21
|
+
export default function search(subscribe) {
|
|
22
|
+
subscribe(searchRequesting$, () => {
|
|
23
|
+
LoadingProvider.setLoading(SEARCH_PATTERN);
|
|
24
|
+
});
|
|
25
|
+
subscribe(searchReceived$, () => {
|
|
26
|
+
LoadingProvider.unsetLoading(SEARCH_PATTERN);
|
|
27
|
+
});
|
|
28
|
+
subscribe(searchBasedRouteWillEnter$, async ({
|
|
29
|
+
action,
|
|
30
|
+
dispatch,
|
|
31
|
+
getState
|
|
32
|
+
}) => {
|
|
33
|
+
if (![ACTION_PUSH, ACTION_REPLACE].includes(action?.historyAction)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
let {
|
|
37
|
+
filters
|
|
38
|
+
} = action.route.state;
|
|
39
|
+
let {
|
|
40
|
+
s: searchPhrase
|
|
41
|
+
} = action.route.query;
|
|
42
|
+
const {
|
|
43
|
+
sort
|
|
44
|
+
} = action.route.query;
|
|
45
|
+
if (action.route.pattern === CATEGORY_ALL_PATTERN) {
|
|
46
|
+
searchPhrase = '*';
|
|
47
|
+
if (!filters) {
|
|
48
|
+
const category = await dispatch(fetchCategory(hex2bin(action.route.params.categoryId)));
|
|
49
|
+
filters = getShowAllProductsFilters(category);
|
|
50
|
+
router.update(action.route.id, {
|
|
51
|
+
filters,
|
|
52
|
+
categoryName: category.name
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const {
|
|
57
|
+
hash,
|
|
58
|
+
expired
|
|
59
|
+
} = getProductsResult(getState(), {
|
|
60
|
+
searchPhrase,
|
|
61
|
+
routeId: action?.route?.id,
|
|
62
|
+
...buildFetchSearchResultsParams()
|
|
63
|
+
});
|
|
64
|
+
if (expired) {
|
|
65
|
+
dispatch(expireProductsByHash(hash));
|
|
66
|
+
}
|
|
67
|
+
dispatch(fetchSearchResults({
|
|
68
|
+
filters,
|
|
69
|
+
searchPhrase,
|
|
70
|
+
sort,
|
|
71
|
+
...buildFetchSearchResultsParams()
|
|
72
|
+
}));
|
|
73
|
+
dispatch(fetchFilters({
|
|
74
|
+
filters: buildFilterParamsForFetchFiltersRequest(filters)
|
|
75
|
+
}));
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// No logic related to "show all products" necessary here, since stream only emits when
|
|
79
|
+
// location based shopping is active. That's currently only supported when new services are
|
|
80
|
+
// used, but the new services don't support "show all products".
|
|
81
|
+
subscribe(searchProductsNeedUpdate$, ({
|
|
82
|
+
dispatch,
|
|
83
|
+
getState
|
|
84
|
+
}) => {
|
|
85
|
+
const {
|
|
86
|
+
query,
|
|
87
|
+
state: {
|
|
88
|
+
filters
|
|
89
|
+
},
|
|
90
|
+
pattern
|
|
91
|
+
} = getCurrentRoute(getState());
|
|
92
|
+
const {
|
|
93
|
+
sort
|
|
94
|
+
} = query;
|
|
95
|
+
let {
|
|
96
|
+
s: searchPhrase
|
|
97
|
+
} = query;
|
|
98
|
+
if (pattern === CATEGORY_ALL_PATTERN) {
|
|
99
|
+
searchPhrase = '*';
|
|
100
|
+
}
|
|
101
|
+
dispatch(fetchSearchResults({
|
|
102
|
+
filters,
|
|
103
|
+
searchPhrase,
|
|
104
|
+
sort,
|
|
105
|
+
...buildFetchSearchResultsParams()
|
|
106
|
+
}));
|
|
107
|
+
});
|
|
108
|
+
subscribe(searchBasedFiltersDidUpdateFromFilterPage$, ({
|
|
109
|
+
dispatch,
|
|
110
|
+
action
|
|
111
|
+
}) => {
|
|
112
|
+
const {
|
|
113
|
+
filters
|
|
114
|
+
} = action.route.state;
|
|
115
|
+
const {
|
|
116
|
+
pattern
|
|
117
|
+
} = action.route;
|
|
118
|
+
const {
|
|
119
|
+
sort
|
|
120
|
+
} = action.route.query;
|
|
121
|
+
let {
|
|
122
|
+
s: searchPhrase
|
|
123
|
+
} = action.route.query;
|
|
124
|
+
if (pattern === CATEGORY_ALL_PATTERN) {
|
|
125
|
+
searchPhrase = '*';
|
|
126
|
+
}
|
|
127
|
+
dispatch(fetchSearchResults({
|
|
128
|
+
filters,
|
|
129
|
+
searchPhrase,
|
|
130
|
+
sort,
|
|
131
|
+
...buildFetchSearchResultsParams()
|
|
132
|
+
}));
|
|
133
|
+
});
|
|
134
|
+
}
|