Add/33443 shipping zones data store (#33830)

* Add shipping zones data store

* Make query object optional in getItems call

* Make query optional

* Add changelog
This commit is contained in:
louwie17 2022-07-14 09:53:26 -03:00 committed by GitHub
parent 39470e9f5c
commit 87e1f3106d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 128 additions and 12 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add new data store for shipping zones. #33830

View File

@ -43,7 +43,7 @@ export const createReducer = () => {
...state.errors, ...state.errors,
[ getResourceName( [ getResourceName(
payload.errorType, payload.errorType,
payload.query as ItemQuery ( payload.query || {} ) as ItemQuery
) ]: payload.error, ) ]: payload.error,
}, },
}; };
@ -114,7 +114,7 @@ export const createReducer = () => {
const itemQuery = getResourceName( const itemQuery = getResourceName(
CRUD_ACTIONS.GET_ITEMS, CRUD_ACTIONS.GET_ITEMS,
payload.query as ItemQuery ( payload.query || {} ) as ItemQuery
); );
return { return {

View File

@ -41,9 +41,9 @@ export const createResolvers = ( {
} }
}; };
const getItems = function* ( query: Partial< ItemQuery > ) { const getItems = function* ( query?: Partial< ItemQuery > ) {
// Require ID when requesting specific fields to later update the resource data. // Require ID when requesting specific fields to later update the resource data.
const resourceQuery = { ...query }; const resourceQuery = query ? { ...query } : {};
if ( if (
resourceQuery && resourceQuery &&

View File

@ -39,8 +39,11 @@ export const getItemError = ( state: ResourceState, id: IdType ) => {
}; };
export const getItems = createSelector( export const getItems = createSelector(
( state: ResourceState, query: ItemQuery ) => { ( state: ResourceState, query?: ItemQuery ) => {
const itemQuery = getResourceName( CRUD_ACTIONS.GET_ITEMS, query ); const itemQuery = getResourceName(
CRUD_ACTIONS.GET_ITEMS,
query || {}
);
const ids = state.items[ itemQuery ] const ids = state.items[ itemQuery ]
? state.items[ itemQuery ].data ? state.items[ itemQuery ].data
@ -50,7 +53,7 @@ export const getItems = createSelector(
return null; return null;
} }
if ( query._fields ) { if ( query && query._fields ) {
return ids.map( ( id: IdType ) => { return ids.map( ( id: IdType ) => {
return query._fields.reduce( return query._fields.reduce(
( item: Partial< Item >, field: string ) => { ( item: Partial< Item >, field: string ) => {
@ -71,7 +74,10 @@ export const getItems = createSelector(
.filter( ( item ) => item !== undefined ); .filter( ( item ) => item !== undefined );
}, },
( state, query ) => { ( state, query ) => {
const itemQuery = getResourceName( CRUD_ACTIONS.GET_ITEMS, query ); const itemQuery = getResourceName(
CRUD_ACTIONS.GET_ITEMS,
query || {}
);
const ids = state.items[ itemQuery ] const ids = state.items[ itemQuery ]
? state.items[ itemQuery ].data ? state.items[ itemQuery ].data
: undefined; : undefined;
@ -84,8 +90,8 @@ export const getItems = createSelector(
} }
); );
export const getItemsError = ( state: ResourceState, query: ItemQuery ) => { export const getItemsError = ( state: ResourceState, query?: ItemQuery ) => {
const itemQuery = getResourceName( CRUD_ACTIONS.GET_ITEMS, query ); const itemQuery = getResourceName( CRUD_ACTIONS.GET_ITEMS, query || {} );
return state.errors[ itemQuery ]; return state.errors[ itemQuery ];
}; };

View File

@ -105,7 +105,7 @@ export type CrudSelectors<
export type MapSelectors< Type, ResourceName, ParamType, ReturnType > = { export type MapSelectors< Type, ResourceName, ParamType, ReturnType > = {
[ Property in keyof Type as `get${ Capitalize< [ Property in keyof Type as `get${ Capitalize<
string & ResourceName string & ResourceName
> }${ Capitalize< string & Property > }` ]: ( x: ParamType ) => ReturnType; > }${ Capitalize< string & Property > }` ]: ( x?: ParamType ) => ReturnType;
}; };
export type MapActions< Type, ResourceName, ParamType, ReturnType > = { export type MapActions< Type, ResourceName, ParamType, ReturnType > = {

View File

@ -20,6 +20,7 @@ export { PRODUCTS_STORE_NAME } from './products';
export { ORDERS_STORE_NAME } from './orders'; export { ORDERS_STORE_NAME } from './orders';
export { PRODUCT_ATTRIBUTES_STORE_NAME } from './product-attributes'; export { PRODUCT_ATTRIBUTES_STORE_NAME } from './product-attributes';
export { EXPERIMENTAL_PRODUCT_SHIPPING_CLASSES_STORE_NAME } from './product-shipping-classes'; export { EXPERIMENTAL_PRODUCT_SHIPPING_CLASSES_STORE_NAME } from './product-shipping-classes';
export { EXPERIMENTAL_SHIPPING_ZONES_STORE_NAME } from './shipping-zones';
export { PaymentGateway } from './payment-gateways/types'; export { PaymentGateway } from './payment-gateways/types';
// Export hooks // Export hooks
@ -93,6 +94,7 @@ import type { PRODUCTS_STORE_NAME } from './products';
import type { ORDERS_STORE_NAME } from './orders'; import type { ORDERS_STORE_NAME } from './orders';
import type { PRODUCT_ATTRIBUTES_STORE_NAME } from './product-attributes'; import type { PRODUCT_ATTRIBUTES_STORE_NAME } from './product-attributes';
import type { EXPERIMENTAL_PRODUCT_SHIPPING_CLASSES_STORE_NAME } from './product-shipping-classes'; import type { EXPERIMENTAL_PRODUCT_SHIPPING_CLASSES_STORE_NAME } from './product-shipping-classes';
import type { EXPERIMENTAL_SHIPPING_ZONES_STORE_NAME } from './shipping-zones';
export type WCDataStoreName = export type WCDataStoreName =
| typeof REVIEWS_STORE_NAME | typeof REVIEWS_STORE_NAME
@ -110,7 +112,8 @@ export type WCDataStoreName =
| typeof PRODUCTS_STORE_NAME | typeof PRODUCTS_STORE_NAME
| typeof ORDERS_STORE_NAME | typeof ORDERS_STORE_NAME
| typeof PRODUCT_ATTRIBUTES_STORE_NAME | typeof PRODUCT_ATTRIBUTES_STORE_NAME
| typeof EXPERIMENTAL_PRODUCT_SHIPPING_CLASSES_STORE_NAME; | typeof EXPERIMENTAL_PRODUCT_SHIPPING_CLASSES_STORE_NAME
| typeof EXPERIMENTAL_SHIPPING_ZONES_STORE_NAME;
/** /**
* Internal dependencies * Internal dependencies
@ -124,6 +127,7 @@ import { ProductsSelectors } from './products/selectors';
import { OrdersSelectors } from './orders/selectors'; import { OrdersSelectors } from './orders/selectors';
import { ProductAttributeSelectors } from './product-attributes/types'; import { ProductAttributeSelectors } from './product-attributes/types';
import { ProductShippingClassSelectors } from './product-shipping-classes/types'; import { ProductShippingClassSelectors } from './product-shipping-classes/types';
import { ShippingZonesSelectors } from './shipping-zones/types';
// As we add types to all the package selectors we can fill out these unknown types with real ones. See one // As we add types to all the package selectors we can fill out these unknown types with real ones. See one
// of the already typed selectors for an example of how you can do this. // of the already typed selectors for an example of how you can do this.
@ -159,6 +163,8 @@ export type WCSelectorType< T > = T extends typeof REVIEWS_STORE_NAME
? ProductShippingClassSelectors ? ProductShippingClassSelectors
: T extends typeof ORDERS_STORE_NAME : T extends typeof ORDERS_STORE_NAME
? OrdersSelectors ? OrdersSelectors
: T extends typeof EXPERIMENTAL_SHIPPING_ZONES_STORE_NAME
? ShippingZonesSelectors
: never; : never;
export interface WCDataSelector { export interface WCDataSelector {
@ -170,3 +176,4 @@ export { ActionDispatchers as PluginsStoreActions } from './plugins/actions';
export { ActionDispatchers as ProductAttributesActions } from './product-attributes/types'; export { ActionDispatchers as ProductAttributesActions } from './product-attributes/types';
export { ActionDispatchers as ProductsStoreActions } from './products/actions'; export { ActionDispatchers as ProductsStoreActions } from './products/actions';
export { ActionDispatchers as ProductShippingClassesActions } from './product-shipping-classes/types'; export { ActionDispatchers as ProductShippingClassesActions } from './product-shipping-classes/types';
export { ActionDispatchers as ShippingZonesActions } from './shipping-zones/types';

View File

@ -0,0 +1,46 @@
# Shipping Zones Data Store
This data store provides functions to interact with the [Shipping Zones REST endpoints](https://woocommerce.github.io/woocommerce-rest-api-docs/#shipping-zones).
Under the hood this data store makes use of the [CRUD data store](../crud/README.md).
**Note: This data store is listed as experimental still as it is still in active development.**
## Usage
This data store can be accessed under the `experimental/wc/admin/shipping/zones` name. It is recommended you make use of the export constant `EXPERIMENTAL_SHIPPING_ZONES_STORE_NAME`.
Example:
```ts
import {
EXPERIMENTAL_SHIPPING_ZONES_STORE_NAME,
ShippingZonesActions,
} from '@woocommerce/data';
import { useDispatch } from '@wordpress/data';
function Component() {
const actions = useDispatch(
EXPERIMENTAL_SHIPPING_ZONES_STORE_NAME
) as ShippingZonesActions;
actions.createShippingZone( { name: 'test' } );
}
```
## Selections and actions:
| Selector | Description |
| -------------------------------------- | ------------------------------------------------------- |
| `getShippingZone( id: number )` | Gets a Shipping Zone by ID |
| `getShippingZoneError( id )` | Get the error for a failing GET shipping zone request. |
| `getShippingZones( query = {} )` | Get all shipping zones, query object is empty. |
| `getShippingZoneesError( query = {} )` | Get the error for a GET request for all shipping zones. |
Example usage: `wp.data.select( EXPERIMENTAL_SHIPPING_ZONES_STORE_NAME ).getShippingZone( 3 );`
| Actions | Method | Description |
| ----------------------------------------------- | ------ | ------------------------------------------------------------------------- |
| `createShippingZone( shippingZoneObject )` | POST | Creates shipping zone, see `ShippingZone` [here](./types.ts) for values |
| `deleteShippingZone( id )` | DELETE | Deletes a shipping class by ID |
| `updatetShippingZone( id, shippingZoneObject )` | PUT | Updates a shipping zone, see `ShippingZone` [here](./types.ts) for values |
Example usage: `wp.data.dispatch( EXPERIMENTAL_SHIPPING_ZONES_STORE_NAME ).updateShippingZone( 3, { name: 'New name' } );`

View File

@ -0,0 +1,3 @@
export const STORE_NAME = 'experimental/wc/admin/shipping/zones';
export const WC_SHIPPING_ZONES_NAMESPACE = '/wc/v3/shipping/zones';

View File

@ -0,0 +1,14 @@
/**
* Internal dependencies
*/
import { STORE_NAME, WC_SHIPPING_ZONES_NAMESPACE } from './constants';
import { createCrudDataStore } from '../crud';
createCrudDataStore( {
storeName: STORE_NAME,
resourceName: 'ShippingZone',
pluralResourceName: 'ShippingZones',
namespace: WC_SHIPPING_ZONES_NAMESPACE,
} );
export const EXPERIMENTAL_SHIPPING_ZONES_STORE_NAME = STORE_NAME;

View File

@ -0,0 +1,36 @@
/**
* External dependencies
*/
import { DispatchFromMap } from '@automattic/data-stores';
/**
* Internal dependencies
*/
import { CrudActions, CrudSelectors } from '../crud/types';
type ShippingZone = {
id: number;
name: string;
order: number;
};
type ReadOnlyProperties = 'id';
type MutableProperties = Omit< ShippingZone, ReadOnlyProperties >;
type ShippingZonesActions = CrudActions<
'ShippingZone',
ShippingZone,
MutableProperties,
'name'
>;
export type ShippingZonesSelectors = CrudSelectors<
'ShippingZone',
'ShippingZones',
ShippingZone,
undefined,
MutableProperties
>;
export type ActionDispatchers = DispatchFromMap< ShippingZonesActions >;