diff --git a/packages/js/data/changelog/add-35778-data-store b/packages/js/data/changelog/add-35778-data-store new file mode 100644 index 00000000000..e44e540625d --- /dev/null +++ b/packages/js/data/changelog/add-35778-data-store @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Extend product variations data store with generate variations actions diff --git a/packages/js/data/src/crud/README.md b/packages/js/data/src/crud/README.md index 48e190951cb..a2b29dfb2a1 100644 --- a/packages/js/data/src/crud/README.md +++ b/packages/js/data/src/crud/README.md @@ -18,6 +18,12 @@ createCrudDataStore( { resourceName: 'MyThing', pluralResourceName: 'MyThings', namespace: '/my/rest/namespace', + storeConfig: { + actions: additionalActions, + selectors: additionalSelectors, + resolvers: additionalResolvers, + controls: additionalControls, + } } ); ``` @@ -55,7 +61,7 @@ If the default settings are not adequate for your needs, you can always create y ```js import { createSelectors } from '../crud/selectors'; -import { createResolvers } from '../crud/selectors'; +import { createResolvers } from '../crud/resolvers'; import { createActions } from '../crud/actions'; import { registerStore, combineReducers } from '@wordpress/data'; diff --git a/packages/js/data/src/crud/index.ts b/packages/js/data/src/crud/index.ts index 6e44a1b50b7..6274f94fcad 100644 --- a/packages/js/data/src/crud/index.ts +++ b/packages/js/data/src/crud/index.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { registerStore } from '@wordpress/data'; +import { combineReducers, registerStore, StoreConfig } from '@wordpress/data'; import { Reducer } from 'redux'; /** @@ -9,7 +9,7 @@ import { Reducer } from 'redux'; */ import { createSelectors } from './selectors'; import { createDispatchActions } from './actions'; -import controls from '../controls'; +import defaultControls from '../controls'; import { createResolvers } from './resolvers'; import { createReducer, ResourceState } from './reducer'; @@ -18,6 +18,7 @@ type CrudDataStore = { resourceName: string; pluralResourceName: string; namespace: string; + storeConfig?: Partial< StoreConfig< ResourceState > >; }; export const createCrudDataStore = ( { @@ -25,29 +26,44 @@ export const createCrudDataStore = ( { resourceName, namespace, pluralResourceName, + storeConfig = {}, }: CrudDataStore ) => { - const reducer = createReducer(); - const actions = createDispatchActions( { + const crudReducer = createReducer(); + + const crudActions = createDispatchActions( { resourceName, namespace, } ); - const resolvers = createResolvers( { + const crudResolvers = createResolvers( { storeName, resourceName, pluralResourceName, namespace, } ); - const selectors = createSelectors( { + const crudSelectors = createSelectors( { resourceName, pluralResourceName, namespace, } ); + const { + reducer, + actions = {}, + selectors = {}, + resolvers = {}, + controls = {}, + } = storeConfig; + registerStore( storeName, { - reducer: reducer as Reducer< ResourceState >, - actions, - selectors, - resolvers, - controls, + reducer: reducer + ? ( combineReducers( { + crudReducer, + reducer, + } ) as Reducer ) + : ( crudReducer as Reducer< ResourceState > ), + actions: { ...crudActions, ...actions }, + selectors: { ...crudSelectors, ...selectors }, + resolvers: { ...crudResolvers, ...resolvers }, + controls: { ...defaultControls, ...controls }, } ); }; diff --git a/packages/js/data/src/product-variations/action-types.ts b/packages/js/data/src/product-variations/action-types.ts new file mode 100644 index 00000000000..4b6beef6b23 --- /dev/null +++ b/packages/js/data/src/product-variations/action-types.ts @@ -0,0 +1,5 @@ +export enum TYPES { + GENERATE_VARIATIONS_ERROR = 'GENERATE_VARIATIONS_ERROR', +} + +export default TYPES; diff --git a/packages/js/data/src/product-variations/actions.ts b/packages/js/data/src/product-variations/actions.ts new file mode 100644 index 00000000000..28b6fc1b4df --- /dev/null +++ b/packages/js/data/src/product-variations/actions.ts @@ -0,0 +1,46 @@ +/** + * External dependencies + */ +import { apiFetch } from '@wordpress/data-controls'; + +/** + * Internal dependencies + */ +import { getUrlParameters, getRestPath, parseId } from '../crud/utils'; +import TYPES from './action-types'; +import { IdQuery, IdType, Item } from '../crud/types'; +import { WC_PRODUCT_VARIATIONS_NAMESPACE } from './constants'; + +export function generateProductVariationsError( key: IdType, error: unknown ) { + return { + type: TYPES.GENERATE_VARIATIONS_ERROR as const, + key, + error, + errorType: 'GENERATE_VARIATIONS', + }; +} + +export const generateProductVariations = function* ( idQuery: IdQuery ) { + const urlParameters = getUrlParameters( + WC_PRODUCT_VARIATIONS_NAMESPACE, + idQuery + ); + + try { + const result: Item = yield apiFetch( { + path: getRestPath( + `${ WC_PRODUCT_VARIATIONS_NAMESPACE }/generate`, + {}, + urlParameters + ), + method: 'POST', + } ); + + return result; + } catch ( error ) { + const { key } = parseId( idQuery, urlParameters ); + + yield generateProductVariationsError( key, error ); + throw error; + } +}; diff --git a/packages/js/data/src/product-variations/index.ts b/packages/js/data/src/product-variations/index.ts index 4a6a444c202..c9b06818f33 100644 --- a/packages/js/data/src/product-variations/index.ts +++ b/packages/js/data/src/product-variations/index.ts @@ -3,12 +3,16 @@ */ import { STORE_NAME, WC_PRODUCT_VARIATIONS_NAMESPACE } from './constants'; import { createCrudDataStore } from '../crud'; +import * as actions from './actions'; createCrudDataStore( { storeName: STORE_NAME, resourceName: 'ProductVariation', pluralResourceName: 'ProductVariations', namespace: WC_PRODUCT_VARIATIONS_NAMESPACE, + storeConfig: { + actions, + }, } ); export const EXPERIMENTAL_PRODUCT_VARIATIONS_STORE_NAME = STORE_NAME;