Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Update the sidebar notice we show for incompatible extensions #10877

Merged
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
16 changes: 8 additions & 8 deletions assets/js/blocks/cart-checkout-shared/sidebar-notices/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { CartCheckoutSidebarCompatibilityNotice } from '@woocommerce/editor-comp
import { NoPaymentMethodsNotice } from '@woocommerce/editor-components/no-payment-methods-notice';
import { PAYMENT_STORE_KEY } from '@woocommerce/block-data';
import { DefaultNotice } from '@woocommerce/editor-components/default-notice';
import { IncompatiblePaymentGatewaysNotice } from '@woocommerce/editor-components/incompatible-payment-gateways-notice';
import { IncompatibleExtensionsNotice } from '@woocommerce/editor-components/incompatible-extension-notice';
import { useSelect } from '@wordpress/data';
import { CartCheckoutFeedbackPrompt } from '@woocommerce/editor-components/feedback-prompt';
import { useState } from '@wordpress/element';
Expand All @@ -38,14 +38,14 @@ const withSidebarNotices = createHigherOrderComponent(
} = props;

const [
isIncompatiblePaymentGatewaysNoticeDismissed,
setIsIncompatiblePaymentGatewaysNoticeDismissed,
isIncompatibleExtensionsNoticeDismissed,
setIsIncompatibleExtensionsNoticeDismissed,
] = useState( true );

