Add react-powered main payments settings screen (#50825)
* Fix payment store selector type * Add changelog * Add react-powered payment settings main screen * Add changelog * Update style * Revert changes * Fix enable payment gateway error * Fix wcpay install busy state * Check if Nonce exist or not * Fix extra payment methods * Fix untranslated texts * Fix lint
This commit is contained in:
parent
cc07a5f902
commit
c63bb88e0e
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: fix
|
||||||
|
|
||||||
|
Fix payment store selector type
|
|
@ -13,7 +13,7 @@ import * as resolvers from './resolvers';
|
||||||
import * as selectors from './selectors';
|
import * as selectors from './selectors';
|
||||||
import reducer from './reducer';
|
import reducer from './reducer';
|
||||||
import { STORE_KEY } from './constants';
|
import { STORE_KEY } from './constants';
|
||||||
import { WPDataActions } from '../types';
|
import { WPDataSelectors } from '../types';
|
||||||
import { PromiseifySelectors } from '../types/promiseify-selectors';
|
import { PromiseifySelectors } from '../types/promiseify-selectors';
|
||||||
|
|
||||||
export const PAYMENT_GATEWAYS_STORE_NAME = STORE_KEY;
|
export const PAYMENT_GATEWAYS_STORE_NAME = STORE_KEY;
|
||||||
|
@ -33,7 +33,7 @@ declare module '@wordpress/data' {
|
||||||
): DispatchFromMap< typeof actions >;
|
): DispatchFromMap< typeof actions >;
|
||||||
function select(
|
function select(
|
||||||
key: typeof STORE_KEY
|
key: typeof STORE_KEY
|
||||||
): SelectFromMap< typeof selectors > & WPDataActions;
|
): SelectFromMap< typeof selectors > & WPDataSelectors;
|
||||||
function resolveSelect(
|
function resolveSelect(
|
||||||
key: typeof STORE_KEY
|
key: typeof STORE_KEY
|
||||||
): PromiseifySelectors< SelectFromMap< typeof selectors > >;
|
): PromiseifySelectors< SelectFromMap< typeof selectors > >;
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import React, { useMemo } from '@wordpress/element';
|
||||||
|
import { Button } from '@wordpress/components';
|
||||||
|
import ExternalIcon from 'gridicons/dist/external';
|
||||||
|
import { __, _x } from '@wordpress/i18n';
|
||||||
|
import {
|
||||||
|
ONBOARDING_STORE_NAME,
|
||||||
|
PAYMENT_GATEWAYS_STORE_NAME,
|
||||||
|
SETTINGS_STORE_NAME,
|
||||||
|
} from '@woocommerce/data';
|
||||||
|
import { useSelect } from '@wordpress/data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { getCountryCode } from '~/dashboard/utils';
|
||||||
|
import {
|
||||||
|
getEnrichedPaymentGateways,
|
||||||
|
getIsGatewayWCPay,
|
||||||
|
getIsWCPayOrOtherCategoryDoneSetup,
|
||||||
|
getSplitGateways,
|
||||||
|
} from '~/task-lists/fills/PaymentGatewaySuggestions/utils';
|
||||||
|
|
||||||
|
type PaymentGateway = {
|
||||||
|
id: string;
|
||||||
|
image_72x72: string;
|
||||||
|
title: string;
|
||||||
|
enabled: boolean;
|
||||||
|
needsSetup: boolean;
|
||||||
|
// Add other properties as needed...
|
||||||
|
};
|
||||||
|
|
||||||
|
const usePaymentGatewayData = () => {
|
||||||
|
return useSelect( ( select ) => {
|
||||||
|
const { getSettings } = select( SETTINGS_STORE_NAME );
|
||||||
|
const { general: settings = {} } = getSettings( 'general' );
|
||||||
|
return {
|
||||||
|
getPaymentGateway: select( PAYMENT_GATEWAYS_STORE_NAME )
|
||||||
|
.getPaymentGateway,
|
||||||
|
installedPaymentGateways: select(
|
||||||
|
PAYMENT_GATEWAYS_STORE_NAME
|
||||||
|
).getPaymentGateways(),
|
||||||
|
isResolving: select( ONBOARDING_STORE_NAME ).isResolving(
|
||||||
|
'getPaymentGatewaySuggestions'
|
||||||
|
),
|
||||||
|
paymentGatewaySuggestions: select(
|
||||||
|
ONBOARDING_STORE_NAME
|
||||||
|
).getPaymentGatewaySuggestions(),
|
||||||
|
countryCode: getCountryCode( settings.woocommerce_default_country ),
|
||||||
|
};
|
||||||
|
}, [] );
|
||||||
|
};
|
||||||
|
|
||||||
|
const AdditionalGatewayImages = ( {
|
||||||
|
additionalGateways,
|
||||||
|
}: {
|
||||||
|
additionalGateways: PaymentGateway[];
|
||||||
|
} ) => (
|
||||||
|
<>
|
||||||
|
{ additionalGateways.map( ( gateway ) => (
|
||||||
|
<img
|
||||||
|
key={ gateway.id }
|
||||||
|
src={ gateway.image_72x72 }
|
||||||
|
alt={ gateway.title }
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
className="other-payment-methods__image"
|
||||||
|
/>
|
||||||
|
) ) }
|
||||||
|
{ _x( '& more.', 'More payment providers to discover', 'woocommerce' ) }
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const OtherPaymentMethods = () => {
|
||||||
|
const {
|
||||||
|
paymentGatewaySuggestions,
|
||||||
|
installedPaymentGateways,
|
||||||
|
isResolving,
|
||||||
|
countryCode,
|
||||||
|
} = usePaymentGatewayData();
|
||||||
|
|
||||||
|
const paymentGateways = useMemo(
|
||||||
|
() =>
|
||||||
|
getEnrichedPaymentGateways(
|
||||||
|
installedPaymentGateways,
|
||||||
|
paymentGatewaySuggestions
|
||||||
|
),
|
||||||
|
[ installedPaymentGateways, paymentGatewaySuggestions ]
|
||||||
|
);
|
||||||
|
|
||||||
|
const isWCPayOrOtherCategoryDoneSetup = useMemo(
|
||||||
|
() =>
|
||||||
|
getIsWCPayOrOtherCategoryDoneSetup( paymentGateways, countryCode ),
|
||||||
|
[ countryCode, paymentGateways ]
|
||||||
|
);
|
||||||
|
|
||||||
|
const isWCPaySupported = Array.from( paymentGateways.values() ).some(
|
||||||
|
getIsGatewayWCPay
|
||||||
|
);
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
|
||||||
|
const [ wcPayGateway, _offlineGateways, additionalGateways ] = useMemo(
|
||||||
|
() =>
|
||||||
|
getSplitGateways(
|
||||||
|
paymentGateways,
|
||||||
|
countryCode ?? '',
|
||||||
|
isWCPaySupported,
|
||||||
|
isWCPayOrOtherCategoryDoneSetup
|
||||||
|
),
|
||||||
|
[
|
||||||
|
paymentGateways,
|
||||||
|
countryCode,
|
||||||
|
isWCPaySupported,
|
||||||
|
isWCPayOrOtherCategoryDoneSetup,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( isResolving || ! wcPayGateway ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasWcPaySetup = wcPayGateway.enabled && ! wcPayGateway.needsSetup;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
className="is-tertiary"
|
||||||
|
href="https://woocommerce.com/product-category/woocommerce-extensions/payment-gateways/?utm_source=payments_recommendations"
|
||||||
|
target="_blank"
|
||||||
|
value="tertiary"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
<span className="other-payment-methods__button-text">
|
||||||
|
{ hasWcPaySetup
|
||||||
|
? __(
|
||||||
|
'Discover additional payment providers',
|
||||||
|
'woocommerce'
|
||||||
|
)
|
||||||
|
: __(
|
||||||
|
'Discover other payment providers',
|
||||||
|
'woocommerce'
|
||||||
|
) }
|
||||||
|
</span>
|
||||||
|
<ExternalIcon size={ 18 } />
|
||||||
|
</Button>
|
||||||
|
{ additionalGateways.length > 0 && (
|
||||||
|
<AdditionalGatewayImages
|
||||||
|
additionalGateways={ additionalGateways }
|
||||||
|
/>
|
||||||
|
) }
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,183 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { useState } from '@wordpress/element';
|
||||||
|
import { __, sprintf } from '@wordpress/i18n';
|
||||||
|
import { PaymentGateway } from '@woocommerce/data';
|
||||||
|
import { WooPaymentMethodsLogos } from '@woocommerce/onboarding';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { getAdminSetting } from '~/utils/admin-settings';
|
||||||
|
import sanitizeHTML from '~/lib/sanitize-html';
|
||||||
|
import { WCPayInstallButton } from './wcpay-install-button';
|
||||||
|
|
||||||
|
export const PaymentMethod = ( {
|
||||||
|
id,
|
||||||
|
enabled,
|
||||||
|
title,
|
||||||
|
method_title,
|
||||||
|
method_description,
|
||||||
|
settings_url,
|
||||||
|
}: PaymentGateway ) => {
|
||||||
|
const isWooPayEligible = getAdminSetting( 'isWooPayEligible', false );
|
||||||
|
const [ isEnabled, setIsEnabled ] = useState( enabled );
|
||||||
|
const [ isLoading, setIsLoading ] = useState( false );
|
||||||
|
|
||||||
|
const toggleEnabled = async ( e: React.MouseEvent ) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setIsLoading( true );
|
||||||
|
|
||||||
|
if ( ! window.woocommerce_admin.nonces?.gateway_toggle ) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn( 'Unexpected error: Nonce not found' );
|
||||||
|
// Redirect to payment setting page if nonce is not found. Users should still be able to toggle the payment method from that page.
|
||||||
|
window.location.href = settings_url;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch( window.woocommerce_admin.ajax_url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
body: new URLSearchParams( {
|
||||||
|
action: 'woocommerce_toggle_gateway_enabled',
|
||||||
|
security: window.woocommerce_admin.nonces?.gateway_toggle,
|
||||||
|
gateway_id: id,
|
||||||
|
} ),
|
||||||
|
} );
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if ( result.success ) {
|
||||||
|
if ( result.data === true ) {
|
||||||
|
setIsEnabled( true );
|
||||||
|
} else if ( result.data === false ) {
|
||||||
|
setIsEnabled( false );
|
||||||
|
} else if ( result.data === 'needs_setup' ) {
|
||||||
|
window.location.href = settings_url;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
window.location.href = settings_url;
|
||||||
|
}
|
||||||
|
} catch ( error ) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error( 'Error toggling gateway:', error );
|
||||||
|
} finally {
|
||||||
|
setIsLoading( false );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr data-gateway_id={ id }>
|
||||||
|
<td className="sort ui-sortable-handle" width="1%"></td>
|
||||||
|
<td className="name" width="">
|
||||||
|
<div className="wc-payment-gateway-method__name">
|
||||||
|
<a
|
||||||
|
href={ settings_url }
|
||||||
|
className="wc-payment-gateway-method-title"
|
||||||
|
>
|
||||||
|
{ method_title }
|
||||||
|
</a>
|
||||||
|
{ id !== 'pre_install_woocommerce_payments_promotion' &&
|
||||||
|
method_title !== title && (
|
||||||
|
<span className="wc-payment-gateway-method-name">
|
||||||
|
–
|
||||||
|
{ title }
|
||||||
|
</span>
|
||||||
|
) }
|
||||||
|
{ id === 'pre_install_woocommerce_payments_promotion' && (
|
||||||
|
<div className="pre-install-payment-gateway__subtitle">
|
||||||
|
<WooPaymentMethodsLogos
|
||||||
|
isWooPayEligible={ isWooPayEligible }
|
||||||
|
maxElements={ 5 }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) }
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className="status" width="1%">
|
||||||
|
<a
|
||||||
|
className="wc-payment-gateway-method-toggle-enabled"
|
||||||
|
href={ settings_url }
|
||||||
|
onClick={ toggleEnabled }
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className={ `woocommerce-input-toggle ${
|
||||||
|
isEnabled
|
||||||
|
? 'woocommerce-input-toggle--enabled'
|
||||||
|
: 'woocommerce-input-toggle--disabled'
|
||||||
|
} ${
|
||||||
|
isLoading ? 'woocommerce-input-toggle--loading' : ''
|
||||||
|
}` }
|
||||||
|
/* translators: %s: payment method title */
|
||||||
|
aria-label={
|
||||||
|
isEnabled
|
||||||
|
? sprintf(
|
||||||
|
/* translators: %s: payment method title */
|
||||||
|
__(
|
||||||
|
'The "%s" payment method is currently enabled',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
method_title
|
||||||
|
)
|
||||||
|
: sprintf(
|
||||||
|
/* translators: %s: payment method title */
|
||||||
|
__(
|
||||||
|
'The "%s" payment method is currently disabled',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
method_title
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{ isEnabled
|
||||||
|
? __( 'Yes', 'woocommerce' )
|
||||||
|
: __( 'No', 'woocommerce' ) }
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="description"
|
||||||
|
width=""
|
||||||
|
dangerouslySetInnerHTML={ sanitizeHTML( method_description ) }
|
||||||
|
/>
|
||||||
|
<td className="action" width="1%">
|
||||||
|
{ id === 'pre_install_woocommerce_payments_promotion' ? (
|
||||||
|
<WCPayInstallButton />
|
||||||
|
) : (
|
||||||
|
<a
|
||||||
|
className="button alignright"
|
||||||
|
aria-label={
|
||||||
|
enabled
|
||||||
|
? sprintf(
|
||||||
|
/* translators: %s: payment method title */
|
||||||
|
__(
|
||||||
|
'Manage the "%s" payment method',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
method_title
|
||||||
|
)
|
||||||
|
: sprintf(
|
||||||
|
/* translators: %s: payment method title */
|
||||||
|
__(
|
||||||
|
'Set up the "%s" payment method',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
method_title
|
||||||
|
)
|
||||||
|
}
|
||||||
|
href={ settings_url }
|
||||||
|
>
|
||||||
|
{ enabled
|
||||||
|
? __( 'Manage', 'woocommerce' )
|
||||||
|
: __( 'Finish setup', 'woocommerce' ) }
|
||||||
|
</a>
|
||||||
|
) }
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,60 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import React, { useState } from '@wordpress/element';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import {
|
||||||
|
PAYMENT_GATEWAYS_STORE_NAME,
|
||||||
|
PLUGINS_STORE_NAME,
|
||||||
|
} from '@woocommerce/data';
|
||||||
|
import { Button } from '@wordpress/components';
|
||||||
|
import { resolveSelect, useDispatch } from '@wordpress/data';
|
||||||
|
import { recordEvent } from '@woocommerce/tracks';
|
||||||
|
|
||||||
|
const slug = 'woocommerce-payments';
|
||||||
|
export const WCPayInstallButton = () => {
|
||||||
|
const [ installing, setInstalling ] = useState( false );
|
||||||
|
const { installAndActivatePlugins } = useDispatch( PLUGINS_STORE_NAME );
|
||||||
|
const { createNotice } = useDispatch( 'core/notices' );
|
||||||
|
|
||||||
|
const redirectToSettings = async () => {
|
||||||
|
const paymentGateway = await resolveSelect(
|
||||||
|
PAYMENT_GATEWAYS_STORE_NAME
|
||||||
|
).getPaymentGateway( slug.replace( /-/g, '_' ) );
|
||||||
|
|
||||||
|
if ( paymentGateway?.settings_url ) {
|
||||||
|
window.location.href = paymentGateway.settings_url;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const installWooCommercePayments = async () => {
|
||||||
|
if ( installing ) return;
|
||||||
|
|
||||||
|
setInstalling( true );
|
||||||
|
recordEvent( 'settings_payments_recommendations_setup', {
|
||||||
|
extension_selected: slug,
|
||||||
|
} );
|
||||||
|
|
||||||
|
try {
|
||||||
|
await installAndActivatePlugins( [ slug ] );
|
||||||
|
redirectToSettings();
|
||||||
|
} catch ( error ) {
|
||||||
|
if ( error instanceof Error ) {
|
||||||
|
createNotice( 'error', error.message );
|
||||||
|
}
|
||||||
|
setInstalling( false );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className="button alignright"
|
||||||
|
onClick={ installWooCommercePayments }
|
||||||
|
variant="secondary"
|
||||||
|
isBusy={ installing }
|
||||||
|
aria-disabled={ installing }
|
||||||
|
>
|
||||||
|
{ __( 'Install', 'woocommerce' ) }
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
|
@ -1,9 +1,29 @@
|
||||||
|
@import "~/wp-admin-scripts/payment-method-promotions/payment-promotion-row.scss";
|
||||||
|
|
||||||
.settings-payments-main__container {
|
.settings-payments-main__container {
|
||||||
h1 {
|
.settings-payments-main__spinner {
|
||||||
color: #fff;
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
table.wc_gateways {
|
||||||
|
.other-payment-methods__button-text {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.other-payment-methods-row {
|
||||||
|
border-top: 1px solid #c3c4c7;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.other-payment-methods__image {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
background: #000;
|
|
||||||
text-align: center;
|
|
||||||
padding: 50px 0;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,108 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import '@wordpress/element';
|
import { useMemo } from '@wordpress/element';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { PaymentGateway } from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import './settings-payments-main.scss';
|
import './settings-payments-main.scss';
|
||||||
|
import { PaymentMethod } from './components/payment-method';
|
||||||
|
import { OtherPaymentMethods } from './components/other-payment-methods';
|
||||||
|
import { PaymentsBannerWrapper } from '~/payments/payment-settings-banner';
|
||||||
|
|
||||||
export const SettingsPaymentsMain: React.FC = () => {
|
export const SettingsPaymentsMain: React.FC = () => {
|
||||||
|
const [ paymentGateways, error ] = useMemo( () => {
|
||||||
|
const script = document.getElementById(
|
||||||
|
'experimental_wc_settings_payments_gateways'
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ( script && script.textContent ) {
|
||||||
|
return [
|
||||||
|
JSON.parse( script.textContent ) as PaymentGateway[],
|
||||||
|
null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
throw new Error( 'Could not find payment gateways data' );
|
||||||
|
} catch ( e ) {
|
||||||
|
return [ [], e as Error ];
|
||||||
|
}
|
||||||
|
}, [] );
|
||||||
|
|
||||||
|
if ( error ) {
|
||||||
|
// This is a temporary error message to be replaced by error boundary.
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>
|
||||||
|
{ __( 'Error loading payment gateways', 'woocommerce' ) }
|
||||||
|
</h1>
|
||||||
|
<p>{ error.message }</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="settings-payments-main__container">
|
<div className="settings-payments-main__container">
|
||||||
<h1>Main payments screen</h1>
|
<div id="wc_payments_settings_slotfill">
|
||||||
|
<PaymentsBannerWrapper />
|
||||||
|
</div>
|
||||||
|
<table className="form-table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
className="wc_payment_gateways_wrapper"
|
||||||
|
colSpan={ 2 }
|
||||||
|
>
|
||||||
|
<table
|
||||||
|
className="wc_gateways widefat"
|
||||||
|
cellSpacing="0"
|
||||||
|
aria-describedby="payment_gateways_options-description"
|
||||||
|
>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="sort"></th>
|
||||||
|
<th className="name">
|
||||||
|
{ __( 'Method', 'woocommerce' ) }
|
||||||
|
</th>
|
||||||
|
<th className="status">
|
||||||
|
{ __( 'Enabled', 'woocommerce' ) }
|
||||||
|
</th>
|
||||||
|
<th className="description">
|
||||||
|
{ __(
|
||||||
|
'Description',
|
||||||
|
'woocommerce'
|
||||||
|
) }
|
||||||
|
</th>
|
||||||
|
<th className="action"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="ui-sortable">
|
||||||
|
{ paymentGateways.map(
|
||||||
|
( gateway: PaymentGateway ) => (
|
||||||
|
<PaymentMethod
|
||||||
|
key={ gateway.id }
|
||||||
|
{ ...gateway }
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
) }
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
className="other-payment-methods-row"
|
||||||
|
colSpan={ 5 }
|
||||||
|
>
|
||||||
|
<OtherPaymentMethods />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -88,6 +88,12 @@ declare global {
|
||||||
getUserSetting?: ( name: string ) => string | undefined;
|
getUserSetting?: ( name: string ) => string | undefined;
|
||||||
setUserSetting?: ( name: string, value: string ) => void;
|
setUserSetting?: ( name: string, value: string ) => void;
|
||||||
deleteUserSetting?: ( name: string ) => void;
|
deleteUserSetting?: ( name: string ) => void;
|
||||||
|
woocommerce_admin: {
|
||||||
|
ajax_url: string;
|
||||||
|
nonces: {
|
||||||
|
gateway_toggle?: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: add
|
||||||
|
|
||||||
|
Add react-powered main payments settings screen
|
|
@ -57,6 +57,16 @@ class WC_Settings_Payment_Gateways_React extends WC_Settings_Page {
|
||||||
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||||
global $current_section;
|
global $current_section;
|
||||||
|
|
||||||
|
// We don't want to output anything from the action for now. So we buffer it and discard it.
|
||||||
|
ob_start();
|
||||||
|
/**
|
||||||
|
* Fires before the payment gateways settings fields are rendered.
|
||||||
|
*
|
||||||
|
* @since 1.5.7
|
||||||
|
*/
|
||||||
|
do_action( 'woocommerce_admin_field_payment_gateways' );
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
// Load gateways so we can show any global options they may have.
|
// Load gateways so we can show any global options they may have.
|
||||||
$payment_gateways = WC()->payment_gateways->payment_gateways();
|
$payment_gateways = WC()->payment_gateways->payment_gateways();
|
||||||
|
|
||||||
|
@ -91,6 +101,11 @@ class WC_Settings_Payment_Gateways_React extends WC_Settings_Page {
|
||||||
global $hide_save_button;
|
global $hide_save_button;
|
||||||
$hide_save_button = true;
|
$hide_save_button = true;
|
||||||
echo '<div id="experimental_wc_settings_payments_' . esc_attr( $section ) . '"></div>';
|
echo '<div id="experimental_wc_settings_payments_' . esc_attr( $section ) . '"></div>';
|
||||||
|
|
||||||
|
// Output the gateways data to the page so the React app can use it.
|
||||||
|
$controller = new WC_REST_Payment_Gateways_Controller();
|
||||||
|
$response = $controller->get_items( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways' ) );
|
||||||
|
echo '<script type="application/json" id="experimental_wc_settings_payments_gateways">' . wp_json_encode( $response->data ) . '</script>';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue