Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Settings UI: Add feature status to REST data, implement refresh button logic (3931) #2925

Merged
merged 3 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions modules/ppcp-applepay/src/ApplepayModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,26 @@ function( array $locations, string $setting_name ): array {
2
);

add_filter(
'woocommerce_paypal_payments_rest_common_merchant_data',
function( array $merchant_data ) use ( $c ): array {
if ( ! isset( $merchant_data['features'] ) ) {
$merchant_data['features'] = array();
}

$product_status = $c->get( 'applepay.apple-product-status' );
assert( $product_status instanceof AppleProductStatus );

$apple_pay_enabled = $product_status->is_active();

$merchant_data['features']['apple_pay'] = array(
'enabled' => $apple_pay_enabled,
);

return $merchant_data;
}
);

return true;
}

Expand Down
20 changes: 20 additions & 0 deletions modules/ppcp-googlepay/src/GooglepayModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,26 @@ function( array $locations, string $setting_name ): array {
2
);

add_filter(
'woocommerce_paypal_payments_rest_common_merchant_data',
function ( array $merchant_data ) use ( $c ): array {
if ( ! isset( $merchant_data['features'] ) ) {
$merchant_data['features'] = array();
}

$product_status = $c->get( 'googlepay.helpers.apm-product-status' );
assert( $product_status instanceof ApmProductStatus );

$google_pay_enabled = $product_status->is_active();

$merchant_data['features']['google_pay'] = array(
'enabled' => $google_pay_enabled,
);

return $merchant_data;
}
);

return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,56 @@ const FeatureSettingsBlock = ( { title, description, ...props } ) => {
}

return (
<span className="ppcp-r-feature-item__notes">
{ notes.map( ( note, index ) => (
<span key={ index }>{ note }</span>
) ) }
</span>
<>
<span className="ppcp-r-feature-item__notes">
{ notes.map( ( note, index ) => (
<span key={ index }>{ note }</span>
) ) }
</span>
</>
);
};

