@shopgate/engage 7.30.0 → 7.30.1-beta.2

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.
Files changed (62) hide show
  1. package/a11y/reducers/index.js +1 -4
  2. package/account/reducers/index.js +2 -4
  3. package/app-rating/reducers/index.js +1 -1
  4. package/back-in-stock/reducers/index.js +1 -1
  5. package/cart/components/CartItem/CartItemProductLayoutWide.js +1 -1
  6. package/cart/components/CartItem/CartItemProductLayoutWide.style.js +1 -1
  7. package/checkout/paymentMethods/paypal/PaypalPayButton.js +1 -1
  8. package/checkout/paymentMethods/stripe/StripeButton.js +6 -2
  9. package/checkout/reducers/index.js +1 -3
  10. package/components/IntersectionVisibility/index.js +14 -9
  11. package/core/actions/getGeolocation.js +4 -4
  12. package/core/actions/grantAppTrackingTransparencyPermission.d.ts +24 -0
  13. package/core/actions/grantAppTrackingTransparencyPermission.js +18 -2
  14. package/core/actions/grantCameraPermissions.d.ts +24 -0
  15. package/core/actions/grantCameraPermissions.js +5 -2
  16. package/core/actions/grantGeolocationPermissions.d.ts +36 -0
  17. package/core/actions/grantGeolocationPermissions.js +18 -6
  18. package/core/actions/grantPermissions.d.ts +142 -0
  19. package/core/actions/grantPermissions.js +132 -18
  20. package/core/actions/grantPushPermissions.d.ts +24 -0
  21. package/core/actions/grantPushPermissions.js +9 -2
  22. package/core/actions/requestAppPermission.js +12 -3
  23. package/core/actions/requestAppPermissionStatus.js +2 -1
  24. package/core/config/config.reducers.js +1 -1
  25. package/core/config/config.selectors.js +6 -1
  26. package/core/constants/index.js +24 -1
  27. package/core/reducers/app.js +1 -4
  28. package/core/reducers/merchantSettings.js +1 -4
  29. package/core/reducers/shopSettings.js +3 -6
  30. package/core/router/permissionRouteRedirectHandler.js +117 -0
  31. package/core/subscriptions/app.js +10 -2
  32. package/development/reducers/settings.js +1 -3
  33. package/development/reducers/storage.js +1 -3
  34. package/filter/components/FilterPageContent/components/ResetButton/style.js +1 -1
  35. package/locations/components/FulfillmentSlotSwitcher/time.js +1 -1
  36. package/locations/reducers/storage.js +2 -6
  37. package/locations/reducers/storeFinderSearch.js +1 -5
  38. package/locations/reducers/user.js +1 -1
  39. package/locations/reducers/userFormInput.js +1 -1
  40. package/locations/reducers/userSearch.js +1 -1
  41. package/locations/selectors/index.js +21 -26
  42. package/orders/reducers/orders.js +4 -11
  43. package/orders/reducers/ordersById.js +4 -9
  44. package/orders/reducers/ordersByNumber.js +4 -9
  45. package/package.json +14 -13
  46. package/page/reducers/index.js +1 -5
  47. package/page/selectors/index.js +2 -1
  48. package/product/components/Description/style.js +1 -1
  49. package/product/components/EffectivityDates/index.js +3 -3
  50. package/product/components/FilterBar/mock.js +1 -1
  51. package/product/components/MapPriceHint/index.js +4 -4
  52. package/product/components/ProductList/components/Item/index.js +2 -5
  53. package/product/components/Swatch/Swatch.js +1 -1
  54. package/product/components/Swatch/VariantSwatch.js +1 -1
  55. package/product/components/Swatches/Swatches.js +1 -1
  56. package/product/selectors/product.js +6 -1
  57. package/push-opt-in/reducers/optInModal.js +1 -1
  58. package/push-opt-in/reducers/optInTrigger.js +1 -1
  59. package/tracking/reducers/cookieConsentModal.js +1 -1
  60. package/tracking/reducers/cookieSettings.js +1 -1
  61. package/tracking/selectors/cookieConsent.js +2 -1
  62. package/tracking/subscriptions/cookieConsent.js +3 -9
