Try add payment method selector to onboarding store (https://github.com/woocommerce/woocommerce-admin/pull/6921)
* Added payment method to onboarding data store * Add reducer test * Address feedback on reducer naming convention, isResolving, enabledMethods * Move out types to live in its own island * Add a comment to remind ourselves for utilizing payments data store for enabled payment gateways * Update changelog
This commit is contained in:
parent
f515ed5b6e
commit
de9cfb210d
|
@ -2,12 +2,11 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
import { useDispatch, useSelect } from '@wordpress/data';
|
||||
import { getHistory, getNewPath } from '@woocommerce/navigation';
|
||||
import { OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||
import { OPTIONS_STORE_NAME, ONBOARDING_STORE_NAME } from '@woocommerce/data';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { useEffect, useMemo, useState } from '@wordpress/element';
|
||||
import { useMemo, useState } from '@wordpress/element';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -19,27 +18,22 @@ import { sift } from '../../../../utils';
|
|||
|
||||
export const RemotePayments = ( { query } ) => {
|
||||
const { updateOptions } = useDispatch( OPTIONS_STORE_NAME );
|
||||
const { getOption } = useSelect( ( select ) => {
|
||||
const {
|
||||
getOption,
|
||||
getPaymentMethodRecommendations,
|
||||
isResolving,
|
||||
} = useSelect( ( select ) => {
|
||||
return {
|
||||
getOption: select( OPTIONS_STORE_NAME ).getOption,
|
||||
getPaymentMethodRecommendations: select( ONBOARDING_STORE_NAME )
|
||||
.getPaymentMethodRecommendations,
|
||||
isResolving: select( ONBOARDING_STORE_NAME ).isResolving(
|
||||
'getPaymentMethodRecommendations'
|
||||
),
|
||||
};
|
||||
} );
|
||||
|
||||
const [ methods, setMethods ] = useState( [] );
|
||||
const [ isFetching, setIsFetching ] = useState( true );
|
||||
|
||||
useEffect( () => {
|
||||
apiFetch( {
|
||||
path: '/wc-admin/onboarding/payments',
|
||||
} )
|
||||
.then( ( results ) => {
|
||||
setMethods( results );
|
||||
setIsFetching( false );
|
||||
} )
|
||||
.catch( () => {
|
||||
setIsFetching( false );
|
||||
} );
|
||||
}, [] );
|
||||
const methods = getPaymentMethodRecommendations();
|
||||
|
||||
const recommendedMethod = useMemo( () => {
|
||||
const method = methods.find(
|
||||
|
@ -73,6 +67,29 @@ export const RemotePayments = ( { query } ) => {
|
|||
} );
|
||||
};
|
||||
|
||||
const getInitiallyEnabledMethods = () =>
|
||||
methods.reduce( ( acc, method ) => {
|
||||
acc[ method.key ] = method.isEnabled;
|
||||
return acc;
|
||||
}, {} );
|
||||
|
||||
// TODO: Ideally when payments data store is merged https://github.com/woocommerce/woocommerce-admin/pull/6918
|
||||
// we can utilize it for keeping track of enabled payment methods and optimistically update that
|
||||
// store when enabling methods.
|
||||
const [ enabledMethods, setEnabledMethods ] = useState(
|
||||
getInitiallyEnabledMethods()
|
||||
);
|
||||
|
||||
// Keeps enabledMethods up to date with methods fetched from API.
|
||||
useMemo(
|
||||
() =>
|
||||
setEnabledMethods( {
|
||||
...getInitiallyEnabledMethods(),
|
||||
...enabledMethods,
|
||||
} ),
|
||||
[ methods ]
|
||||
);
|
||||
|
||||
const markConfigured = async ( methodKey, queryParams = {} ) => {
|
||||
const method = methods.find( ( option ) => option.key === methodKey );
|
||||
|
||||
|
@ -103,7 +120,7 @@ export const RemotePayments = ( { query } ) => {
|
|||
};
|
||||
|
||||
const currentMethod = useMemo( () => {
|
||||
if ( ! query.method || isFetching ) {
|
||||
if ( ! query.method || isResolving ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -114,14 +131,7 @@ export const RemotePayments = ( { query } ) => {
|
|||
}
|
||||
|
||||
return method;
|
||||
}, [ isFetching, query ] );
|
||||
|
||||
const [ enabledMethods, setEnabledMethods ] = useState(
|
||||
methods.reduce( ( acc, method ) => {
|
||||
acc[ method.key ] = method.isEnabled;
|
||||
return acc;
|
||||
}, {} )
|
||||
);
|
||||
}, [ isResolving, query, methods ] );
|
||||
|
||||
if ( currentMethod ) {
|
||||
return (
|
||||
|
|
|
@ -3,6 +3,7 @@ const TYPES = {
|
|||
SET_IS_REQUESTING: 'SET_IS_REQUESTING',
|
||||
SET_PROFILE_ITEMS: 'SET_PROFILE_ITEMS',
|
||||
SET_TASKS_STATUS: 'SET_TASKS_STATUS',
|
||||
GET_PAYMENT_METHODS_SUCCESS: 'GET_PAYMENT_METHODS_SUCCESS',
|
||||
};
|
||||
|
||||
export default TYPES;
|
||||
|
|
|
@ -40,6 +40,13 @@ export function setTasksStatus( tasksStatus ) {
|
|||
};
|
||||
}
|
||||
|
||||
export function setPaymentMethods( paymentMethods ) {
|
||||
return {
|
||||
type: TYPES.GET_PAYMENT_METHODS_SUCCESS,
|
||||
paymentMethods,
|
||||
};
|
||||
}
|
||||
|
||||
export function* updateProfileItems( items ) {
|
||||
yield setIsRequesting( 'updateProfileItems', true );
|
||||
|
||||
|
|
|
@ -20,13 +20,23 @@ export const defaultState = {
|
|||
theme: null,
|
||||
wccom_connected: null,
|
||||
},
|
||||
paymentMethods: [],
|
||||
requesting: {},
|
||||
tasksStatus: {},
|
||||
};
|
||||
|
||||
const onboarding = (
|
||||
state = defaultState,
|
||||
{ type, profileItems, replace, error, isRequesting, selector, tasksStatus }
|
||||
{
|
||||
type,
|
||||
profileItems,
|
||||
paymentMethods,
|
||||
replace,
|
||||
error,
|
||||
isRequesting,
|
||||
selector,
|
||||
tasksStatus,
|
||||
}
|
||||
) => {
|
||||
switch ( type ) {
|
||||
case TYPES.SET_PROFILE_ITEMS:
|
||||
|
@ -57,6 +67,11 @@ const onboarding = (
|
|||
[ selector ]: isRequesting,
|
||||
},
|
||||
};
|
||||
case TYPES.GET_PAYMENT_METHODS_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
paymentMethods,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,12 @@ import { apiFetch } from '@wordpress/data-controls';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { WC_ADMIN_NAMESPACE } from '../constants';
|
||||
import { setProfileItems, setError, setTasksStatus } from './actions';
|
||||
import {
|
||||
setProfileItems,
|
||||
setError,
|
||||
setTasksStatus,
|
||||
setPaymentMethods,
|
||||
} from './actions';
|
||||
|
||||
export function* getProfileItems() {
|
||||
try {
|
||||
|
@ -34,3 +39,16 @@ export function* getTasksStatus() {
|
|||
yield setError( 'getTasksStatus', error );
|
||||
}
|
||||
}
|
||||
|
||||
export function* getPaymentMethodRecommendations() {
|
||||
try {
|
||||
const results = yield apiFetch( {
|
||||
path: WC_ADMIN_NAMESPACE + '/onboarding/payments',
|
||||
method: 'GET',
|
||||
} );
|
||||
|
||||
yield setPaymentMethods( results );
|
||||
} catch ( error ) {
|
||||
yield setError( 'getPaymentMethodRecommendations', error );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { WPDataSelectors } from '../types';
|
||||
import { WPDataSelectors, RuleProcessor } from '../types';
|
||||
|
||||
export const getProfileItems = (
|
||||
state: OnboardingState
|
||||
|
@ -15,6 +15,12 @@ export const getTasksStatus = (
|
|||
return state.tasksStatus || {};
|
||||
};
|
||||
|
||||
export const getPaymentMethodRecommendations = (
|
||||
state: OnboardingState
|
||||
): PaymentMethodsState[] => {
|
||||
return state.paymentMethods || [];
|
||||
};
|
||||
|
||||
export const getOnboardingError = (
|
||||
state: OnboardingState,
|
||||
selector: string
|
||||
|
@ -33,6 +39,9 @@ export const isOnboardingRequesting = (
|
|||
export type OnboardingSelectors = {
|
||||
getProfileItems: () => ReturnType< typeof getProfileItems >;
|
||||
getTasksStatus: () => ReturnType< typeof getTasksStatus >;
|
||||
getPaymentMethodRecommendations: () => ReturnType<
|
||||
typeof getPaymentMethodRecommendations
|
||||
>;
|
||||
getOnboardingError: () => ReturnType< typeof getOnboardingError >;
|
||||
isOnboardingRequesting: () => ReturnType< typeof isOnboardingRequesting >;
|
||||
} & WPDataSelectors;
|
||||
|
@ -40,6 +49,7 @@ export type OnboardingSelectors = {
|
|||
export type OnboardingState = {
|
||||
profileItems: ProfileItemsState;
|
||||
tasksStatus: TasksStatusState;
|
||||
paymentMethods: PaymentMethodsState[];
|
||||
// TODO clarify what the error record's type is
|
||||
errors: Record< string, unknown >;
|
||||
requesting: Record< string, boolean >;
|
||||
|
@ -112,3 +122,31 @@ export type ProfileItemsState = {
|
|||
theme: string | null;
|
||||
wccom_connected: boolean | null;
|
||||
};
|
||||
|
||||
export type FieldLocale = {
|
||||
locale: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export type MethodFields = {
|
||||
name: string;
|
||||
option?: string;
|
||||
label?: string;
|
||||
locales?: FieldLocale[];
|
||||
type?: string;
|
||||
value?: string;
|
||||
};
|
||||
|
||||
export type PaymentMethodsState = {
|
||||
locale: string;
|
||||
title: string;
|
||||
content: string;
|
||||
key: string;
|
||||
image: string;
|
||||
is_visible: boolean | RuleProcessor[];
|
||||
plugins: string[];
|
||||
is_configured: boolean | RuleProcessor[];
|
||||
fields: MethodFields[];
|
||||
api_details_url: string;
|
||||
manage_url: string;
|
||||
};
|
||||
|
|
|
@ -47,6 +47,24 @@ describe( 'plugins reducer', () => {
|
|||
expect( state.profileItems.propertyName ).toBe( 'value' );
|
||||
} );
|
||||
|
||||
it( 'should handle GET_PAYMENT_METHODS_SUCCESS', () => {
|
||||
const state = reducer(
|
||||
{
|
||||
paymentMethods: [ { previousItem: 'value' } ],
|
||||
},
|
||||
{
|
||||
type: TYPES.GET_PAYMENT_METHODS_SUCCESS,
|
||||
paymentMethods: [ { newItem: 'changed' } ],
|
||||
}
|
||||
);
|
||||
|
||||
expect( state.paymentMethods[ 0 ] ).not.toHaveProperty(
|
||||
'previousItem'
|
||||
);
|
||||
expect( state.paymentMethods[ 0 ] ).toHaveProperty( 'newItem' );
|
||||
expect( state.paymentMethods[ 0 ].newItem ).toBe( 'changed' );
|
||||
} );
|
||||
|
||||
it( 'should handle SET_ERROR', () => {
|
||||
const state = reducer( defaultState, {
|
||||
type: TYPES.SET_ERROR,
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
export * from './wp-data';
|
||||
export * from './rule-processor';
|
|
@ -0,0 +1,45 @@
|
|||
export type RuleProcessor = {
|
||||
type: RuleType;
|
||||
value?: string | number | boolean;
|
||||
default?: string | number | boolean;
|
||||
index?: string;
|
||||
operation?: RuleOperation;
|
||||
status?: string;
|
||||
operand?: RuleProcessor;
|
||||
operands?: RuleProcessor[] | RuleProcessor[][];
|
||||
option_name?: string;
|
||||
plugin?: string;
|
||||
plugins?: string[];
|
||||
publish_after?: string;
|
||||
};
|
||||
|
||||
export type RuleType =
|
||||
| 'plugins_activated'
|
||||
| 'publish_after_time'
|
||||
| 'publish_before_time'
|
||||
| 'not'
|
||||
| 'or'
|
||||
| 'fail'
|
||||
| 'pass'
|
||||
| 'plugin_version'
|
||||
| 'stored_state'
|
||||
| 'order_count'
|
||||
| 'wcadmin_active_for'
|
||||
| 'product_count'
|
||||
| 'onboarding_profile'
|
||||
| 'is_ecommerce'
|
||||
| 'base_location_country'
|
||||
| 'base_location_state'
|
||||
| 'note_status'
|
||||
| 'option'
|
||||
| 'wca_updated';
|
||||
|
||||
export type RuleOperation =
|
||||
| '='
|
||||
| '<'
|
||||
| '<='
|
||||
| '>'
|
||||
| '>='
|
||||
| '!='
|
||||
| 'contains'
|
||||
| '!contains';
|
|
@ -90,6 +90,8 @@ Release and roadmap notes are available on the [WooCommerce Developers Blog](htt
|
|||
- Dev: Fixed storybook build script #6875
|
||||
- Dev: Removed allowed keys list for adding woocommerce_meta data. #6889 🎉 @xristos3490
|
||||
- Dev: Delete all products when running product import tests, unskip previously skipped test. #6905
|
||||
- Dev: Add payment method selector to onboarding store #6921
|
||||
- Dev: Add disabled prop to SelectControl #6902
|
||||
- Dev: Do a git clean before the core release. #6945
|
||||
- Enhancement: Add recommended payment methods in payment settings. #6760
|
||||
- Enhancement: Add expand/collapse to extendable task list. #6910
|
||||
|
@ -133,7 +135,6 @@ Release and roadmap notes are available on the [WooCommerce Developers Blog](htt
|
|||
- Update: UI updates to Payment Task screen #6766
|
||||
- Update: Adding setup required icon for non-configured payment methods #6811
|
||||
- Update: Task list component with new Experimental Task list. #6849
|
||||
- Dev: Add disabled prop to SelectControl #6902
|
||||
- Update: Redirect to WC Home after setting up a payment method #6891
|
||||
- Dev: Fix a bug where trying to load an asset registry causes a crash. #6951
|
||||
|
||||
|
|
Loading…
Reference in New Issue