return (
<SettingsBlock { ...props } className="ppcp-r-settings-block__feature">
<Header>
<Title>
{ title }
{ props.actionProps?.featureStatus && (
<TitleBadge { ...props.actionProps?.badge } />
) }
</Title>
<Description className="ppcp-r-settings-block__feature__description">
{ description }
{ printNotes() }
</Description>
</Header>
<Action>
<div className="ppcp-r-feature-item__buttons">
{ props.actionProps?.buttons.map( ( button ) => (
<Button
href={ button.url }
key={ button.text }
variant={ button.type }
>
{ button.text }
</Button>
) ) }
</div>
</Action>
</SettingsBlock>
<SettingsBlock
{ ...props }
className="ppcp-r-settings-block__feature"
components={ [
() => (
<>
<Header>
<Title>
{ title }
{ props.actionProps?.enabled && (
<TitleBadge
{ ...props.actionProps?.badge }
/>
) }
</Title>
<Description className="ppcp-r-settings-block__feature__description">
{ description }
{ printNotes() }
</Description>
</Header>
<Action>
<div className="ppcp-r-feature-item__buttons">
{ props.actionProps?.buttons.map(
( button ) => (
<Button
href={ button.url }
key={ button.text }
variant={ button.type }
>
{ button.text }
</Button>
)
) }
</div>
</Action>
</>
),
] }
/>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,42 @@ import TodoSettingsBlock from '../../ReusableComponents/SettingsBlocks/TodoSetti
import FeatureSettingsBlock from '../../ReusableComponents/SettingsBlocks/FeatureSettingsBlock';
import { TITLE_BADGE_POSITIVE } from '../../ReusableComponents/TitleBadge';
import data from '../../../utils/data';
import { useMerchantInfo } from '../../../data/common/hooks';
import { useDispatch } from '@wordpress/data';
import { STORE_NAME } from '../../../data/common';

const TabOverview = () => {
const [ todos, setTodos ] = useState( [] );
const [ todosData, setTodosData ] = useState( todosDataDefault );
const [ isRefreshing, setIsRefreshing ] = useState( false );

const { merchant } = useMerchantInfo();
const { refreshFeatureStatuses } = useDispatch( STORE_NAME );

const features = featuresDefault.map( ( feature ) => {
const merchantFeature = merchant?.features?.[ feature.id ];
return {
...feature,
enabled: merchantFeature?.enabled ?? false,
};
} );

const refreshHandler = async () => {
setIsRefreshing( true );

const result = await refreshFeatureStatuses();

if ( result && ! result.success ) {
console.error(
'Failed to refresh features:',
result.message || 'Unknown error'
);
} else {
console.log( 'Features refreshed successfully.' );
}

setIsRefreshing( false );
};

return (
<div className="ppcp-r-tab-overview">
Expand Down Expand Up @@ -39,30 +71,54 @@ const TabOverview = () => {
title={ __( 'Features', 'woocommerce-paypal-payments' ) }
description={
<div>
<p>{ __( 'Enable additional features…' ) }</p>
<p>{ __( 'Click Refresh…' ) }</p>
<Button variant="tertiary">
<p>
{ __(
'Enable additional features…',
'woocommerce-paypal-payments'
) }
</p>
<p>
{ __(
'Click Refresh…',
'woocommerce-paypal-payments'
) }
</p>
<Button
variant="tertiary"
onClick={ refreshHandler }
disabled={ isRefreshing }
>
{ data().getImage( 'icon-refresh.svg' ) }
{ __( 'Refresh', 'woocommerce-paypal-payments' ) }
{ isRefreshing
? __(
'Refreshing…',
'woocommerce-paypal-payments'
)
: __(
'Refresh',
'woocommerce-paypal-payments'
) }
</Button>
</div>
}
contentItems={ featuresDefault.map( ( feature ) => (
contentItems={ features.map( ( feature ) => (
<FeatureSettingsBlock
key={ feature.id }
title={ feature.title }
description={ feature.description }
actionProps={ {
buttons: feature.buttons,
featureStatus: feature.featureStatus,
enabled: feature.enabled,
notes: feature.notes,
badge: {
text: __(
'Active',
'woocommerce-paypal-payments'
),
type: TITLE_BADGE_POSITIVE,
},
badge: feature.enabled
? {
text: __(
'Active',
'woocommerce-paypal-payments'
),
type: TITLE_BADGE_POSITIVE,
}
: undefined,
} }
/>
) ) }
Expand Down Expand Up @@ -133,7 +189,6 @@ const featuresDefault = [
'Advanced Credit and Debit Cards',
'woocommerce-paypal-payments'
),
featureStatus: true,
description: __(
'Process major credit and debit cards including Visa, Mastercard, American Express and Discover.',
'woocommerce-paypal-payments'
Expand Down Expand Up @@ -181,7 +236,6 @@ const featuresDefault = [
'Let customers pay using their Google Pay wallet.',
'woocommerce-paypal-payments'
),
featureStatus: true,
buttons: [
{
type: 'secondary',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ export default {
DO_SANDBOX_LOGIN: 'COMMON:DO_SANDBOX_LOGIN',
DO_PRODUCTION_LOGIN: 'COMMON:DO_PRODUCTION_LOGIN',
DO_REFRESH_MERCHANT: 'COMMON:DO_REFRESH_MERCHANT',
DO_REFRESH_FEATURES: 'DO_REFRESH_FEATURES',
};
19 changes: 18 additions & 1 deletion modules/ppcp-settings/resources/js/data/common/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @file
*/

import { select } from '@wordpress/data';
import { dispatch, select } from '@wordpress/data';

import ACTION_TYPES from './action-types';
import { STORE_NAME } from './constants';
Expand Down Expand Up @@ -189,3 +189,20 @@ export const connectViaIdAndSecret = function* () {
export const refreshMerchantData = function* () {
return yield { type: ACTION_TYPES.DO_REFRESH_MERCHANT };
};

/**
* Side effect.
* Purges all feature status data via a REST request.
* Refreshes the merchant data via a REST request.
*
* @return {Action} The action.
*/
export const refreshFeatureStatuses = function* () {
const result = yield { type: ACTION_TYPES.DO_REFRESH_FEATURES };

if ( result && result.success ) {
return yield dispatch( STORE_NAME ).refreshMerchantData();
}

return result;
};
11 changes: 11 additions & 0 deletions modules/ppcp-settings/resources/js/data/common/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,14 @@ export const REST_MANUAL_CONNECTION_PATH = '/wc/v3/wc_paypal/connect_manual';
* @type {string}
*/
export const REST_CONNECTION_URL_PATH = '/wc/v3/wc_paypal/login_link';

/**
* REST path to refresh the feature status.
*
* Used by: Controls
* See: RefreshFeatureStatusEndpoint.php
*
* @type {string}
*/
export const REST_REFRESH_FEATURES_PATH =
'/wc/v3/wc_paypal/refresh-feature-status';
24 changes: 24 additions & 0 deletions modules/ppcp-settings/resources/js/data/common/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
REST_MANUAL_CONNECTION_PATH,
REST_CONNECTION_URL_PATH,
REST_HYDRATE_MERCHANT_PATH,
REST_REFRESH_FEATURES_PATH,
} from './constants';
import ACTION_TYPES from './action-types';

Expand Down Expand Up @@ -121,4 +122,27 @@ export const controls = {

return result;
},

async [ ACTION_TYPES.DO_REFRESH_FEATURES ]() {
let result = null;

try {
result = await apiFetch( {
path: REST_REFRESH_FEATURES_PATH,
method: 'POST',
} );

if ( result.success ) {
result = await dispatch( STORE_NAME ).refreshMerchantData();
}
} catch ( e ) {
result = {
success: false,
error: e,
message: e.message,
};
}

return result;
},
};
8 changes: 8 additions & 0 deletions modules/ppcp-settings/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use WooCommerce\PayPalCommerce\Settings\Endpoint\ConnectManualRestEndpoint;
use WooCommerce\PayPalCommerce\Settings\Endpoint\LoginLinkRestEndpoint;
use WooCommerce\PayPalCommerce\Settings\Endpoint\OnboardingRestEndpoint;
use WooCommerce\PayPalCommerce\Settings\Endpoint\RefreshFeatureStatusEndpoint;
use WooCommerce\PayPalCommerce\Settings\Endpoint\SwitchSettingsUiEndpoint;
use WooCommerce\PayPalCommerce\Settings\Service\ConnectionUrlGenerator;
use WooCommerce\PayPalCommerce\Settings\Service\OnboardingUrlManager;
Expand Down Expand Up @@ -70,6 +71,13 @@
'settings.rest.common' => static function ( ContainerInterface $container ) : CommonRestEndpoint {
return new CommonRestEndpoint( $container->get( 'settings.data.common' ) );
},
'settings.rest.refresh_feature_status' => static function ( ContainerInterface $container ) : RefreshFeatureStatusEndpoint {
return new RefreshFeatureStatusEndpoint(
$container->get( 'wcgateway.settings' ),
new Cache( 'ppcp-timeout' ),
$container->get( 'woocommerce.logger.woocommerce' )
);
},
'settings.rest.connect_manual' => static function ( ContainerInterface $container ) : ConnectManualRestEndpoint {
return new ConnectManualRestEndpoint(
$container->get( 'api.paypal-host-production' ),
Expand Down
5 changes: 5 additions & 0 deletions modules/ppcp-settings/src/Endpoint/CommonRestEndpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,11 @@ protected function add_merchant_info( array $extra_data ) : array {
$this->merchant_info_map
);

$extra_data['merchant'] = apply_filters(
'woocommerce_paypal_payments_rest_common_merchant_data',
$extra_data['merchant'],
);

return $extra_data;
}

Expand Down
Loading
Loading