const toggleIncompatiblePaymentGatewaysNoticeDismissedStatus = (
const toggleIncompatibleExtensionsNoticeDismissedStatus = (
isDismissed: boolean
) => {
setIsIncompatiblePaymentGatewaysNoticeDismissed( isDismissed );
setIsIncompatibleExtensionsNoticeDismissed( isDismissed );
};

const { isCart, isCheckout, isPaymentMethodsBlock, hasPaymentMethods } =
Expand Down Expand Up @@ -91,9 +91,9 @@ const withSidebarNotices = createHigherOrderComponent(
return (
<>
<InspectorControls>
<IncompatiblePaymentGatewaysNotice
<IncompatibleExtensionsNotice
toggleDismissedStatus={
toggleIncompatiblePaymentGatewaysNoticeDismissedStatus
toggleIncompatibleExtensionsNoticeDismissedStatus
}
block={
isCheckout
Expand All @@ -104,7 +104,7 @@ const withSidebarNotices = createHigherOrderComponent(

<DefaultNotice block={ isCheckout ? 'checkout' : 'cart' } />

{ isIncompatiblePaymentGatewaysNoticeDismissed ? (
{ isIncompatibleExtensionsNoticeDismissed ? (
<CartCheckoutSidebarCompatibilityNotice
block={ isCheckout ? 'checkout' : 'cart' }
/>
Expand Down
6 changes: 3 additions & 3 deletions assets/js/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import '@wordpress/notices';
/**
* Internal dependencies
*/
export { SCHEMA_STORE_KEY } from './schema';
export { COLLECTIONS_STORE_KEY } from './collections';
export { CART_STORE_KEY } from './cart';
export { CHECKOUT_STORE_KEY } from './checkout';
export { COLLECTIONS_STORE_KEY } from './collections';
export { PAYMENT_STORE_KEY } from './payment';
export { VALIDATION_STORE_KEY } from './validation';
export { QUERY_STATE_STORE_KEY } from './query-state';
export { SCHEMA_STORE_KEY } from './schema';
export { STORE_NOTICES_STORE_KEY } from './store-notices';
export { VALIDATION_STORE_KEY } from './validation';
export * from './constants';
export * from './utils';
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,24 @@ import { Icon } from '@wordpress/icons';
/**
* Internal dependencies
*/
import { useIncompatiblePaymentGatewaysNotice } from './use-incompatible-payment-gateways-notice';
import { useCombinedIncompatibilityNotice } from './use-combined-incompatibility-notice';
import './editor.scss';

interface PaymentGatewaysNoticeProps {
interface ExtensionNoticeProps {
toggleDismissedStatus: ( status: boolean ) => void;
block: 'woocommerce/cart' | 'woocommerce/checkout';
}

export function IncompatiblePaymentGatewaysNotice( {
export function IncompatibleExtensionsNotice( {
toggleDismissedStatus,
block,
}: PaymentGatewaysNoticeProps ) {
}: ExtensionNoticeProps ) {
const [
isVisible,
dismissNotice,
incompatiblePaymentMethods,
numberOfIncompatiblePaymentMethods,
] = useIncompatiblePaymentGatewaysNotice( block );
] = useCombinedIncompatibilityNotice( block );

useEffect( () => {
toggleDismissedStatus( ! isVisible );
Expand All @@ -38,8 +38,8 @@ export function IncompatiblePaymentGatewaysNotice( {

const noticeContent = createInterpolateElement(
_n(
'The following extension is incompatible with the block-based checkout. <a>Learn more</a>',
'The following extensions are incompatible with the block-based checkout. <a>Learn more</a>',
'The following extension might be incompatible with the block-based checkout. <a>Learn more</a>',
'The following extensions might be incompatible with the block-based checkout. <a>Learn more</a>',
numberOfIncompatiblePaymentMethods,
'woo-gutenberg-products-block'
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/**
* External dependencies
*/
import { useSelect } from '@wordpress/data';
import { useEffect, useState } from '@wordpress/element';
import { useState, useEffect } from '@wordpress/element';
import { useLocalStorageState } from '@woocommerce/base-hooks';

/**
* Internal dependencies
*/
import { STORE_KEY as PAYMENT_STORE_KEY } from '../../data/payment/constants';
import { useIncompatiblePaymentGatewaysNotice } from './use-incompatible-payment-gateways-notice';
import { useIncompatibleExtensionNotice } from './use-incompatible-extensions-notice';

type StoredIncompatibleGateway = { [ k: string ]: string[] };
type StoredIncompatibleExtension = { [ k: string ]: string[] };
const initialDismissedNotices: React.SetStateAction<
StoredIncompatibleGateway[]
StoredIncompatibleExtension[]
> = [];

const areEqual = ( array1: string[], array2: string[] ) => {
Expand All @@ -25,44 +25,68 @@ const areEqual = ( array1: string[], array2: string[] ) => {
return uniqueCollectionValues.size === array1.length;
};

export const useIncompatiblePaymentGatewaysNotice = (
const sortAlphabetically = ( obj: {
[ key: string ]: string;
} ): { [ key: string ]: string } =>
Object.fromEntries(
Object.entries( obj ).sort( ( [ , a ], [ , b ] ) =>
a.localeCompare( b )
)
);

export const useCombinedIncompatibilityNotice = (
blockName: string
): [ boolean, () => void, { [ k: string ]: string }, number ] => {
const [
incompatibleExtensions,
incompatibleExtensionSlugs,
incompatibleExtensionCount,
] = useIncompatibleExtensionNotice();

const [
incompatiblePaymentMethods,
incompatiblePaymentMethodSlugs,
incompatiblePaymentMethodCount,
] = useIncompatiblePaymentGatewaysNotice();

const allIncompatibleItems = {
...incompatibleExtensions,
...incompatiblePaymentMethods,
};

const allIncompatibleItemSlugs = [
...incompatibleExtensionSlugs,
...incompatiblePaymentMethodSlugs,
];

const allIncompatibleItemCount =
incompatibleExtensionCount + incompatiblePaymentMethodCount;

const [ dismissedNotices, setDismissedNotices ] = useLocalStorageState<
StoredIncompatibleGateway[]
StoredIncompatibleExtension[]
>(
`wc-blocks_dismissed_incompatible_payment_gateways_notices`,
`wc-blocks_dismissed_incompatible_extensions_notices`,
initialDismissedNotices
);
const [ isVisible, setIsVisible ] = useState( false );

const { incompatiblePaymentMethods } = useSelect( ( select ) => {
const { getIncompatiblePaymentMethods } = select( PAYMENT_STORE_KEY );
return {
incompatiblePaymentMethods: getIncompatiblePaymentMethods(),
};
}, [] );
const incompatiblePaymentMethodsIDs = Object.keys(
incompatiblePaymentMethods
);
const numberOfIncompatiblePaymentMethods =
incompatiblePaymentMethodsIDs.length;
const [ isVisible, setIsVisible ] = useState( false );

const isDismissedNoticeUpToDate = dismissedNotices.some(
( notice ) =>
Object.keys( notice ).includes( blockName ) &&
areEqual(
notice[ blockName as keyof object ],
incompatiblePaymentMethodsIDs
allIncompatibleItemSlugs
)
);

const shouldBeDismissed =
numberOfIncompatiblePaymentMethods === 0 || isDismissedNoticeUpToDate;
allIncompatibleItemCount === 0 || isDismissedNoticeUpToDate;

const dismissNotice = () => {
const dismissedNoticesSet = new Set( dismissedNotices );
dismissedNoticesSet.add( {
[ blockName ]: incompatiblePaymentMethodsIDs,
[ blockName ]: allIncompatibleItemSlugs,
} );
setDismissedNotices( [ ...dismissedNoticesSet ] );
};
Expand All @@ -75,7 +99,7 @@ export const useIncompatiblePaymentGatewaysNotice = (
if ( ! shouldBeDismissed && ! isDismissedNoticeUpToDate ) {
setDismissedNotices( ( previousDismissedNotices ) =>
previousDismissedNotices.reduce(
( acc: StoredIncompatibleGateway[], curr ) => {
( acc: StoredIncompatibleExtension[], curr ) => {
if ( Object.keys( curr ).includes( blockName ) ) {
return acc;
}
Expand All @@ -97,7 +121,7 @@ export const useIncompatiblePaymentGatewaysNotice = (
return [
isVisible,
dismissNotice,
incompatiblePaymentMethods,
numberOfIncompatiblePaymentMethods,
sortAlphabetically( allIncompatibleItems ),
allIncompatibleItemCount,
];
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* External dependencies
*/
import { getSetting } from '@woocommerce/settings';

export const useIncompatibleExtensionNotice = (): [
{ [ k: string ]: string } | null,
string[],
number
] => {
interface GlobalIncompatibleExtensions {
id: string;
title: string;
}

const incompatibleExtensions: Record< string, string > = {};

if ( getSetting( 'incompatibleExtensions' ) ) {
getSetting< GlobalIncompatibleExtensions[] >(
'incompatibleExtensions'
).forEach( ( extension ) => {
incompatibleExtensions[ extension.id ] = extension.title;
} );
}

const incompatibleExtensionSlugs = Object.keys( incompatibleExtensions );
const incompatibleExtensionCount = incompatibleExtensionSlugs.length;

return [
incompatibleExtensions,
incompatibleExtensionSlugs,
incompatibleExtensionCount,
];
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* External dependencies
*/
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import { STORE_KEY as PAYMENT_STORE_KEY } from '../../data/payment/constants';

export const useIncompatiblePaymentGatewaysNotice = (): [
{ [ k: string ]: string },
string[],
number
] => {
const { incompatiblePaymentMethods } = useSelect( ( select ) => {
const { getIncompatiblePaymentMethods } = select( PAYMENT_STORE_KEY );
return {
incompatiblePaymentMethods: getIncompatiblePaymentMethods(),
};
}, [] );

const incompatiblePaymentMethodSlugs = Object.keys(
incompatiblePaymentMethods
);

const incompatiblePaymentMethodCount =
incompatiblePaymentMethodSlugs.length;

return [
incompatiblePaymentMethods,
incompatiblePaymentMethodSlugs,
incompatiblePaymentMethodCount,
];
};
Loading