woocommerce/plugins/woocommerce-blocks/assets/js/data/cart/actions.js

311 lines
7.4 KiB
JavaScript
Raw Normal View History

/**
* External dependencies
*/
improve responsiveness when setting cart item quantities (https://github.com/woocommerce/woocommerce-blocks/pull/1864) * rework the quantity change generator action so the UI updates quick: - work in progress - still need to figure out how to debounce API call - add new action for updating quantity for an item - don't set cart item as pending while quantity is updating - this leaves QuantitySelector enabled so user can click more/less - use receiveCartItemQuantity to update quantity in UI before sending request * debounce line item quantity first cut: - use local state for quantity, so ui allows multiple clicks up/down - debounce store updates (and server/API call) * correct comment on cart item quantity reducer * remove recieveCartItemQuantity - no longer needed * remove delegation for deleted RECEIVE_CART_ITEM_QUANTITY * only update quantity in component sideffect if it has changed: - reduces unnecessary renders * factor out debounced quantity update into cartItem hook (hat tip @senadir) * use quantity from store, instead of passing in to hook + + fix latent bug in useStoreCartItem - the cartItem value is now object: - was previously single-item array - (note no client code is using this at present) * tidy/refactor cart item hook - separate dispatch from select * remove dud reset of item pending flag (came back in rebase) * add quantity to StoreCartItem hook return value typedef * fix js error when adding cart block in editor – cartItem not found * fix typedef * fix logic for debouncing * don’t update quantity on server unnecessarily Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
2020-03-09 02:09:47 +00:00
import { apiFetch, select } from '@wordpress/data-controls';
/**
* Internal dependencies
*/
import { ACTION_TYPES as types } from './action-types';
improve responsiveness when setting cart item quantities (https://github.com/woocommerce/woocommerce-blocks/pull/1864) * rework the quantity change generator action so the UI updates quick: - work in progress - still need to figure out how to debounce API call - add new action for updating quantity for an item - don't set cart item as pending while quantity is updating - this leaves QuantitySelector enabled so user can click more/less - use receiveCartItemQuantity to update quantity in UI before sending request * debounce line item quantity first cut: - use local state for quantity, so ui allows multiple clicks up/down - debounce store updates (and server/API call) * correct comment on cart item quantity reducer * remove recieveCartItemQuantity - no longer needed * remove delegation for deleted RECEIVE_CART_ITEM_QUANTITY * only update quantity in component sideffect if it has changed: - reduces unnecessary renders * factor out debounced quantity update into cartItem hook (hat tip @senadir) * use quantity from store, instead of passing in to hook + + fix latent bug in useStoreCartItem - the cartItem value is now object: - was previously single-item array - (note no client code is using this at present) * tidy/refactor cart item hook - separate dispatch from select * remove dud reset of item pending flag (came back in rebase) * add quantity to StoreCartItem hook return value typedef * fix js error when adding cart block in editor – cartItem not found * fix typedef * fix logic for debouncing * don’t update quantity on server unnecessarily Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
2020-03-09 02:09:47 +00:00
import { STORE_KEY as CART_STORE_KEY } from './constants';
/**
* Returns an action object used in updating the store with the provided items
* retrieved from a request using the given querystring.
*
* This is a generic response action.
*
* @param {Object} [response={}] An object containing the response from the
* request.
* @return {Object} Object for action.
*/
export function receiveCart( response = {} ) {
return {
type: types.RECEIVE_CART,
response,
};
}
/**
* Returns an action object used for receiving customer facing errors from the
* API.
*
* @param {Object} [error={}] An error object containing the error message
* and response code.
* @param {boolean} [replace=true] Should existing errors be replaced, or should
* the error be appended.
* @return {Object} Object for action.
*/
export function receiveError( error = {}, replace = true ) {
return {
type: replace ? types.REPLACE_ERRORS : types.RECEIVE_ERROR,
error,
};
}
/**
* Returns an action object used to track when a coupon is applying.
*
* @param {string} [couponCode] Coupon being added.
* @return {Object} Object for action.
*/
export function receiveApplyingCoupon( couponCode ) {
return {
type: types.APPLYING_COUPON,
couponCode,
};
}
/**
* Returns an action object used to track when a coupon is removing.
*
* @param {string} [couponCode] Coupon being removed.
* @return {Object} Object for action.
*/
export function receiveRemovingCoupon( couponCode ) {
return {
type: types.REMOVING_COUPON,
couponCode,
};
}
/**
* Applies a coupon code and either invalidates caches, or receives an error if
* the coupon cannot be applied.
*
* @throws Will throw an error if there is an API problem.
* @param {string} couponCode The coupon code to apply to the cart.
*/
export function* applyCoupon( couponCode ) {
yield receiveApplyingCoupon( couponCode );
try {
const result = yield apiFetch( {
path: '/wc/store/cart/apply-coupon',
method: 'POST',
data: {
code: couponCode,
},
cache: 'no-store',
} );
if ( result ) {
yield receiveCart( result );
}
// Finished handling the coupon.
yield receiveApplyingCoupon( '' );
} catch ( error ) {
// Store the error message in state.
yield receiveError( error );
// Finished handling the coupon.
yield receiveApplyingCoupon( '' );
// Re-throw the error.
throw error;
}
return true;
}
/**
* Removes a coupon code and either invalidates caches, or receives an error if
* the coupon cannot be removed.
*
* @throws Will throw an error if there is an API problem.
* @param {string} couponCode The coupon code to remove from the cart.
*/
export function* removeCoupon( couponCode ) {
yield receiveRemovingCoupon( couponCode );
try {
const result = yield apiFetch( {
path: '/wc/store/cart/remove-coupon',
method: 'POST',
data: {
code: couponCode,
},
cache: 'no-store',
} );
if ( result ) {
yield receiveCart( result );
}
// Finished handling the coupon.
yield receiveRemovingCoupon( '' );
} catch ( error ) {
// Store the error message in state.
yield receiveError( error );
// Finished handling the coupon.
yield receiveRemovingCoupon( '' );
// Re-throw the error.
throw error;
}
return true;
}
Support updating quantity of cart items & sold_individually product option (https://github.com/woocommerce/woocommerce-blocks/pull/1824) * first cut - removing an item from cart: - add actions to cart store for removing an item and keeping track of pending removal API call - add reducer logic for storing pending state on an item, and removing an item - expose removeCartItem on new useStoreCartItems hook - hook it up to remove link / trashcan icon in row item * disable cart quantity picker/remove link while API request in progress: - expose cart item pending status from store using selector - use selector to disable quantity related components in line item row * add typedef for cart items store object provided by hook * allow user to change quantity of cart items (first cut): - add action for replacing a cart item in the store - add generator action for changing quantity - expose change quantity action on useStoreCartItems hook - hook up to quantity UI in cart block (work in progress) * post-rebase fixes & fix broken typedef: - rework cart item change quantity callback - now supplies item key like remove callback - fix hook StoreCartItem return value typedef - single item with specified key, was array of all items - add quantity JSDoc for changeCartItemQuantity action - remove changeQuantity callback from UI (currently infinite looping) * fix bug in recieveCartItem reducer - check keys for equality: - was key === object * fix invalid url in POST cart/items/quantity request * hook up cart line item quantity to API: - remove internal state/ref for QuantitySelector, is now a controlled component - call changeQuantity action from QuantitySelector change callback * QuantitySelector no longer needs a ref to wrangle number input value * hoist quantity state out of QuantitySelector into story (fix storybook) * add product sold_individually option to cart item API response * limit sold_individually items to 1 per cart/order: - support optional max value in QuantitySelector - set maximum dependent on sold_individually API field * prevent user from requesting zero x cart item (API 500 errors): - add minimum limit to QuantitySelector - default limit to 1 + fix bug with limiting to maximum value in number input change handler * remove useStoreCartItems, zombie hook coming back from rebase 🧟‍♂️ * address various review feedback: - inline undefined check, don't use lodash - quantityInputOnKeyDown callback hook depends on canIncrease/canDecrease - also removed undefined check for minimum, as minimum has default 0 * use safer typeof check for presence of maximum prop
2020-03-03 01:08:19 +00:00
/**
* Returns an action object for updating a single cart item in the store.
*
* @param {Object} [response={}] A cart item API response.
* @return {Object} Object for action.
*/
export function receiveCartItem( response = {} ) {
return {
type: types.RECEIVE_CART_ITEM,
cartItem: response,
};
}
/**
* Returns an action object to indicate if the specified cart item
* is being updated; i.e. removing, or changing quantity.
*
* @param {string} cartItemKey Cart item being updated.
* @param {boolean} isQuantityPending Flag for update state; true if API request is pending.
* @return {Object} Object for action.
*/
export function itemQuantityPending( cartItemKey, isQuantityPending ) {
return {
type: types.ITEM_QUANTITY_PENDING,
cartItemKey,
isQuantityPending,
};
}
/**
* Returns an action object to remove a cart item from the store.
*
* @param {string} cartItemKey Cart item to remove.
* @return {Object} Object for action.
*/
export function receiveRemovedItem( cartItemKey ) {
return {
type: types.RECEIVE_REMOVED_ITEM,
cartItemKey,
};
}
/**
* Removes specified item from the cart:
* - Calls API to remove item.
* - If successful, yields action to remove item from store.
* - If error, yields action to store error.
* - Sets cart item as pending while API request is in progress.
*
* @param {string} cartItemKey Cart item being updated.
*/
export function* removeItemFromCart( cartItemKey ) {
yield itemQuantityPending( cartItemKey, true );
try {
ensure cart totals update when items are removed or quantity changed (https://github.com/woocommerce/woocommerce-blocks/pull/1840) * ensure cart totals update when items are removed (prototype): - return complete cart object from DELETE cart/items/:key - use receiveCart on client to update whole cart including total * move API endpoint for removing cart items to cart controller: - returns full cart schema so should be part of cart controller - is now a POST request with param - not strict REST - fix up client action to use new API * move API test for removing cart items (API has moved) * use correct path for remove API in tests (doh!) * add extra API test for remove_cart_item with bad key => 404 (experiment) * experiment: delete test_remove_cart_item, does test_remove_bad_cart_item work? * reinstate test_remove_cart_item with single valid request * remove unnecessary newline * tidy comments in PHP api tests, rerun travis? * remove test_remove_cart_item which may be causing problems * reinstate troublesome remove cart item api test (experiment): - see if this works now travis issue is resolved * whitespace * show correct total when changing cart item quantity: - move update cart item quantity API to cart controller - & return full cart response - update js action to new API route & receive full cart response * simplify test_remove_cart_item API test - now just tests a valid remove succeeds * remove test_update_item (API has moved) + + experimentally remove test_remove_bad_cart_item - testing if cart remove tests interact with each other * fix tests (🤞) - pass params in body, not as query params * reinstate test for re-deleting same item * update API docs - update/delete cart item have moved to /cart * add response data checks to new cart API tests: - extra protection against expected 404 "false positives" * reinstate API test for changing cart item quantity * fix remove cart item body tests - MIA items return error code, not cart * fix test - quantity param is int not string * attempt fix 404ing test_update_item: - only allow POST, remove trailing `/` - align array equals for good measure :) * fix action for update-item - method=POST, now takes body params * fix response body asserts in test_update_item * reinstate update_item and delete_item on CartItems controller * typos + examples in new cart items API docs * reorder previous cart item docs to minimise diff/churn * reinstate tabs in docs response example
2020-03-05 19:11:39 +00:00
const cart = yield apiFetch( {
path: `/wc/store/cart/remove-item/?key=${ cartItemKey }`,
method: 'POST',
cache: 'no-store',
} );
ensure cart totals update when items are removed or quantity changed (https://github.com/woocommerce/woocommerce-blocks/pull/1840) * ensure cart totals update when items are removed (prototype): - return complete cart object from DELETE cart/items/:key - use receiveCart on client to update whole cart including total * move API endpoint for removing cart items to cart controller: - returns full cart schema so should be part of cart controller - is now a POST request with param - not strict REST - fix up client action to use new API * move API test for removing cart items (API has moved) * use correct path for remove API in tests (doh!) * add extra API test for remove_cart_item with bad key => 404 (experiment) * experiment: delete test_remove_cart_item, does test_remove_bad_cart_item work? * reinstate test_remove_cart_item with single valid request * remove unnecessary newline * tidy comments in PHP api tests, rerun travis? * remove test_remove_cart_item which may be causing problems * reinstate troublesome remove cart item api test (experiment): - see if this works now travis issue is resolved * whitespace * show correct total when changing cart item quantity: - move update cart item quantity API to cart controller - & return full cart response - update js action to new API route & receive full cart response * simplify test_remove_cart_item API test - now just tests a valid remove succeeds * remove test_update_item (API has moved) + + experimentally remove test_remove_bad_cart_item - testing if cart remove tests interact with each other * fix tests (🤞) - pass params in body, not as query params * reinstate test for re-deleting same item * update API docs - update/delete cart item have moved to /cart * add response data checks to new cart API tests: - extra protection against expected 404 "false positives" * reinstate API test for changing cart item quantity * fix remove cart item body tests - MIA items return error code, not cart * fix test - quantity param is int not string * attempt fix 404ing test_update_item: - only allow POST, remove trailing `/` - align array equals for good measure :) * fix action for update-item - method=POST, now takes body params * fix response body asserts in test_update_item * reinstate update_item and delete_item on CartItems controller * typos + examples in new cart items API docs * reorder previous cart item docs to minimise diff/churn * reinstate tabs in docs response example
2020-03-05 19:11:39 +00:00
yield receiveCart( cart );
} catch ( error ) {
yield receiveError( error );
}
yield itemQuantityPending( cartItemKey, false );
}
Support updating quantity of cart items & sold_individually product option (https://github.com/woocommerce/woocommerce-blocks/pull/1824) * first cut - removing an item from cart: - add actions to cart store for removing an item and keeping track of pending removal API call - add reducer logic for storing pending state on an item, and removing an item - expose removeCartItem on new useStoreCartItems hook - hook it up to remove link / trashcan icon in row item * disable cart quantity picker/remove link while API request in progress: - expose cart item pending status from store using selector - use selector to disable quantity related components in line item row * add typedef for cart items store object provided by hook * allow user to change quantity of cart items (first cut): - add action for replacing a cart item in the store - add generator action for changing quantity - expose change quantity action on useStoreCartItems hook - hook up to quantity UI in cart block (work in progress) * post-rebase fixes & fix broken typedef: - rework cart item change quantity callback - now supplies item key like remove callback - fix hook StoreCartItem return value typedef - single item with specified key, was array of all items - add quantity JSDoc for changeCartItemQuantity action - remove changeQuantity callback from UI (currently infinite looping) * fix bug in recieveCartItem reducer - check keys for equality: - was key === object * fix invalid url in POST cart/items/quantity request * hook up cart line item quantity to API: - remove internal state/ref for QuantitySelector, is now a controlled component - call changeQuantity action from QuantitySelector change callback * QuantitySelector no longer needs a ref to wrangle number input value * hoist quantity state out of QuantitySelector into story (fix storybook) * add product sold_individually option to cart item API response * limit sold_individually items to 1 per cart/order: - support optional max value in QuantitySelector - set maximum dependent on sold_individually API field * prevent user from requesting zero x cart item (API 500 errors): - add minimum limit to QuantitySelector - default limit to 1 + fix bug with limiting to maximum value in number input change handler * remove useStoreCartItems, zombie hook coming back from rebase 🧟‍♂️ * address various review feedback: - inline undefined check, don't use lodash - quantityInputOnKeyDown callback hook depends on canIncrease/canDecrease - also removed undefined check for minimum, as minimum has default 0 * use safer typeof check for presence of maximum prop
2020-03-03 01:08:19 +00:00
/**
improve responsiveness when setting cart item quantities (https://github.com/woocommerce/woocommerce-blocks/pull/1864) * rework the quantity change generator action so the UI updates quick: - work in progress - still need to figure out how to debounce API call - add new action for updating quantity for an item - don't set cart item as pending while quantity is updating - this leaves QuantitySelector enabled so user can click more/less - use receiveCartItemQuantity to update quantity in UI before sending request * debounce line item quantity first cut: - use local state for quantity, so ui allows multiple clicks up/down - debounce store updates (and server/API call) * correct comment on cart item quantity reducer * remove recieveCartItemQuantity - no longer needed * remove delegation for deleted RECEIVE_CART_ITEM_QUANTITY * only update quantity in component sideffect if it has changed: - reduces unnecessary renders * factor out debounced quantity update into cartItem hook (hat tip @senadir) * use quantity from store, instead of passing in to hook + + fix latent bug in useStoreCartItem - the cartItem value is now object: - was previously single-item array - (note no client code is using this at present) * tidy/refactor cart item hook - separate dispatch from select * remove dud reset of item pending flag (came back in rebase) * add quantity to StoreCartItem hook return value typedef * fix js error when adding cart block in editor – cartItem not found * fix typedef * fix logic for debouncing * don’t update quantity on server unnecessarily Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
2020-03-09 02:09:47 +00:00
* Persists a quantity change the for specified cart item:
Support updating quantity of cart items & sold_individually product option (https://github.com/woocommerce/woocommerce-blocks/pull/1824) * first cut - removing an item from cart: - add actions to cart store for removing an item and keeping track of pending removal API call - add reducer logic for storing pending state on an item, and removing an item - expose removeCartItem on new useStoreCartItems hook - hook it up to remove link / trashcan icon in row item * disable cart quantity picker/remove link while API request in progress: - expose cart item pending status from store using selector - use selector to disable quantity related components in line item row * add typedef for cart items store object provided by hook * allow user to change quantity of cart items (first cut): - add action for replacing a cart item in the store - add generator action for changing quantity - expose change quantity action on useStoreCartItems hook - hook up to quantity UI in cart block (work in progress) * post-rebase fixes & fix broken typedef: - rework cart item change quantity callback - now supplies item key like remove callback - fix hook StoreCartItem return value typedef - single item with specified key, was array of all items - add quantity JSDoc for changeCartItemQuantity action - remove changeQuantity callback from UI (currently infinite looping) * fix bug in recieveCartItem reducer - check keys for equality: - was key === object * fix invalid url in POST cart/items/quantity request * hook up cart line item quantity to API: - remove internal state/ref for QuantitySelector, is now a controlled component - call changeQuantity action from QuantitySelector change callback * QuantitySelector no longer needs a ref to wrangle number input value * hoist quantity state out of QuantitySelector into story (fix storybook) * add product sold_individually option to cart item API response * limit sold_individually items to 1 per cart/order: - support optional max value in QuantitySelector - set maximum dependent on sold_individually API field * prevent user from requesting zero x cart item (API 500 errors): - add minimum limit to QuantitySelector - default limit to 1 + fix bug with limiting to maximum value in number input change handler * remove useStoreCartItems, zombie hook coming back from rebase 🧟‍♂️ * address various review feedback: - inline undefined check, don't use lodash - quantityInputOnKeyDown callback hook depends on canIncrease/canDecrease - also removed undefined check for minimum, as minimum has default 0 * use safer typeof check for presence of maximum prop
2020-03-03 01:08:19 +00:00
* - Calls API to set quantity.
* - If successful, yields action to update store.
* - If error, yields action to store error.
*
* @param {string} cartItemKey Cart item being updated.
* @param {number} quantity Specified (new) quantity.
*/
export function* changeCartItemQuantity( cartItemKey, quantity ) {
improve responsiveness when setting cart item quantities (https://github.com/woocommerce/woocommerce-blocks/pull/1864) * rework the quantity change generator action so the UI updates quick: - work in progress - still need to figure out how to debounce API call - add new action for updating quantity for an item - don't set cart item as pending while quantity is updating - this leaves QuantitySelector enabled so user can click more/less - use receiveCartItemQuantity to update quantity in UI before sending request * debounce line item quantity first cut: - use local state for quantity, so ui allows multiple clicks up/down - debounce store updates (and server/API call) * correct comment on cart item quantity reducer * remove recieveCartItemQuantity - no longer needed * remove delegation for deleted RECEIVE_CART_ITEM_QUANTITY * only update quantity in component sideffect if it has changed: - reduces unnecessary renders * factor out debounced quantity update into cartItem hook (hat tip @senadir) * use quantity from store, instead of passing in to hook + + fix latent bug in useStoreCartItem - the cartItem value is now object: - was previously single-item array - (note no client code is using this at present) * tidy/refactor cart item hook - separate dispatch from select * remove dud reset of item pending flag (came back in rebase) * add quantity to StoreCartItem hook return value typedef * fix js error when adding cart block in editor – cartItem not found * fix typedef * fix logic for debouncing * don’t update quantity on server unnecessarily Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
2020-03-09 02:09:47 +00:00
const cartItem = yield select( CART_STORE_KEY, 'getCartItem', cartItemKey );
Support updating quantity of cart items & sold_individually product option (https://github.com/woocommerce/woocommerce-blocks/pull/1824) * first cut - removing an item from cart: - add actions to cart store for removing an item and keeping track of pending removal API call - add reducer logic for storing pending state on an item, and removing an item - expose removeCartItem on new useStoreCartItems hook - hook it up to remove link / trashcan icon in row item * disable cart quantity picker/remove link while API request in progress: - expose cart item pending status from store using selector - use selector to disable quantity related components in line item row * add typedef for cart items store object provided by hook * allow user to change quantity of cart items (first cut): - add action for replacing a cart item in the store - add generator action for changing quantity - expose change quantity action on useStoreCartItems hook - hook up to quantity UI in cart block (work in progress) * post-rebase fixes & fix broken typedef: - rework cart item change quantity callback - now supplies item key like remove callback - fix hook StoreCartItem return value typedef - single item with specified key, was array of all items - add quantity JSDoc for changeCartItemQuantity action - remove changeQuantity callback from UI (currently infinite looping) * fix bug in recieveCartItem reducer - check keys for equality: - was key === object * fix invalid url in POST cart/items/quantity request * hook up cart line item quantity to API: - remove internal state/ref for QuantitySelector, is now a controlled component - call changeQuantity action from QuantitySelector change callback * QuantitySelector no longer needs a ref to wrangle number input value * hoist quantity state out of QuantitySelector into story (fix storybook) * add product sold_individually option to cart item API response * limit sold_individually items to 1 per cart/order: - support optional max value in QuantitySelector - set maximum dependent on sold_individually API field * prevent user from requesting zero x cart item (API 500 errors): - add minimum limit to QuantitySelector - default limit to 1 + fix bug with limiting to maximum value in number input change handler * remove useStoreCartItems, zombie hook coming back from rebase 🧟‍♂️ * address various review feedback: - inline undefined check, don't use lodash - quantityInputOnKeyDown callback hook depends on canIncrease/canDecrease - also removed undefined check for minimum, as minimum has default 0 * use safer typeof check for presence of maximum prop
2020-03-03 01:08:19 +00:00
improve responsiveness when setting cart item quantities (https://github.com/woocommerce/woocommerce-blocks/pull/1864) * rework the quantity change generator action so the UI updates quick: - work in progress - still need to figure out how to debounce API call - add new action for updating quantity for an item - don't set cart item as pending while quantity is updating - this leaves QuantitySelector enabled so user can click more/less - use receiveCartItemQuantity to update quantity in UI before sending request * debounce line item quantity first cut: - use local state for quantity, so ui allows multiple clicks up/down - debounce store updates (and server/API call) * correct comment on cart item quantity reducer * remove recieveCartItemQuantity - no longer needed * remove delegation for deleted RECEIVE_CART_ITEM_QUANTITY * only update quantity in component sideffect if it has changed: - reduces unnecessary renders * factor out debounced quantity update into cartItem hook (hat tip @senadir) * use quantity from store, instead of passing in to hook + + fix latent bug in useStoreCartItem - the cartItem value is now object: - was previously single-item array - (note no client code is using this at present) * tidy/refactor cart item hook - separate dispatch from select * remove dud reset of item pending flag (came back in rebase) * add quantity to StoreCartItem hook return value typedef * fix js error when adding cart block in editor – cartItem not found * fix typedef * fix logic for debouncing * don’t update quantity on server unnecessarily Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
2020-03-09 02:09:47 +00:00
if ( cartItem?.quantity === quantity ) {
return;
}
Support updating quantity of cart items & sold_individually product option (https://github.com/woocommerce/woocommerce-blocks/pull/1824) * first cut - removing an item from cart: - add actions to cart store for removing an item and keeping track of pending removal API call - add reducer logic for storing pending state on an item, and removing an item - expose removeCartItem on new useStoreCartItems hook - hook it up to remove link / trashcan icon in row item * disable cart quantity picker/remove link while API request in progress: - expose cart item pending status from store using selector - use selector to disable quantity related components in line item row * add typedef for cart items store object provided by hook * allow user to change quantity of cart items (first cut): - add action for replacing a cart item in the store - add generator action for changing quantity - expose change quantity action on useStoreCartItems hook - hook up to quantity UI in cart block (work in progress) * post-rebase fixes & fix broken typedef: - rework cart item change quantity callback - now supplies item key like remove callback - fix hook StoreCartItem return value typedef - single item with specified key, was array of all items - add quantity JSDoc for changeCartItemQuantity action - remove changeQuantity callback from UI (currently infinite looping) * fix bug in recieveCartItem reducer - check keys for equality: - was key === object * fix invalid url in POST cart/items/quantity request * hook up cart line item quantity to API: - remove internal state/ref for QuantitySelector, is now a controlled component - call changeQuantity action from QuantitySelector change callback * QuantitySelector no longer needs a ref to wrangle number input value * hoist quantity state out of QuantitySelector into story (fix storybook) * add product sold_individually option to cart item API response * limit sold_individually items to 1 per cart/order: - support optional max value in QuantitySelector - set maximum dependent on sold_individually API field * prevent user from requesting zero x cart item (API 500 errors): - add minimum limit to QuantitySelector - default limit to 1 + fix bug with limiting to maximum value in number input change handler * remove useStoreCartItems, zombie hook coming back from rebase 🧟‍♂️ * address various review feedback: - inline undefined check, don't use lodash - quantityInputOnKeyDown callback hook depends on canIncrease/canDecrease - also removed undefined check for minimum, as minimum has default 0 * use safer typeof check for presence of maximum prop
2020-03-03 01:08:19 +00:00
try {
ensure cart totals update when items are removed or quantity changed (https://github.com/woocommerce/woocommerce-blocks/pull/1840) * ensure cart totals update when items are removed (prototype): - return complete cart object from DELETE cart/items/:key - use receiveCart on client to update whole cart including total * move API endpoint for removing cart items to cart controller: - returns full cart schema so should be part of cart controller - is now a POST request with param - not strict REST - fix up client action to use new API * move API test for removing cart items (API has moved) * use correct path for remove API in tests (doh!) * add extra API test for remove_cart_item with bad key => 404 (experiment) * experiment: delete test_remove_cart_item, does test_remove_bad_cart_item work? * reinstate test_remove_cart_item with single valid request * remove unnecessary newline * tidy comments in PHP api tests, rerun travis? * remove test_remove_cart_item which may be causing problems * reinstate troublesome remove cart item api test (experiment): - see if this works now travis issue is resolved * whitespace * show correct total when changing cart item quantity: - move update cart item quantity API to cart controller - & return full cart response - update js action to new API route & receive full cart response * simplify test_remove_cart_item API test - now just tests a valid remove succeeds * remove test_update_item (API has moved) + + experimentally remove test_remove_bad_cart_item - testing if cart remove tests interact with each other * fix tests (🤞) - pass params in body, not as query params * reinstate test for re-deleting same item * update API docs - update/delete cart item have moved to /cart * add response data checks to new cart API tests: - extra protection against expected 404 "false positives" * reinstate API test for changing cart item quantity * fix remove cart item body tests - MIA items return error code, not cart * fix test - quantity param is int not string * attempt fix 404ing test_update_item: - only allow POST, remove trailing `/` - align array equals for good measure :) * fix action for update-item - method=POST, now takes body params * fix response body asserts in test_update_item * reinstate update_item and delete_item on CartItems controller * typos + examples in new cart items API docs * reorder previous cart item docs to minimise diff/churn * reinstate tabs in docs response example
2020-03-05 19:11:39 +00:00
const cart = yield apiFetch( {
path: `/wc/store/cart/update-item`,
method: 'POST',
data: {
key: cartItemKey,
quantity,
},
Support updating quantity of cart items & sold_individually product option (https://github.com/woocommerce/woocommerce-blocks/pull/1824) * first cut - removing an item from cart: - add actions to cart store for removing an item and keeping track of pending removal API call - add reducer logic for storing pending state on an item, and removing an item - expose removeCartItem on new useStoreCartItems hook - hook it up to remove link / trashcan icon in row item * disable cart quantity picker/remove link while API request in progress: - expose cart item pending status from store using selector - use selector to disable quantity related components in line item row * add typedef for cart items store object provided by hook * allow user to change quantity of cart items (first cut): - add action for replacing a cart item in the store - add generator action for changing quantity - expose change quantity action on useStoreCartItems hook - hook up to quantity UI in cart block (work in progress) * post-rebase fixes & fix broken typedef: - rework cart item change quantity callback - now supplies item key like remove callback - fix hook StoreCartItem return value typedef - single item with specified key, was array of all items - add quantity JSDoc for changeCartItemQuantity action - remove changeQuantity callback from UI (currently infinite looping) * fix bug in recieveCartItem reducer - check keys for equality: - was key === object * fix invalid url in POST cart/items/quantity request * hook up cart line item quantity to API: - remove internal state/ref for QuantitySelector, is now a controlled component - call changeQuantity action from QuantitySelector change callback * QuantitySelector no longer needs a ref to wrangle number input value * hoist quantity state out of QuantitySelector into story (fix storybook) * add product sold_individually option to cart item API response * limit sold_individually items to 1 per cart/order: - support optional max value in QuantitySelector - set maximum dependent on sold_individually API field * prevent user from requesting zero x cart item (API 500 errors): - add minimum limit to QuantitySelector - default limit to 1 + fix bug with limiting to maximum value in number input change handler * remove useStoreCartItems, zombie hook coming back from rebase 🧟‍♂️ * address various review feedback: - inline undefined check, don't use lodash - quantityInputOnKeyDown callback hook depends on canIncrease/canDecrease - also removed undefined check for minimum, as minimum has default 0 * use safer typeof check for presence of maximum prop
2020-03-03 01:08:19 +00:00
cache: 'no-store',
} );
ensure cart totals update when items are removed or quantity changed (https://github.com/woocommerce/woocommerce-blocks/pull/1840) * ensure cart totals update when items are removed (prototype): - return complete cart object from DELETE cart/items/:key - use receiveCart on client to update whole cart including total * move API endpoint for removing cart items to cart controller: - returns full cart schema so should be part of cart controller - is now a POST request with param - not strict REST - fix up client action to use new API * move API test for removing cart items (API has moved) * use correct path for remove API in tests (doh!) * add extra API test for remove_cart_item with bad key => 404 (experiment) * experiment: delete test_remove_cart_item, does test_remove_bad_cart_item work? * reinstate test_remove_cart_item with single valid request * remove unnecessary newline * tidy comments in PHP api tests, rerun travis? * remove test_remove_cart_item which may be causing problems * reinstate troublesome remove cart item api test (experiment): - see if this works now travis issue is resolved * whitespace * show correct total when changing cart item quantity: - move update cart item quantity API to cart controller - & return full cart response - update js action to new API route & receive full cart response * simplify test_remove_cart_item API test - now just tests a valid remove succeeds * remove test_update_item (API has moved) + + experimentally remove test_remove_bad_cart_item - testing if cart remove tests interact with each other * fix tests (🤞) - pass params in body, not as query params * reinstate test for re-deleting same item * update API docs - update/delete cart item have moved to /cart * add response data checks to new cart API tests: - extra protection against expected 404 "false positives" * reinstate API test for changing cart item quantity * fix remove cart item body tests - MIA items return error code, not cart * fix test - quantity param is int not string * attempt fix 404ing test_update_item: - only allow POST, remove trailing `/` - align array equals for good measure :) * fix action for update-item - method=POST, now takes body params * fix response body asserts in test_update_item * reinstate update_item and delete_item on CartItems controller * typos + examples in new cart items API docs * reorder previous cart item docs to minimise diff/churn * reinstate tabs in docs response example
2020-03-05 19:11:39 +00:00
yield receiveCart( cart );
Support updating quantity of cart items & sold_individually product option (https://github.com/woocommerce/woocommerce-blocks/pull/1824) * first cut - removing an item from cart: - add actions to cart store for removing an item and keeping track of pending removal API call - add reducer logic for storing pending state on an item, and removing an item - expose removeCartItem on new useStoreCartItems hook - hook it up to remove link / trashcan icon in row item * disable cart quantity picker/remove link while API request in progress: - expose cart item pending status from store using selector - use selector to disable quantity related components in line item row * add typedef for cart items store object provided by hook * allow user to change quantity of cart items (first cut): - add action for replacing a cart item in the store - add generator action for changing quantity - expose change quantity action on useStoreCartItems hook - hook up to quantity UI in cart block (work in progress) * post-rebase fixes & fix broken typedef: - rework cart item change quantity callback - now supplies item key like remove callback - fix hook StoreCartItem return value typedef - single item with specified key, was array of all items - add quantity JSDoc for changeCartItemQuantity action - remove changeQuantity callback from UI (currently infinite looping) * fix bug in recieveCartItem reducer - check keys for equality: - was key === object * fix invalid url in POST cart/items/quantity request * hook up cart line item quantity to API: - remove internal state/ref for QuantitySelector, is now a controlled component - call changeQuantity action from QuantitySelector change callback * QuantitySelector no longer needs a ref to wrangle number input value * hoist quantity state out of QuantitySelector into story (fix storybook) * add product sold_individually option to cart item API response * limit sold_individually items to 1 per cart/order: - support optional max value in QuantitySelector - set maximum dependent on sold_individually API field * prevent user from requesting zero x cart item (API 500 errors): - add minimum limit to QuantitySelector - default limit to 1 + fix bug with limiting to maximum value in number input change handler * remove useStoreCartItems, zombie hook coming back from rebase 🧟‍♂️ * address various review feedback: - inline undefined check, don't use lodash - quantityInputOnKeyDown callback hook depends on canIncrease/canDecrease - also removed undefined check for minimum, as minimum has default 0 * use safer typeof check for presence of maximum prop
2020-03-03 01:08:19 +00:00
} catch ( error ) {
yield receiveError( error );
}
}
Update and select shipping rates dynamically (https://github.com/woocommerce/woocommerce-blocks/pull/1794) * add select shipping endpoint to router * add select shipping method * add selected rates to cart * better select rates * move schema function to seperate function * move validation to Cart Controller * fix wrong session key * Update shipping/cart endpoints (https://github.com/woocommerce/woocommerce-blocks/pull/1833) * Items should not have keys in API response * Include package ID in response (this is just a basic index) * /cart/select-shipping-rate/package_id * Add package_id to package array * Update responses and add shipping-rates to main cart endpoint * update-shipping endpoint * Add querying selected shipping rate to the store (https://github.com/woocommerce/woocommerce-blocks/pull/1829) * add selecting shipping to store * directly call useSelectShippingRate * refactor cart keys transformation to reducer * remove selecting first result and accept selecting * move update shipping to new endpoint * pass selected rates down * select shipping right directly and fix editor issues * fix some broken prop types * key -> package id * Update and fix cart/shipping-rate tests * fix case for when rates are set * Update useShippingRates test * add args to rest endpoint * move selecting shipping rate logic to hook * fix some naming issues * update propTypes * update action call * fully watch cart state * address review issues * fix prop type issues * fix issue with rates not loading in checkout * remove extra package for shipping * move ShippingCalculatorOptions to outside Co-authored-by: Mike Jolley <mike.jolley@me.com> Co-authored-by: Albert Juhé Lluveras <aljullu@gmail.com>
2020-03-05 19:54:05 +00:00
/**
* Selects a shipping rate.
*
* @param {string} rateId the id of the rate being selected.
* @param {number} [packageId] the key of the packages that we will select within.
*/
export function* selectShippingRate( rateId, packageId = 0 ) {
try {
const result = yield apiFetch( {
path: `/wc/store/cart/select-shipping-rate/${ packageId }`,
method: 'POST',
data: {
rate_id: rateId,
},
cache: 'no-store',
} );
if ( result ) {
yield receiveCart( result );
}
} catch ( error ) {
yield receiveError( error );
}
}
/**
* Returns an action object used to track what shipping address are we updating to.
*
* @param {boolean} isResolving if we're loading shipping address or not.
* @return {Object} Object for action.
*/
export function shippingRatesAreResolving( isResolving ) {
return {
type: types.UPDATING_SHIPPING_ADDRESS,
isResolving,
};
}
/**
* Applies a coupon code and either invalidates caches, or receives an error if
the coupon cannot be applied.
*
* @param {Object} address shipping address to be updated
*/
export function* updateShippingAddress( address ) {
yield shippingRatesAreResolving( true );
try {
const result = yield apiFetch( {
path: '/wc/store/cart/update-shipping',
method: 'POST',
data: address,
cache: 'no-store',
} );
if ( result ) {
yield receiveCart( result );
}
} catch ( error ) {
yield receiveError( error );
}
yield shippingRatesAreResolving( false );
}