Skip to content

Commit

Permalink
Merge branch 'develop' into 2352-storybook-venia-concept
Browse files Browse the repository at this point in the history
  • Loading branch information
dpatil-magento authored May 26, 2020
2 parents ce3fb70 + e69419d commit 7905bcb
Show file tree
Hide file tree
Showing 30 changed files with 622 additions and 465 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ jest.mock('@apollo/react-hooks', () => {
loading: false
}
]),
useMutation: jest.fn().mockReturnValue([jest.fn()])
useMutation: jest.fn().mockReturnValue([
jest.fn(),
{
loading: false
}
])
};
});

Expand All @@ -58,6 +63,15 @@ jest.mock('@magento/peregrine/lib/context/cart', () => {
return { useCartContext };
});

jest.mock('@magento/peregrine/lib/context/user', () => {
const state = { isSignedIn: false };
const api = {};

const useUserContext = jest.fn(() => [state, api]);

return { useUserContext };
});

/*
* Member Variables.
*/
Expand Down
147 changes: 96 additions & 51 deletions packages/peregrine/lib/talons/CheckoutPage/useShippingMethod.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { useCallback, useEffect, useState } from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useLazyQuery, useMutation } from '@apollo/react-hooks';

import { useCartContext } from '@magento/peregrine/lib/context/cart';
import { useUserContext } from '@magento/peregrine/lib/context/user';

export const displayStates = {
DONE: 'done',
EDITING: 'editing'
EDITING: 'editing',
INITIALIZING: 'initializing'
};

const serializeShippingMethod = method => {
Expand Down Expand Up @@ -36,6 +38,9 @@ const addSerializedProperty = shippingMethod => {
};
};

const DEFAULT_SELECTED_SHIPPING_METHOD = null;
const DEFAULT_AVAILABLE_SHIPPING_METHODS = [];

