diff --git a/modules/ppcp-settings/resources/js/data/onboarding/action-types.js b/modules/ppcp-settings/resources/js/data/onboarding/action-types.js index fb387e29c..f4834bbf5 100644 --- a/modules/ppcp-settings/resources/js/data/onboarding/action-types.js +++ b/modules/ppcp-settings/resources/js/data/onboarding/action-types.js @@ -1,21 +1,11 @@ export default { - RESET_ONBOARDING: 'RESET_ONBOARDING', - // Transient data. - SET_ONBOARDING_IS_READY: 'SET_ONBOARDING_IS_READY', - SET_IS_SAVING_ONBOARDING: 'SET_IS_SAVING_ONBOARDING', - SET_MANUAL_CONNECTION_BUSY: 'SET_MANUAL_CONNECTION_BUSY', + SET_TRANSIENT: 'ONBOARDING:SET_TRANSIENT', // Persistent data. - SET_ONBOARDING_COMPLETED: 'SET_ONBOARDING_COMPLETED', - SET_ONBOARDING_DETAILS: 'SET_ONBOARDING_DETAILS', - SET_ONBOARDING_STEP: 'SET_ONBOARDING_STEP', - SET_SANDBOX_MODE: 'SET_SANDBOX_MODE', - SET_MANUAL_CONNECTION_MODE: 'SET_MANUAL_CONNECTION_MODE', - SET_CLIENT_ID: 'SET_CLIENT_ID', - SET_CLIENT_SECRET: 'SET_CLIENT_SECRET', - SET_IS_CASUAL_SELLER: 'SET_IS_CASUAL_SELLER', - SET_PRODUCTS: 'SET_PRODUCTS', + SET_PERSISTENT: 'ONBOARDING:SET_PERSISTENT', + RESET: 'ONBOARDING:RESET', + HYDRATE: 'ONBOARDING:HYDRATE', // Controls - always start with "DO_". DO_PERSIST_DATA: 'ONBOARDING:DO_PERSIST_DATA', diff --git a/modules/ppcp-settings/resources/js/data/onboarding/actions.js b/modules/ppcp-settings/resources/js/data/onboarding/actions.js index 9fc03b24e..22c9571e1 100644 --- a/modules/ppcp-settings/resources/js/data/onboarding/actions.js +++ b/modules/ppcp-settings/resources/js/data/onboarding/actions.js @@ -9,48 +9,48 @@ import ACTION_TYPES from './action-types'; /** * Special. Resets all values in the onboarding store to initial defaults. * - * @return {{type: string}} The action. + * @return {Action} The action. */ export const resetOnboarding = () => { - return { type: ACTION_TYPES.RESET_ONBOARDING }; + return { type: ACTION_TYPES.RESET }; }; /** - * Non-persistent. Marks the onboarding details as "ready", i.e., fully initialized. + * Transient. Marks the onboarding details as "ready", i.e., fully initialized. * * @param {boolean} isReady - * @return {{type: string, isReady}} The action. + * @return {Action} The action. */ export const setIsReady = ( isReady ) => { return { - type: ACTION_TYPES.SET_ONBOARDING_IS_READY, - isReady, + type: ACTION_TYPES.SET_TRANSIENT, + payload: { isReady }, }; }; /** - * Non-persistent. Changes the "saving" flag. + * Transient. Changes the "saving" flag. * * @param {boolean} isSaving - * @return {{type: string, isSaving}} The action. + * @return {Action} The action. */ export const setIsSaving = ( isSaving ) => { return { - type: ACTION_TYPES.SET_IS_SAVING_ONBOARDING, - isSaving, + type: ACTION_TYPES.SET_TRANSIENT, + payload: { isSaving }, }; }; /** - * Non-persistent. Changes the "manual connection is busy" flag. + * Transient. Changes the "manual connection is busy" flag. * * @param {boolean} isBusy - * @return {{type: string, isBusy}} The action. + * @return {Action} The action. */ export const setManualConnectionIsBusy = ( isBusy ) => { return { - type: ACTION_TYPES.SET_MANUAL_CONNECTION_BUSY, - isBusy, + type: ACTION_TYPES.SET_TRANSIENT, + payload: { isBusy }, }; }; @@ -58,11 +58,11 @@ export const setManualConnectionIsBusy = ( isBusy ) => { * Persistent. Set the full onboarding details, usually during app initialization. * * @param {{data: {}, flags?: {}}} payload - * @return {{type: string, payload}} The action. + * @return {Action} The action. */ -export const setOnboardingDetails = ( payload ) => { +export const hydrateOnboardingDetails = ( payload ) => { return { - type: ACTION_TYPES.SET_ONBOARDING_DETAILS, + type: ACTION_TYPES.HYDRATE, payload, }; }; @@ -71,12 +71,12 @@ export const setOnboardingDetails = ( payload ) => { * Persistent.Set the "onboarding completed" flag which shows or hides the wizard. * * @param {boolean} completed - * @return {{type: string, payload}} The action. + * @return {Action} The action. */ export const setCompleted = ( completed ) => { return { - type: ACTION_TYPES.SET_ONBOARDING_COMPLETED, - completed, + type: ACTION_TYPES.SET_PERSISTENT, + payload: { completed }, }; }; @@ -84,38 +84,38 @@ export const setCompleted = ( completed ) => { * Persistent. Sets the onboarding wizard to a new step. * * @param {number} step - * @return {{type: string, step}} An action. + * @return {Action} The action. */ export const setOnboardingStep = ( step ) => { return { - type: ACTION_TYPES.SET_ONBOARDING_STEP, - step, + type: ACTION_TYPES.SET_PERSISTENT, + payload: { step }, }; }; /** * Persistent. Sets the sandbox mode on or off. * - * @param {boolean} sandboxMode - * @return {{type: string, useSandbox}} An action. + * @param {boolean} useSandbox + * @return {Action} The action. */ -export const setSandboxMode = ( sandboxMode ) => { +export const setSandboxMode = ( useSandbox ) => { return { - type: ACTION_TYPES.SET_SANDBOX_MODE, - useSandbox: sandboxMode, + type: ACTION_TYPES.SET_PERSISTENT, + payload: { useSandbox }, }; }; /** * Persistent. Toggles the "Manual Connection" mode on or off. * - * @param {boolean} manualConnectionMode - * @return {{type: string, useManualConnection}} An action. + * @param {boolean} useManualConnection + * @return {Action} The action. */ -export const setManualConnectionMode = ( manualConnectionMode ) => { +export const setManualConnectionMode = ( useManualConnection ) => { return { - type: ACTION_TYPES.SET_MANUAL_CONNECTION_MODE, - useManualConnection: manualConnectionMode, + type: ACTION_TYPES.SET_PERSISTENT, + payload: { useManualConnection }, }; }; @@ -123,12 +123,12 @@ export const setManualConnectionMode = ( manualConnectionMode ) => { * Persistent. Changes the "client ID" value. * * @param {string} clientId - * @return {{type: string, clientId}} The action. + * @return {Action} The action. */ export const setClientId = ( clientId ) => { return { - type: ACTION_TYPES.SET_CLIENT_ID, - clientId, + type: ACTION_TYPES.SET_PERSISTENT, + payload: { clientId }, }; }; @@ -136,12 +136,12 @@ export const setClientId = ( clientId ) => { * Persistent. Changes the "client secret" value. * * @param {string} clientSecret - * @return {{type: string, clientSecret}} The action. + * @return {Action} The action. */ export const setClientSecret = ( clientSecret ) => { return { - type: ACTION_TYPES.SET_CLIENT_SECRET, - clientSecret, + type: ACTION_TYPES.SET_PERSISTENT, + payload: { clientSecret }, }; }; @@ -149,12 +149,12 @@ export const setClientSecret = ( clientSecret ) => { * Persistent. Sets the "isCasualSeller" value. * * @param {boolean} isCasualSeller - * @return {{type: string, isCasualSeller}} The action. + * @return {Action} The action. */ export const setIsCasualSeller = ( isCasualSeller ) => { return { - type: ACTION_TYPES.SET_IS_CASUAL_SELLER, - isCasualSeller, + type: ACTION_TYPES.SET_PERSISTENT, + payload: { isCasualSeller }, }; }; @@ -162,12 +162,12 @@ export const setIsCasualSeller = ( isCasualSeller ) => { * Persistent. Sets the "products" array. * * @param {string[]} products - * @return {{type: string, products}} The action. + * @return {Action} The action. */ export const setProducts = ( products ) => { return { - type: ACTION_TYPES.SET_PRODUCTS, - products, + type: ACTION_TYPES.SET_PERSISTENT, + payload: { products }, }; }; diff --git a/modules/ppcp-settings/resources/js/data/onboarding/hooks.js b/modules/ppcp-settings/resources/js/data/onboarding/hooks.js index ff9052d69..d74fa2010 100644 --- a/modules/ppcp-settings/resources/js/data/onboarding/hooks.js +++ b/modules/ppcp-settings/resources/js/data/onboarding/hooks.js @@ -1,7 +1,6 @@ import { useSelect, useDispatch } from '@wordpress/data'; -import apiFetch from '@wordpress/api-fetch'; -import { NAMESPACE, PRODUCT_TYPES, STORE_NAME } from '../constants'; -import { getFlags } from './selectors'; + +import { PRODUCT_TYPES, STORE_NAME } from '../constants'; const useOnboardingDetails = () => { const { @@ -16,55 +15,60 @@ const useOnboardingDetails = () => { setProducts, } = useDispatch( STORE_NAME ); - // Transient accessors. - const isSaving = useSelect( ( select ) => { - return select( STORE_NAME ).getTransientData().isSaving; - }, [] ); - - const isReady = useSelect( ( select ) => { - return select( STORE_NAME ).getTransientData().isReady; - } ); - - const isManualConnectionBusy = useSelect( ( select ) => { - return select( STORE_NAME ).getTransientData().isManualConnectionBusy; - }, [] ); + const transientData = ( select ) => + select( STORE_NAME ).onboardingTransientData(); + const persistentData = ( select ) => + select( STORE_NAME ).onboardingPersistentData(); // Read-only flags. const flags = useSelect( ( select ) => { - return select( STORE_NAME ).getFlags(); + return select( STORE_NAME ).onboardingFlags(); } ); + // Transient accessors. + const isSaving = useSelect( ( select ) => { + return transientData( select ).isSaving; + }, [] ); + + const isReady = useSelect( ( select ) => { + return transientData( select ).isReady; + } ); + + const isManualConnectionBusy = useSelect( ( select ) => { + return transientData( select ).isManualConnectionBusy; + }, [] ); + // Persistent accessors. const step = useSelect( ( select ) => { - return select( STORE_NAME ).getPersistentData().step || 0; + return persistentData( select ).step || 0; } ); const completed = useSelect( ( select ) => { - return select( STORE_NAME ).getPersistentData().completed; + return persistentData( select ).completed; } ); const clientId = useSelect( ( select ) => { - return select( STORE_NAME ).getPersistentData().clientId; + return persistentData( select ).clientId; }, [] ); const clientSecret = useSelect( ( select ) => { - return select( STORE_NAME ).getPersistentData().clientSecret; + return persistentData( select ).clientSecret; }, [] ); const isSandboxMode = useSelect( ( select ) => { - return select( STORE_NAME ).getPersistentData().useSandbox; + return persistentData( select ).useSandbox; }, [] ); const isManualConnectionMode = useSelect( ( select ) => { - return select( STORE_NAME ).getPersistentData().useManualConnection; + return persistentData( select ).useManualConnection; }, [] ); const isCasualSeller = useSelect( ( select ) => { - return select( STORE_NAME ).getPersistentData().isCasualSeller; + return persistentData( select ).isCasualSeller; }, [] ); const products = useSelect( ( select ) => { - return select( STORE_NAME ).getPersistentData().products || []; + return persistentData( select ).products || []; }, [] ); const toggleProduct = ( list ) => { diff --git a/modules/ppcp-settings/resources/js/data/onboarding/reducer.js b/modules/ppcp-settings/resources/js/data/onboarding/reducer.js index 9cdeb7018..a037928f3 100644 --- a/modules/ppcp-settings/resources/js/data/onboarding/reducer.js +++ b/modules/ppcp-settings/resources/js/data/onboarding/reducer.js @@ -34,69 +34,26 @@ const [ setTransient, setPersistent ] = createSetters( defaultPersistent ); -const defaultState = { - ...defaultTransient, - data: { ...defaultPersistent }, -}; +const onboardingReducer = createReducer( defaultTransient, defaultPersistent, { + [ ACTION_TYPES.SET_TRANSIENT ]: ( state, { payload } ) => + setTransient( state, payload ), -export const onboardingReducer = ( - state = defaultState, - { type, ...action } -) => { - switch ( type ) { - // Reset store to initial state. - case ACTION_TYPES.RESET_ONBOARDING: - return setPersistent( defaultState.data ); + [ ACTION_TYPES.SET_PERSISTENT ]: ( state, { payload } ) => + setPersistent( state, payload ), - // Transient data. - case ACTION_TYPES.SET_ONBOARDING_IS_READY: - return setTransient( { isReady: action.isReady } ); + [ ACTION_TYPES.RESET ]: ( state ) => + setPersistent( state, defaultPersistent ), - case ACTION_TYPES.SET_IS_SAVING_ONBOARDING: - return setTransient( { isSaving: action.isSaving } ); + [ ACTION_TYPES.HYDRATE ]: ( state, { payload } ) => { + const newState = setPersistent( payload ); - case ACTION_TYPES.SET_MANUAL_CONNECTION_BUSY: - return setTransient( { isManualConnectionBusy: action.isBusy } ); + // Flags are not updated by `setPersistent()`. + if ( payload.flags ) { + newState.flags = { ...newState.flags, ...payload.flags }; + } - // Persistent data. - case ACTION_TYPES.SET_ONBOARDING_DETAILS: - const newState = setPersistent( action.payload.data ); - - if ( action.payload.flags ) { - newState.flags = { ...newState.flags, ...action.payload.flags }; - } - - return newState; - - case ACTION_TYPES.SET_ONBOARDING_COMPLETED: - return setPersistent( { completed: action.completed } ); - - case ACTION_TYPES.SET_CLIENT_ID: - return setPersistent( { clientId: action.clientId } ); - - case ACTION_TYPES.SET_CLIENT_SECRET: - return setPersistent( { clientSecret: action.clientSecret } ); - - case ACTION_TYPES.SET_ONBOARDING_STEP: - return setPersistent( { step: action.step } ); - - case ACTION_TYPES.SET_SANDBOX_MODE: - return setPersistent( { useSandbox: action.useSandbox } ); - - case ACTION_TYPES.SET_MANUAL_CONNECTION_MODE: - return setPersistent( { - useManualConnection: action.useManualConnection, - } ); - - case ACTION_TYPES.SET_IS_CASUAL_SELLER: - return setPersistent( { isCasualSeller: action.isCasualSeller } ); - - case ACTION_TYPES.SET_PRODUCTS: - return setPersistent( { products: action.products } ); - - default: - return state; - } -}; + return newState; + }, +} ); export default onboardingReducer; diff --git a/modules/ppcp-settings/resources/js/data/onboarding/resolvers.js b/modules/ppcp-settings/resources/js/data/onboarding/resolvers.js index c1a647804..7009ecff4 100644 --- a/modules/ppcp-settings/resources/js/data/onboarding/resolvers.js +++ b/modules/ppcp-settings/resources/js/data/onboarding/resolvers.js @@ -1,19 +1,20 @@ import { dispatch } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { apiFetch } from '@wordpress/data-controls'; + import { NAMESPACE } from '../constants'; import { REST_HYDRATE_PATH } from './constants'; -import { setIsReady, setOnboardingDetails } from './actions'; +import { setIsReady, hydrateOnboardingDetails } from './actions'; /** * Retrieve settings from the site's REST API. */ -export function* getPersistentData() { +export function* onboardingPersistentData() { const path = `${ NAMESPACE }/${ REST_HYDRATE_PATH }`; try { const result = yield apiFetch( { path } ); - yield setOnboardingDetails( result ); + yield hydrateOnboardingDetails( result ); yield setIsReady( true ); } catch ( e ) { yield dispatch( 'core/notices' ).createErrorNotice( diff --git a/modules/ppcp-settings/resources/js/data/onboarding/selectors.js b/modules/ppcp-settings/resources/js/data/onboarding/selectors.js index eb329c7d4..a2a16af13 100644 --- a/modules/ppcp-settings/resources/js/data/onboarding/selectors.js +++ b/modules/ppcp-settings/resources/js/data/onboarding/selectors.js @@ -10,15 +10,15 @@ const getState = ( state ) => { return state[ STORE_KEY ] || EMPTY_OBJ; }; -export const getPersistentData = ( state ) => { +export const onboardingPersistentData = ( state ) => { return getState( state ).data || EMPTY_OBJ; }; -export const getTransientData = ( state ) => { +export const onboardingTransientData = ( state ) => { const { data, flags, ...transientState } = getState( state ); return transientState || EMPTY_OBJ; }; -export const getFlags = ( state ) => { +export const onboardingFlags = ( state ) => { return getState( state ).flags || EMPTY_OBJ; };