From 964dd1f4491841f889b795ea722d3faeea55c6ea Mon Sep 17 00:00:00 2001 From: RJ <27843274+rjchow@users.noreply.github.com> Date: Tue, 15 Aug 2023 21:26:37 +1000 Subject: [PATCH] dev/refactor core profiler utils (#39581) * dev: added useFullScreen hook - foresee using this in more developments * dev: made findComponentMeta generic * changelog --- .../client/core-profiler/index.tsx | 21 +++------- .../client/core-profiler/types.tsx | 17 ++++++++ .../core-profiler/utils/find-component.tsx | 39 ------------------- .../woocommerce-admin/client/utils/index.js | 24 ++++++++++++ .../client/utils/xstate/find-component.tsx | 23 +++++++++++ .../xstate}/test/find-component.test.tsx | 6 ++- .../dev-refactor-core-profiler-utils | 4 ++ 7 files changed, 78 insertions(+), 56 deletions(-) create mode 100644 plugins/woocommerce-admin/client/core-profiler/types.tsx delete mode 100644 plugins/woocommerce-admin/client/core-profiler/utils/find-component.tsx create mode 100644 plugins/woocommerce-admin/client/utils/xstate/find-component.tsx rename plugins/woocommerce-admin/client/{core-profiler/utils => utils/xstate}/test/find-component.test.tsx (92%) create mode 100644 plugins/woocommerce/changelog/dev-refactor-core-profiler-utils diff --git a/plugins/woocommerce-admin/client/core-profiler/index.tsx b/plugins/woocommerce-admin/client/core-profiler/index.tsx index 50073823e2f..81ecffae1af 100644 --- a/plugins/woocommerce-admin/client/core-profiler/index.tsx +++ b/plugins/woocommerce-admin/client/core-profiler/index.tsx @@ -38,6 +38,7 @@ import { getAdminLink } from '@woocommerce/settings'; /** * Internal dependencies */ +import { findComponentMeta } from '~/utils/xstate/find-component'; import { IntroOptIn } from './pages/IntroOptIn'; import { UserProfile, @@ -54,7 +55,7 @@ import { BusinessLocation } from './pages/BusinessLocation'; import { getCountryStateOptions } from './services/country'; import { Loader } from './pages/Loader'; import { Plugins } from './pages/Plugins'; -import { getPluginSlug } from '~/utils'; +import { getPluginSlug, useFullScreen } from '~/utils'; import './style.scss'; import { InstallationCompletedResult, @@ -64,7 +65,7 @@ import { } from './services/installAndActivatePlugins'; import { ProfileSpinner } from './components/profile-spinner/profile-spinner'; import recordTracksActions from './actions/tracks'; -import { findComponentMeta } from './utils/find-component'; +import { ComponentMeta } from './types'; export type InitializationCompleteEvent = { type: 'INITIALIZATION_COMPLETE'; @@ -1437,7 +1438,7 @@ export const CoreProfilerController = ( { // 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( currentState?.meta ?? undefined ) + findComponentMeta< ComponentMeta >( currentState?.meta ?? undefined ) ); const navigationProgress = currentNodeMeta?.progress; @@ -1455,19 +1456,7 @@ export const CoreProfilerController = ( { ? Object.keys( state.value )[ 0 ] : state.value; - useEffect( () => { - document.body.classList.remove( 'woocommerce-admin-is-loading' ); - document.body.classList.add( 'woocommerce-profile-wizard__body' ); - document.body.classList.add( 'woocommerce-admin-full-screen' ); - document.body.classList.add( 'is-wp-toolbar-disabled' ); - return () => { - document.body.classList.remove( - 'woocommerce-profile-wizard__body' - ); - document.body.classList.remove( 'woocommerce-admin-full-screen' ); - document.body.classList.remove( 'is-wp-toolbar-disabled' ); - }; - } ); + useFullScreen( [ 'woocommerce-profile-wizard__body' ] ); return ( <> diff --git a/plugins/woocommerce-admin/client/core-profiler/types.tsx b/plugins/woocommerce-admin/client/core-profiler/types.tsx new file mode 100644 index 00000000000..335842d5b6f --- /dev/null +++ b/plugins/woocommerce-admin/client/core-profiler/types.tsx @@ -0,0 +1,17 @@ +/** + * Internal dependencies + */ +import { CoreProfilerStateMachineContext } from '.'; + +export type ComponentMeta = { + /** React component that is rendered when state matches the location this meta key is defined */ + component: ( arg0: ComponentProps ) => JSX.Element; + /** number between 0 - 100 */ + progress: number; +}; + +export type ComponentProps = { + navigationProgress: number | undefined; + sendEvent: unknown; + context: CoreProfilerStateMachineContext; +}; diff --git a/plugins/woocommerce-admin/client/core-profiler/utils/find-component.tsx b/plugins/woocommerce-admin/client/core-profiler/utils/find-component.tsx deleted file mode 100644 index c330a1ac50f..00000000000 --- a/plugins/woocommerce-admin/client/core-profiler/utils/find-component.tsx +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Internal dependencies - */ -import { CoreProfilerStateMachineContext } from '..'; - -export type ComponentMeta = { - /** React component that is rendered when state matches the location this meta key is defined */ - component: ( arg0: ComponentProps ) => JSX.Element; - /** number between 0 - 100 */ - progress: number; -}; - -export type ComponentProps = { - navigationProgress: number | undefined; - sendEvent: unknown; - context: CoreProfilerStateMachineContext; -}; - -/** - * Does a depth-first search of a meta object to find the first instance of a component. - */ -export function findComponentMeta( - obj: Record< string, unknown > -): ComponentMeta | undefined { - for ( const key in obj ) { - if ( key === 'component' ) { - return obj as ComponentMeta; - } else if ( typeof obj[ key ] === 'object' && obj[ key ] !== null ) { - const found = findComponentMeta( - obj[ key ] as Record< string, unknown > - ); - if ( found !== undefined ) { - return found; - } - } - } - - return undefined; -} diff --git a/plugins/woocommerce-admin/client/utils/index.js b/plugins/woocommerce-admin/client/utils/index.js index f351e0c5d4f..fed08f7897b 100644 --- a/plugins/woocommerce-admin/client/utils/index.js +++ b/plugins/woocommerce-admin/client/utils/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { useEffect } from '@wordpress/element'; + export * from './plugins'; export * from './slot-fill-ordering'; @@ -91,3 +96,22 @@ export const getTimeFrame = ( timeInMs ) => { } } }; + +/** + * Goes into fullscreen mode when the component is loaded + * + * @param {string[]} classes - classes to add to document.body + */ +export const useFullScreen = ( classes ) => { + useEffect( () => { + document.body.classList.remove( 'woocommerce-admin-is-loading' ); + document.body.classList.add( classes ); + document.body.classList.add( 'woocommerce-admin-full-screen' ); + document.body.classList.add( 'is-wp-toolbar-disabled' ); + return () => { + document.body.classList.remove( classes ); + document.body.classList.remove( 'woocommerce-admin-full-screen' ); + document.body.classList.remove( 'is-wp-toolbar-disabled' ); + }; + } ); +}; diff --git a/plugins/woocommerce-admin/client/utils/xstate/find-component.tsx b/plugins/woocommerce-admin/client/utils/xstate/find-component.tsx new file mode 100644 index 00000000000..63b892165e6 --- /dev/null +++ b/plugins/woocommerce-admin/client/utils/xstate/find-component.tsx @@ -0,0 +1,23 @@ +/** + * Does a depth-first search of a meta object to find the first instance of a component. + * + * @template T - The type of the component meta object + */ +export function findComponentMeta< T >( + obj: Record< string, unknown > +): T | undefined { + for ( const key in obj ) { + if ( key === 'component' ) { + return obj as T; + } else if ( typeof obj[ key ] === 'object' && obj[ key ] !== null ) { + const found = findComponentMeta< T >( + obj[ key ] as Record< string, unknown > + ); + if ( found !== undefined ) { + return found; + } + } + } + + return undefined; +} diff --git a/plugins/woocommerce-admin/client/core-profiler/utils/test/find-component.test.tsx b/plugins/woocommerce-admin/client/utils/xstate/test/find-component.test.tsx similarity index 92% rename from plugins/woocommerce-admin/client/core-profiler/utils/test/find-component.test.tsx rename to plugins/woocommerce-admin/client/utils/xstate/test/find-component.test.tsx index 49facb15e36..1d7911635a3 100644 --- a/plugins/woocommerce-admin/client/core-profiler/utils/test/find-component.test.tsx +++ b/plugins/woocommerce-admin/client/utils/xstate/test/find-component.test.tsx @@ -1,7 +1,11 @@ /** * Internal dependencies */ -import { findComponentMeta, ComponentProps } from '../find-component'; +import { findComponentMeta } from '../find-component'; + +type ComponentProps = { + context: string; +}; describe( 'findComponentMeta', () => { it( 'should return the whole object once "component" key is found in a nested object', () => { diff --git a/plugins/woocommerce/changelog/dev-refactor-core-profiler-utils b/plugins/woocommerce/changelog/dev-refactor-core-profiler-utils new file mode 100644 index 00000000000..557e4613edd --- /dev/null +++ b/plugins/woocommerce/changelog/dev-refactor-core-profiler-utils @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +Refactored some core profiler utils out to reuse them in customise your store.