@shopgate/pwa-common 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/App.js +48 -6
- package/action-creators/app/index.js +75 -12
- package/action-creators/app/spec.js +96 -1
- package/action-creators/client/index.js +27 -5
- package/action-creators/client/spec.js +44 -1
- package/action-creators/error/index.js +15 -3
- package/action-creators/index.js +9 -1
- package/action-creators/menu/index.js +23 -4
- package/action-creators/menu/spec.js +37 -1
- package/action-creators/modal/index.js +15 -3
- package/action-creators/modal/spec.js +26 -1
- package/action-creators/page/index.js +24 -4
- package/action-creators/page/spec.js +38 -1
- package/action-creators/router/index.js +48 -7
- package/action-creators/url/index.js +24 -4
- package/action-creators/url/spec.js +45 -1
- package/action-creators/user/index.js +90 -13
- package/action-creators/user/spec.js +186 -2
- package/actions/app/handleDeepLink.js +11 -2
- package/actions/app/handleLink.js +62 -6
- package/actions/app/handlePushNotification.js +32 -4
- package/actions/app/handleUniversalLink.js +11 -2
- package/actions/app/registerLinkEvents.js +24 -3
- package/actions/client/fetchClientInformation.js +26 -2
- package/actions/menu/fetchMenu.js +23 -2
- package/actions/modal/closeModal.js +18 -2
- package/actions/modal/promiseMap.js +3 -1
- package/actions/modal/showModal.js +54 -8
- package/actions/page/fetchPageConfig.js +69 -2
- package/actions/page/getPageConfig.js +6 -2
- package/actions/page/index.js +1 -1
- package/actions/router/historyPop.js +12 -2
- package/actions/router/historyPopToRoute.js +27 -2
- package/actions/router/historyPush.js +12 -2
- package/actions/router/historyRedirect.js +21 -2
- package/actions/router/historyReplace.js +20 -3
- package/actions/router/historyReset.js +11 -2
- package/actions/router/historyResetTo.js +12 -2
- package/actions/router/index.js +17 -1
- package/actions/router/routeDidPop.js +11 -2
- package/actions/router/routeDidPush.js +13 -2
- package/actions/router/routeDidReplace.js +11 -2
- package/actions/router/routeDidReset.js +11 -2
- package/actions/router/routeDidUpdate.js +10 -2
- package/actions/router/routeWillPop.js +11 -2
- package/actions/router/routeWillPush.js +13 -2
- package/actions/router/routeWillReplace.js +11 -2
- package/actions/router/routeWillReset.js +11 -2
- package/actions/router/windowOpenOverride.js +10 -2
- package/actions/user/fetchRegisterUrl.js +36 -2
- package/actions/user/fetchUser.js +29 -3
- package/actions/user/getUser.js +6 -2
- package/actions/user/index.js +1 -1
- package/actions/user/login.js +76 -9
- package/actions/user/logout.js +30 -2
- package/collections/AuthRoutes.js +73 -14
- package/collections/Configuration.js +54 -7
- package/collections/EmbeddedMedia.js +84 -11
- package/collections/PersistedReducers.js +41 -6
- package/collections/Redirects.js +103 -17
- package/collections/index.js +5 -1
- package/collections/media-providers/MediaProvider.js +151 -26
- package/collections/media-providers/Vimeo.js +113 -19
- package/collections/media-providers/YouTube.js +74 -14
- package/collections/media-providers/index.js +3 -1
- package/collections/media-providers/style.js +52 -2
- package/components/Backdrop/index.js +95 -6
- package/components/Backdrop/spec.js +23 -1
- package/components/Backdrop/style.js +11 -2
- package/components/Button/index.js +47 -5
- package/components/Button/spec.js +36 -1
- package/components/Button/style.js +6 -1
- package/components/Checkbox/index.js +126 -32
- package/components/Checkbox/spec.js +94 -3
- package/components/Consume/helpers/buildParams.js +13 -2
- package/components/Consume/index.js +14 -2
- package/components/CountdownTimer/index.js +115 -17
- package/components/CountdownTimer/spec.js +126 -12
- package/components/Drawer/index.js +131 -16
- package/components/Drawer/spec.js +76 -1
- package/components/Drawer/style.js +37 -1
- package/components/Dropdown/index.js +65 -6
- package/components/Dropdown/style.js +4 -1
- package/components/Dropdown/transitions.js +34 -1
- package/components/Ellipsis/index.js +16 -2
- package/components/Ellipsis/spec.js +13 -1
- package/components/EmbeddedMedia/index.js +56 -6
- package/components/EmbeddedMedia/spec.js +52 -3
- package/components/ErrorBoundary/connector.js +9 -2
- package/components/ErrorBoundary/index.js +43 -7
- package/components/Grid/components/Item/index.js +40 -4
- package/components/Grid/components/Item/spec.js +23 -1
- package/components/Grid/components/Item/style.js +17 -3
- package/components/Grid/index.js +36 -4
- package/components/Grid/spec.js +23 -1
- package/components/Grid/style.js +11 -2
- package/components/HtmlSanitizer/connector.js +24 -3
- package/components/HtmlSanitizer/index.js +104 -12
- package/components/HtmlSanitizer/spec.js +207 -6
- package/components/I18n/components/FormatDate/index.js +26 -2
- package/components/I18n/components/FormatDate/spec.js +46 -1
- package/components/I18n/components/FormatNumber/index.js +34 -2
- package/components/I18n/components/FormatNumber/spec.js +41 -2
- package/components/I18n/components/FormatPrice/index.js +32 -2
- package/components/I18n/components/FormatPrice/spec.js +46 -1
- package/components/I18n/components/FormatTime/index.js +26 -2
- package/components/I18n/components/FormatTime/spec.js +43 -2
- package/components/I18n/components/I18nProvider/index.js +52 -9
- package/components/I18n/components/I18nProvider/spec.js +39 -1
- package/components/I18n/components/Placeholder/index.js +8 -2
- package/components/I18n/components/Placeholder/spec.js +30 -1
- package/components/I18n/components/Translate/index.js +68 -7
- package/components/I18n/components/Translate/spec.js +30 -1
- package/components/I18n/index.js +16 -1
- package/components/Icon/index.js +25 -2
- package/components/Icon/style.js +6 -1
- package/components/Image/Image.js +176 -19
- package/components/Image/ImageInner.js +48 -2
- package/components/Image/index.js +1 -1
- package/components/Image/style.js +29 -2
- package/components/InfiniteContainer/index.js +381 -49
- package/components/InfiniteContainer/spec.js +199 -10
- package/components/Input/components/DateInput.js +262 -6
- package/components/Input/components/MultiLineInput.js +98 -12
- package/components/Input/components/SimpleInput.js +207 -31
- package/components/Input/index.js +32 -3
- package/components/Input/spec.js +122 -1
- package/components/KeyboardConsumer/index.js +48 -7
- package/components/Link/connector.js +7 -1
- package/components/Link/index.js +96 -11
- package/components/Link/spec.js +56 -1
- package/components/Link/style.js +10 -1
- package/components/List/components/Item/index.js +35 -3
- package/components/List/components/Item/style.js +16 -1
- package/components/List/index.js +20 -2
- package/components/List/spec.js +31 -1
- package/components/Loading/index.js +6 -2
- package/components/Modal/index.js +38 -3
- package/components/Modal/style.js +36 -1
- package/components/ModalContainer/connector.js +17 -3
- package/components/ModalContainer/index.js +36 -3
- package/components/ModalContainer/spec.js +105 -5
- package/components/Picker/components/Button/index.js +34 -2
- package/components/Picker/components/Button/style.js +19 -1
- package/components/Picker/components/List/index.js +33 -2
- package/components/Picker/components/List/style.js +17 -1
- package/components/Picker/components/Modal/index.js +60 -7
- package/components/Picker/components/Modal/style.js +78 -1
- package/components/Picker/index.js +167 -21
- package/components/Picker/spec.js +83 -2
- package/components/Portal/index.js +130 -19
- package/components/ProductCharacteristics/connector.js +33 -4
- package/components/ProductCharacteristics/context.js +2 -1
- package/components/ProductCharacteristics/helpers/index.js +135 -21
- package/components/ProductCharacteristics/index.js +266 -31
- package/components/RangeSlider/components/Handle/index.js +25 -2
- package/components/RangeSlider/components/Handle/style.js +14 -1
- package/components/RangeSlider/helper.js +43 -8
- package/components/RangeSlider/index.js +228 -38
- package/components/RangeSlider/style.js +14 -1
- package/components/Route/RouteNotFound.js +46 -3
- package/components/Route/index.js +78 -10
- package/components/Router/connector.js +9 -2
- package/components/Router/index.js +237 -31
- package/components/ScannerContainer/connector.js +9 -2
- package/components/ScannerContainer/index.js +42 -6
- package/components/Select/components/Item/index.js +20 -4
- package/components/Select/components/Item/style.js +4 -1
- package/components/Select/index.js +149 -28
- package/components/Select/spec.js +86 -2
- package/components/Select/style.js +17 -1
- package/components/SelectBox/components/Item/index.js +47 -5
- package/components/SelectBox/components/Item/style.js +7 -1
- package/components/SelectBox/index.js +173 -17
- package/components/SelectBox/spec.js +59 -3
- package/components/SelectBox/style.js +18 -1
- package/components/Slider/index.js +6 -2
- package/components/SurroundPortals/index.js +26 -2
- package/components/Swiper/components/SwiperItem/index.js +28 -4
- package/components/Swiper/components/SwiperItem/spec.js +17 -1
- package/components/Swiper/components/SwiperItem/styles.js +5 -1
- package/components/Swiper/index.js +210 -18
- package/components/Swiper/styles.js +75 -7
- package/components/Toaster/index.js +10 -2
- package/components/Transition/index.js +89 -13
- package/components/Widgets/components/Widget/index.js +52 -4
- package/components/Widgets/components/Widget/spec.js +68 -3
- package/components/Widgets/components/Widget/style.js +21 -3
- package/components/Widgets/components/WidgetGrid/index.js +52 -7
- package/components/Widgets/components/WidgetGrid/spec.js +46 -2
- package/components/Widgets/components/WidgetGrid/style.js +8 -1
- package/components/Widgets/helpers/shouldShowWidget.js +44 -7
- package/components/Widgets/index.js +127 -15
- package/components/Widgets/spec.js +213 -6
- package/components/index.js +9 -1
- package/constants/ActionTypes.js +97 -19
- package/constants/Configuration.js +12 -2
- package/constants/Device.js +29 -2
- package/constants/DisplayOptions.js +8 -1
- package/constants/MenuIDs.js +2 -1
- package/constants/ModalTypes.js +1 -1
- package/constants/PageIDs.js +1 -1
- package/constants/Pipelines.js +7 -1
- package/constants/Portals.js +136 -3
- package/constants/Registration.js +3 -1
- package/constants/RoutePaths.js +13 -2
- package/constants/Tracking.js +3 -1
- package/constants/client.js +6 -1
- package/constants/ui.js +2 -1
- package/constants/user.js +6 -2
- package/context/index.js +33 -3
- package/helpers/config/index.js +139 -21
- package/helpers/config/mock.js +200 -8
- package/helpers/config/theme.js +50 -4
- package/helpers/data/index.js +204 -29
- package/helpers/data/spec.js +187 -7
- package/helpers/date/index.js +58 -6
- package/helpers/date/spec.js +92 -1
- package/helpers/dom/index.js +48 -11
- package/helpers/environment/index.js +14 -2
- package/helpers/html/decodeHTML.js +7 -1
- package/helpers/html/handleDOM.js +172 -21
- package/helpers/html/parseHTML.js +67 -12
- package/helpers/i18n/getDateFormatter.js +23 -4
- package/helpers/i18n/getNumberFormatter.js +32 -4
- package/helpers/i18n/getPriceFormatter.js +38 -4
- package/helpers/i18n/getTimeFormatter.js +23 -4
- package/helpers/i18n/getTranslator.js +62 -8
- package/helpers/i18n/index.js +5 -1
- package/helpers/i18n/mergeTranslations.js +36 -9
- package/helpers/i18n/messageCache.js +3 -1
- package/helpers/legacy/index.js +47 -9
- package/helpers/modal/withShowModal.js +13 -2
- package/helpers/portals/portalCollection.js +28 -6
- package/helpers/portals/routePortals.js +12 -1
- package/helpers/redux/compareObjects.js +7 -2
- package/helpers/redux/generateResultHash.js +36 -3
- package/helpers/redux/generateSortedHash.js +7 -2
- package/helpers/redux/hasExpired.js +10 -2
- package/helpers/redux/index.js +7 -1
- package/helpers/redux/mutable.js +143 -24
- package/helpers/redux/shouldFetchData.js +46 -10
- package/helpers/redux/shouldFetchFilters.js +17 -4
- package/helpers/router/index.js +49 -5
- package/helpers/style/index.js +43 -4
- package/helpers/style/spec.js +108 -2
- package/helpers/tracking/index.js +52 -9
- package/helpers/validation/index.js +39 -12
- package/helpers/validation/spec.js +10 -1
- package/package.json +3 -3
- package/providers/index.js +4 -1
- package/providers/loading/context.js +2 -1
- package/providers/loading/index.js +137 -22
- package/providers/toast/context.js +2 -1
- package/providers/toast/index.js +105 -11
- package/reducers/client/connectivity.js +22 -2
- package/reducers/client/index.js +7 -1
- package/reducers/client/info.js +27 -2
- package/reducers/index.js +23 -4
- package/reducers/menu/index.js +5 -1
- package/reducers/menu/menusById.js +41 -2
- package/reducers/modal/index.js +14 -2
- package/reducers/page/index.js +68 -5
- package/reducers/router/index.js +48 -2
- package/reducers/url/index.js +42 -3
- package/reducers/user/data.js +27 -2
- package/reducers/user/index.js +7 -1
- package/reducers/user/login.js +65 -2
- package/selectors/client.js +138 -21
- package/selectors/history.js +49 -11
- package/selectors/menu.js +34 -6
- package/selectors/modal.js +15 -4
- package/selectors/page.js +25 -4
- package/selectors/router.js +154 -30
- package/selectors/url.js +25 -4
- package/selectors/user.js +90 -13
- package/store/index.js +60 -6
- package/store/middelwares/logger.js +7 -1
- package/store/middelwares/streams.js +19 -2
- package/streams/app.js +60 -8
- package/streams/client.js +8 -2
- package/streams/error.js +14 -3
- package/streams/index.js +6 -1
- package/streams/interval.js +6 -2
- package/streams/main.js +27 -2
- package/streams/router.js +45 -8
- package/streams/user.js +89 -15
- package/streams/view.js +97 -25
- package/styles/reset/form.js +57 -5
- package/styles/reset/index.js +6 -1
- package/styles/reset/media.js +22 -1
- package/styles/reset/root.js +33 -1
- package/styles/reset/table.js +10 -1
- package/styles/reset/typography.js +26 -1
- package/subscriptions/app.js +148 -17
- package/subscriptions/error.js +292 -13
- package/subscriptions/helpers/buildRegisterUrl.js +25 -6
- package/subscriptions/helpers/clearUpInAppBrowser.js +14 -3
- package/subscriptions/helpers/handleLinks.js +267 -25
- package/subscriptions/helpers/pipeline.js +12 -1
- package/subscriptions/history.js +34 -6
- package/subscriptions/index.js +25 -4
- package/subscriptions/menu.js +22 -5
- package/subscriptions/mock.js +39 -7
- package/subscriptions/router.js +336 -23
- package/subscriptions/user.js +93 -3
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import IntlMessageFormat from 'intl-messageformat';
|
|
2
|
+
import curry from 'lodash/curry';
|
|
3
|
+
import appConfig from '@shopgate/pwa-common/helpers/config';
|
|
4
|
+
import messageCache from "./messageCache";
|
|
5
|
+
const {
|
|
6
|
+
showPriceGrouping
|
|
7
|
+
} = appConfig;
|
|
8
|
+
|
|
9
|
+
/**
|
|
2
10
|
* Returns an instance of IntlMessageFormat from cache based on a hash.
|
|
3
11
|
* The hash is generated from given language code and translation key.
|
|
4
12
|
* If no instance exists yet, a new instance will be created and returned.
|
|
@@ -6,12 +14,38 @@ function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj
|
|
|
6
14
|
* @param {string} currency The current currency.
|
|
7
15
|
* @param {boolean} fractions With or without fraction digits.
|
|
8
16
|
* @returns {IntlMessageFormat}
|
|
9
|
-
*/
|
|
10
|
-
|
|
17
|
+
*/
|
|
18
|
+
const getFormattedPriceFromCache = (langCode, currency, fractions) => {
|
|
19
|
+
const hash = `${langCode}_price_${currency}_${fractions}`;
|
|
20
|
+
|
|
21
|
+
// Check if a cached instance already exists.
|
|
22
|
+
if (messageCache[hash]) {
|
|
23
|
+
return messageCache[hash];
|
|
24
|
+
}
|
|
25
|
+
messageCache[hash] = new IntlMessageFormat(`{price, number, ${currency}}`, langCode, {
|
|
26
|
+
number: {
|
|
27
|
+
[currency]: {
|
|
28
|
+
style: 'currency',
|
|
29
|
+
currency,
|
|
30
|
+
minimumFractionDigits: fractions ? 2 : 0,
|
|
31
|
+
maximumFractionDigits: fractions ? 2 : 0,
|
|
32
|
+
useGrouping: showPriceGrouping
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return messageCache[hash];
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
11
40
|
* Get a formatted price by currency and language code.
|
|
12
41
|
* @param {string} langCode A language code.
|
|
13
42
|
* @param {number} price The price to format.
|
|
14
43
|
* @param {string} currency The current currency.
|
|
15
44
|
* @param {boolean} fractions With or without fraction digits.
|
|
16
45
|
* @returns {string}
|
|
17
|
-
*/
|
|
46
|
+
*/
|
|
47
|
+
const formatPrice = (langCode, price, currency, fractions) => getFormattedPriceFromCache(langCode, currency, fractions).format({
|
|
48
|
+
price
|
|
49
|
+
});
|
|
50
|
+
const getPriceFormatter = curry(formatPrice);
|
|
51
|
+
export default getPriceFormatter;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import IntlMessageFormat from'intl-messageformat';
|
|
1
|
+
import IntlMessageFormat from 'intl-messageformat';
|
|
2
|
+
import curry from 'lodash/curry';
|
|
3
|
+
import messageCache from "./messageCache";
|
|
4
|
+
|
|
5
|
+
/**
|
|
2
6
|
* Returns an instance of IntlMessageFormat from cache based on a hash.
|
|
3
7
|
* The hash is generated from given language code and translation key.
|
|
4
8
|
* If no instance exists yet, a new instance will be created and returned.
|
|
@@ -6,12 +10,27 @@ import IntlMessageFormat from'intl-messageformat';import curry from'lodash/curry
|
|
|
6
10
|
* @param {string} format The time format.
|
|
7
11
|
* Possible values: 'short', 'medium' (default), 'long','full'
|
|
8
12
|
* @returns {IntlMessageFormat}
|
|
9
|
-
*/
|
|
10
|
-
|
|
13
|
+
*/
|
|
14
|
+
const getFormattedTimeFromCache = (langCode, format) => {
|
|
15
|
+
const hash = `${langCode}_time_${format}`;
|
|
16
|
+
|
|
17
|
+
// Check if a cached instance already exists.
|
|
18
|
+
if (messageCache[hash]) {
|
|
19
|
+
return messageCache[hash];
|
|
20
|
+
}
|
|
21
|
+
messageCache[hash] = new IntlMessageFormat(`{timestamp, time, ${format}}`, langCode);
|
|
22
|
+
return messageCache[hash];
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
11
26
|
* Get a formatted time from a timestamp.
|
|
12
27
|
* @param {string} langCode A language code.
|
|
13
28
|
* @param {number} timestamp The current time's timestamp.
|
|
14
29
|
* @param {string} [format='medium'] The time format.
|
|
15
30
|
* Possible values: 'short', 'medium', 'long','full'
|
|
16
31
|
* @returns {string}
|
|
17
|
-
*/
|
|
32
|
+
*/
|
|
33
|
+
const formatTime = (langCode, timestamp, format = 'medium') => getFormattedTimeFromCache(langCode, format).format({
|
|
34
|
+
timestamp
|
|
35
|
+
});
|
|
36
|
+
export default curry(formatTime);
|
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
1
|
+
import "core-js/modules/es.array.reduce.js";
|
|
2
|
+
import IntlMessageFormat from 'intl-messageformat';
|
|
3
|
+
import curry from 'lodash/curry';
|
|
4
|
+
// eslint-disable-next-line import/no-named-default
|
|
5
|
+
import { default as getPath } from 'lodash/get';
|
|
6
|
+
import moment from 'moment';
|
|
7
|
+
import messageCache from "./messageCache";
|
|
8
|
+
|
|
9
|
+
/**
|
|
3
10
|
* Pure function to return original key whet Intl message not found
|
|
4
11
|
* @param {*} key origin intl key to return
|
|
5
12
|
* @returns {*}
|
|
6
|
-
*/
|
|
13
|
+
*/
|
|
14
|
+
const pureReturn = key => ({
|
|
15
|
+
format: () => key
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/**
|
|
7
19
|
* Returns an instance of IntlMessageFormat from cache based on a hash.
|
|
8
20
|
* The hash is generated from given language code and translation key.
|
|
9
21
|
* If no instance exists yet, a new instance will be created and returned.
|
|
@@ -14,9 +26,32 @@ import{default as getPath}from'lodash/get';import moment from'moment';import mes
|
|
|
14
26
|
* @param {boolean} [options.acceptPlainTextWithPlaceholders = false] When set to TRUE, the
|
|
15
27
|
* translator can also handle human readable texts that contain text replacement placeholders.
|
|
16
28
|
* @returns {IntlMessageFormat}
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
|
|
29
|
+
*/
|
|
30
|
+
const getMessageFromCache = (locales, langCode, key, options = {}) => {
|
|
31
|
+
const {
|
|
32
|
+
acceptPlainTextWithPlaceholders = false
|
|
33
|
+
} = options;
|
|
34
|
+
const hash = `${langCode}_${key}_${acceptPlainTextWithPlaceholders ? 1 : 0}`;
|
|
35
|
+
|
|
36
|
+
// Check if a cached instance already exists.
|
|
37
|
+
if (messageCache[hash]) {
|
|
38
|
+
return messageCache[hash];
|
|
39
|
+
}
|
|
40
|
+
const message = getPath(locales, key, acceptPlainTextWithPlaceholders ? key : undefined);
|
|
41
|
+
if (typeof message !== 'string' || message.length === 0) {
|
|
42
|
+
return pureReturn(key);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Prevent the app from crashing when strings (like product names) don't comply with the format
|
|
46
|
+
try {
|
|
47
|
+
messageCache[hash] = new IntlMessageFormat(message, langCode, getPath(locales, 'formats'));
|
|
48
|
+
} catch (e) {
|
|
49
|
+
messageCache[hash] = pureReturn(key);
|
|
50
|
+
}
|
|
51
|
+
return messageCache[hash];
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
20
55
|
* Get a translation for a given key.
|
|
21
56
|
* @param {Object} locales A locales object.
|
|
22
57
|
* @param {string} langCode A language code.
|
|
@@ -26,6 +61,25 @@ try{messageCache[hash]=new IntlMessageFormat(message,langCode,getPath(locales,'f
|
|
|
26
61
|
* @param {boolean} [options.acceptPlainTextWithPlaceholders = false] When set to TRUE, the
|
|
27
62
|
* translator can also handle human readable texts that contain text replacement placeholders.
|
|
28
63
|
* @returns {string}
|
|
29
|
-
*/
|
|
64
|
+
*/
|
|
65
|
+
const translate = (locales, langCode, key, args = {}, options = {}) => {
|
|
66
|
+
/**
|
|
30
67
|
* @returns {Object}
|
|
31
|
-
*/
|
|
68
|
+
*/
|
|
69
|
+
const sanitizeArgs = () => {
|
|
70
|
+
if (typeof args !== 'object' || args === null) {
|
|
71
|
+
return args;
|
|
72
|
+
}
|
|
73
|
+
return Object.keys(args).reduce((acc, arg) => {
|
|
74
|
+
const date = moment(args[arg], moment.ISO_8601, true);
|
|
75
|
+
if (date.isValid() && date.toISOString() === args[arg]) {
|
|
76
|
+
acc[arg] = new Date(args[arg]).getTime();
|
|
77
|
+
} else {
|
|
78
|
+
acc[arg] = args[arg];
|
|
79
|
+
}
|
|
80
|
+
return acc;
|
|
81
|
+
}, {});
|
|
82
|
+
};
|
|
83
|
+
return getMessageFromCache(locales, langCode, key, options).format(sanitizeArgs());
|
|
84
|
+
};
|
|
85
|
+
export default curry(translate);
|
package/helpers/i18n/index.js
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export{default as getTranslator
|
|
1
|
+
export { default as getTranslator } from "./getTranslator";
|
|
2
|
+
export { default as getPriceFormatter } from "./getPriceFormatter";
|
|
3
|
+
export { default as getDateFormatter } from "./getDateFormatter";
|
|
4
|
+
export { default as getTimeFormatter } from "./getTimeFormatter";
|
|
5
|
+
export { default as getNumberFormatter } from "./getNumberFormatter";
|
|
@@ -1,21 +1,48 @@
|
|
|
1
|
-
|
|
1
|
+
import "core-js/modules/es.array.reduce.js";
|
|
2
|
+
import isPlainObject from 'lodash/isPlainObject';
|
|
3
|
+
import cloneDeep from 'lodash/cloneDeep';
|
|
4
|
+
import merge from 'lodash/merge';
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* Checks if an extension locale matches the theme locale.
|
|
3
8
|
* @param {string} themeLocale The locale of the theme.
|
|
4
9
|
* @param {string} extensionLocale The locale of an extension.
|
|
5
10
|
* @return {boolean}
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
*/
|
|
12
|
+
const localesMatch = (themeLocale, extensionLocale) => {
|
|
13
|
+
// Extract the actual locale string from the extension locale.
|
|
14
|
+
const [locale] = extensionLocale.split('/').reverse();
|
|
15
|
+
// Extract the language from the theme locale.
|
|
16
|
+
const [themeLanguage] = themeLocale.split('-');
|
|
17
|
+
|
|
18
|
+
/**
|
|
9
19
|
* Theme locales always contain language and region (en-US). But extension locales
|
|
10
20
|
* might only scoped for a language (en). To be sure that all extension translations
|
|
11
21
|
* are considered for the merge, both variants are checked.
|
|
12
|
-
*/
|
|
22
|
+
*/
|
|
23
|
+
return locale.toLowerCase() === themeLocale.toLowerCase() || locale.toLowerCase() === themeLanguage;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
13
27
|
* Merges extension translations into the theme translations.
|
|
14
28
|
* @param {Object} theme The translations object of a theme.
|
|
15
29
|
* @param {Object} extensions The extension translations.
|
|
16
30
|
* @param {string} [locale=process.env.LOCALE_FILE] The current active locale of the theme.
|
|
17
31
|
* @return {Object}
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
32
|
+
*/
|
|
33
|
+
const mergeTranslations = (theme, extensions, locale = process.env.LOCALE_FILE) => {
|
|
34
|
+
if (!isPlainObject(extensions) || Object.keys(extensions).length === 0) {
|
|
35
|
+
// No extension translations provided.
|
|
36
|
+
return cloneDeep(theme);
|
|
37
|
+
}
|
|
38
|
+
return Object.keys(extensions).reduce((result, extensionLocale) => {
|
|
39
|
+
if (!localesMatch(locale, extensionLocale)) {
|
|
40
|
+
// Continue if the current extension locale doesn't match the theme locale.
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Merge the current extensions into the result.
|
|
45
|
+
return merge(result, extensions[extensionLocale]);
|
|
46
|
+
}, cloneDeep(theme));
|
|
47
|
+
};
|
|
48
|
+
export default mergeTranslations;
|
package/helpers/legacy/index.js
CHANGED
|
@@ -1,21 +1,59 @@
|
|
|
1
|
-
import hideMenuBar from'@shopgate/pwa-core/commands/hideMenuBar';
|
|
1
|
+
import hideMenuBar from '@shopgate/pwa-core/commands/hideMenuBar';
|
|
2
|
+
import broadcastEvent from '@shopgate/pwa-core/commands/broadcastEvent';
|
|
3
|
+
import showTab from '@shopgate/pwa-core/commands/showTab';
|
|
4
|
+
import { appSupportsAndroidEdgeToEdge } from '@shopgate/engage/core/helpers';
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* Page context that comes from the app.
|
|
3
8
|
* @type {Object}
|
|
4
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
let currentPageContext = {};
|
|
11
|
+
|
|
12
|
+
/**
|
|
5
13
|
* Get Page context if available.
|
|
6
14
|
* @returns {Object}
|
|
7
|
-
*/
|
|
15
|
+
*/
|
|
16
|
+
export const getPageContext = () => currentPageContext;
|
|
17
|
+
|
|
18
|
+
/**
|
|
8
19
|
* Prepares the NavigationBar and the MenuBar of the app legacy part for the PWA.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
|
|
20
|
+
*/
|
|
21
|
+
export const prepareLegacyNavigation = () => {
|
|
22
|
+
// Logic below causes issues on Android app with edge-to-edge screens. For compatibility reasons
|
|
23
|
+
// logic is skipped for now on those devices. Function could potentially be removed in the future.
|
|
24
|
+
if (appSupportsAndroidEdgeToEdge()) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
12
28
|
* Broadcasts an event to the pwa_navigation_bar webview and updates the navigation bar with
|
|
13
29
|
* type "none". Event parameters are defined accordingly to the specification of the native
|
|
14
30
|
* updateNavigationBar event.
|
|
15
|
-
*/
|
|
31
|
+
*/
|
|
32
|
+
broadcastEvent({
|
|
33
|
+
event: 'updateNavigationBar',
|
|
34
|
+
parameters: ['', 'none', {
|
|
35
|
+
type: 'none'
|
|
36
|
+
}]
|
|
37
|
+
});
|
|
38
|
+
hideMenuBar({
|
|
39
|
+
animation: null
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
16
44
|
* Shows the main tab when legacy system requests the previous tab.
|
|
17
45
|
* @param {Object} context The page context from the app.
|
|
18
46
|
* @param {string} context.tab The tab where the page is opened.
|
|
19
|
-
*/
|
|
47
|
+
*/
|
|
48
|
+
export const pageContext = context => {
|
|
49
|
+
currentPageContext = context;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
20
53
|
* Shows the main tab when legacy system requests the previous tab.
|
|
21
|
-
*/
|
|
54
|
+
*/
|
|
55
|
+
export const showPreviousTab = () => {
|
|
56
|
+
showTab({
|
|
57
|
+
targetTab: currentPageContext.tab ? currentPageContext.tab : 'main'
|
|
58
|
+
});
|
|
59
|
+
};
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
import { connect } from 'react-redux';
|
|
2
|
+
import showModal from '@shopgate/pwa-common/actions/modal/showModal';
|
|
3
|
+
|
|
4
|
+
/**
|
|
2
5
|
* @param {Function} dispatch The redux dispatch function
|
|
3
6
|
* @return {Object}
|
|
4
|
-
*/
|
|
7
|
+
*/
|
|
8
|
+
const mapDispatchToProps = dispatch => ({
|
|
9
|
+
showModal: options => dispatch(showModal({
|
|
10
|
+
confirm: 'modal.ok',
|
|
11
|
+
dismiss: null,
|
|
12
|
+
...options
|
|
13
|
+
}))
|
|
14
|
+
});
|
|
15
|
+
export default connect(null, mapDispatchToProps);
|
|
@@ -1,15 +1,37 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
2
|
* The portals collection.
|
|
3
|
-
*/
|
|
3
|
+
*/
|
|
4
|
+
class PortalCollection {
|
|
5
|
+
/**
|
|
4
6
|
* Returns the portal definitions.
|
|
5
7
|
* @return {Object}
|
|
6
|
-
*/
|
|
8
|
+
*/
|
|
9
|
+
getPortals() {
|
|
10
|
+
return this.portals;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
7
14
|
* Registers the portal definitions.
|
|
8
15
|
* @param {Object} [portals={}] The portals to register.
|
|
9
|
-
*/
|
|
16
|
+
*/
|
|
17
|
+
registerPortals(portals = {}) {
|
|
18
|
+
this.portals = portals;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
10
22
|
* Registers the portal config.
|
|
11
23
|
* @param {Object} [config={}] The portals config.
|
|
12
|
-
*/
|
|
24
|
+
*/
|
|
25
|
+
registerConfig(config = {}) {
|
|
26
|
+
this.config = config;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
13
30
|
* Returns the portal config.
|
|
14
31
|
* @return {Object}
|
|
15
|
-
*/
|
|
32
|
+
*/
|
|
33
|
+
getConfig() {
|
|
34
|
+
return this.config;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export default new PortalCollection();
|
|
@@ -1 +1,12 @@
|
|
|
1
|
-
import{componentsConfig}from"../config";
|
|
1
|
+
import { componentsConfig } from "../config";
|
|
2
|
+
import collection from "./portalCollection";
|
|
3
|
+
import { APP_ROUTES } from "../../constants/Portals";
|
|
4
|
+
const portals = collection.getPortals();
|
|
5
|
+
const config = collection.getConfig() || componentsConfig.portals;
|
|
6
|
+
const routes = Object.keys(config).map(component => {
|
|
7
|
+
if (config[component].target !== APP_ROUTES) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
return portals[component]();
|
|
11
|
+
}).filter(Boolean);
|
|
12
|
+
export default routes;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import{generateSortedHash}from"./generateSortedHash"
|
|
1
|
+
import { generateSortedHash } from "./generateSortedHash";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Deep compares two objects.
|
|
3
5
|
* @param {Object} input1 The first object.
|
|
4
6
|
* @param {Object} input2 The second object.
|
|
5
7
|
* @return {boolean}
|
|
6
|
-
*/
|
|
8
|
+
*/
|
|
9
|
+
export function compareObjects(input1, input2) {
|
|
10
|
+
return generateSortedHash(input1) === generateSortedHash(input2);
|
|
11
|
+
}
|
|
@@ -1,11 +1,44 @@
|
|
|
1
|
-
|
|
1
|
+
import { logger } from '@shopgate/pwa-core/helpers';
|
|
2
|
+
import * as pipelines from "../../constants/Pipelines";
|
|
3
|
+
import { generateSortedHash } from "./generateSortedHash";
|
|
4
|
+
|
|
5
|
+
/**
|
|
2
6
|
* Generates a hash for product collection results.
|
|
3
7
|
* @param {Object} params The request parameters.
|
|
4
8
|
* @param {boolean} [includeSort=true] Whether to include the sorting in the hash.
|
|
5
9
|
* @param {boolean} [includeFilters=true] Whether to include the filters in the hash.
|
|
6
10
|
* @param {string} [defaultSort=null] A default value for the sort parameter
|
|
7
11
|
* @return {string} The generated hash.
|
|
8
|
-
*/
|
|
12
|
+
*/
|
|
13
|
+
export function generateResultHash(params, includeSort = true, includeFilters = true, defaultSort = null) {
|
|
14
|
+
const defaultParams = {
|
|
15
|
+
pipeline: pipelines.SHOPGATE_CATALOG_GET_PRODUCTS,
|
|
16
|
+
...(includeFilters && {
|
|
17
|
+
filters: {}
|
|
18
|
+
}),
|
|
19
|
+
...(includeSort && defaultSort && {
|
|
20
|
+
sort: defaultSort
|
|
21
|
+
})
|
|
22
|
+
};
|
|
23
|
+
const mergedParams = {
|
|
24
|
+
...defaultParams,
|
|
25
|
+
...params
|
|
26
|
+
};
|
|
27
|
+
if (includeSort && !mergedParams.sort) {
|
|
28
|
+
logger.error('generateResultHash() needs to be called with a sort parameter when the sort is supposed to be included');
|
|
29
|
+
}
|
|
30
|
+
if (!includeSort && mergedParams.sort) {
|
|
31
|
+
delete mergedParams.sort;
|
|
32
|
+
}
|
|
33
|
+
const {
|
|
34
|
+
searchPhrase
|
|
35
|
+
} = mergedParams;
|
|
36
|
+
if (searchPhrase) {
|
|
37
|
+
/**
|
|
9
38
|
* We trim the search phrase here, because otherwise we will create different hash and cache
|
|
10
39
|
* entries for the same search term (because whitespaces don't influence the search results)
|
|
11
|
-
*/
|
|
40
|
+
*/
|
|
41
|
+
mergedParams.searchPhrase = searchPhrase.trim();
|
|
42
|
+
}
|
|
43
|
+
return generateSortedHash(mergedParams);
|
|
44
|
+
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import{sortObject}from"../data"
|
|
1
|
+
import { sortObject } from "../data";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Generates a hash from an object with sorted values.
|
|
3
5
|
* @param {Object} input The input object.
|
|
4
6
|
* @return {string} The generated hash.
|
|
5
|
-
*/
|
|
7
|
+
*/
|
|
8
|
+
export function generateSortedHash(input) {
|
|
9
|
+
return JSON.stringify(sortObject(input));
|
|
10
|
+
}
|
|
@@ -2,5 +2,13 @@
|
|
|
2
2
|
* Determines if an item has expired and therefore should fetch or re-fetch it's data.
|
|
3
3
|
* @param {Object} item The item to determine if it has expired.
|
|
4
4
|
* @return {boolean}
|
|
5
|
-
*/
|
|
6
|
-
|
|
5
|
+
*/
|
|
6
|
+
export function hasExpired(item) {
|
|
7
|
+
if (!item.isFetching) {
|
|
8
|
+
// If the expiry date has expired or is set to 0 (initial value).
|
|
9
|
+
if (item.expires === 0 || item.expires && item.expires > 0 && item.expires < Date.now()) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}
|
package/helpers/redux/index.js
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
|
-
export{hasExpired}from"./hasExpired";
|
|
1
|
+
export { hasExpired } from "./hasExpired";
|
|
2
|
+
export { shouldFetchData } from "./shouldFetchData";
|
|
3
|
+
export { shouldFetchFilters } from "./shouldFetchFilters";
|
|
4
|
+
export { compareObjects } from "./compareObjects";
|
|
5
|
+
export { generateSortedHash } from "./generateSortedHash";
|
|
6
|
+
export { generateResultHash } from "./generateResultHash";
|
|
7
|
+
export { mutable, mutableActions } from "./mutable";
|