Add create product actions in products data store (#33278)
* Add create product actions in products data store * Add changelog entry * Yield to actions in generator * Add mutable properties type
This commit is contained in:
parent
1bca9327ac
commit
17d9e8072d
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Add create product actions in products data store #33278
|
|
@ -155,3 +155,4 @@ export interface WCDataSelector {
|
|||
|
||||
// Other exports
|
||||
export { ActionDispatchers as PluginsStoreActions } from './plugins/actions';
|
||||
export { ActionDispatchers as ProductsStoreActions } from './products/actions';
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
export enum TYPES {
|
||||
CREATE_PRODUCT_ERROR = 'CREATE_PRODUCT_ERROR',
|
||||
CREATE_PRODUCT_SUCCESS = 'CREATE_PRODUCT_SUCCESS',
|
||||
GET_PRODUCT_SUCCESS = 'GET_PRODUCT_SUCCESS',
|
||||
GET_PRODUCT_ERROR = 'GET_PRODUCT_ERROR',
|
||||
GET_PRODUCTS_SUCCESS = 'GET_PRODUCTS_SUCCESS',
|
||||
|
|
|
@ -1,8 +1,20 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { apiFetch } from '@wordpress/data-controls';
|
||||
import { DispatchFromMap } from '@automattic/data-stores';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import TYPES from './action-types';
|
||||
import { PartialProduct, ProductQuery } from './types';
|
||||
import {
|
||||
MutableProperties,
|
||||
PartialProduct,
|
||||
Product,
|
||||
ProductQuery,
|
||||
} from './types';
|
||||
import { WC_PRODUCT_NAMESPACE } from './constants';
|
||||
|
||||
export function getProductSuccess( id: number, product: PartialProduct ) {
|
||||
return {
|
||||
|
@ -23,6 +35,25 @@ export function getProductError(
|
|||
};
|
||||
}
|
||||
|
||||
function createProductSuccess( id: number, product: PartialProduct ) {
|
||||
return {
|
||||
type: TYPES.CREATE_PRODUCT_SUCCESS as const,
|
||||
id,
|
||||
product,
|
||||
};
|
||||
}
|
||||
|
||||
export function createProductError(
|
||||
query: Partial< Product >,
|
||||
error: unknown
|
||||
) {
|
||||
return {
|
||||
type: TYPES.CREATE_PRODUCT_ERROR as const,
|
||||
query,
|
||||
error,
|
||||
};
|
||||
}
|
||||
|
||||
export function getProductsSuccess(
|
||||
query: Partial< ProductQuery >,
|
||||
products: PartialProduct[],
|
||||
|
@ -69,7 +100,25 @@ export function getProductsTotalCountError(
|
|||
};
|
||||
}
|
||||
|
||||
export function* createProduct( data: Pick< Product, MutableProperties > ) {
|
||||
try {
|
||||
const product: Product = yield apiFetch( {
|
||||
path: WC_PRODUCT_NAMESPACE,
|
||||
method: 'POST',
|
||||
data,
|
||||
} );
|
||||
|
||||
yield createProductSuccess( product.id, product );
|
||||
return product;
|
||||
} catch ( error ) {
|
||||
yield createProductError( data, error );
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export type Actions = ReturnType<
|
||||
| typeof createProductError
|
||||
| typeof createProductSuccess
|
||||
| typeof getProductSuccess
|
||||
| typeof getProductError
|
||||
| typeof getProductsSuccess
|
||||
|
@ -77,3 +126,7 @@ export type Actions = ReturnType<
|
|||
| typeof getProductsTotalCountSuccess
|
||||
| typeof getProductsTotalCountError
|
||||
>;
|
||||
|
||||
export type ActionDispatchers = DispatchFromMap< {
|
||||
createProduct: typeof createProduct;
|
||||
} >;
|
||||
|
|
|
@ -37,6 +37,7 @@ const reducer: Reducer< ProductState, Actions > = (
|
|||
) => {
|
||||
if ( payload && 'type' in payload ) {
|
||||
switch ( payload.type ) {
|
||||
case TYPES.CREATE_PRODUCT_SUCCESS:
|
||||
case TYPES.GET_PRODUCT_SUCCESS:
|
||||
const productData = state.data || {};
|
||||
return {
|
||||
|
@ -88,6 +89,7 @@ const reducer: Reducer< ProductState, Actions > = (
|
|||
case TYPES.GET_PRODUCT_ERROR:
|
||||
case TYPES.GET_PRODUCTS_ERROR:
|
||||
case TYPES.GET_PRODUCTS_TOTAL_COUNT_ERROR:
|
||||
case TYPES.CREATE_PRODUCT_ERROR:
|
||||
return {
|
||||
...state,
|
||||
errors: {
|
||||
|
|
|
@ -77,7 +77,16 @@ export const getProductsError = (
|
|||
return state.errors[ resourceName ];
|
||||
};
|
||||
|
||||
export const getCreateProductError = (
|
||||
state: ProductState,
|
||||
query: ProductQuery
|
||||
) => {
|
||||
const resourceName = getProductResourceName( query );
|
||||
return state.errors[ resourceName ];
|
||||
};
|
||||
|
||||
export type ProductsSelectors = {
|
||||
getCreateProductError: WPDataSelector< typeof getCreateProductError >;
|
||||
getProducts: WPDataSelector< typeof getProducts >;
|
||||
getProductsTotalCount: WPDataSelector< typeof getProductsTotalCount >;
|
||||
getProductsError: WPDataSelector< typeof getProductsError >;
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
getTotalProductCountResourceName,
|
||||
} from '../utils';
|
||||
import { Actions } from '../actions';
|
||||
import { PartialProduct, ProductQuery } from '../types';
|
||||
import { PartialProduct, ProductQuery, Product } from '../types';
|
||||
|
||||
const defaultState: ProductState = {
|
||||
products: {},
|
||||
|
@ -180,4 +180,34 @@ describe( 'products reducer', () => {
|
|||
|
||||
expect( state.errors[ resourceName ] ).toBe( error );
|
||||
} );
|
||||
|
||||
it( 'should handle CREATE_PRODUCT_SUCCESS', () => {
|
||||
const update: PartialProduct = {
|
||||
id: 2,
|
||||
name: 'Off the hook!',
|
||||
status: 'draft',
|
||||
};
|
||||
|
||||
const state = reducer( defaultState, {
|
||||
type: TYPES.CREATE_PRODUCT_SUCCESS,
|
||||
id: update.id,
|
||||
product: update,
|
||||
} );
|
||||
|
||||
expect( state.data[ 2 ].name ).toEqual( update.name );
|
||||
expect( state.data[ 2 ].status ).toEqual( update.status );
|
||||
} );
|
||||
|
||||
it( 'should handle CREATE_PRODUCT_ERROR', () => {
|
||||
const query: Partial< Product > = { name: 'Donkey Sauce' };
|
||||
const resourceName = getProductResourceName( query );
|
||||
const error = 'Baaam!';
|
||||
const state = reducer( defaultState, {
|
||||
type: TYPES.GET_PRODUCTS_ERROR,
|
||||
query,
|
||||
error,
|
||||
} );
|
||||
|
||||
expect( state.errors[ resourceName ] ).toBe( error );
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -40,6 +40,18 @@ export type Product<
|
|||
sale_price: string;
|
||||
};
|
||||
|
||||
export type MutableProperties =
|
||||
| 'name'
|
||||
| 'slug'
|
||||
| 'type'
|
||||
| 'status'
|
||||
| 'featured'
|
||||
| 'description'
|
||||
| 'short_description'
|
||||
| 'sku'
|
||||
| 'regular_price'
|
||||
| 'sale_price';
|
||||
|
||||
export type PartialProduct = Partial< Product > & Pick< Product, 'id' >;
|
||||
|
||||
export type ProductQuery<
|
||||
|
|
Loading…
Reference in New Issue