@shopgate/pwa-common 7.30.0-alpha.7 → 7.30.0-alpha.9
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 +214 -7
- 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 +21 -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 +228 -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 -4
- 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,59 +1,204 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "core-js/modules/web.url.js";
|
|
2
|
+
import "core-js/modules/web.url.to-json.js";
|
|
3
|
+
import "core-js/modules/web.url-search-params.js";
|
|
4
|
+
import { router, ACTION_REPLACE } from '@virtuous/conductor';
|
|
5
|
+
import flushTab from '@shopgate/pwa-core/commands/flushTab';
|
|
6
|
+
import openPage from '@shopgate/pwa-core/commands/openPage';
|
|
7
|
+
import showTab from '@shopgate/pwa-core/commands/showTab';
|
|
8
|
+
import { openPageExtern } from '@shopgate/pwa-core';
|
|
9
|
+
import appConfig from '@shopgate/pwa-common/helpers/config';
|
|
10
|
+
import { hasNewServices, hasWebBridge, logger, hasSGJavaScriptBridge } from '@shopgate/engage/core/helpers';
|
|
11
|
+
import { getCurrentRoute } from '@shopgate/pwa-common/selectors/router';
|
|
12
|
+
import authRoutes from "../../collections/AuthRoutes";
|
|
13
|
+
const SHOPGATE_DOMAIN = 'shopgate.com';
|
|
14
|
+
const SHOPGATEPG_DOMAIN = 'shopgatepg.com';
|
|
15
|
+
const SHOPGATE_DOMAINS = [SHOPGATE_DOMAIN, `www.${SHOPGATE_DOMAIN}`];
|
|
16
|
+
const PROTOCOL_HTTP = 'http:';
|
|
17
|
+
const PROTOCOL_HTTPS = 'https:';
|
|
18
|
+
const PROTOCOL_TEL = 'tel:';
|
|
19
|
+
const PROTOCOL_MAILTO = 'mailto:';
|
|
20
|
+
export const LEGACY_LINK_ACCOUNT = '/account';
|
|
21
|
+
export const LEGACY_LINK_STOREFINDER = '/storefinder';
|
|
22
|
+
export const LEGACY_LINK_CHANNEL = '/channel';
|
|
23
|
+
export const LEGACY_LINK_ORDERS = '/orders_legacy';
|
|
24
|
+
export const LEGACY_LINK_CHECKOUT = '/checkout_legacy';
|
|
25
|
+
export const LEGACY_LINK_REGISTER = '/register_legacy';
|
|
26
|
+
export const LEGACY_LINK_REGISTER_GUEST = '/register_legacy_guest';
|
|
27
|
+
export const LEGACY_LINK_CONNECT_REGISTER = '/connect_register';
|
|
28
|
+
const protocols = [PROTOCOL_HTTP, PROTOCOL_HTTPS, PROTOCOL_TEL, PROTOCOL_MAILTO];
|
|
29
|
+
const legacyPages = ['/page/terms', '/page/return_policy', '/page/privacy', '/page/imprint', '/page/shipping', '/page/payment', '/page/warranty'];
|
|
30
|
+
const legacyLinks = [LEGACY_LINK_ACCOUNT, LEGACY_LINK_STOREFINDER, LEGACY_LINK_CHANNEL, LEGACY_LINK_ORDERS, LEGACY_LINK_CHECKOUT, LEGACY_LINK_REGISTER, LEGACY_LINK_REGISTER_GUEST, LEGACY_LINK_CONNECT_REGISTER];
|
|
31
|
+
|
|
32
|
+
/**
|
|
2
33
|
* Checks whether the location starts with a URL protocol.
|
|
3
34
|
* @param {string} location The location to open.
|
|
4
35
|
* @return {boolean}
|
|
5
|
-
*/
|
|
36
|
+
*/
|
|
37
|
+
export const hasKnownProtocols = location => new RegExp(protocols.join('|')).test(location);
|
|
38
|
+
|
|
39
|
+
/**
|
|
6
40
|
* Checks whether the location is an external link.
|
|
7
41
|
* @param {string} location The location to open.
|
|
8
42
|
* @return {boolean}
|
|
9
|
-
*/
|
|
43
|
+
*/
|
|
44
|
+
export const isExternalLink = location => location.startsWith(PROTOCOL_HTTP) || location.startsWith(PROTOCOL_HTTPS);
|
|
45
|
+
|
|
46
|
+
/**
|
|
10
47
|
* Checks whether the location is an native link.
|
|
11
48
|
* @param {string} location The location to open.
|
|
12
49
|
* @return {boolean}
|
|
13
|
-
*/
|
|
50
|
+
*/
|
|
51
|
+
export const isNativeLink = location => location.startsWith(PROTOCOL_TEL) || location.startsWith(PROTOCOL_MAILTO);
|
|
52
|
+
|
|
53
|
+
/**
|
|
14
54
|
* Checks whether the location is a legacy page.
|
|
15
55
|
* @param {string} location The location to open.
|
|
16
56
|
* @return {boolean}
|
|
17
|
-
*/
|
|
57
|
+
*/
|
|
58
|
+
export const isLegacyPage = location => legacyPages.includes(location);
|
|
59
|
+
|
|
60
|
+
/**
|
|
18
61
|
* Checks whether it is a legacy link.
|
|
19
62
|
* @param {string} location The location to open.
|
|
20
63
|
* @return {boolean}
|
|
21
|
-
*/
|
|
64
|
+
*/
|
|
65
|
+
export const isLegacyLink = location => {
|
|
66
|
+
if (hasNewServices() && [LEGACY_LINK_STOREFINDER, LEGACY_LINK_ACCOUNT].some(link => location.startsWith(link))) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
return !!legacyLinks.find(link => location.startsWith(link));
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
22
73
|
* Checks whether it is a shop link.
|
|
23
74
|
* @param {string} location The location to open.
|
|
24
75
|
* @return {boolean}
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
76
|
+
*/
|
|
77
|
+
export const isShopLink = location => {
|
|
78
|
+
if (!appConfig.shopCNAME) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Check for a non-absolute link.
|
|
83
|
+
if (!location.startsWith(PROTOCOL_HTTPS) && !location.startsWith(PROTOCOL_HTTP)) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Dissect the hostname form the given location.
|
|
88
|
+
let hostname;
|
|
89
|
+
try {
|
|
90
|
+
({
|
|
91
|
+
hostname
|
|
92
|
+
} = new URL(location));
|
|
93
|
+
} catch (e) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Check for an exact match against the shop CNAME.
|
|
98
|
+
if (hostname === appConfig.shopCNAME.toLowerCase()) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Check that the hostname contains a Shopgate domain.
|
|
103
|
+
if (!hostname.endsWith(SHOPGATE_DOMAIN || !hostname.endsWith(SHOPGATEPG_DOMAIN))) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Lastly, check explicitly for Shopgate domains.
|
|
108
|
+
if (SHOPGATE_DOMAINS.includes(hostname)) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
return true;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
31
115
|
* Sanitizes a link.
|
|
32
116
|
* @param {string} location The location to sanitize.
|
|
33
117
|
* @return {string}
|
|
34
|
-
*/
|
|
35
|
-
|
|
118
|
+
*/
|
|
119
|
+
export const sanitizeLink = location => {
|
|
120
|
+
let sanitized = location;
|
|
121
|
+
|
|
122
|
+
// Remove trailing slashes from the location.
|
|
123
|
+
if (sanitized && sanitized.length > 1) {
|
|
124
|
+
const parts = sanitized.split('?');
|
|
125
|
+
if (parts[0].endsWith('/')) {
|
|
126
|
+
parts[0] = parts[0].slice(0, -1);
|
|
127
|
+
}
|
|
128
|
+
sanitized = parts.join('?');
|
|
129
|
+
}
|
|
130
|
+
return sanitized;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
36
134
|
* Takes care that protector routes are removed from the history stack when a user is redirected
|
|
37
135
|
* to a protected route after a successful login.
|
|
38
136
|
* Usually those routes are replaced with the protected route, but at redirects to a legacy app page
|
|
39
137
|
* or the in-app-browser they need to be removed from history.
|
|
40
138
|
* @param {string} historyAction The history action which was used to navigate.
|
|
41
139
|
* @param {Object} state The application state.
|
|
42
|
-
*/
|
|
140
|
+
*/
|
|
141
|
+
export const handleAppRedirect = (historyAction, state) => {
|
|
142
|
+
const {
|
|
143
|
+
pathname
|
|
144
|
+
} = getCurrentRoute(state);
|
|
145
|
+
if (authRoutes.isProtector(pathname) && historyAction === ACTION_REPLACE) {
|
|
146
|
+
/**
|
|
43
147
|
* A replace action on a protector route indicates that the authentication was successful.
|
|
44
148
|
* So the protector route can be popped from the history stack.
|
|
45
|
-
*/
|
|
149
|
+
*/
|
|
150
|
+
router.pop();
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/**
|
|
46
155
|
* Opens a link in the in-app-browser.
|
|
47
156
|
* @param {string} location The location to open.
|
|
48
157
|
* @param {string} historyAction The history action which was used to open the link.
|
|
49
158
|
* @param {Object} state The application state.
|
|
50
159
|
* @param {Object} locationState state params for location
|
|
51
|
-
*/
|
|
160
|
+
*/
|
|
161
|
+
export const openExternalLink = (location, historyAction, state, locationState = {}) => {
|
|
162
|
+
const {
|
|
163
|
+
target
|
|
164
|
+
} = locationState;
|
|
165
|
+
if (!hasSGJavaScriptBridge() || hasWebBridge()) {
|
|
166
|
+
/**
|
|
52
167
|
* window.open is overwritten within the router subscriptions with a custom implementation.
|
|
53
168
|
* It needs to be called here with "true" as last parameter, so that the original window.open is
|
|
54
169
|
* invoked. Otherwise there would be the risk of infinite call cycles.
|
|
55
|
-
*/
|
|
56
|
-
|
|
170
|
+
*/
|
|
171
|
+
window.open(location, '_blank', undefined, true);
|
|
172
|
+
handleAppRedirect(historyAction, state);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (target === '_blank') {
|
|
176
|
+
// Deeplinks to social apps: fb, whatsapp, etc. Treat as native links
|
|
177
|
+
openPageExtern({
|
|
178
|
+
src: location
|
|
179
|
+
});
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
showTab({
|
|
183
|
+
targetTab: 'in_app_browser',
|
|
184
|
+
animation: 'slideInFromBottom'
|
|
185
|
+
});
|
|
186
|
+
openPage({
|
|
187
|
+
src: location,
|
|
188
|
+
previewSrc: 'sgapi:page_preview',
|
|
189
|
+
emulateBrowser: true,
|
|
190
|
+
targetTab: 'in_app_browser',
|
|
191
|
+
animated: false,
|
|
192
|
+
navigationBarParams: {
|
|
193
|
+
type: 'in-app-browser-default',
|
|
194
|
+
popTab: 'in_app_browser',
|
|
195
|
+
animation: 'none'
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
handleAppRedirect(historyAction, state);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/**
|
|
57
202
|
* Opens an legacy link in the old system in the given targetTab.
|
|
58
203
|
* @param {Object} options Options of the link.
|
|
59
204
|
* @param {string} options.location Link url.
|
|
@@ -62,19 +207,116 @@ openPageExtern({src:location});return;}showTab({targetTab:'in_app_browser',anima
|
|
|
62
207
|
* @param {Function} options.backCallback Function that is executed when hitting the back button.
|
|
63
208
|
* @param {string} options.historyAction The history action which was used to open the link.
|
|
64
209
|
* @param {Object} state The application state.
|
|
65
|
-
*/
|
|
66
|
-
|
|
210
|
+
*/
|
|
211
|
+
export const handleLegacyLink = (options, state) => {
|
|
212
|
+
if (options.location) {
|
|
213
|
+
let src = `sgapi:${options.location.substring(1)}`;
|
|
214
|
+
// `sgapi` links must not end with slash.
|
|
215
|
+
if (src.endsWith('/')) {
|
|
216
|
+
src = src.slice(0, -1);
|
|
217
|
+
}
|
|
218
|
+
openPage({
|
|
219
|
+
src,
|
|
220
|
+
previewSrc: 'sgapi:page_preview',
|
|
221
|
+
targetTab: options.targetTab,
|
|
222
|
+
animated: false,
|
|
223
|
+
navigationBarParams: {
|
|
224
|
+
type: options.navigationType ? options.navigationType : 'default',
|
|
225
|
+
leftButtonCallback: options.backCallback ? options.backCallback : ''
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
if (options.targetTab) {
|
|
229
|
+
showTab({
|
|
230
|
+
targetTab: options.targetTab
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
if (options.flushTab) {
|
|
234
|
+
flushTab({
|
|
235
|
+
targetTab: options.flushTab
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
handleAppRedirect(options.historyAction, state);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
/**
|
|
67
243
|
* Opens a legacy CMS page.
|
|
68
244
|
* @param {string} location The location to open.
|
|
69
245
|
* @param {string} historyAction The history action which was used to open the link.
|
|
70
246
|
* @param {Object} state The application state.
|
|
71
|
-
*/
|
|
247
|
+
*/
|
|
248
|
+
export const openLegacy = (location, historyAction, state) => {
|
|
249
|
+
handleLegacyLink({
|
|
250
|
+
targetTab: 'main',
|
|
251
|
+
location,
|
|
252
|
+
historyAction
|
|
253
|
+
}, state);
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
/**
|
|
72
257
|
* Opens a native link.
|
|
73
258
|
* @param {string} location The location to open.
|
|
74
|
-
*/
|
|
259
|
+
*/
|
|
260
|
+
export const openNativeLink = location => {
|
|
261
|
+
window.location.href = location;
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
/**
|
|
75
265
|
* Opens a legacy links.
|
|
76
266
|
* @param {string} location The location to open.
|
|
77
267
|
* @param {string} historyAction The history action which was used to open the link.
|
|
78
268
|
* @param {Object} state The application state.
|
|
79
|
-
*/
|
|
80
|
-
|
|
269
|
+
*/
|
|
270
|
+
export const openLegacyLink = (location, historyAction, state) => {
|
|
271
|
+
// Remove route parameters and query parameters to get the pure route of the legacy link.
|
|
272
|
+
const route = `/${location.split(/[?/]/)[1]}`;
|
|
273
|
+
switch (route) {
|
|
274
|
+
case LEGACY_LINK_ACCOUNT:
|
|
275
|
+
case LEGACY_LINK_STOREFINDER:
|
|
276
|
+
case LEGACY_LINK_CHANNEL:
|
|
277
|
+
openLegacy(location, historyAction, state);
|
|
278
|
+
break;
|
|
279
|
+
case LEGACY_LINK_ORDERS:
|
|
280
|
+
handleLegacyLink({
|
|
281
|
+
targetTab: 'main',
|
|
282
|
+
location: '/orders',
|
|
283
|
+
historyAction
|
|
284
|
+
}, state);
|
|
285
|
+
break;
|
|
286
|
+
case LEGACY_LINK_CHECKOUT:
|
|
287
|
+
handleLegacyLink({
|
|
288
|
+
targetTab: 'cart',
|
|
289
|
+
flushTab: 'cart',
|
|
290
|
+
navigationType: 'checkout',
|
|
291
|
+
location: '/checkout/default',
|
|
292
|
+
backCallback: 'SGAction.popTabToRoot(); SGAction.showTab({ targetTab: "main" });',
|
|
293
|
+
historyAction
|
|
294
|
+
}, state);
|
|
295
|
+
break;
|
|
296
|
+
case LEGACY_LINK_REGISTER:
|
|
297
|
+
handleLegacyLink({
|
|
298
|
+
targetTab: 'main',
|
|
299
|
+
location: '/register/default',
|
|
300
|
+
historyAction
|
|
301
|
+
}, state);
|
|
302
|
+
break;
|
|
303
|
+
case LEGACY_LINK_REGISTER_GUEST:
|
|
304
|
+
handleLegacyLink({
|
|
305
|
+
targetTab: 'main',
|
|
306
|
+
location: '/register/guest',
|
|
307
|
+
historyAction
|
|
308
|
+
});
|
|
309
|
+
break;
|
|
310
|
+
case LEGACY_LINK_CONNECT_REGISTER:
|
|
311
|
+
handleLegacyLink({
|
|
312
|
+
location: `/${LEGACY_LINK_CONNECT_REGISTER}`,
|
|
313
|
+
targetTab: 'main',
|
|
314
|
+
backCallback: 'SGAction.popTabToRoot(); SGAction.showTab({ targetTab: "main" });',
|
|
315
|
+
historyAction
|
|
316
|
+
}, state);
|
|
317
|
+
break;
|
|
318
|
+
default:
|
|
319
|
+
logger.warn(`openLegacyLink not handled: ${location}`);
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
};
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @param {Object} error error
|
|
3
3
|
* @returns {string|*}
|
|
4
|
-
*/
|
|
4
|
+
*/
|
|
5
|
+
export function transformGeneralPipelineError(error) {
|
|
6
|
+
const {
|
|
7
|
+
message
|
|
8
|
+
} = error;
|
|
9
|
+
const generalPipelineErrors = ['An internal error occured', 'An internal error occurred', '502 Bad Gateway', 'error from bigApi', 'BigApi request', 'error in bigApi'];
|
|
10
|
+
const general = new RegExp(`(${generalPipelineErrors.join('|')})`, 'i');
|
|
11
|
+
if (general.test(message)) {
|
|
12
|
+
return 'error.general';
|
|
13
|
+
}
|
|
14
|
+
return message;
|
|
15
|
+
}
|
package/subscriptions/history.js
CHANGED
|
@@ -1,9 +1,37 @@
|
|
|
1
|
-
import{event}from'@shopgate/pwa-core';
|
|
1
|
+
import { event } from '@shopgate/pwa-core';
|
|
2
|
+
import { hasWebBridge, INDEX_PATH } from '@shopgate/engage/core';
|
|
3
|
+
import { routeDidChange$, userDidLogout$ } from "../streams";
|
|
4
|
+
import { historyReset, historyResetTo } from "../actions/router";
|
|
5
|
+
import { makeGetIsCurrentRouteProtected } from "../selectors/router";
|
|
6
|
+
|
|
7
|
+
/**
|
|
2
8
|
* History subscriptions.
|
|
3
9
|
* @param {Function} subscribe The subscribe function.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
dispatch
|
|
10
|
+
*/
|
|
11
|
+
export default function history(subscribe) {
|
|
12
|
+
subscribe(userDidLogout$, ({
|
|
13
|
+
dispatch,
|
|
14
|
+
action,
|
|
15
|
+
getState
|
|
16
|
+
}) => {
|
|
17
|
+
const isAutoLogout = action.autoLogout;
|
|
18
|
+
if (isAutoLogout && !makeGetIsCurrentRouteProtected()(getState())) {
|
|
19
|
+
// When users where automatically logged out, we only redirect to the index screen if
|
|
20
|
+
// currently a route is active that needs a login.
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (hasWebBridge()) {
|
|
24
|
+
// Within the website there is no guarantee that the index page is the first stack entry
|
|
25
|
+
dispatch(historyResetTo(INDEX_PATH));
|
|
26
|
+
} else {
|
|
27
|
+
dispatch(historyReset());
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
/**
|
|
8
32
|
* @deprecated Will be removed in Next versions
|
|
9
|
-
*/
|
|
33
|
+
*/
|
|
34
|
+
subscribe(routeDidChange$, () => {
|
|
35
|
+
event.trigger('routeDidChange');
|
|
36
|
+
});
|
|
37
|
+
}
|
package/subscriptions/index.js
CHANGED
|
@@ -1,14 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A registry for all subscribers.
|
|
3
3
|
* @type {Array}
|
|
4
|
-
*/
|
|
4
|
+
*/
|
|
5
|
+
const subscriptionRegistry = [];
|
|
6
|
+
|
|
7
|
+
/**
|
|
5
8
|
* A wrapper for stream$.subscribe() that gets injected into each subscriber.
|
|
6
9
|
* @param {Observable} stream$ A observable stream.
|
|
7
10
|
* @param {Function} subscriberFn The subscriber function.
|
|
8
|
-
*/
|
|
11
|
+
*/
|
|
12
|
+
const handleSubscribers = (stream$, subscriberFn) => {
|
|
13
|
+
subscriptionRegistry.push(stream$.subscribe(subscriberFn));
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
9
17
|
* Unsubscribes all cached subscriptions.
|
|
10
|
-
*/
|
|
18
|
+
*/
|
|
19
|
+
const unsubscribe = () => {
|
|
20
|
+
subscriptionRegistry.splice(0).forEach(subscription => subscription.unsubscribe());
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
11
24
|
* Calls each subscriber function and passes the handleSubscribers() to it.
|
|
12
25
|
* @param {Array} subscribers The subscribers from the theme.
|
|
13
26
|
* @return {Function} A reference to unsubscribe().
|
|
14
|
-
*/
|
|
27
|
+
*/
|
|
28
|
+
const initSubscribers = subscribers => {
|
|
29
|
+
if (subscriptionRegistry.length) {
|
|
30
|
+
unsubscribe();
|
|
31
|
+
}
|
|
32
|
+
subscribers.forEach(subscription => subscription(handleSubscribers));
|
|
33
|
+
return unsubscribe;
|
|
34
|
+
};
|
|
35
|
+
export default initSubscribers;
|
package/subscriptions/menu.js
CHANGED
|
@@ -1,8 +1,25 @@
|
|
|
1
|
-
import{hasNewServices}from'@shopgate/engage/core/helpers';
|
|
1
|
+
import { hasNewServices } from '@shopgate/engage/core/helpers';
|
|
2
|
+
import { appDidStart$ } from "../streams";
|
|
3
|
+
import fetchMenu from "../actions/menu/fetchMenu";
|
|
4
|
+
import { QUICKLINKS_MENU, LEGAL_MENU } from "../constants/MenuIDs";
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* Menu subscriptions.
|
|
3
8
|
* @param {Function} subscribe The subscribe function.
|
|
4
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
export default function menu(subscribe) {
|
|
11
|
+
/**
|
|
5
12
|
* Gets triggered when the app starts.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
*/
|
|
14
|
+
subscribe(appDidStart$, ({
|
|
15
|
+
dispatch
|
|
16
|
+
}) => {
|
|
17
|
+
dispatch(fetchMenu(QUICKLINKS_MENU));
|
|
18
|
+
|
|
19
|
+
// The "Legal Menu" is maintained inside the Next Admin and not available when running with
|
|
20
|
+
// old services
|
|
21
|
+
if (hasNewServices()) {
|
|
22
|
+
dispatch(fetchMenu(LEGAL_MENU));
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
package/subscriptions/mock.js
CHANGED
|
@@ -18,26 +18,58 @@
|
|
|
18
18
|
* `resetSubscriptions` before your next test run.
|
|
19
19
|
* 3. To test if a particular subscription has any subscribers, just use `getSubscriptionCount` and
|
|
20
20
|
* pass your Rx observable (stream) as a parameter.
|
|
21
|
-
*/
|
|
22
|
-
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
// Stores all subscriptions for tests
|
|
24
|
+
const subscriptions = [];
|
|
25
|
+
|
|
26
|
+
/**
|
|
23
27
|
* Stores the callback of each subscription to test
|
|
24
28
|
* @param {Observable} stream The Rx observable to subscribe to
|
|
25
29
|
* @param {Function} handler The handler function to perform an action on incoming events.
|
|
26
|
-
*/
|
|
30
|
+
*/
|
|
31
|
+
export const subscribe = (stream, handler) => {
|
|
32
|
+
subscriptions.push([stream, handler]);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
27
36
|
* Triggers a subscription handler to be called with the given parameters.
|
|
28
37
|
* @param {Observable} stream The Rx observable to invoke a call upon
|
|
29
38
|
* @param {Object} params An object which contains all params to pass to the sibscription handler
|
|
30
39
|
* @param {number|null} [index=0] Define which subscription it is about or leave empty to get all
|
|
31
40
|
* @returns {*|[]|undefined} Returns an array of results if no index is given or one result else
|
|
32
|
-
*/
|
|
41
|
+
*/
|
|
42
|
+
export const invoke = (stream, params, index = 0) => {
|
|
43
|
+
const result = subscriptions.filter(s => s[0] === stream).filter((s, i) => index === null || i === index).map(s => s[1](params));
|
|
44
|
+
if (index !== null) {
|
|
45
|
+
return result.length > 0 ? result[0] : undefined;
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
33
51
|
* Returns the count of subscriptions for the given stream or count of all subscriptions if the
|
|
34
52
|
* stream param is left blank.
|
|
35
53
|
* @param {Observable|null} [stream=null] The stream to get the count for or null for all.
|
|
36
54
|
* @returns {number}
|
|
37
|
-
*/
|
|
55
|
+
*/
|
|
56
|
+
export const getSubscriptionCount = (stream = null) => subscriptions.filter(s => stream === null || s[0] === stream).length;
|
|
57
|
+
|
|
58
|
+
/**
|
|
38
59
|
* Removes all subscriptions from all Rx observables.
|
|
39
|
-
*/
|
|
60
|
+
*/
|
|
61
|
+
export const resetSubscriptions = () => {
|
|
62
|
+
subscriptions.length = 0;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
40
66
|
* Removes all handlers from the given Rx observable.
|
|
41
67
|
* @param {Observable} stream The Rx observable to remove all handlers for.
|
|
42
68
|
* @returns {undefined}
|
|
43
|
-
*/
|
|
69
|
+
*/
|
|
70
|
+
export const unsubscribe = stream => {
|
|
71
|
+
const remainingSubscriptions = subscriptions.filter(s => s[0] !== stream);
|
|
72
|
+
resetSubscriptions();
|
|
73
|
+
subscribe(remainingSubscriptions);
|
|
74
|
+
return undefined;
|
|
75
|
+
};
|