From 01588f21687cd29a33189fdba00bddc761af7578 Mon Sep 17 00:00:00 2001
From: Joel Thiessen <444632+joelclimbsthings@users.noreply.github.com>
Date: Thu, 10 Jun 2021 10:10:42 -0700
Subject: [PATCH] Fixing local WCPay payment task and refactoring for dumber
components (https://github.com/woocommerce/woocommerce-admin/pull/7151)
---
.../task-list/tasks/payments/LocalPayments.js | 15 +-
.../components/List/Item.js | 31 +--
.../components/List/List.js | 14 +-
.../components/Setup/Connect.js | 14 +-
.../components/Setup/Setup.js | 73 ++++----
.../PaymentGatewaySuggestions/index.js | 177 ++++++++++--------
...{WCPayMethodCard.js => WCPaySuggestion.js} | 17 +-
.../task-list/tasks/payments/methods/index.js | 2 +-
.../WooPaymentGatewayConnect/README.md | 1 +
.../WooPaymentGatewaySetup/README.md | 1 +
plugins/woocommerce-admin/readme.txt | 1 +
.../PaymentGatewaySuggestions/Init.php | 20 --
12 files changed, 191 insertions(+), 175 deletions(-)
rename plugins/woocommerce-admin/client/task-list/tasks/payments/components/{WCPayMethodCard.js => WCPaySuggestion.js} (79%)
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/LocalPayments.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/LocalPayments.js
index ed449dfa04f..d29e94ef68b 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks/payments/LocalPayments.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/LocalPayments.js
@@ -17,7 +17,7 @@ import { useMemo, useState } from '@wordpress/element';
* Internal dependencies
*/
import { PaymentMethodList } from './components/PaymentMethodList';
-import { WCPayMethodCard } from './components/WCPayMethodCard';
+import { WCPaySuggestion } from './components/WCPaySuggestion';
import { getCountryCode } from '../../../dashboard/utils';
import { getPaymentMethods } from './methods';
import { PaymentSetup } from './components/PaymentSetup';
@@ -219,12 +219,21 @@ export const LocalPayments = ( { query } ) => {
const wcPayMethod =
wcPayIndex === -1
? null
- : additionalCardMethods.splice( wcPayIndex, 1 );
+ : additionalCardMethods.splice( wcPayIndex, 1 )[ 0 ];
return (
{ !! wcPayMethod && (
-
+
) }
{ !! enabledCardMethods.length && (
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/List/Item.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/List/Item.js
index 90c1bcb006a..c0910e33295 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/List/Item.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/List/Item.js
@@ -18,31 +18,32 @@ import './List.scss';
export const Item = ( {
isRecommended,
markConfigured,
- paymentGateways,
- suggestion,
- suggestionKeys,
+ paymentGateway,
+ gatewayIds,
} ) => {
- const { image, content, id, plugins = [], title, loading } = suggestion;
+ const {
+ image,
+ content,
+ id,
+ plugins = [],
+ title,
+ loading,
+ enabled: isEnabled = false,
+ needsSetup = false,
+ requiredSettings,
+ settingsUrl: manageUrl,
+ } = paymentGateway;
const connectSlot = useSlot(
`woocommerce_payment_gateway_connect_${ id }`
);
const setupSlot = useSlot( `woocommerce_payment_gateway_setup_${ id }` );
- const paymentGateway = paymentGateways[ id ] || {};
-
- const {
- enabled: isEnabled = false,
- needs_setup: needsSetup = false,
- required_settings_keys: requiredSettingsKeys = [],
- settings_url: manageUrl,
- } = paymentGateway;
-
const hasFills =
Boolean( connectSlot?.fills?.length ) ||
Boolean( setupSlot?.fills?.length );
const hasSetup = Boolean(
- plugins.length || requiredSettingsKeys.length || hasFills
+ plugins.length || requiredSettings.length || hasFills
);
const showRecommendedRibbon = isRecommended && needsSetup;
@@ -84,7 +85,7 @@ export const Item = ( {
markConfigured={ markConfigured }
onSetup={ () =>
recordEvent( 'tasklist_payment_setup', {
- options: suggestionKeys,
+ options: gatewayIds,
selected: id,
} )
}
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/List/List.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/List/List.js
index ff166ffa538..87a78eb7a97 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/List/List.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/List/List.js
@@ -13,23 +13,23 @@ import './List.scss';
export const List = ( {
heading,
markConfigured,
- paymentGateways,
recommendation,
- suggestions,
+ paymentGateways,
} ) => {
return (
{ heading }
- { Array.from( suggestions.values() ).map( ( suggestion ) => {
- const { id } = suggestion;
+ { paymentGateways.map( ( paymentGateway ) => {
+ const { id } = paymentGateway;
return (
- gateway.id
+ ) }
/>
);
} ) }
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/Setup/Connect.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/Setup/Connect.js
index 53f72cd7167..5bcd862079b 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/Setup/Connect.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/Setup/Connect.js
@@ -21,23 +21,17 @@ export const Connect = ( {
} ) => {
const {
id,
- connection_url: connectionUrl,
- setup_help_text: setupHelpText,
- required_settings_keys: settingKeys,
- settings,
- settings_url: settingsUrl,
+ connectionUrl,
+ setupHelpText,
+ settingsUrl,
title,
+ requiredSettings: fields,
} = paymentGateway;
const { createNotice } = useDispatch( 'core/notices' );
const { updatePaymentGateway } = useDispatch( PAYMENT_GATEWAYS_STORE_NAME );
const slot = useSlot( `woocommerce_payment_gateway_connect_${ id }` );
const hasFills = Boolean( slot?.fills?.length );
- const fields = settingKeys
- ? settingKeys
- .map( ( settingKey ) => settings[ settingKey ] )
- .filter( Boolean )
- : [];
const { isUpdating } = useSelect( ( select ) => {
const { isPaymentGatewayUpdating } = select(
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/Setup/Setup.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/Setup/Setup.js
index c7fa96669d5..5fb62478a84 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/Setup/Setup.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/components/Setup/Setup.js
@@ -14,7 +14,7 @@ import { Plugins, Stepper } from '@woocommerce/components';
import { WooPaymentGatewaySetup } from '@woocommerce/onboarding';
import { recordEvent } from '@woocommerce/tracks';
import { useEffect, useState, useMemo, useCallback } from '@wordpress/element';
-import { useSelect } from '@wordpress/data';
+import { useSelect, useDispatch } from '@wordpress/data';
import { useSlot } from '@woocommerce/experimental';
/**
@@ -26,10 +26,16 @@ import './Setup.scss';
export const Setup = ( {
markConfigured,
- suggestion,
+ paymentGateway,
recordConnectStartEvent,
} ) => {
- const { id, plugins = [], title } = suggestion;
+ const {
+ id,
+ plugins = [],
+ title,
+ postInstallScripts,
+ installed: gatewayInstalled,
+ } = paymentGateway;
const slot = useSlot( `woocommerce_payment_gateway_setup_${ id }` );
const hasFills = Boolean( slot?.fills?.length );
const [ isPluginLoaded, setIsPluginLoaded ] = useState( false );
@@ -40,16 +46,17 @@ export const Setup = ( {
} );
}, [] );
+ const { invalidateResolutionForStoreSelector } = useDispatch(
+ PAYMENT_GATEWAYS_STORE_NAME
+ );
+
const {
isOptionUpdating,
isPaymentGatewayResolving,
needsPluginInstall,
- paymentGateway,
} = useSelect( ( select ) => {
const { isOptionsUpdating } = select( OPTIONS_STORE_NAME );
- const { getPaymentGateway, isResolving } = select(
- PAYMENT_GATEWAYS_STORE_NAME
- );
+ const { isResolving } = select( PAYMENT_GATEWAYS_STORE_NAME );
const activePlugins = select( PLUGINS_STORE_NAME ).getActivePlugins();
const pluginsToInstall = plugins.filter(
( m ) => ! activePlugins.includes( m )
@@ -57,22 +64,16 @@ export const Setup = ( {
return {
isOptionUpdating: isOptionsUpdating(),
- isPaymentGatewayResolving: isResolving( 'getPaymentGateway', [
- id,
- ] ),
- paymentGateway: ! pluginsToInstall.length
- ? getPaymentGateway( id )
- : null,
+ isPaymentGatewayResolving: isResolving( 'getPaymentGateways' ),
needsPluginInstall: !! pluginsToInstall.length,
};
} );
useEffect( () => {
- if ( ! paymentGateway ) {
+ if ( needsPluginInstall ) {
return;
}
- const { post_install_scripts: postInstallScripts } = paymentGateway;
if ( postInstallScripts && postInstallScripts.length ) {
const scriptPromises = postInstallScripts.map( ( script ) =>
enqueueScript( script )
@@ -84,7 +85,7 @@ export const Setup = ( {
}
setIsPluginLoaded( true );
- }, [ paymentGateway ] );
+ }, [ postInstallScripts, needsPluginInstall ] );
const pluginNamesString = plugins
.map( ( pluginSlug ) => pluginNames[ pluginSlug ] )
@@ -103,6 +104,9 @@ export const Setup = ( {
{
createNoticesFromResponse( response );
+ invalidateResolutionForStoreSelector(
+ 'getPaymentGateways'
+ );
recordEvent(
'tasklist_payment_install_method',
{
@@ -122,22 +126,25 @@ export const Setup = ( {
: null;
}, [ needsPluginInstall ] );
- const connectStep = {
- key: 'connect',
- label: sprintf(
- __( 'Connect your %(title)s account', 'woocommerce-admin' ),
- {
- title,
- }
- ),
- content: paymentGateway ? (
-
- ) : null,
- };
+ const connectStep = useMemo(
+ () => ( {
+ key: 'connect',
+ label: sprintf(
+ __( 'Connect your %(title)s account', 'woocommerce-admin' ),
+ {
+ title,
+ }
+ ),
+ content: gatewayInstalled ? (
+
+ ) : null,
+ } ),
+ [ gatewayInstalled ]
+ );
const stepperPending =
! installStep?.isComplete ||
@@ -155,7 +162,7 @@ export const Setup = ( {
{ ...props }
/>
),
- [ stepperPending, installStep ]
+ [ stepperPending, installStep, connectStep ]
);
return (
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/index.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/index.js
index d9ef39e900f..07c4491e827 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/index.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/PaymentGatewaySuggestions/index.js
@@ -17,7 +17,7 @@ import { useMemo, useCallback } from '@wordpress/element';
*/
import { List, Placeholder as ListPlaceholder } from './components/List';
import { Setup, Placeholder as SetupPlaceholder } from './components/Setup';
-import { WCPayMethodCard } from '../components/WCPayMethodCard';
+import { WCPaySuggestion } from '../components/WCPaySuggestion';
import './plugins/Bacs';
const RECOMMENDED_GATEWAY_IDS = [
@@ -28,63 +28,65 @@ const RECOMMENDED_GATEWAY_IDS = [
export const PaymentGatewaySuggestions = ( { query } ) => {
const { updatePaymentGateway } = useDispatch( PAYMENT_GATEWAYS_STORE_NAME );
- const {
- additionalSuggestions,
- enabledSuggestions,
- getPaymentGateway,
- paymentGateways,
- suggestions,
- isResolving,
- wcPaySuggestion,
- } = useSelect( ( select ) => {
- const gateways = select( PAYMENT_GATEWAYS_STORE_NAME )
- .getPaymentGateways()
- .reduce( ( map, gateway ) => {
- map[ gateway.id ] = gateway;
- return map;
- }, {} );
-
- const enabled = new Map();
- const additional = new Map();
- let wcPay = null;
- const mappedSuggestions = select( ONBOARDING_STORE_NAME )
- .getPaymentGatewaySuggestions()
- .reduce( ( map, suggestion ) => {
- const { id } = suggestion;
- map.set( id, suggestion );
-
- // WCPay is handled separately when not installed and configured
- if (
- id === 'woocommerce_payments' &&
- ! ( gateways[ id ] && ! gateways[ id ].needs_setup )
- ) {
- wcPay = suggestion;
+ const { getPaymentGateway, paymentGateways, isResolving } = useSelect(
+ ( select ) => {
+ const installedPaymentGateways = select(
+ PAYMENT_GATEWAYS_STORE_NAME
+ )
+ .getPaymentGateways()
+ .reduce( ( map, gateway ) => {
+ map[ gateway.id ] = gateway;
return map;
- }
+ }, {} );
- if ( gateways[ id ] && gateways[ id ].enabled ) {
- enabled.set( id, suggestion );
- } else {
- additional.set( id, suggestion );
- }
+ const mappedSuggestions = select( ONBOARDING_STORE_NAME )
+ .getPaymentGatewaySuggestions()
+ .reduce( ( map, suggestion ) => {
+ const { id } = suggestion;
+ const installedGateway = installedPaymentGateways[
+ suggestion.id
+ ]
+ ? installedPaymentGateways[ id ]
+ : {};
- return map;
- }, new Map() );
+ const enrichedSuggestion = {
+ installed: !! installedPaymentGateways[ id ],
+ postInstallScripts:
+ installedGateway.post_install_scripts,
+ enabled: installedGateway.enabled,
+ needsSetup: installedGateway.needs_setup,
+ settingsUrl: installedGateway.settings_url,
+ connectionUrl: installedGateway.connection_url,
+ setupHelpText: installedGateway.setup_help_text,
+ title: installedGateway.title,
+ requiredSettings: installedGateway.required_settings_keys
+ ? installedGateway.required_settings_keys
+ .map(
+ ( settingKey ) =>
+ installedGateway.settings[
+ settingKey
+ ]
+ )
+ .filter( Boolean )
+ : [],
+ ...suggestion,
+ };
- return {
- additionalSuggestions: additional,
- enabledSuggestions: enabled,
- getPaymentGateway: select( PAYMENT_GATEWAYS_STORE_NAME )
- .getPaymentGateway,
- getOption: select( OPTIONS_STORE_NAME ).getOption,
- isResolving: select( ONBOARDING_STORE_NAME ).isResolving(
- 'getPaymentGatewaySuggestions'
- ),
- paymentGateways: gateways,
- suggestions: mappedSuggestions,
- wcPaySuggestion: wcPay,
- };
- } );
+ map.set( id, enrichedSuggestion );
+ return map;
+ }, new Map() );
+
+ return {
+ getPaymentGateway: select( PAYMENT_GATEWAYS_STORE_NAME )
+ .getPaymentGateway,
+ getOption: select( OPTIONS_STORE_NAME ).getOption,
+ isResolving: select( ONBOARDING_STORE_NAME ).isResolving(
+ 'getPaymentGatewaySuggestions'
+ ),
+ paymentGateways: mappedSuggestions,
+ };
+ }
+ );
const enablePaymentGateway = ( id ) => {
if ( ! id ) {
@@ -104,7 +106,7 @@ export const PaymentGatewaySuggestions = ( { query } ) => {
const markConfigured = useCallback(
async ( id, queryParams = {} ) => {
- if ( ! suggestions.get( id ) ) {
+ if ( ! paymentGateways.get( id ) ) {
throw `Payment gateway ${ id } not found in available gateways list`;
}
@@ -118,47 +120,72 @@ export const PaymentGatewaySuggestions = ( { query } ) => {
getNewPath( { ...queryParams, task: 'payments' }, '/', {} )
);
},
- [ paymentGateways, suggestions ]
+ [ paymentGateways ]
);
- const recordConnectStartEvent = useCallback( ( gatewayKey ) => {
+ const recordConnectStartEvent = useCallback( ( gatewayId ) => {
recordEvent( 'tasklist_payment_connect_start', {
- payment_method: gatewayKey,
+ payment_method: gatewayId,
} );
}, [] );
const recommendation = useMemo( () => {
for ( const id in RECOMMENDED_GATEWAY_IDS ) {
- const gateway = suggestions.get( id );
+ const gateway = paymentGateways.get( id );
if ( gateway ) {
return gateway;
}
}
return null;
- }, [ suggestions ] );
+ }, [ paymentGateways ] );
- const currentSuggestion = useMemo( () => {
- if ( ! query.id || isResolving || ! suggestions.size ) {
+ const currentGateway = useMemo( () => {
+ if ( ! query.id || isResolving || ! paymentGateways.size ) {
return null;
}
- const gateway = suggestions.get( query.id );
+ const gateway = paymentGateways.get( query.id );
if ( ! gateway ) {
throw `Current gateway ${ query.id } not found in available gateways list`;
}
return gateway;
- }, [ isResolving, query, suggestions ] );
+ }, [ isResolving, query, paymentGateways ] );
- if ( query.id && ! currentSuggestion ) {
+ const [ wcPayGateway, enabledGateways, additionalGateways ] = useMemo(
+ () =>
+ Array.from( paymentGateways.values() ).reduce(
+ ( all, gateway ) => {
+ const [ wcPay, enabled, additional ] = all;
+
+ // WCPay is handled separately when not installed and configured
+ if (
+ gateway.id === 'woocommerce_payments' &&
+ ! ( gateway.installed && ! gateway.needsSetup )
+ ) {
+ wcPay.push( gateway );
+ } else if ( gateway.enabled ) {
+ enabled.push( gateway );
+ } else {
+ additional.push( gateway );
+ }
+
+ return all;
+ },
+ [ [], [], [] ]
+ ),
+ [ paymentGateways ]
+ );
+
+ if ( query.id && ! currentGateway ) {
return ;
}
- if ( currentSuggestion ) {
+ if ( currentGateway ) {
return (
@@ -167,33 +194,31 @@ export const PaymentGatewaySuggestions = ( { query } ) => {
return (
- { ! suggestions.size &&
}
+ { ! paymentGateways.size &&
}
- { !! wcPaySuggestion && (
-
+ { !! wcPayGateway.length && (
+
) }
- { !! enabledSuggestions.size && (
+ { !! enabledGateways.length && (
) }
- { !! additionalSuggestions.size && (
+ { !! additionalGateways.length && (
) }
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/components/WCPayMethodCard.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/components/WCPaySuggestion.js
similarity index 79%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/components/WCPayMethodCard.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/components/WCPaySuggestion.js
index c0079f28ee4..172e0a95a23 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks/payments/components/WCPayMethodCard.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/components/WCPaySuggestion.js
@@ -4,10 +4,8 @@
import { __ } from '@wordpress/i18n';
import interpolateComponents from 'interpolate-components';
import { Link, Pill } from '@woocommerce/components';
-import { PAYMENT_GATEWAYS_STORE_NAME } from '@woocommerce/data';
import { recordEvent } from '@woocommerce/tracks';
import { Text } from '@woocommerce/experimental';
-import { useSelect } from '@wordpress/data';
import {
WCPayCard,
WCPayCardHeader,
@@ -39,14 +37,11 @@ const TosPrompt = () =>
},
} );
-export const WCPayMethodCard = ( { suggestion } ) => {
- const { description, id } = suggestion;
- const paymentGateway = useSelect( ( select ) => {
- return (
- select( PAYMENT_GATEWAYS_STORE_NAME ).getPaymentGateway( id ) || {}
- );
- } );
- const { enabled: isEnabled, needs_setup: needsSetup } = paymentGateway;
+export const WCPaySuggestion = ( {
+ paymentGateway,
+ onSetupCallback = null,
+} ) => {
+ const { description, id, needsSetup, isEnabled } = paymentGateway;
return (
@@ -64,6 +59,7 @@ export const WCPayMethodCard = ( { suggestion } ) => {
recordEvent( 'tasklist_payment_learn_more' );
} }
/>
+
<>
@@ -79,6 +75,7 @@ export const WCPayMethodCard = ( { suggestion } ) => {
'Get started',
'woocommerce-admin'
) }
+ onSetupCallback={ onSetupCallback }
/>
>
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/index.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/index.js
index 992747f62be..e8b272ff2f7 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/index.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/index.js
@@ -578,7 +578,7 @@ export function getPaymentMethods( {
),
before: (
),
diff --git a/plugins/woocommerce-admin/packages/onboarding/src/components/WooPaymentGatewayConnect/README.md b/plugins/woocommerce-admin/packages/onboarding/src/components/WooPaymentGatewayConnect/README.md
index 7a19d0b7549..e3bcc82cf55 100644
--- a/plugins/woocommerce-admin/packages/onboarding/src/components/WooPaymentGatewayConnect/README.md
+++ b/plugins/woocommerce-admin/packages/onboarding/src/components/WooPaymentGatewayConnect/README.md
@@ -22,6 +22,7 @@ This is the fill component. You must provide the `id` prop to identify the slot
| `defaultSubmit` | Function | The default submit handler that is provided to the