dev: refactor core profiler pages (#38606)

* dev: refactor core-profiler - modularise each page

- wrapped each page's pre, post, and main states into their top level states for tidiness
- tagged them with id so that we can easily jump to them when doing routing
- generalised component finder code such that it recursively traverses the state meta object until it finds a component key
- fixed css label to use top level state key

* moved initializing into introOptIn so it's not a special case by itself
This commit is contained in:
RJ 2023-06-07 13:39:38 +10:00 committed by GitHub
parent 532f3ca3f8
commit 1b1f86066f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 734 additions and 559 deletions

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ import { useState, useEffect } from '@wordpress/element';
*/ */
import { CoreProfilerStateMachineContext } from '..'; import { CoreProfilerStateMachineContext } from '..';
import ProgressBar from '../components/progress-bar/progress-bar'; import ProgressBar from '../components/progress-bar/progress-bar';
import { getLoaderStageMeta } from '../get-loader-stage-meta'; import { getLoaderStageMeta } from '../utils/get-loader-stage-meta';
export type Stage = { export type Stage = {
title: string; title: string;

View File

@ -1897,7 +1897,7 @@ Object {
/> />
<div> <div>
<div <div
class="woocommerce-profile-wizard__container woocommerce-profile-wizard__step-skipFlowBusinessLocation" class="woocommerce-profile-wizard__container woocommerce-profile-wizard__step-skipGuidedSetup"
> >
<div <div
class="woocommerce-profiler-business-location" class="woocommerce-profiler-business-location"
@ -2049,7 +2049,7 @@ Object {
</body>, </body>,
"container": <div> "container": <div>
<div <div
class="woocommerce-profile-wizard__container woocommerce-profile-wizard__step-skipFlowBusinessLocation" class="woocommerce-profile-wizard__container woocommerce-profile-wizard__step-skipGuidedSetup"
> >
<div <div
class="woocommerce-profiler-business-location" class="woocommerce-profiler-business-location"

View File

@ -0,0 +1,39 @@
/**
* 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;
}

View File

@ -6,11 +6,11 @@ import { __ } from '@wordpress/i18n';
/** /**
* Internal dependencies * Internal dependencies
*/ */
import LightBulbImage from './assets/images/loader-lightbulb.svg'; import LightBulbImage from '../assets/images/loader-lightbulb.svg';
import DevelopingImage from './assets/images/loader-developing.svg'; import DevelopingImage from '../assets/images/loader-developing.svg';
import LayoutImage from './assets/images/loader-layout.svg'; import LayoutImage from '../assets/images/loader-layout.svg';
import { Stages } from './pages/Loader'; import { Stages } from '../pages/Loader';
const LightbulbStage = { const LightbulbStage = {
title: __( 'Turning on the lights', 'woocommerce' ), title: __( 'Turning on the lights', 'woocommerce' ),

View File

@ -0,0 +1,60 @@
/**
* Internal dependencies
*/
import { findComponentMeta, ComponentProps } from '../find-component';
describe( 'findComponentMeta', () => {
it( 'should return the whole object once "component" key is found in a nested object', () => {
const obj: Record< string, unknown > = {
'coreProfiler.skipGuidedSetup.skipFlowBusinessLocation': {
component: ( props: ComponentProps ) => (
<div>{ props.context }</div>
),
progress: 50,
},
};
const result = findComponentMeta( obj );
expect( result ).toEqual( {
component: expect.any( Function ),
progress: 50,
} );
} );
it( 'should return undefined if no "component" key is present', () => {
const obj: Record< string, unknown > = {
a: 1,
b: {
key: 'value',
},
c: 2,
};
const result = findComponentMeta( obj );
expect( result ).toBeUndefined();
} );
it( 'should handle deeply nested objects', () => {
const obj: Record< string, unknown > = {
a: 1,
b: {
key: 'value',
nested: {
anotherKey: 'anotherValue',
component: ( props: ComponentProps ) => (
<div>{ props.context }</div>
),
progress: 100,
},
},
c: 2,
};
const result = findComponentMeta( obj );
expect( result ).toEqual( {
anotherKey: 'anotherValue',
component: expect.any( Function ),
progress: 100,
} );
} );
} );

View File

@ -0,0 +1,4 @@
Significance: patch
Type: dev
Refactored core profiler state machine by modularising each page