@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,51 +1,257 @@
|
|
|
1
|
-
|
|
1
|
+
import "core-js/modules/es.string.replace.js";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import { router, stack as routeStack, onDidPush, onDidPop, onDidReplace, onDidReset, onUpdate, ACTION_POP } from '@virtuous/conductor';
|
|
5
|
+
import Route from '@virtuous/conductor/Route';
|
|
6
|
+
import { RouterContext, Router as OrigRouter } from '@virtuous/react-conductor';
|
|
7
|
+
import { UIEvents } from '@shopgate/pwa-core';
|
|
8
|
+
import { hasSGJavaScriptBridge } from '@shopgate/pwa-core/helpers';
|
|
9
|
+
import { hasWebBridge } from '@shopgate/engage/core';
|
|
10
|
+
import { sanitizeLink } from "../../subscriptions/helpers/handleLinks";
|
|
11
|
+
import authRoutes from "../../collections/AuthRoutes";
|
|
12
|
+
import { EVENT_USER_INITIALIZED } from "../../constants/user";
|
|
13
|
+
import connect from "./connector";
|
|
14
|
+
|
|
15
|
+
/**
|
|
2
16
|
* Adds additional history listeners to compensate bugs and improve the behaviour within
|
|
3
17
|
* browser environments.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
18
|
+
*/
|
|
19
|
+
const createBrowserListeners = () => {
|
|
20
|
+
const {
|
|
21
|
+
history
|
|
22
|
+
} = router;
|
|
23
|
+
|
|
24
|
+
// Remove the original listener from the router.
|
|
25
|
+
router.historyListener();
|
|
26
|
+
|
|
27
|
+
// Add new one which injects an intermediate function which intercepts history events
|
|
28
|
+
router.historyListener = history.listen((location, action) => {
|
|
29
|
+
const {
|
|
30
|
+
pathname: locationPathname,
|
|
31
|
+
search,
|
|
32
|
+
hash,
|
|
33
|
+
state
|
|
34
|
+
} = location;
|
|
35
|
+
|
|
36
|
+
// Create a pathname which fulfills the router expectations
|
|
37
|
+
const pathname = `${locationPathname}${search}${hash}`;
|
|
38
|
+
if (action === ACTION_POP && router.routeIndex === 0) {
|
|
39
|
+
/**
|
|
8
40
|
* Within browser environments we need to handle situations where users come back to old
|
|
9
41
|
* Engage history entries from previous sessions, Without special handling the page wouldn't
|
|
10
42
|
* render correct content. So we replace the current visible page with content from the route.
|
|
11
|
-
*/
|
|
43
|
+
*/
|
|
44
|
+
router.replace({
|
|
45
|
+
pathname,
|
|
46
|
+
state
|
|
47
|
+
});
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
12
52
|
* Conductor 2.5.0 contains a bug within the handler for native history events. It ignores that
|
|
13
53
|
* the search and hash parameters are stored within separate properties of the history location
|
|
14
54
|
* object. The routing methods expect those parameters as part of the pathname.
|
|
15
|
-
*/
|
|
55
|
+
*/
|
|
56
|
+
router.handleNativeEvent({
|
|
57
|
+
...location,
|
|
58
|
+
pathname
|
|
59
|
+
}, action);
|
|
60
|
+
}).bind(router);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
16
64
|
* The Router component.
|
|
17
|
-
*/
|
|
65
|
+
*/
|
|
66
|
+
class Router extends React.Component {
|
|
67
|
+
/**
|
|
18
68
|
* @param {Object} props The component props.
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
69
|
+
*/
|
|
70
|
+
constructor(props) {
|
|
71
|
+
super(props);
|
|
72
|
+
/**
|
|
73
|
+
* Updates the user initialized component state
|
|
74
|
+
*/
|
|
75
|
+
this.setUserInitialized = () => {
|
|
76
|
+
this.setState({
|
|
77
|
+
userInitialized: true
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Determines the current location from the browser history
|
|
82
|
+
* @returns {string}
|
|
83
|
+
*/
|
|
84
|
+
this.getHistoryLocation = () => {
|
|
85
|
+
const {
|
|
86
|
+
hash,
|
|
87
|
+
pathname,
|
|
88
|
+
search
|
|
89
|
+
} = router.history.location;
|
|
90
|
+
return sanitizeLink(`${pathname}${search}${hash}`);
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Determines if the current route is a protected route
|
|
94
|
+
* @returns {null|string}
|
|
95
|
+
*/
|
|
96
|
+
this.getRouteProtector = () => authRoutes.getProtector(this.getHistoryLocation());
|
|
97
|
+
/**
|
|
98
|
+
* @param {Object} data Data for the update method
|
|
99
|
+
*/
|
|
100
|
+
this.update = data => {
|
|
101
|
+
const {
|
|
102
|
+
prev,
|
|
103
|
+
next
|
|
104
|
+
} = data;
|
|
105
|
+
if (data?.id) {
|
|
106
|
+
/**
|
|
107
|
+
* The only change right now compared to the original component. When invoked for "onUpdate"
|
|
108
|
+
* only the updated route is passed instead of an object with prev and next.
|
|
109
|
+
*/
|
|
110
|
+
this.setState({
|
|
111
|
+
updated: Date.now()
|
|
112
|
+
});
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this.setState({
|
|
116
|
+
prev: prev ? prev.id : null,
|
|
117
|
+
next: next.id,
|
|
118
|
+
updated: Date.now()
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
if (typeof props.history === 'function') {
|
|
122
|
+
router.constructor(props.history);
|
|
123
|
+
}
|
|
124
|
+
this.state = {
|
|
125
|
+
prev: null,
|
|
126
|
+
next: null,
|
|
127
|
+
updated: null,
|
|
128
|
+
userInitialized: false,
|
|
129
|
+
initialRouteProtected: !!this.getRouteProtector()
|
|
130
|
+
};
|
|
131
|
+
UIEvents.addListener(EVENT_USER_INITIALIZED, this.setUserInitialized);
|
|
132
|
+
onDidPush(this.update);
|
|
133
|
+
onDidPop(this.update);
|
|
134
|
+
onDidReplace(this.update);
|
|
135
|
+
onDidReset(this.update);
|
|
136
|
+
onUpdate(this.update);
|
|
137
|
+
if (hasWebBridge() || hasSGJavaScriptBridge()) {
|
|
138
|
+
createBrowserListeners();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
33
143
|
* @param {Object} nextProps The next component props.
|
|
34
144
|
* @param {Object} nextState The next component state.
|
|
35
145
|
* @returns {boolean}
|
|
36
|
-
*/
|
|
146
|
+
*/
|
|
147
|
+
shouldComponentUpdate(nextProps, nextState) {
|
|
148
|
+
const {
|
|
149
|
+
isUserLoggedIn
|
|
150
|
+
} = this.props;
|
|
151
|
+
const {
|
|
152
|
+
updated,
|
|
153
|
+
userInitialized
|
|
154
|
+
} = this.state;
|
|
155
|
+
return updated !== nextState.updated || userInitialized !== nextState.userInitialized || isUserLoggedIn !== nextProps.isUserLoggedIn;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
37
159
|
* Replaces the initial route with a protector if necessary
|
|
38
160
|
* @param {Object} nextProps The next component props
|
|
39
161
|
* @param {Object} nextState The next components state
|
|
40
|
-
*/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
162
|
+
*/
|
|
163
|
+
UNSAFE_componentWillUpdate(nextProps, nextState) {
|
|
164
|
+
const {
|
|
165
|
+
isUserLoggedIn
|
|
166
|
+
} = nextProps;
|
|
167
|
+
const {
|
|
168
|
+
userInitialized,
|
|
169
|
+
initialRouteProtected
|
|
170
|
+
} = nextState;
|
|
171
|
+
if (initialRouteProtected && userInitialized && !isUserLoggedIn) {
|
|
172
|
+
const protector = this.getRouteProtector();
|
|
173
|
+
const location = this.getHistoryLocation();
|
|
174
|
+
|
|
175
|
+
// Get the initial route from the route stack which was created by the router on init
|
|
176
|
+
const initialRoute = routeStack.getByIndex(0);
|
|
177
|
+
const {
|
|
178
|
+
id
|
|
179
|
+
} = initialRoute;
|
|
180
|
+
|
|
181
|
+
// Prepare the redirect state for the protector route
|
|
182
|
+
const state = {
|
|
183
|
+
redirect: {
|
|
184
|
+
location
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const routeReplacement = new Route({
|
|
188
|
+
id,
|
|
189
|
+
state,
|
|
190
|
+
pathname: protector
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// Replace the auto-generated route with the replacement
|
|
194
|
+
routeStack.update(id, routeReplacement);
|
|
195
|
+
|
|
196
|
+
// Update the browser url with the protector route
|
|
197
|
+
router.history.replace({
|
|
198
|
+
pathname: protector,
|
|
199
|
+
state: {
|
|
200
|
+
...state,
|
|
201
|
+
route: {
|
|
202
|
+
id
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
this.setState({
|
|
207
|
+
initialRouteProtected: false
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
45
213
|
* Removes the listener for the EVENT_USER_INITIALIZED event
|
|
46
|
-
*/
|
|
214
|
+
*/
|
|
215
|
+
componentWillUnmount() {
|
|
216
|
+
UIEvents.removeListener(EVENT_USER_INITIALIZED, this.setUserInitialized);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
47
219
|
* @returns {JSX}
|
|
48
|
-
*/
|
|
220
|
+
*/
|
|
221
|
+
render() {
|
|
222
|
+
const {
|
|
223
|
+
children
|
|
224
|
+
} = this.props;
|
|
225
|
+
const {
|
|
226
|
+
prev,
|
|
227
|
+
next,
|
|
228
|
+
initialRouteProtected,
|
|
229
|
+
userInitialized
|
|
230
|
+
} = this.state;
|
|
231
|
+
if (initialRouteProtected && !userInitialized) {
|
|
232
|
+
/**
|
|
49
233
|
* When the initial route is a protected route, the first rendering of the Router needs to
|
|
50
234
|
* be postponed till we know the final login state of the user.
|
|
51
|
-
*/
|
|
235
|
+
*/
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
const stack = Array.from(routeStack.getAll());
|
|
239
|
+
return /*#__PURE__*/React.createElement(RouterContext.Provider, {
|
|
240
|
+
value: {
|
|
241
|
+
prev,
|
|
242
|
+
next,
|
|
243
|
+
stack
|
|
244
|
+
}
|
|
245
|
+
}, children);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
Router.defaultProps = {
|
|
249
|
+
history: null,
|
|
250
|
+
isUserLoggedIn: false
|
|
251
|
+
};
|
|
252
|
+
Router.Push = OrigRouter.Push;
|
|
253
|
+
Router.Pop = OrigRouter.Pop;
|
|
254
|
+
Router.Replace = OrigRouter.Replace;
|
|
255
|
+
Router.Reset = OrigRouter.Reset;
|
|
256
|
+
Router.ResetTo = OrigRouter.ResetTo;
|
|
257
|
+
export default connect(Router);
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import{connect}from'react-redux';
|
|
1
|
+
import { connect } from 'react-redux';
|
|
2
|
+
import { hasScannerSupport } from '@shopgate/pwa-common/selectors/client';
|
|
3
|
+
|
|
4
|
+
/**
|
|
2
5
|
* Maps the contents of the state to the component props.
|
|
3
6
|
* @param {Object} state The current application state.
|
|
4
7
|
* @return {Object} The extended component props.
|
|
5
|
-
*/
|
|
8
|
+
*/
|
|
9
|
+
const mapStateToProps = state => ({
|
|
10
|
+
hasScannerSupport: hasScannerSupport(state)
|
|
11
|
+
});
|
|
12
|
+
export default connect(mapStateToProps);
|
|
@@ -1,11 +1,47 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React, { Fragment, PureComponent } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import AppScanner from '@shopgate/pwa-core/classes/Scanner';
|
|
4
|
+
import connect from "./connector";
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* Wraps the Scanner overlay with functionality to automatically open and close the scanner,
|
|
3
8
|
* as well as triggering the removal and reset of the background.
|
|
4
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
class ScannerContainer extends PureComponent {
|
|
11
|
+
/**
|
|
12
|
+
* Starts up the app scanner.
|
|
13
|
+
*/
|
|
14
|
+
async componentDidMount() {
|
|
15
|
+
// Avoid trying to open the scanner if the app does not support it.
|
|
16
|
+
if (!this.props.hasScannerSupport) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
await AppScanner.open(this.props.scope, this.props.type);
|
|
20
|
+
this.props.scannerDidOpen();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
5
24
|
* Shut down the app scanner.
|
|
6
|
-
*/
|
|
25
|
+
*/
|
|
26
|
+
componentWillUnmount() {
|
|
27
|
+
if (!this.props.hasScannerSupport) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
this.props.scannerDidClose();
|
|
31
|
+
AppScanner.close();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
7
35
|
* Does not render anything when the app does not support the scanner.
|
|
8
36
|
* @returns {JSX}
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
|
|
37
|
+
*/
|
|
38
|
+
render() {
|
|
39
|
+
return /*#__PURE__*/React.createElement(Fragment, null, this.props.hasScannerSupport && this.props.children);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
ScannerContainer.defaultProps = {
|
|
43
|
+
children: null,
|
|
44
|
+
scannerDidClose: () => {},
|
|
45
|
+
scannerDidOpen: () => {}
|
|
46
|
+
};
|
|
47
|
+
export default connect(ScannerContainer);
|
|
@@ -1,12 +1,28 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styles from "./style";
|
|
4
|
+
|
|
5
|
+
/**
|
|
2
6
|
* The select item component.
|
|
3
7
|
* @param {Object} props - The component props.
|
|
4
8
|
* @param {React.Children} props.children - Some content to display inside.
|
|
5
9
|
* @returns {JSX}
|
|
6
|
-
*/
|
|
10
|
+
*/
|
|
11
|
+
const SelectItem = props => /*#__PURE__*/React.createElement("div", {
|
|
12
|
+
className: `${styles} ${props.className}`,
|
|
13
|
+
onTouchEnd: () => props.onSelect(props.value, props.label)
|
|
14
|
+
}, props.label);
|
|
15
|
+
|
|
16
|
+
/**
|
|
7
17
|
* The component prop types.
|
|
8
18
|
* @type {Object}
|
|
9
|
-
*/
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
10
22
|
* The component default props.
|
|
11
23
|
* @type {Object}
|
|
12
|
-
*/
|
|
24
|
+
*/
|
|
25
|
+
SelectItem.defaultProps = {
|
|
26
|
+
className: ''
|
|
27
|
+
};
|
|
28
|
+
export default SelectItem;
|
|
@@ -1,47 +1,168 @@
|
|
|
1
|
-
|
|
1
|
+
import React, { Component } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styles from "./style";
|
|
4
|
+
import SelectItem from "./components/Item";
|
|
5
|
+
const DEFAULT_PLACEHOLDER_TEXT = 'Select ...';
|
|
6
|
+
|
|
7
|
+
/**
|
|
2
8
|
* Finds an item in a list of items by value.
|
|
3
9
|
* @param {Array} items - The list of items.
|
|
4
10
|
* @param {*} value - The value to look for.
|
|
5
11
|
* @returns {*} The found item or undefined.
|
|
6
|
-
*/
|
|
12
|
+
*/
|
|
13
|
+
const findItemByValue = (items, value) => items.filter(item => item.value === value).shift();
|
|
14
|
+
|
|
15
|
+
/**
|
|
7
16
|
* Converts an item of any type (e.g. string or number)
|
|
8
17
|
* to an object representation containing value and label properties.
|
|
9
18
|
* @param {*} item - An item of any type.
|
|
10
19
|
* @returns {Object} An object representation of the item.
|
|
11
|
-
*/
|
|
20
|
+
*/
|
|
21
|
+
const normalizeItem = item => ({
|
|
22
|
+
value: item.value || item,
|
|
23
|
+
label: item.label || item.value || item
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/**
|
|
12
27
|
* The select component.
|
|
13
28
|
* @param {Object} props - The component props.
|
|
14
29
|
* @param {React.Children} props.children - Some content to display inside.
|
|
15
|
-
*/
|
|
30
|
+
*/
|
|
31
|
+
class Select extends Component {
|
|
32
|
+
/**
|
|
16
33
|
* The constructor.
|
|
17
34
|
* @param {Object} props - The component props.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
*/
|
|
36
|
+
constructor(props) {
|
|
37
|
+
super(props);
|
|
38
|
+
/**
|
|
39
|
+
* Triggers the onChange callback if the selected value has changed.
|
|
40
|
+
* @param {Object} nextState - The next state.
|
|
41
|
+
*/
|
|
42
|
+
this.triggerChangeCallback = nextState => {
|
|
43
|
+
if (this.state.selected && this.state.selected.value === nextState.selected.value) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (this.props.onChange instanceof Function) {
|
|
47
|
+
this.props.onChange(nextState.selected.value);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Handles any interaction the user does outside of the component.
|
|
52
|
+
* In this case the select gets closed.
|
|
53
|
+
* @param {Event} event - The event of the user interaction (e.g. TouchEvent).
|
|
54
|
+
*/
|
|
55
|
+
this.handleInteractionOutside = event => {
|
|
56
|
+
if (!this.domElement.contains(event.target)) {
|
|
57
|
+
this.setState({
|
|
58
|
+
isOpen: false
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Gets called when a new item is selected
|
|
64
|
+
* @param {*} value - The selected value.
|
|
65
|
+
* @param {string} label - The selected label.
|
|
66
|
+
*/
|
|
67
|
+
this.handleItemSelect = (value, label) => {
|
|
68
|
+
const stateUpdate = {
|
|
69
|
+
selected: {
|
|
70
|
+
label,
|
|
71
|
+
value
|
|
72
|
+
},
|
|
73
|
+
isOpen: false
|
|
74
|
+
};
|
|
75
|
+
this.triggerChangeCallback(stateUpdate);
|
|
76
|
+
this.setState(stateUpdate);
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Toggles the open state of the component.
|
|
80
|
+
*/
|
|
81
|
+
this.toggleOpenState = () => {
|
|
82
|
+
this.setState(({
|
|
83
|
+
isOpen
|
|
84
|
+
}) => ({
|
|
85
|
+
isOpen: !isOpen
|
|
86
|
+
}));
|
|
87
|
+
};
|
|
88
|
+
this.state = {
|
|
89
|
+
selected: null,
|
|
90
|
+
isOpen: false
|
|
91
|
+
};
|
|
92
|
+
this.domElement = null;
|
|
93
|
+
if (props.value) {
|
|
94
|
+
this.state.selected = normalizeItem(findItemByValue(props.items, props.value));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
32
99
|
* Adds event listener when the component is mounted.
|
|
33
|
-
*/
|
|
100
|
+
*/
|
|
101
|
+
componentDidMount() {
|
|
102
|
+
document.addEventListener('touchstart', this.handleInteractionOutside);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
34
106
|
* Updates the selected item when the value prop changes.
|
|
35
107
|
* @param {Object} nextProps - The next props.
|
|
36
|
-
*/
|
|
108
|
+
*/
|
|
109
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
110
|
+
if (!this.state.selected || nextProps.value !== this.state.selected.value) {
|
|
111
|
+
this.state.selected = normalizeItem(findItemByValue(nextProps.items, nextProps.value));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
37
116
|
* Removes event listener when the component will unmount.
|
|
38
|
-
*/
|
|
117
|
+
*/
|
|
118
|
+
componentWillUnmount() {
|
|
119
|
+
document.removeEventListener('touchstart', this.handleInteractionOutside);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
39
122
|
* Renders the component.
|
|
40
123
|
* @returns {JSX}
|
|
41
|
-
*/
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
124
|
+
*/
|
|
125
|
+
render() {
|
|
126
|
+
const hasSelection = this.state.selected && this.state.selected.value !== undefined;
|
|
127
|
+
const selectedLabel = hasSelection ? this.state.selected.label : this.props.placeholder;
|
|
128
|
+
const items = this.state.isOpen ? /*#__PURE__*/React.createElement("div", {
|
|
129
|
+
className: styles.items
|
|
130
|
+
}, this.props.items.map(item => {
|
|
131
|
+
const normalizedItem = normalizeItem(item);
|
|
132
|
+
const selected = hasSelection && this.state.selected.value === normalizedItem.value;
|
|
133
|
+
return /*#__PURE__*/React.createElement(SelectItem, {
|
|
134
|
+
key: normalizedItem.value,
|
|
135
|
+
value: normalizedItem.value,
|
|
136
|
+
label: normalizedItem.label,
|
|
137
|
+
selected: selected,
|
|
138
|
+
onSelect: this.handleItemSelect
|
|
139
|
+
});
|
|
140
|
+
})) : null;
|
|
141
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
142
|
+
className: `${styles.container} ${this.props.className} common_select`,
|
|
143
|
+
ref: ref => {
|
|
144
|
+
this.domElement = ref;
|
|
145
|
+
}
|
|
146
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
147
|
+
onTouchStart: this.toggleOpenState
|
|
148
|
+
}, /*#__PURE__*/React.createElement("span", null, selectedLabel), /*#__PURE__*/React.createElement("span", {
|
|
149
|
+
className: styles.selectHandle
|
|
150
|
+
}, "\u25BE")), items);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* The component prop types.
|
|
155
|
+
* @type {Object}
|
|
156
|
+
*/
|
|
157
|
+
/**
|
|
158
|
+
* The component default props.
|
|
159
|
+
* @type {Object}
|
|
160
|
+
*/
|
|
161
|
+
Select.defaultProps = {
|
|
162
|
+
className: '',
|
|
163
|
+
items: [],
|
|
164
|
+
onChange: () => {},
|
|
165
|
+
placeholder: DEFAULT_PLACEHOLDER_TEXT,
|
|
166
|
+
value: null
|
|
167
|
+
};
|
|
168
|
+
export default Select;
|