CYS - Core: install font when user clicks opt-in (#45580)

* CYS - Core: install font when user clicks opt-in

* remove debugger

* CYS - Core: fix wp-admin page visible when click on start designing

* Add changefile(s) from automation for the following project(s): woocommerce

* use sendEvent instead of redirect

* Add changefile(s) from automation for the following project(s): woocommerce

* not show wp-admin after the click on the dialog button

* use sendEventToIntroMachine

* fix font installation

* fix eslint error

* fix install font phase when the iframe is not loaded

* remove not necessary async

---------

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Luigi Teschio 2024-03-18 16:49:41 +01:00 committed by GitHub
parent d69ceaa0a1
commit f9c0d406ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 166 additions and 55 deletions

View File

@ -9,7 +9,7 @@ import {
useContext, useContext,
useState, useState,
} from '@wordpress/element'; } from '@wordpress/element';
import { dispatch, useSelect } from '@wordpress/data'; import { useSelect } from '@wordpress/data';
import { Link } from '@woocommerce/components'; import { Link } from '@woocommerce/components';
import { OPTIONS_STORE_NAME } from '@woocommerce/data'; import { OPTIONS_STORE_NAME } from '@woocommerce/data';
import { recordEvent } from '@woocommerce/tracks'; import { recordEvent } from '@woocommerce/tracks';
@ -24,8 +24,9 @@ import { ADMIN_URL } from '~/utils/admin-settings';
import { FontPairing } from './global-styles'; import { FontPairing } from './global-styles';
import { CustomizeStoreContext } from '..'; import { CustomizeStoreContext } from '..';
import { FlowType } from '~/customize-store/types'; import { FlowType } from '~/customize-store/types';
import { isIframe, sendMessageToParent } from '~/customize-store/utils';
export const SidebarNavigationScreenTypography = () => { export const SidebarNavigationScreenTypography = () => {
const { context } = useContext( CustomizeStoreContext ); const { context, sendEvent } = useContext( CustomizeStoreContext );
const aiOnline = context.flowType === FlowType.AIOnline; const aiOnline = context.flowType === FlowType.AIOnline;
const isFontLibraryAvailable = context.isFontLibraryAvailable; const isFontLibraryAvailable = context.isFontLibraryAvailable;
@ -67,7 +68,7 @@ export const SidebarNavigationScreenTypography = () => {
upgradeNotice = ''; upgradeNotice = '';
} }
const OptIn = () => { const optIn = () => {
recordEvent( recordEvent(
'customize_your_store_assembler_hub_opt_in_usage_tracking' 'customize_your_store_assembler_hub_opt_in_usage_tracking'
); );
@ -200,19 +201,17 @@ export const SidebarNavigationScreenTypography = () => {
{ __( 'Cancel', 'woocommerce' ) } { __( 'Cancel', 'woocommerce' ) }
</Button> </Button>
<Button <Button
onClick={ async () => { onClick={ () => {
await dispatch( optIn();
OPTIONS_STORE_NAME if ( isIframe( window ) ) {
).updateOptions( { sendMessageToParent( {
woocommerce_allow_tracking: type: 'INSTALL_FONTS',
OptInDataSharing } );
? 'yes' } else {
: 'no', sendEvent(
} ); 'INSTALL_FONTS'
);
OptIn(); }
closeModal();
window.location.href = `${ ADMIN_URL }admin.php?page=wc-admin&path=%2Fcustomize-store%2Fassembler-hub`;
} } } }
variant="primary" variant="primary"
disabled={ ! OptInDataSharing } disabled={ ! OptInDataSharing }

View File

@ -15,7 +15,7 @@ import {
} from '../types'; } from '../types';
import { designWithNoAiStateMachineDefinition } from './state-machine'; import { designWithNoAiStateMachineDefinition } from './state-machine';
import { findComponentMeta } from '~/utils/xstate/find-component'; import { findComponentMeta } from '~/utils/xstate/find-component';
import { AssembleHubLoader } from '../design-with-ai/pages'; import { AssembleHubLoader } from './pages/ApiCallLoader';
export type DesignWithoutAiComponent = typeof AssembleHubLoader; export type DesignWithoutAiComponent = typeof AssembleHubLoader;
export type DesignWithoutAiComponentMeta = { export type DesignWithoutAiComponentMeta = {
@ -30,15 +30,18 @@ export const DesignWithNoAiController = ( {
sendEventToParent?: Sender< customizeStoreStateMachineEvents >; sendEventToParent?: Sender< customizeStoreStateMachineEvents >;
parentContext?: customizeStoreStateMachineContext; parentContext?: customizeStoreStateMachineContext;
} ) => { } ) => {
const [ , , service ] = useMachine( designWithNoAiStateMachineDefinition, { const [ , send, service ] = useMachine(
devTools: process.env.NODE_ENV === 'development', designWithNoAiStateMachineDefinition,
parent: parentMachine, {
context: { devTools: process.env.NODE_ENV === 'development',
...designWithNoAiStateMachineDefinition.context, parent: parentMachine,
isFontLibraryAvailable: context: {
parentContext?.isFontLibraryAvailable ?? false, ...designWithNoAiStateMachineDefinition.context,
}, isFontLibraryAvailable:
} ); parentContext?.isFontLibraryAvailable ?? false,
},
}
);
// eslint-disable-next-line react-hooks/exhaustive-deps -- false positive due to function name match, this isn't from react std lib // eslint-disable-next-line react-hooks/exhaustive-deps -- false positive due to function name match, this isn't from react std lib
const currentNodeMeta = useSelector( service, ( currentState ) => const currentNodeMeta = useSelector( service, ( currentState ) =>
@ -59,7 +62,11 @@ export const DesignWithNoAiController = ( {
return ( return (
<> <>
<div className={ `woocommerce-design-without-ai__container` }> <div className={ `woocommerce-design-without-ai__container` }>
{ CurrentComponent ? <CurrentComponent /> : <div /> } { CurrentComponent ? (
<CurrentComponent sendEvent={ send } />
) : (
<div />
) }
</div> </div>
</> </>
); );

View File

@ -17,6 +17,7 @@ import {
createAugmentedSteps, createAugmentedSteps,
onIframeLoad, onIframeLoad,
} from '~/customize-store/utils'; } from '~/customize-store/utils';
import { DesignWithoutAIStateMachineEvents } from '../state-machine';
const loaderSteps = [ const loaderSteps = [
{ {
@ -103,11 +104,21 @@ export const ApiCallLoader = () => {
); );
}; };
const AssemblerHub = () => { type SendEventFn = ( event: DesignWithoutAIStateMachineEvents ) => void;
const AssemblerHub = ( { sendEvent }: { sendEvent: SendEventFn } ) => {
const assemblerUrl = getNewPath( {}, '/customize-store/assembler-hub', {} ); const assemblerUrl = getNewPath( {}, '/customize-store/assembler-hub', {} );
const iframe = useRef< HTMLIFrameElement >( null ); const iframe = useRef< HTMLIFrameElement >( null );
const [ isVisible, setIsVisible ] = useState( false ); const [ isVisible, setIsVisible ] = useState( false );
useEffect( () => {
window.addEventListener( 'message', ( event ) => {
if ( event.data?.type === 'INSTALL_FONTS' ) {
sendEvent( { type: 'INSTALL_FONTS' } );
}
} );
}, [ sendEvent ] );
return ( return (
<iframe <iframe
ref={ iframe } ref={ iframe }
@ -127,7 +138,11 @@ const AssemblerHub = () => {
); );
}; };
export const AssembleHubLoader = () => { export const AssembleHubLoader = ( {
sendEvent,
}: {
sendEvent: SendEventFn;
} ) => {
// Show the last two steps of the loader so that the last frame is the shortest time possible // Show the last two steps of the loader so that the last frame is the shortest time possible
const augmentedSteps = createAugmentedSteps( loaderSteps.slice( -2 ), 10 ); const augmentedSteps = createAugmentedSteps( loaderSteps.slice( -2 ), 10 );
@ -160,7 +175,7 @@ export const AssembleHubLoader = () => {
progress={ progress || 0 } progress={ progress || 0 }
/> />
</Loader> </Loader>
<AssemblerHub /> <AssemblerHub sendEvent={ sendEvent } />
</> </>
); );
}; };

View File

@ -235,6 +235,17 @@ const createProducts = async () => {
} }
}; };
export const enableTracking = async () => {
try {
await dispatch( OPTIONS_STORE_NAME ).updateOptions( {
woocommerce_allow_tracking: 'yes',
} );
window.wcTracks.isEnabled = true;
} catch ( error ) {
throw error;
}
};
export const services = { export const services = {
assembleSite, assembleSite,
browserPopstateHandler, browserPopstateHandler,
@ -242,4 +253,5 @@ export const services = {
createProducts, createProducts,
installFontFamilies, installFontFamilies,
updateGlobalStylesWithDefaultValues, updateGlobalStylesWithDefaultValues,
enableTracking,
}; };

View File

@ -29,8 +29,49 @@ export const hasStepInUrl = (
); );
}; };
export const hasFontInstallInUrl = () => {
const { path = '' } = getQuery() as { path: string };
const pathFragments = path.split( '/' );
return (
pathFragments[ 2 ] === 'design' &&
pathFragments[ 3 ] === 'install-fonts'
);
};
const installFontFamiliesState = {
initial: 'checkFontLibrary',
states: {
checkFontLibrary: {
always: [
{
cond: {
type: 'isFontLibraryAvailable',
},
target: 'pending',
},
{ target: 'success' },
],
},
pending: {
invoke: {
src: 'installFontFamilies',
onDone: {
target: 'success',
},
onError: {
actions: 'redirectToIntroWithError',
},
},
},
success: {
type: 'final',
},
},
};
export type DesignWithoutAIStateMachineEvents = export type DesignWithoutAIStateMachineEvents =
| { type: 'EXTERNAL_URL_UPDATE' } | { type: 'EXTERNAL_URL_UPDATE' }
| { type: 'INSTALL_FONTS' }
| { type: 'NO_AI_FLOW_ERROR'; payload: { hasError: boolean } }; | { type: 'NO_AI_FLOW_ERROR'; payload: { hasError: boolean } };
export const designWithNoAiStateMachineDefinition = createMachine( export const designWithNoAiStateMachineDefinition = createMachine(
@ -49,6 +90,9 @@ export const designWithNoAiStateMachineDefinition = createMachine(
EXTERNAL_URL_UPDATE: { EXTERNAL_URL_UPDATE: {
target: 'navigate', target: 'navigate',
}, },
INSTALL_FONTS: {
target: 'installFontFamilies',
},
}, },
context: { context: {
startLoadingTime: null, startLoadingTime: null,
@ -62,6 +106,13 @@ export const designWithNoAiStateMachineDefinition = createMachine(
states: { states: {
navigate: { navigate: {
always: [ always: [
{
cond: {
type: 'hasFontInstallInUrl',
step: 'design',
},
target: 'installFontFamilies',
},
{ {
cond: { cond: {
type: 'hasStepInUrl', type: 'hasStepInUrl',
@ -71,6 +122,31 @@ export const designWithNoAiStateMachineDefinition = createMachine(
}, },
], ],
}, },
installFontFamilies: {
meta: {
component: ApiCallLoader,
},
initial: 'enableTracking',
states: {
enableTracking: {
invoke: {
src: 'enableTracking',
onDone: {
target: 'checkFontLibrary',
},
},
},
checkFontLibrary:
installFontFamiliesState.states.checkFontLibrary,
pending: installFontFamiliesState.states.pending,
success: {
type: 'final',
},
},
onDone: {
target: '#designWithoutAI.showAssembleHub',
},
},
preAssembleSite: { preAssembleSite: {
initial: 'preApiCallLoader', initial: 'preApiCallLoader',
id: 'preAssembleSite', id: 'preAssembleSite',
@ -141,31 +217,13 @@ export const designWithNoAiStateMachineDefinition = createMachine(
}, },
}, },
installFontFamilies: { installFontFamilies: {
initial: 'checkFontLibrary', initial: installFontFamiliesState.initial,
states: { states: {
checkFontLibrary: { checkFontLibrary:
always: [ installFontFamiliesState.states
{ .checkFontLibrary,
cond: { pending:
type: 'isFontLibraryAvailable', installFontFamiliesState.states.pending,
},
target: 'pending',
},
{ target: 'success' },
],
},
pending: {
invoke: {
src: 'installFontFamilies',
onDone: {
target: 'success',
},
onError: {
actions:
'redirectToIntroWithError',
},
},
},
success: { success: {
type: 'final', type: 'final',
}, },
@ -184,7 +242,6 @@ export const designWithNoAiStateMachineDefinition = createMachine(
component: AssembleHubLoader, component: AssembleHubLoader,
}, },
entry: [ 'redirectToAssemblerHub' ], entry: [ 'redirectToAssemblerHub' ],
type: 'final',
}, },
}, },
}, },
@ -194,6 +251,7 @@ export const designWithNoAiStateMachineDefinition = createMachine(
guards: { guards: {
hasStepInUrl, hasStepInUrl,
isFontLibraryAvailable, isFontLibraryAvailable,
hasFontInstallInUrl,
}, },
} }
); );

View File

@ -57,6 +57,7 @@ export type customizeStoreStateMachineEvents =
| transitionalEvents | transitionalEvents
| { type: 'AI_WIZARD_CLOSED_BEFORE_COMPLETION'; payload: { step: string } } | { type: 'AI_WIZARD_CLOSED_BEFORE_COMPLETION'; payload: { step: string } }
| { type: 'EXTERNAL_URL_UPDATE' } | { type: 'EXTERNAL_URL_UPDATE' }
| { type: 'INSTALL_FONTS' }
| { type: 'NO_AI_FLOW_ERROR'; payload: { hasError: boolean } } | { type: 'NO_AI_FLOW_ERROR'; payload: { hasError: boolean } }
| { type: 'IS_FONT_LIBRARY_AVAILABLE'; payload: boolean }; | { type: 'IS_FONT_LIBRARY_AVAILABLE'; payload: boolean };
@ -202,6 +203,9 @@ export const customizeStoreStateMachineDefinition = createMachine( {
{ type: 'updateQueryStep', step: 'intro' }, { type: 'updateQueryStep', step: 'intro' },
], ],
}, },
INSTALL_FONTS: {
target: 'designWithoutAi.installFonts',
},
}, },
states: { states: {
setFlags: { setFlags: {
@ -365,6 +369,18 @@ export const customizeStoreStateMachineDefinition = createMachine( {
component: DesignWithoutAi, component: DesignWithoutAi,
}, },
}, },
// This state is used to install fonts and then redirect to the assembler hub.
installFonts: {
entry: [
{
type: 'updateQueryStep',
step: 'design/install-fonts',
},
],
meta: {
component: DesignWithoutAi,
},
},
}, },
}, },
designWithAi: { designWithAi: {

View File

@ -0,0 +1,4 @@
Significance: minor
Type: fix
CYS - Core: install font when user clicks opt-in