export const useShippingMethod = props => {
const {
onSave,
Expand All @@ -45,32 +50,72 @@ export const useShippingMethod = props => {
} = props;

const [{ cartId }] = useCartContext();
const [{ isSignedIn }] = useUserContext();

/*
* Apollo Hooks.
*/
const [setShippingMethodCall] = useMutation(setShippingMethod);

const [fetchShippingMethodInfo, { data, loading }] = useLazyQuery(
getSelectedAndAvailableShippingMethods,
{
fetchPolicy: 'cache-and-network'
}
);
const [
setShippingMethodCall,
{ loading: isSettingShippingMethod }
] = useMutation(setShippingMethod);

const [
fetchShippingMethodInfo,
{ data, loading: isLoadingShippingMethods }
] = useLazyQuery(getSelectedAndAvailableShippingMethods, {
fetchPolicy: 'cache-and-network'
});

/*
* State / Derived state.
*/
const [displayState, setDisplayState] = useState(displayStates.EDITING);
const [shippingMethods, setShippingMethods] = useState([]);
const [selectedShippingMethod, setSelectedShippingMethod] = useState(null);
const [isUpdateMode, setIsUpdateMode] = useState(false);

const hasData =
data &&
data.cart.shipping_addresses.length &&
data.cart.shipping_addresses[0].selected_shipping_method;

const derivedPrimaryShippingAddress =
data &&
data.cart.shipping_addresses &&
data.cart.shipping_addresses.length
? data.cart.shipping_addresses[0]
: null;

const derivedSelectedShippingMethod = derivedPrimaryShippingAddress
? addSerializedProperty(
derivedPrimaryShippingAddress.selected_shipping_method
)
: DEFAULT_SELECTED_SHIPPING_METHOD;

const derivedShippingMethods = useMemo(() => {
if (!derivedPrimaryShippingAddress)
return DEFAULT_AVAILABLE_SHIPPING_METHODS;

// Shape the list of available shipping methods.
// Sort them by price and add a serialized property to each.
const rawShippingMethods =
derivedPrimaryShippingAddress.available_shipping_methods;
const shippingMethodsByPrice = [...rawShippingMethods].sort(byPrice);
const result = shippingMethodsByPrice.map(addSerializedProperty);

return result;
}, [derivedPrimaryShippingAddress]);

// Determine the component's display state.
const isBackgroundAutoSelecting =
isSignedIn &&
!derivedSelectedShippingMethod &&
Boolean(derivedShippingMethods.length);
const displayState = derivedSelectedShippingMethod
? displayStates.DONE
: isLoadingShippingMethods ||
(isSettingShippingMethod && isBackgroundAutoSelecting)
? displayStates.INITIALIZING
: displayStates.EDITING;

/*
* Callbacks.
*/
Expand All @@ -94,15 +139,8 @@ export const useShippingMethod = props => {

setPageIsUpdating(false);
setIsUpdateMode(false);
setDisplayState(displayStates.DONE);
},
[
cartId,
setDisplayState,
setIsUpdateMode,
setPageIsUpdating,
setShippingMethodCall
]
[cartId, setIsUpdateMode, setPageIsUpdating, setShippingMethodCall]
);

const handleCancelUpdate = useCallback(() => {
Expand Down Expand Up @@ -133,44 +171,51 @@ export const useShippingMethod = props => {
}
}, [hasData, onSave]);

// If an authenticated user does not have a preferred shipping method,
// auto-select the least expensive one for them.
useEffect(() => {
if (!data) return;

// Determine the "primary" shipping address by using
// the first shipping address on the cart.
const primaryShippingAddress = data.cart.shipping_addresses[0];

// Shape the list of available shipping methods.
// Sort them by price and add a serialized property to each.
const rawShippingMethods =
primaryShippingAddress.available_shipping_methods;
const shippingMethodsByPrice = [...rawShippingMethods].sort(byPrice);
const shippingMethods = shippingMethodsByPrice.map(
addSerializedProperty
);
setShippingMethods(shippingMethods);

// Determine the selected shipping method.
const selectedMethod = addSerializedProperty(
primaryShippingAddress.selected_shipping_method
);
setSelectedShippingMethod(selectedMethod);

// Determine the component's display state.
const nextDisplayState = selectedMethod
? displayStates.DONE
: displayStates.EDITING;
setDisplayState(nextDisplayState);
}, [data]);
if (!cartId) return;
if (!isSignedIn) return;

if (!derivedSelectedShippingMethod) {
// The shipping methods are sorted by price.
const leastExpensiveShippingMethod = derivedShippingMethods[0];

if (leastExpensiveShippingMethod) {
const {
carrier_code,
method_code
} = leastExpensiveShippingMethod;

setShippingMethodCall({
variables: {
cartId,
shippingMethod: {
carrier_code,
method_code
}
}
});
}
}
}, [
cartId,
data,
derivedSelectedShippingMethod,
derivedShippingMethods,
isSignedIn,
setShippingMethodCall
]);

