@shopgate/engage
Version:
Shopgate's ENGAGE library.
121 lines (109 loc) • 4.46 kB
JavaScript
import { createSelector } from 'reselect';
import { makeGetProductByCharacteristics } from '@shopgate/engage/product';
import { appConfig } from '@shopgate/engage';
import { hasNewServices, hasSGJavaScriptBridge, hasWebBridge } from '@shopgate/engage/core/helpers';
import { getClientInformation } from '@shopgate/engage/core/selectors';
import { PERMISSION_STATUS_GRANTED, PERMISSION_STATUS_NOT_SUPPORTED } from '@shopgate/engage/core/constants';
/**
* @param {Object} state The application state.
* @returns {Object}
*/
export const getBackInStockState = state => state.backInStock;
/**
* Selector to retrieve the back-in-stock subscriptions list
* @returns {Array}
*/
export const getBackInStockSubscriptions = createSelector(getBackInStockState, state => state.subscriptions);
/**
* Selector to retrieve the current fetching state of back-in-stock subscriptions
* @returns {boolean}
*/
export const getBackInStockSubscriptionsFetching = createSelector(getBackInStockState, state => state.isFetching);
/**
* Selector to determine if back-in-stock subscriptions have been fetched before
* @returns {boolean}
*/
export const getBackInStockSubscriptionsInitial = createSelector(getBackInStockState, state => state.isInitial);
/**
* Selector to retrieve the current status of the push app permission
* @returns {string}
*/
export const getBackInStockPushPermissionStatus = createSelector(getBackInStockState, state => state.pushPermissionStatus);
/**
* Creates a selector that retrieves the subscription of
* a product / variant or null by its variantId / productId
* @param {Object} params Params
* @param {string} params.status Get subscription for a specific status
* @returns {Function}
*/
export const makeGetSubscriptionByProduct = ({
status
} = {}) => createSelector((state, props = {}) => props.variantId ? props.variantId : props.productId, getBackInStockSubscriptions, (requestedProductCode, subscriptions) => {
if (!requestedProductCode) {
return false;
}
return subscriptions.find(({
productCode,
status: subscriptionStatus
}) => {
let match = productCode === requestedProductCode;
if (match && status) {
// When the selector factory is created for a specific status, the subscription also
// needs to fulfill this condition
match = subscriptionStatus === status;
}
return match;
}) || null;
});
/**
* Creates a selector that retrieves the subscription of
* a product / variant by its characteristics
* @returns {Function}
*/
export const makeGetSubscriptionByCharacteristics = () => {
const getProductByCharacteristics = makeGetProductByCharacteristics();
return createSelector(getProductByCharacteristics, getBackInStockSubscriptions, (product, subscriptions) => {
if (!product) {
return null;
}
return subscriptions.find(({
productCode
}) => productCode === product.id) || null;
});
};
/**
* Selector to determine if the back-in-stock feature is enabled
* @returns {boolean}
*/
export const getIsBackInStockEnabled = createSelector(getClientInformation, getBackInStockPushPermissionStatus, (clientInformation, pushPermissionStatus) => {
// Feature is not supported with the new services right now, since non ROPE inventory is
// not fully supported.
if (hasNewServices() || hasWebBridge()) {
return false;
}
// Perform app version checks when PWA runs outside the browser
if (hasSGJavaScriptBridge()) {
const {
codebaseVersion = '0.0.0'
} = clientInformation;
const [major] = codebaseVersion.split('.');
/**
* The feature can be enabled on react-native-engage based apps (>= 11.0.0) with proper
* support for push permissions checks
*/
if (parseInt(major, 10) < 11 || pushPermissionStatus === PERMISSION_STATUS_NOT_SUPPORTED) {
return false;
}
}
return appConfig?.showBackInStock || false;
});
/**
* Selector to determine if back-in-stock related requests are currently possible.
* @returns {boolean}
*/
export const getAreBackInStockRequestsPossible = createSelector(getIsBackInStockEnabled, getBackInStockPushPermissionStatus, (featureEnabled, pushPermissionStatus) => featureEnabled && pushPermissionStatus === PERMISSION_STATUS_GRANTED);
/**
* Returns if subscription list is in use
* @returns {boolean}
*/
export const getHasBackInStockSubscriptions = createSelector(getBackInStockSubscriptions, subscriptions => !!subscriptions.length);