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:
parent
532f3ca3f8
commit
1b1f86066f
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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' ),
|
|
@ -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,
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
} );
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: dev
|
||||||
|
|
||||||
|
Refactored core profiler state machine by modularising each page
|
Loading…
Reference in New Issue