CYS: Fix opt-in flow patterns (#50080)
* CYS: Fix opt-in flow patterns * clean up not necessary state * Add changefile(s) from automation for the following project(s): woocommerce * show spinner * improve e2e test * fix e2e test * fix lint error --------- Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
parent
d4696f0437
commit
d4e686a063
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { dispatch, useSelect } from '@wordpress/data';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { store as coreStore } from '@wordpress/core-data';
|
||||
import { useEffect, useMemo, useState } from '@wordpress/element';
|
||||
|
@ -17,24 +17,29 @@ import { Pattern } from '~/customize-store/types/pattern';
|
|||
import { THEME_SLUG } from '~/customize-store/data/constants';
|
||||
|
||||
export const usePatterns = () => {
|
||||
const { blockPatterns, isLoading } = useSelect(
|
||||
const { blockPatterns, isLoading, invalidateCache } = useSelect(
|
||||
( select ) => ( {
|
||||
blockPatterns: select(
|
||||
coreStore
|
||||
// @ts-ignore - This is valid.
|
||||
// @ts-expect-error -- No types for this exist yet.
|
||||
).getBlockPatterns() as Pattern[],
|
||||
isLoading:
|
||||
// @ts-ignore - This is valid.
|
||||
// @ts-expect-error -- No types for this exist yet.
|
||||
! select( coreStore ).hasFinishedResolution(
|
||||
'getBlockPatterns'
|
||||
),
|
||||
} ),
|
||||
[]
|
||||
invalidateCache: () =>
|
||||
// @ts-expect-error -- No types for this exist yet.
|
||||
dispatch( coreStore ).invalidateResolutionForStoreSelector(
|
||||
'getBlockPatterns'
|
||||
),
|
||||
} )
|
||||
);
|
||||
|
||||
return {
|
||||
blockPatterns,
|
||||
isLoading,
|
||||
invalidateCache,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
Modal,
|
||||
// @ts-ignore No types for this exist yet.
|
||||
__experimentalNavigatorButton as NavigatorButton,
|
||||
Spinner,
|
||||
// @ts-ignore No types for this exist yet.
|
||||
} from '@wordpress/components';
|
||||
import {
|
||||
|
@ -41,13 +42,14 @@ import { capitalize } from 'lodash';
|
|||
import { getNewPath, navigateTo, useQuery } from '@woocommerce/navigation';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { useNetworkStatus } from '~/utils/react-hooks/use-network-status';
|
||||
import { isIframe, sendMessageToParent } from '~/customize-store/utils';
|
||||
import { useEditorBlocks } from '../../hooks/use-editor-blocks';
|
||||
import { isTrackingAllowed } from '../../utils/is-tracking-allowed';
|
||||
import clsx from 'clsx';
|
||||
import './style.scss';
|
||||
import { usePatterns } from '~/customize-store/assembler-hub/hooks/use-patterns';
|
||||
import { THEME_SLUG } from '~/customize-store/data/constants';
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
import { enableTracking } from '~/customize-store/design-without-ai/services';
|
||||
|
||||
const isActiveElement = ( path: string | undefined, category: string ) => {
|
||||
if ( path?.includes( category ) ) {
|
||||
|
@ -60,7 +62,7 @@ export const SidebarNavigationScreenHomepagePTK = ( {
|
|||
}: {
|
||||
onNavigateBackClick: () => void;
|
||||
} ) => {
|
||||
const { context, sendEvent } = useContext( CustomizeStoreContext );
|
||||
const { context } = useContext( CustomizeStoreContext );
|
||||
|
||||
const isNetworkOffline = useNetworkStatus();
|
||||
const isPTKPatternsAPIAvailable = context.isPTKPatternsAPIAvailable;
|
||||
|
@ -107,7 +109,12 @@ export const SidebarNavigationScreenHomepagePTK = ( {
|
|||
}, initialAccumulator );
|
||||
}, [ blocks ] );
|
||||
|
||||
const { blockPatterns, isLoading: isLoadingPatterns } = usePatterns();
|
||||
const {
|
||||
blockPatterns,
|
||||
isLoading: isLoadingPatterns,
|
||||
invalidateCache,
|
||||
} = usePatterns();
|
||||
|
||||
const patternsFromPTK = blockPatterns.filter(
|
||||
( pattern ) =>
|
||||
! pattern.name.includes( THEME_SLUG ) &&
|
||||
|
@ -118,28 +125,36 @@ export const SidebarNavigationScreenHomepagePTK = ( {
|
|||
pattern.source !== 'pattern-directory/core'
|
||||
);
|
||||
|
||||
let notice;
|
||||
if ( isNetworkOffline ) {
|
||||
notice = __(
|
||||
"Looks like we can't detect your network. Please double-check your internet connection and refresh the page.",
|
||||
'woocommerce'
|
||||
);
|
||||
} else if ( ! isPTKPatternsAPIAvailable ) {
|
||||
notice = __(
|
||||
"Unfortunately, we're experiencing some technical issues — please come back later to access more patterns.",
|
||||
'woocommerce'
|
||||
);
|
||||
} else if ( ! isTrackingAllowed() ) {
|
||||
notice = __(
|
||||
'Opt in to <OptInModal>usage tracking</OptInModal> to get access to more patterns.',
|
||||
'woocommerce'
|
||||
);
|
||||
} else if ( ! isLoadingPatterns && patternsFromPTK.length === 0 ) {
|
||||
notice = __(
|
||||
'Unfortunately, a technical issue is preventing more patterns from being displayed. Please <FetchPatterns>try again</FetchPatterns> later.',
|
||||
'woocommerce'
|
||||
);
|
||||
}
|
||||
const notice = useMemo( () => {
|
||||
let noticeText;
|
||||
if ( isNetworkOffline ) {
|
||||
noticeText = __(
|
||||
"Looks like we can't detect your network. Please double-check your internet connection and refresh the page.",
|
||||
'woocommerce'
|
||||
);
|
||||
} else if ( ! isPTKPatternsAPIAvailable ) {
|
||||
noticeText = __(
|
||||
"Unfortunately, we're experiencing some technical issues — please come back later to access more patterns.",
|
||||
'woocommerce'
|
||||
);
|
||||
} else if ( ! isTrackingAllowed() ) {
|
||||
noticeText = __(
|
||||
'Opt in to <OptInModal>usage tracking</OptInModal> to get access to more patterns.',
|
||||
'woocommerce'
|
||||
);
|
||||
} else if ( ! isLoadingPatterns && patternsFromPTK.length === 0 ) {
|
||||
noticeText = __(
|
||||
'Unfortunately, a technical issue is preventing more patterns from being displayed. Please <FetchPatterns>try again</FetchPatterns> later.',
|
||||
'woocommerce'
|
||||
);
|
||||
}
|
||||
return noticeText;
|
||||
}, [
|
||||
isNetworkOffline,
|
||||
isPTKPatternsAPIAvailable,
|
||||
isLoadingPatterns,
|
||||
patternsFromPTK.length,
|
||||
] );
|
||||
|
||||
const [ isModalOpen, setIsModalOpen ] = useState( false );
|
||||
|
||||
|
@ -149,6 +164,8 @@ export const SidebarNavigationScreenHomepagePTK = ( {
|
|||
const [ optInDataSharing, setIsOptInDataSharing ] =
|
||||
useState< boolean >( true );
|
||||
|
||||
const [ isFetchingPatterns, setIsFetchingPatterns ] = useState( false );
|
||||
|
||||
const optIn = () => {
|
||||
trackEvent(
|
||||
'customize_your_store_assembler_hub_opt_in_usage_tracking'
|
||||
|
@ -265,16 +282,13 @@ export const SidebarNavigationScreenHomepagePTK = ( {
|
|||
),
|
||||
FetchPatterns: (
|
||||
<Button
|
||||
onClick={ () => {
|
||||
if ( isIframe( window ) ) {
|
||||
sendMessageToParent( {
|
||||
type: 'INSTALL_PATTERNS',
|
||||
} );
|
||||
} else {
|
||||
sendEvent(
|
||||
'INSTALL_PATTERNS'
|
||||
);
|
||||
}
|
||||
onClick={ async () => {
|
||||
await apiFetch( {
|
||||
path: `/wc/private/patterns`,
|
||||
method: 'POST',
|
||||
} );
|
||||
|
||||
invalidateCache();
|
||||
} }
|
||||
variant="link"
|
||||
/>
|
||||
|
@ -327,24 +341,34 @@ export const SidebarNavigationScreenHomepagePTK = ( {
|
|||
) }
|
||||
</Button>
|
||||
<Button
|
||||
onClick={ () => {
|
||||
onClick={ async () => {
|
||||
optIn();
|
||||
if ( isIframe( window ) ) {
|
||||
sendMessageToParent( {
|
||||
type: 'INSTALL_PATTERNS',
|
||||
} );
|
||||
} else {
|
||||
sendEvent(
|
||||
'INSTALL_PATTERNS'
|
||||
);
|
||||
}
|
||||
await enableTracking();
|
||||
setIsFetchingPatterns(
|
||||
true
|
||||
);
|
||||
await apiFetch< {
|
||||
success: boolean;
|
||||
} >( {
|
||||
path: `/wc/private/patterns`,
|
||||
method: 'POST',
|
||||
} );
|
||||
invalidateCache();
|
||||
closeModal();
|
||||
setIsFetchingPatterns(
|
||||
false
|
||||
);
|
||||
} }
|
||||
variant="primary"
|
||||
disabled={ ! optInDataSharing }
|
||||
>
|
||||
{ __(
|
||||
'Opt in',
|
||||
'woocommerce'
|
||||
{ isFetchingPatterns ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
__(
|
||||
'Opt in',
|
||||
'woocommerce'
|
||||
)
|
||||
) }
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
@ -116,10 +116,6 @@ const AssemblerHub = ( { sendEvent }: { sendEvent: SendEventFn } ) => {
|
|||
if ( event.data?.type === 'INSTALL_FONTS' ) {
|
||||
sendEvent( { type: 'INSTALL_FONTS' } );
|
||||
}
|
||||
|
||||
if ( event.data?.type === 'INSTALL_PATTERNS' ) {
|
||||
sendEvent( { type: 'INSTALL_PATTERNS' } );
|
||||
}
|
||||
} );
|
||||
}, [ sendEvent ] );
|
||||
|
||||
|
|
|
@ -81,7 +81,6 @@ const installFontFamiliesState = {
|
|||
export type DesignWithoutAIStateMachineEvents =
|
||||
| { type: 'EXTERNAL_URL_UPDATE' }
|
||||
| { type: 'INSTALL_FONTS' }
|
||||
| { type: 'INSTALL_PATTERNS' }
|
||||
| { type: 'NO_AI_FLOW_ERROR'; payload: { hasError: boolean } };
|
||||
|
||||
export const designWithNoAiStateMachineDefinition = createMachine(
|
||||
|
@ -103,9 +102,6 @@ export const designWithNoAiStateMachineDefinition = createMachine(
|
|||
INSTALL_FONTS: {
|
||||
target: 'installFontFamilies',
|
||||
},
|
||||
INSTALL_PATTERNS: {
|
||||
target: 'installPatterns',
|
||||
},
|
||||
},
|
||||
context: {
|
||||
startLoadingTime: null,
|
||||
|
|
|
@ -62,7 +62,6 @@ export type customizeStoreStateMachineEvents =
|
|||
| { type: 'AI_WIZARD_CLOSED_BEFORE_COMPLETION'; payload: { step: string } }
|
||||
| { type: 'EXTERNAL_URL_UPDATE' }
|
||||
| { type: 'INSTALL_FONTS' }
|
||||
| { type: 'INSTALL_PATTERNS' }
|
||||
| { type: 'NO_AI_FLOW_ERROR'; payload: { hasError: boolean } }
|
||||
| { type: 'IS_FONT_LIBRARY_AVAILABLE'; payload: boolean };
|
||||
|
||||
|
@ -242,9 +241,6 @@ export const customizeStoreStateMachineDefinition = createMachine( {
|
|||
INSTALL_FONTS: {
|
||||
target: 'designWithoutAi.installFonts',
|
||||
},
|
||||
INSTALL_PATTERNS: {
|
||||
target: 'designWithoutAi.installPatterns',
|
||||
},
|
||||
},
|
||||
states: {
|
||||
setFlags: {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: update
|
||||
|
||||
CYS: Improve opt-in flow patterns.
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Automattic\WooCommerce\StoreApi\Routes\V1;
|
||||
|
||||
use Automattic\WooCommerce\Blocks\BlockPatterns;
|
||||
use Automattic\WooCommerce\Blocks\Package;
|
||||
use Automattic\WooCommerce\Blocks\Patterns\PTKClient;
|
||||
use Automattic\WooCommerce\Blocks\Patterns\PTKPatternsStore;
|
||||
|
@ -114,7 +115,11 @@ class Patterns extends AbstractRoute {
|
|||
protected function get_route_post_response( WP_REST_Request $request ) {
|
||||
$ptk_patterns_store = Package::container()->get( PTKPatternsStore::class );
|
||||
|
||||
$ptk_patterns_store->fetch_patterns();
|
||||
$patterns = $ptk_patterns_store->fetch_patterns();
|
||||
|
||||
$block_patterns = Package::container()->get( BlockPatterns::class );
|
||||
|
||||
$block_patterns->register_ptk_patterns( $patterns );
|
||||
|
||||
return rest_ensure_response(
|
||||
array(
|
||||
|
|
|
@ -47,6 +47,13 @@ test.describe( 'Assembler -> Full composability', { tag: '@gutenberg' }, () => {
|
|||
'woocommerce_customize_store_onboarding_tour_hidden',
|
||||
'yes'
|
||||
);
|
||||
|
||||
await setOption(
|
||||
request,
|
||||
baseURL,
|
||||
'woocommerce_allow_tracking',
|
||||
'no'
|
||||
);
|
||||
} catch ( error ) {
|
||||
console.log( 'Store completed option not updated' );
|
||||
}
|
||||
|
@ -76,6 +83,13 @@ test.describe( 'Assembler -> Full composability', { tag: '@gutenberg' }, () => {
|
|||
'no'
|
||||
);
|
||||
|
||||
await setOption(
|
||||
request,
|
||||
baseURL,
|
||||
'woocommerce_allow_tracking',
|
||||
'no'
|
||||
);
|
||||
|
||||
await activateTheme( DEFAULT_THEME );
|
||||
} catch ( error ) {
|
||||
console.log( 'Store completed option not updated' );
|
||||
|
@ -300,4 +314,33 @@ test.describe( 'Assembler -> Full composability', { tag: '@gutenberg' }, () => {
|
|||
await expect( emptyPatternsBlock ).toBeHidden();
|
||||
await expect( defaultPattern ).toBeVisible();
|
||||
} );
|
||||
|
||||
test( 'Clicking opt-in new patterns should be available', async ( {
|
||||
pageObject,
|
||||
baseURL,
|
||||
} ) => {
|
||||
await prepareAssembler( pageObject, baseURL );
|
||||
const assembler = await pageObject.getAssembler();
|
||||
|
||||
await assembler.getByText( 'Usage tracking' ).click();
|
||||
await expect(
|
||||
assembler.getByText( 'Access more patterns' )
|
||||
).toBeVisible();
|
||||
|
||||
await assembler.getByRole( 'button', { name: 'Opt in' } ).click();
|
||||
|
||||
await assembler
|
||||
.getByText( 'Access more patterns' )
|
||||
.waitFor( { state: 'hidden' } );
|
||||
|
||||
const sidebarPattern = assembler.locator(
|
||||
'.block-editor-block-patterns-list'
|
||||
);
|
||||
|
||||
await sidebarPattern.waitFor( { state: 'visible' } );
|
||||
|
||||
await expect(
|
||||
assembler.locator( '.block-editor-block-patterns-list__list-item' )
|
||||
).toHaveCount( 10 );
|
||||
} );
|
||||
} );
|
||||
|
|
Loading…
Reference in New Issue