@@ -20,8 +20,7 @@ const initialState = {
20
20
  * @param {Object} action The redux action.
21
21
  * @returns {Object}
22
22
  */
23
- export default function storageReducer(state = initialState, action) {
24
- /* eslint-disable no-param-reassign */
23
+ export default function storageReducer(state = initialState, action = {}) {
25
24
  const producer = produce(/** @param {DevToolsStorageState} draft The draft */draft => {
26
25
  if (!isDev) {
27
26
  return;
@@ -36,6 +35,5 @@ export default function storageReducer(state = initialState, action) {
36
35
  break;
37
36
  }
38
37
  });
39
- /* eslint-enable no-param-reassign */
40
38
  return producer(state);
41
39
  }
@@ -3,4 +3,4 @@ export default css({
3
3
  marginTop: 4,
4
4
  marginBottom: 40,
5
5
  textAlign: 'right'
6
- });
6
+ }).toString();
@@ -1,5 +1,5 @@
1
1
  import moment from 'moment';
2
- import { i18n } from '@shopgate/engage/core';
2
+ import { i18n } from '@shopgate/engage/core/helpers';
3
3
 
4
4
  /**
5
5
  * Creates a display string for the given slot.
@@ -26,8 +26,6 @@ const initialState = {
26
26
  fulfillmentSlotsByLocation: {}
27
27
  };
28
28
 
29
- /* eslint-disable no-param-reassign */
30
-
31
29
  /**
32
30
  * Stores a list of locations and updates the store.
33
31
  * @param {Object} draft Draft
@@ -47,7 +45,7 @@ const storeLocationData = (draft, locations) => {
47
45
  draft.locationsByCode[location.code].address = location.addresses.find(a => a.isPrimary) || location.addresses[0];
48
46
  });
49
47
  };
50
- export default (state = initialState, action) => {
48
+ export default (state = initialState, action = {}) => {
51
49
  const producer = produce(draft => {
52
50
  switch (action.type) {
53
51
  case REQUEST_LOCATIONS:
@@ -151,6 +149,4 @@ export default (state = initialState, action) => {
151
149
  }
152
150
  });
153
151
  return producer(state);
154
- };
155
-
156
- /* eslint-enable no-param-reassign */
152
+ };
@@ -10,8 +10,7 @@ export const defaultState = {
10
10
  * @param {Object} action The action object.
11
11
  * @returns {Object} The new state.
12
12
  */
13
- const storeFinderSearch = (state = defaultState, action) => {
14
- /* eslint-disable no-param-reassign */
13
+ const storeFinderSearch = (state = defaultState, action = {}) => {
15
14
  const producer = produce(draft => {
16
15
  switch (action.type) {
17
16
  case SET_STORE_FINDER_SEARCH_RADIUS:
@@ -22,10 +21,7 @@ const storeFinderSearch = (state = defaultState, action) => {
22
21
  default:
23
22
  break;
24
23
  }
25
- return undefined;
26
24
  });
27
-
28
- /* eslint-enable no-param-reassign */
29
25
  return producer(state);
30
26
  };
31
27
  export default storeFinderSearch;
@@ -8,7 +8,7 @@ export const defaultState = {
8
8
  * @param {Object} action The action Object
9
9
  * @returns {Object} The new state.
10
10
  */
11
- export default function user(state = defaultState, action) {
11
+ export default function user(state = defaultState, action = {}) {
12
12
  switch (action.type) {
13
13
  case SET_USER_GEOLOCATION:
14
14
  return {
@@ -9,7 +9,7 @@ import { STORE_FORM_INPUT } from "../constants";
9
9
  * @param {Object} [action.input] The input data to store.
10
10
  * @returns {UserLocationState} The new state.
11
11
  */
12
- const formInput = (state = {}, action) => {
12
+ const formInput = (state = {}, action = {}) => {
13
13
  switch (action.type) {
14
14
  case STORE_FORM_INPUT:
15
15
  return {
@@ -12,7 +12,7 @@ export const defaultState = {
12
12
  * @param {Object} action The action Object
13
13
  * @returns {Object} The new state.
14
14
  */
15
- export default function search(state = defaultState, action) {
15
+ export default function search(state = defaultState, action = {}) {
16
16
  switch (action.type) {
17
17
  case SET_USER_SEARCH_COUNTRY_CODE:
18
18
  return {
@@ -20,13 +20,15 @@ export const getProductFulfillmentMethods = createSelector(getProduct, product =
20
20
  }
21
21
  return product.fulfillmentMethods;
22
22
  });
23
+ const EMPTY_OBJ = {};
24
+ const EMPTY_ARRAY = [];
23
25
 
24
26
  /**
25
27
  * Gets the location state.
26
28
  * @param {Object} state State.
27
29
  * @return {Object}
28
30
  */
29
- const getLocationsState = state => state.locations || {};
31
+ const getLocationsState = state => state.locations || EMPTY_OBJ;
30
32
 
31
33
  /**
32
34
  * Gets the location storage state.
@@ -40,7 +42,7 @@ export const getLocationsStorage = state => state.locations.storage;
40
42
  * @param {Object} state State.
41
43
  * @return {Object}
42
44
  */
43
- const getUserState = state => state.locations.user || {};
45
+ const getUserState = state => state.locations.user || EMPTY_OBJ;
44
46
 
45
47
  /**
46
48
  * Retrieves the store finder search.
@@ -124,13 +126,10 @@ export const getActiveFilter = createSelector(getLocationsState, locationsState
124
126
  * @returns {Object}
125
127
  */
126
128
  export const makeGetLocationsForProduct = getProductCode => {
127
- /* eslint-disable require-jsdoc */
128
- const getFilters = (state, props) => ({
129
- productCode: getProductCode(state, props),
130
- ...pickBy(getActiveFilter(state))
131
- });
132
-
133
- /* eslint-enable require-jsdoc */
129
+ const getFilters = createSelector(getProductCode, getActiveFilter, (productCode, activeFilter) => ({
130
+ productCode,
131
+ ...activeFilter
132
+ }));
134
133
  return makeGetFilteredLocations(getFilters);
135
134
  };
136
135
 
@@ -139,14 +138,11 @@ export const makeGetLocationsForProduct = getProductCode => {
139
138
  * @returns {Object}
140
139
  */
141
140
  export const makeGetLocationsForStoreFinder = () => {
142
- /* eslint-disable require-jsdoc */
143
- const getFilters = state => ({
141
+ const getFilters = createSelector(getStoreFinderSearch, getActiveFilter, (search, activeFilter) => ({
144
142
  enableInLocationFinder: true,
145
- ...pickBy(getStoreFinderSearch(state)),
146
- ...pickBy(getActiveFilter(state))
147
- });
148
- /* eslint-enable require-jsdoc */
149
-
143
+ ...pickBy(search || EMPTY_OBJ),
144
+ ...activeFilter
145
+ }));
150
146
  return makeGetFilteredLocations(getFilters);
151
147
  };
152
148
 
@@ -306,7 +302,7 @@ export const makeGetLocationInventory = (getLocationCode, getProductCode) => (st
306
302
  */
307
303
  export const makeGetLocationFulfillmentMethods = getLocationCode => {
308
304
  const getLocation = makeGetLocation(getLocationCode);
309
- return createSelector(getLocation, location => location?.supportedFulfillmentMethods || []);
305
+ return createSelector(getLocation, location => location?.supportedFulfillmentMethods || EMPTY_ARRAY);
310
306
  };
311
307
 
312
308
  /**
@@ -515,15 +511,14 @@ export const getProductAlternativeLocations = createSelector((_, props) => props
515
511
  * @returns {Function}
516
512
  */
517
513
  export const makeGetNearbyLocationsByLocationCode = locationCode => {
518
- const getFilteredLocationsForRoute = makeGetFilteredLocations(state => {
519
- const routeLocation = makeGetLocation(() => locationCode)(state);
520
- return {
521
- latitude: routeLocation?.latitude,
522
- longitude: routeLocation?.longitude,
523
- limit: NEARBY_LOCATIONS_LIMIT,
524
- radius: NEARBY_LOCATIONS_RADIUS
525
- };
526
- });
514
+ const getRouteLocation = makeGetLocation(() => locationCode);
515
+ const getFilters = createSelector(getRouteLocation, routeLocation => ({
516
+ latitude: routeLocation?.latitude,
517
+ longitude: routeLocation?.longitude,
518
+ limit: NEARBY_LOCATIONS_LIMIT,
519
+ radius: NEARBY_LOCATIONS_RADIUS
520
+ }));
521
+ const getFilteredLocationsForRoute = makeGetFilteredLocations(getFilters);
527
522
  return createSelector(getFilteredLocationsForRoute, locations => {
528
523
  // remove current location from nearby locations
529
524
  const filteredLocations = locations.filter(location => location.code !== locationCode);
@@ -1,7 +1,5 @@
1
1
  import { produce } from 'immer';
2
2
  import { REQUEST_ORDER_HISTORY, RECEIVE_ORDER_HISTORY, ERROR_ORDER_HISTORY, CLEAR_ORDERS } from "../constants";
3
- export const CACHE_TIME = 60 * 60 * 1000; // 1 hr in milliseconds
4
-
5
3
  const defaultState = {
6
4
  orders: []
7
5
  };
@@ -12,8 +10,10 @@ const defaultState = {
12
10
  * @param {Object} action The action object.
13
11
  * @returns {Object} The new state.
14
12
  */
15
- const orders = (state = defaultState, action) => {
16
- /* eslint-disable no-param-reassign */
13
+ const orders = (state = defaultState, action = {}) => {
14
+ if (action.type === CLEAR_ORDERS) {
15
+ return defaultState;
16
+ }
17
17
  const producer = produce(draft => {
18
18
  switch (action.type) {
19
19
  case REQUEST_ORDER_HISTORY:
@@ -33,17 +33,10 @@ const orders = (state = defaultState, action) => {
33
33
  draft.isFetching = false;
34
34
  break;
35
35
  }
36
- case CLEAR_ORDERS:
37
- {
38
- return defaultState;
39
- }
40
36
  default:
41
37
  break;
42
38
  }
43
- return undefined;
44
39
  });
45
-
46
- /* eslint-enable no-param-reassign */
47
40
  return producer(state);
48
41
  };
49
42
  export default orders;
@@ -10,8 +10,10 @@ const defaultState = {};
10
10
  * @param {Object} action The action object.
11
11
  * @returns {Object} The new state.
12
12
  */
13
- const ordersById = (state = defaultState, action) => {
14
- /* eslint-disable no-param-reassign */
13
+ const ordersById = (state = defaultState, action = {}) => {
14
+ if (action.type === CLEAR_ORDERS) {
15
+ return defaultState;
16
+ }
15
17
  const producer = produce(draft => {
16
18
  switch (action.type) {
17
19
  case REQUEST_ORDER_DETAILS:
@@ -47,17 +49,10 @@ const ordersById = (state = defaultState, action) => {
47
49
  }
48
50
  break;
49
51
  }
50
- case CLEAR_ORDERS:
51
- {
52
- return defaultState;
53
- }
54
52
  default:
55
53
  break;
56
54
  }
57
- return undefined;
58
55
  });
59
-
60
- /* eslint-enable no-param-reassign */
61
56
  return producer(state);
62
57
  };
63
58
  export default ordersById;
@@ -10,8 +10,10 @@ const defaultState = {};
10
10
  * @param {Object} action The action object.
11
11
  * @returns {Object} The new state.
12
12
  */
13
- const ordersByNumber = (state = defaultState, action) => {
14
- /* eslint-disable no-param-reassign */
13
+ const ordersByNumber = (state = defaultState, action = {}) => {
14
+ if (action.type === CLEAR_ORDERS) {
15
+ return defaultState;
16
+ }
15
17
  const producer = produce(draft => {
16
18
  switch (action.type) {
17
19
  case REQUEST_ORDER_DETAILS:
@@ -59,17 +61,10 @@ const ordersByNumber = (state = defaultState, action) => {
59
61
  };
60
62
  break;
61
63
  }
62
- case CLEAR_ORDERS:
63
- {
64
- return defaultState;
65
- }
66
64
  default:
67
65
  break;
68
66
  }
69
- return undefined;
70
67
  });
71
-
72
- /* eslint-enable no-param-reassign */
73
68
  return producer(state);
74
69
  };
75
70
  export default ordersByNumber;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopgate/engage",
3
- "version": "7.30.0",
3
+ "version": "7.30.1-beta.2",
4
4
  "description": "Shopgate's ENGAGE library.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Shopgate <support@shopgate.com>",
@@ -17,41 +17,42 @@
17
17
  "dependencies": {
18
18
  "@emotion/react": "^11.14.0",
19
19
  "@shopgate/native-modules": "1.0.0-beta.25",
20
- "@shopgate/pwa-common": "7.30.0",
21
- "@shopgate/pwa-common-commerce": "7.30.0",
22
- "@shopgate/pwa-core": "7.30.0",
23
- "@shopgate/pwa-ui-ios": "7.30.0",
24
- "@shopgate/pwa-ui-material": "7.30.0",
25
- "@shopgate/pwa-ui-shared": "7.30.0",
20
+ "@shopgate/pwa-common": "7.30.1-beta.2",
21
+ "@shopgate/pwa-common-commerce": "7.30.1-beta.2",
22
+ "@shopgate/pwa-core": "7.30.1-beta.2",
23
+ "@shopgate/pwa-ui-ios": "7.30.1-beta.2",
24
+ "@shopgate/pwa-ui-material": "7.30.1-beta.2",
25
+ "@shopgate/pwa-ui-shared": "7.30.1-beta.2",
26
26
  "@stripe/react-stripe-js": "^1.16.5",
27
27
  "@stripe/stripe-js": "^1.44.1",
28
28
  "@virtuous/conductor": "~2.5.0",
29
29
  "color": "^3.1.2",
30
30
  "focus-trap-react": "^10.3.1",
31
- "immer": "^8.0.1",
31
+ "immer": "^11.1.3",
32
32
  "intersection-observer": "^0.6.0",
33
33
  "leaflet": "^1.8.0",
34
34
  "leaflet-gesture-handling": "^1.2.2",
35
- "lodash": "^4.17.21",
35
+ "lodash": "^4.17.23",
36
36
  "moment": "^2.30.1",
37
37
  "react-helmet": "^6.1.0",
38
38
  "react-leaflet": "^3.2.5",
39
- "react-phone-number-input": "^3.2.16",
39
+ "react-phone-number-input": "^3.4.14",
40
40
  "react-player": "1.11.0",
41
41
  "react-portal": "^3.1.0",
42
42
  "react-scroll-parallax": "^3.5.0",
43
- "tss-react": "^4.9.18",
43
+ "tss-react": "^4.9.20",
44
44
  "validate.js": "^0.13.1"
45
45
  },
46
46
  "devDependencies": {
47
47
  "classnames": "2.5.1",
48
48
  "jest-mock-console": "^2.0.0",
49
- "lodash": "^4.17.21",
49
+ "lodash": "^4.17.23",
50
50
  "prop-types": "~15.8.1",
51
51
  "react": "^17.0.2",
52
52
  "react-redux": "^8.1.3",
53
- "redux": "^4.2.1",
53
+ "redux": "^5.0.1",
54
54
  "redux-mock-store": "^1.5.4",
55
+ "redux-thunk": "^3.1.0",
55
56
  "reselect": "^4.1.8"
56
57
  }
57
58
  }
@@ -67,8 +67,7 @@ const defaultState = {};
67
67
  * @param {Object} action The action object.
68
68
  * @returns {Object} The new state.
69
69
  */
70
- export function pageV2(state = defaultState, action) {
71
- /* eslint-disable no-param-reassign */
70
+ export function pageV2(state = defaultState, action = {}) {
72
71
  const producer = produce(draft => {
73
72
  const {
74
73
  pageType,
@@ -129,8 +128,5 @@ export function pageV2(state = defaultState, action) {
129
128
  break;
130
129
  }
131
130
  });
132
-
133
- /* eslint-enable no-param-reassign */
134
-
135
131
  return producer(state);
136
132
  }
@@ -217,7 +217,8 @@ const makeGetWidgetProductResultsByHash = (type, options, id) => {
217
217
  export const makeGetWidgetProducts = (type, options, id) => {
218
218
  const getWidgetProductResultsHash = makeGetWidgetProductsResultHash(type, options, id);
219
219
  const getWidgetProductResultsByHash = makeGetWidgetProductResultsByHash(type, options, id);
220
- return createSelector(state => state, (state, props) => props ?? {}, getWidgetProductResultsHash, getWidgetProductResultsByHash, (state, props, resultsHash, resultsByHash) => ({
220
+ const emptyObject = {};
221
+ return createSelector(state => state, (state, props) => props ?? emptyObject, getWidgetProductResultsHash, getWidgetProductResultsByHash, (state, props, resultsHash, resultsByHash) => ({
221
222
  isFetching: resultsByHash?.isFetching || false,
222
223
  ...getPopulatedProductsResult(state, props, resultsHash, resultsByHash)
223
224
  }));
@@ -35,7 +35,7 @@ export const content = css({
35
35
  padding: '.35em',
36
36
  position: 'relative'
37
37
  }
38
- });
38
+ }).toString();
39
39
  export const placeholder = css({
40
40
  height: '0.875rem'
41
41
  }).toString();
@@ -1,4 +1,4 @@
1
- import React, { Fragment } from 'react';
1
+ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import classNames from 'classnames';
4
4
  import { css } from 'glamor';
@@ -20,11 +20,11 @@ const EffectivityDates = ({
20
20
  productNotAvailable,
21
21
  productId
22
22
  }) => {
23
+ const settings = useWidgetSettings('@shopgate/engage/product/EffectivityDates');
24
+ const styles = useWidgetStyles('@shopgate/engage/product/EffectivityDates');
23
25
  if (!isBeta() || !dates) {
24
26
  return children;
25
27
  }
26
- const settings = useWidgetSettings('@shopgate/engage/product/EffectivityDates');
27
- const styles = useWidgetStyles('@shopgate/engage/product/EffectivityDates');
28
28
  const startDate = dates.startDate ? new Date(dates.startDate) : null;
29
29
  const endDate = dates.endDate ? new Date(dates.endDate) : null;
30
30
  const hintAddClass = styles && styles.hint ? css(styles.hint).toString() : null;
@@ -1,5 +1,5 @@
1
1
  import configureStore from 'redux-mock-store';
2
- import thunk from 'redux-thunk';
2
+ import { thunk } from 'redux-thunk';
3
3
  import { FILTER_TYPE_SINGLE_SELECT, FILTER_TYPE_MULTISELECT } from '@shopgate/pwa-common-commerce/filter/constants';
4
4
  import { themeConfig as mockThemeConfig } from '@shopgate/pwa-common/helpers/config/mock';
5
5
  const mockedStoreDefault = {
@@ -20,14 +20,14 @@ const MapPriceHint = ({
20
20
  price,
21
21
  mapPrice
22
22
  }) => {
23
- if (!isBeta()) {
24
- return null;
25
- }
23
+ const styles = useWidgetStyles('@shopgate/engage/product/MapPrice');
26
24
  const settings = useWidgetSettings('@shopgate/engage/product/MapPrice');
27
25
  if (!settings.showHint || !settings.hint) {
28
26
  return null;
29
27
  }
30
- const styles = useWidgetStyles('@shopgate/engage/product/MapPrice');
28
+ if (!isBeta()) {
29
+ return null;
30
+ }
31
31
  return /*#__PURE__*/_jsx(SurroundPortals, {
32
32
  portalName: PRODUCT_MAP_PRICE,
33
33
  children: showHint(price, mapPrice) && /*#__PURE__*/_jsx(TimeBoundary, {
@@ -1,8 +1,6 @@
1
- import React, { Fragment } from 'react';
1
+ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import Grid from '@shopgate/pwa-common/components/Grid';
4
- import Image from '@shopgate/pwa-common/components/Image';
5
- import Link from '@shopgate/pwa-common/components/Link';
3
+ import { Image, Link, Grid, Availability } from '@shopgate/engage/components';
6
4
  import { bin2hex } from '@shopgate/pwa-common/helpers/data';
7
5
  import Portal from '@shopgate/pwa-common/components/Portal';
8
6
  import * as portals from '@shopgate/pwa-common-commerce/category/constants/Portals';
@@ -11,7 +9,6 @@ import DiscountBadge from '@shopgate/pwa-ui-shared/DiscountBadge';
11
9
  import Price from '@shopgate/pwa-ui-shared/Price';
12
10
  import PriceStriked from '@shopgate/pwa-ui-shared/PriceStriked';
13
11
  import Manufacturer from '@shopgate/pwa-ui-shared/Manufacturer';
14
- import { Availability } from '@shopgate/engage/components';
15
12
  import { PriceInfo, ProductName, ProductBadges } from '@shopgate/engage/product';
16
13
  import { i18n } from '@shopgate/engage/core';
17
14
  import styles from "./style";
@@ -14,10 +14,10 @@ export const WIDGET_ID = '@shopgate/engage/product/Swatch';
14
14
  const Swatch = ({
15
15
  swatch
16
16
  }) => {
17
+ const styles = useWidgetStyles(WIDGET_ID);
17
18
  if (!swatch) {
18
19
  return null;
19
20
  }
20
- const styles = useWidgetStyles(WIDGET_ID);
21
21
  const classNames = {
22
22
  swatch: styles && styles.swatch ? css(styles.swatch).toString() : null,
23
23
  item: styles && styles.item ? css(styles.item).toString() : null,
@@ -16,10 +16,10 @@ const VariantSwatch = ({
16
16
  swatch,
17
17
  onClick
18
18
  }) => {
19
+ const styles = useWidgetStyles(WIDGET_ID);
19
20
  if (!swatch) {
20
21
  return null;
21
22
  }
22
- const styles = useWidgetStyles(WIDGET_ID);
23
23
  const classNames = {
24
24
  swatch: styles && styles.swatch ? css(styles.swatch).toString() : null,
25
25
  item: styles && styles.item ? css(styles.item).toString() : null,
@@ -18,13 +18,13 @@ const Swatches = ({
18
18
  productId,
19
19
  characteristics
20
20
  }) => {
21
+ const settings = useWidgetSettings(WIDGET_ID);
21
22
  if (!isBeta()) {
22
23
  return null;
23
24
  }
24
25
  if (!characteristics) {
25
26
  return null;
26
27
  }
27
- const settings = useWidgetSettings(WIDGET_ID);
28
28
  let swatches = characteristics.filter(c => c.swatch === true);
29
29
  if (settings.filter && settings.filter.length) {
30
30
  swatches = swatches.filter(swatch => settings.filter.includes(swatch.id));
@@ -7,12 +7,17 @@ import { filterProperties } from "./helpers";
7
7
  * to prevent circular dependencies.
8
8
  */
9
9
 
10
+ /**
11
+ * Shared empty product state to keep the fallback referentially stable.
12
+ */
13
+ const EMPTY_PRODUCT_STATE = {};
14
+
10
15
  /**
11
16
  * Retrieves the product state from the store.
12
17
  * @param {Object} state The current application state.
13
18
  * @return {Object} The product state.
14
19
  */
15
- export const getProductState = state => state.product || {};
20
+ export const getProductState = state => state.product || EMPTY_PRODUCT_STATE;
16
21
 
17
22
  /**
18
23
  * Selects the product properties state.
@@ -10,7 +10,7 @@ const defaultState = {
10
10
  * @param {Object} action The action object.
11
11
  * @return {Object} The new state.
12
12
  */
13
- const pushOptInModalReducer = (state = defaultState, action) => {
13
+ const pushOptInModalReducer = (state = defaultState, action = {}) => {
14
14
  switch (action.type) {
15
15
  case SHOW_PUSH_OPT_IN_MODAL:
16
16
  {
@@ -16,7 +16,7 @@ const defaultState = {
16
16
  * @param {Object} action The action object.
17
17
  * @return {Object} The new state.
18
18
  */
19
- const pushOptInReducer = (state = defaultState, action) => {
19
+ const pushOptInReducer = (state = defaultState, action = {}) => {
20
20
  switch (action.type) {
21
21
  case PUSH_OPT_IN_INCREASE_APP_START_COUNT:
22
22
  {
@@ -9,7 +9,7 @@ const defaultState = {
9
9
  * @param {Object} action The action object.
10
10
  * @return {Object} The new state.
11
11
  */
12
- const cookieConsentModalReducer = (state = defaultState, action) => {
12
+ const cookieConsentModalReducer = (state = defaultState, action = {}) => {
13
13
  switch (action.type) {
14
14
  case SHOW_COOKIE_CONSENT_MODAL:
15
15
  {
@@ -10,7 +10,7 @@ const defaultState = {
10
10
  * @param {Object} action The action object.
11
11
  * @return {Object} The new state.
12
12
  */
13
- const cookieSettingsReducer = (state = defaultState, action) => {
13
+ const cookieSettingsReducer = (state = defaultState, action = {}) => {
14
14
  switch (action.type) {
15
15
  case UPDATE_COOKIE_CONSENT:
16
16
  {
@@ -86,11 +86,12 @@ export const getIsCookieConsentModalVisible = createSelector(getCookieConsentMod
86
86
  * Determines if the cookie consent feature is activated
87
87
  */
88
88
  export const getIsCookieConsentActivated = createSelector(() => isCookieConsentActivated && appSupportsCookieConsent());
89
+ const EMPTY_OBJECT = {};
89
90
 
90
91
  /**
91
92
  * Creates a meta data object for tracking opt in tracking events
92
93
  */
93
- export const getCookieConsentTrackingMeta = createSelector(getIsCookieConsentActivated, (_, props = {}) => props, (isActivated, states) => ({
94
+ export const getCookieConsentTrackingMeta = createSelector(getIsCookieConsentActivated, (_, props = EMPTY_OBJECT) => props, (isActivated, states) => ({
94
95
  permission: 'tracking',
95
96
  usesSoftTrackingOptIn: isActivated,
96
97
  ...states
@@ -1,9 +1,8 @@
1
1
  import { appDidStart$ } from '@shopgate/engage/core/streams';
2
- import { appSupportsCookieConsent } from '@shopgate/engage/core/helpers';
3
- import { grantAppTrackingTransparencyPermission, historyReset, historyPop } from '@shopgate/engage/core/actions';
2
+ import { historyReset, historyPop } from '@shopgate/engage/core/actions';
4
3
  import { softOptInShown } from '@shopgate/engage/core/action-creators';
5
4
  import { handleCookieConsent, showCookieConsentModal, hideCookieConsentModal } from "../action-creators";
6
- import { getIsCookieConsentHandled, getAreComfortCookiesAccepted, getAreStatisticsCookiesAccepted, getCookieConsentTrackingMeta } from "../selectors/cookieConsent";
5
+ import { getIsCookieConsentHandled, getAreComfortCookiesAccepted, getAreStatisticsCookiesAccepted, getCookieConsentTrackingMeta, getIsCookieConsentActivated } from "../selectors/cookieConsent";
7
6
  import { cookieConsentInitializedByUserInternal$, privacySettingsConfirmedWithoutChangeInternal$, cookieConsentModalShouldToggleInternal$ } from "../streams/cookieConsent";
8
7
 
9
8
  /**
@@ -31,12 +30,7 @@ export default function cookieConsent(subscribe) {
31
30
  comfortCookiesAccepted,
32
31
  statisticsCookiesAccepted
33
32
  }));
34
- if (appSupportsCookieConsent() && (comfortCookiesAccepted || statisticsCookiesAccepted)) {
35
- await dispatch(grantAppTrackingTransparencyPermission({
36
- meta: trackingMeta
37
- }));
38
- }
39
- } else {
33
+ } else if (getIsCookieConsentActivated(state)) {
40
34
  // if merchant has activated cookie feature but user has not chosen cookies yet:
41
35
  // show cookie consent modal to make user choose them
42
36
  dispatch(softOptInShown({