CYS - Core - Check the Font Library availability (#44206)

* Ensure that the Font Library is available

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

* fix iframe issue

* improve comment

* don't return any object

---------

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Luigi Teschio 2024-02-01 12:30:50 +01:00 committed by GitHub
parent 1130380f73
commit 42a2d00cba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 99 additions and 2 deletions

View File

@ -4,7 +4,7 @@ import { store as coreStore } from '@wordpress/core-data';
/**
* External dependencies
*/
import { Sender, createMachine } from 'xstate';
import { EventData, Sender, createMachine } from 'xstate';
import { useEffect, useMemo, useState } from '@wordpress/element';
import { useMachine, useSelector } from '@xstate/react';
import {
@ -17,6 +17,8 @@ import { dispatch, resolveSelect } from '@wordpress/data';
import { Spinner } from '@woocommerce/components';
import { getAdminLink } from '@woocommerce/settings';
import { PluginArea } from '@wordpress/plugins';
import apiFetch from '@wordpress/api-fetch';
/**
* Internal dependencies
*/
@ -56,7 +58,8 @@ export type customizeStoreStateMachineEvents =
| transitionalEvents
| { type: 'AI_WIZARD_CLOSED_BEFORE_COMPLETION'; payload: { step: string } }
| { type: 'EXTERNAL_URL_UPDATE' }
| { type: 'NO_AI_FLOW_ERROR'; payload: { hasError: boolean } };
| { type: 'NO_AI_FLOW_ERROR'; payload: { hasError: boolean } }
| { type: 'IS_FONT_LIBRARY_AVAILABLE'; payload: boolean };
const updateQueryStep = (
_context: unknown,
@ -116,6 +119,18 @@ const CYSSpinner = () => (
</div>
);
const fetchIsFontLibraryAvailable = async () => {
try {
await apiFetch( {
path: '/wp/v2/font-collections',
method: 'GET',
} );
return true;
} catch ( err ) {
return false;
}
};
export const machineActions = {
updateQueryStep,
redirectToWooHome,
@ -166,6 +181,7 @@ export const customizeStoreStateMachineDefinition = createMachine( {
hasCompleteSurvey: false,
},
flowType: FlowType.noAI,
isFontLibraryAvailable: null,
} as customizeStoreStateMachineContext,
invoke: {
src: 'browserPopstateHandler',
@ -185,6 +201,9 @@ export const customizeStoreStateMachineDefinition = createMachine( {
{ type: 'updateQueryStep', step: 'intro' },
],
},
IS_FONT_LIBRARY_AVAILABLE: {
actions: [ 'assignIsFontLibraryAvailable' ],
},
},
states: {
navigate: {
@ -511,6 +530,55 @@ export const customizeStoreStateMachineDefinition = createMachine( {
},
} );
declare global {
interface Window {
__wcCustomizeStore: {
isFontLibraryAvailable: boolean | null;
};
}
}
// HACK: This is a temporary solution to pass flags computed into the iframe instance state machines.
// This is needed because the iframe loads the entire Customize Store app. This means that the iframe instance will have different state machines than the parent window.
// Check https://github.com/woocommerce/woocommerce/pull/44206 for more details.
const setFlagsForIframeInstance = async (
send: (
event: customizeStoreStateMachineEvents,
payload?: EventData | undefined
) => void
) => {
if ( ! window.frameElement ) {
// To improve the readability of the code, we want to use a dictionary where the key is the feature flag name and the value is the function to retrive flag value.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const _featureFlags = {
FONT_LIBRARY_AVAILABLE: ( async () => {
const isFontLibraryAvailable =
await fetchIsFontLibraryAvailable();
window.__wcCustomizeStore = {
...window.__wcCustomizeStore,
isFontLibraryAvailable,
};
} )(),
};
return;
}
// To improve the readability of the code, we want to use a dictionary where the key is the feature flag name and the value is the function to send the event to set the flag value to the iframe instance state machine.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const _featureFlagsEvents = {
FONT_LIBRARY_AVAILABLE: ( async () => {
window.__wcCustomizeStore = window.__wcCustomizeStore ?? {};
const isFontLibraryAvailable =
window.__wcCustomizeStore.isFontLibraryAvailable || false;
send( {
type: 'IS_FONT_LIBRARY_AVAILABLE',
payload: isFontLibraryAvailable,
} );
} )(),
};
};
export const CustomizeStoreController = ( {
actionOverrides,
servicesOverrides,
@ -560,6 +628,11 @@ export const CustomizeStoreController = ( {
const [ state, send, service ] = useMachine( augmentedStateMachine, {
devTools: process.env.NODE_ENV === 'development',
} );
useEffect( () => {
setFlagsForIframeInstance( send );
}, [ send ] );
// 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 ) =>
findComponentMeta< CustomizeStoreComponentMeta >(

View File

@ -155,3 +155,16 @@ export const assignNoAIFlowError = assign<
return { ...context.intro, hasErrors: true };
},
} );
export const assignIsFontLibraryAvailable = assign<
customizeStoreStateMachineContext,
customizeStoreStateMachineEvents
>( {
isFontLibraryAvailable: ( context, event: unknown ) => {
return (
event as {
payload: boolean;
}
).payload;
},
} );

View File

@ -46,6 +46,7 @@ describe( 'Intro Banners', () => {
hasCompleteSurvey: false,
},
flowType: FlowType.AIOnline,
isFontLibraryAvailable: false,
} }
currentState={ 'intro' }
parentMachine={ null as unknown as AnyInterpreter }
@ -84,6 +85,7 @@ describe( 'Intro Banners', () => {
hasCompleteSurvey: false,
},
flowType: FlowType.AIOnline,
isFontLibraryAvailable: false,
} }
currentState={ 'intro' }
parentMachine={ null as unknown as AnyInterpreter }
@ -128,6 +130,7 @@ describe( 'Intro Banners', () => {
hasCompleteSurvey: false,
},
flowType: FlowType.AIOnline,
isFontLibraryAvailable: false,
} }
currentState={ 'intro' }
parentMachine={ null as unknown as AnyInterpreter }

View File

@ -44,6 +44,7 @@ describe( 'Intro Modals', () => {
hasCompleteSurvey: false,
},
flowType: FlowType.AIOnline,
isFontLibraryAvailable: false,
} }
currentState={ 'intro' }
parentMachine={ null as unknown as AnyInterpreter }
@ -99,6 +100,7 @@ describe( 'Intro Modals', () => {
hasCompleteSurvey: false,
},
flowType: FlowType.AIOnline,
isFontLibraryAvailable: false,
} }
currentState={ 'intro' }
parentMachine={ null as unknown as AnyInterpreter }
@ -152,6 +154,7 @@ describe( 'Intro Modals', () => {
hasCompleteSurvey: false,
},
flowType: FlowType.AIOnline,
isFontLibraryAvailable: false,
} }
currentState={ 'intro' }
parentMachine={ null as unknown as AnyInterpreter }

View File

@ -58,4 +58,5 @@ export type customizeStoreStateMachineContext = {
hasCompleteSurvey: boolean;
};
flowType: FlowType;
isFontLibraryAvailable: boolean | null;
};

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
CYS - Core - Check the Font Library availability.