return {
displayState,
handleCancelUpdate,
handleSubmit,
isLoading: loading,
isLoading: isLoadingShippingMethods,
isUpdateMode,
selectedShippingMethod,
shippingMethods,
selectedShippingMethod: derivedSelectedShippingMethod,
shippingMethods: derivedShippingMethods,
showUpdateMode
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import Region from '../../../Region';
import TextInput from '../../../TextInput';
import { CartPageFragment } from '../../cartPageFragments.gql';
import defaultClasses from './shippingForm.css';
import { GET_SHIPPING_METHODS } from './shippingMethods';
import { ShippingMethodsFragment } from './shippingMethodsFragments';
import { GET_SHIPPING_METHODS } from './shippingMethods.gql';
import { ShippingMethodsCartFragment } from './shippingMethodsFragments.gql';

const ShippingForm = props => {
const { hasMethods, selectedShippingFields, setIsCartUpdating } = props;
Expand Down Expand Up @@ -99,12 +99,12 @@ export const SET_SHIPPING_ADDRESS_MUTATION = gql`
cart {
id
...CartPageFragment
...ShippingMethodsFragment
...ShippingMethodsCartFragment
...ShippingInformationFragment
}
}
}
${CartPageFragment}
${ShippingMethodsFragment}
${ShippingMethodsCartFragment}
${ShippingInformationFragment}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import gql from 'graphql-tag';

import { ShippingMethodsCartFragment } from './shippingMethodsFragments.gql';

export const GET_SHIPPING_METHODS = gql`
query GetShippingMethods($cartId: String!) {
cart(cart_id: $cartId) @connection(key: "Cart") {
id
...ShippingMethodsCartFragment
}
}
${ShippingMethodsCartFragment}
`;

export default {
mutations: {},
queries: {
getShippingMethodsQuery: GET_SHIPPING_METHODS
}
};
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import React, { Fragment } from 'react';
import gql from 'graphql-tag';
import { Form } from 'informed';
import { useShippingMethods } from '@magento/peregrine/lib/talons/CartPage/PriceAdjustments/ShippingMethods/useShippingMethods';

import { mergeClasses } from '../../../../classify';
import Button from '../../../Button';
import ShippingForm from './shippingForm';
import defaultClasses from './shippingMethods.css';
import { ShippingMethodsFragment } from './shippingMethodsFragments';
import ShippingMethodsOperations from './shippingMethods.gql';
import ShippingRadios from './shippingRadios';

const ShippingMethods = props => {
Expand All @@ -19,11 +18,7 @@ const ShippingMethods = props => {
selectedShippingMethod,
shippingMethods,
showForm
} = useShippingMethods({
queries: {
getShippingMethodsQuery: GET_SHIPPING_METHODS
}
});
} = useShippingMethods({ ...ShippingMethodsOperations });

const classes = mergeClasses(defaultClasses, props.classes);

Expand Down Expand Up @@ -74,13 +69,3 @@ const ShippingMethods = props => {
};

export default ShippingMethods;

export const GET_SHIPPING_METHODS = gql`
query GetShippingMethods($cartId: String!) {
cart(cart_id: $cartId) @connection(key: "Cart") {
id
...ShippingMethodsFragment
}
}
${ShippingMethodsFragment}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import gql from 'graphql-tag';
* It is intentionally not included in the CartPageFragment. Make sure you are
* conscious about the side effects when including it in queries and mutations.
*/
export const AvailableShippingMethodsFragment = gql`
fragment AvailableShippingMethodsFragment on Cart {
export const AvailableShippingMethodsCartFragment = gql`
fragment AvailableShippingMethodsCartFragment on Cart {
id
shipping_addresses {
available_shipping_methods {
Expand All @@ -25,8 +25,8 @@ export const AvailableShippingMethodsFragment = gql`
}
`;

export const SelectedShippingMethodFragment = gql`
fragment SelectedShippingMethodFragment on Cart {
export const SelectedShippingMethodCartFragment = gql`
fragment SelectedShippingMethodCartFragment on Cart {
id
shipping_addresses {
selected_shipping_method {
Expand All @@ -37,11 +37,11 @@ export const SelectedShippingMethodFragment = gql`
}
`;

export const ShippingMethodsFragment = gql`
fragment ShippingMethodsFragment on Cart {
export const ShippingMethodsCartFragment = gql`
fragment ShippingMethodsCartFragment on Cart {
id
...AvailableShippingMethodsFragment
...SelectedShippingMethodFragment
...AvailableShippingMethodsCartFragment
...SelectedShippingMethodCartFragment
shipping_addresses {
country {
code
Expand All @@ -52,6 +52,6 @@ export const ShippingMethodsFragment = gql`
}
}
}
${AvailableShippingMethodsFragment}
${SelectedShippingMethodFragment}
${AvailableShippingMethodsCartFragment}
${SelectedShippingMethodCartFragment}
`;
Loading

0 comments on commit 7905bcb

Please # to comment.