diff --git a/plugins/woocommerce-admin/client/launch-your-store/hub/index.tsx b/plugins/woocommerce-admin/client/launch-your-store/hub/index.tsx index c0f9cd4cf5a..c1998e46e9d 100644 --- a/plugins/woocommerce-admin/client/launch-your-store/hub/index.tsx +++ b/plugins/woocommerce-admin/client/launch-your-store/hub/index.tsx @@ -32,6 +32,11 @@ export type LaunchYourStoreComponentProps = { className?: string; }; +export type LaunchYourStoreQueryParams = { + sidebar?: 'hub' | 'launch-success'; + content?: 'site-preview' | 'launch-store-success'; +}; + const LaunchStoreController = () => { useFullScreen( [ 'woocommerce-launch-your-store' ] ); useEffect( () => { diff --git a/plugins/woocommerce-admin/client/launch-your-store/hub/main-content/xstate.tsx b/plugins/woocommerce-admin/client/launch-your-store/hub/main-content/xstate.tsx index 715b77b7a50..49e01f2785d 100644 --- a/plugins/woocommerce-admin/client/launch-your-store/hub/main-content/xstate.tsx +++ b/plugins/woocommerce-admin/client/launch-your-store/hub/main-content/xstate.tsx @@ -14,8 +14,14 @@ import { getSetting } from '@woocommerce/settings'; */ import { LoadingPage } from './pages/loading'; import { SitePreviewPage } from './pages/site-preview'; -import type { LaunchYourStoreComponentProps } from '..'; -import { createQueryParamsListener, updateQueryParams } from '../common'; +import type { + LaunchYourStoreComponentProps, + LaunchYourStoreQueryParams, +} from '..'; +import { + updateQueryParams, + createQueryParamsListener, +} from '~/utils/xstate/url-handling'; import { services as congratsServices, events as congratsEvents, @@ -54,11 +60,8 @@ export const mainContentMachine = setup( { events: MainContentMachineEvents; }, actions: { - updateQueryParams: ( - _, - params: { sidebar?: string; content?: string } - ) => { - updateQueryParams( params ); + updateQueryParams: ( _, params: LaunchYourStoreQueryParams ) => { + updateQueryParams< LaunchYourStoreQueryParams >( params ); }, assignSiteCachedStatus: assign( { siteIsShowingCachedContent: true, @@ -92,9 +95,9 @@ export const mainContentMachine = setup( { guards: { hasContentLocation: ( _, - { contentLocation }: { contentLocation: string } + { content: contentLocation }: LaunchYourStoreQueryParams ) => { - const { content } = getQuery() as { content?: string }; + const { content } = getQuery() as LaunchYourStoreQueryParams; return !! content && content === contentLocation; }, }, @@ -125,13 +128,13 @@ export const mainContentMachine = setup( { { guard: { type: 'hasContentLocation', - params: { contentLocation: 'site-preview' }, + params: { content: 'site-preview' }, }, }, { guard: { type: 'hasContentLocation', - params: { contentLocation: 'launch-store-success' }, + params: { content: 'launch-store-success' }, }, target: 'launchStoreSuccess', }, diff --git a/plugins/woocommerce-admin/client/launch-your-store/hub/sidebar/xstate.tsx b/plugins/woocommerce-admin/client/launch-your-store/hub/sidebar/xstate.tsx index 96d33eff1f5..a1d0cbf4a35 100644 --- a/plugins/woocommerce-admin/client/launch-your-store/hub/sidebar/xstate.tsx +++ b/plugins/woocommerce-admin/client/launch-your-store/hub/sidebar/xstate.tsx @@ -29,9 +29,15 @@ import apiFetch from '@wordpress/api-fetch'; * Internal dependencies */ import { LaunchYourStoreHubSidebar } from './components/launch-store-hub'; -import type { LaunchYourStoreComponentProps } from '..'; +import type { + LaunchYourStoreComponentProps, + LaunchYourStoreQueryParams, +} from '..'; import type { mainContentMachine } from '../main-content/xstate'; -import { updateQueryParams, createQueryParamsListener } from '../common'; +import { + updateQueryParams, + createQueryParamsListener, +} from '~/utils/xstate/url-handling'; import { taskClickedAction, getLysTasklist } from './tasklist'; import { fetchCongratsData } from '../main-content/pages/launch-store-success/services'; import { getTimeFrame } from '~/utils'; @@ -253,11 +259,8 @@ export const sidebarMachine = setup( { ( { context } ) => context.mainContentMachineRef, { type: 'SHOW_LOADING' } ), - updateQueryParams: ( - _, - params: { sidebar?: string; content?: string } - ) => { - updateQueryParams( params ); + updateQueryParams: ( _, params: LaunchYourStoreQueryParams ) => { + updateQueryParams< LaunchYourStoreQueryParams >( params ); }, taskClicked: ( { event } ) => { if ( event.type === 'TASK_CLICKED' ) { @@ -293,9 +296,9 @@ export const sidebarMachine = setup( { guards: { hasSidebarLocation: ( _, - { sidebarLocation }: { sidebarLocation: string } + { sidebar: sidebarLocation }: LaunchYourStoreQueryParams ) => { - const { sidebar } = getQuery() as { sidebar?: string }; + const { sidebar } = getQuery() as LaunchYourStoreQueryParams; return !! sidebar && sidebar === sidebarLocation; }, hasWooPayments: ( { context } ) => { @@ -333,14 +336,14 @@ export const sidebarMachine = setup( { { guard: { type: 'hasSidebarLocation', - params: { sidebarLocation: 'hub' }, + params: { sidebar: 'hub' }, }, target: 'launchYourStoreHub', }, { guard: { type: 'hasSidebarLocation', - params: { sidebarLocation: 'launch-success' }, + params: { sidebar: 'launch-success' }, }, target: 'storeLaunchSuccessful', }, diff --git a/plugins/woocommerce-admin/client/launch-your-store/hub/test/common.test.ts b/plugins/woocommerce-admin/client/utils/xstate/test/url-handling.test.ts similarity index 99% rename from plugins/woocommerce-admin/client/launch-your-store/hub/test/common.test.ts rename to plugins/woocommerce-admin/client/utils/xstate/test/url-handling.test.ts index 6b891808e97..760d1f5eee8 100644 --- a/plugins/woocommerce-admin/client/launch-your-store/hub/test/common.test.ts +++ b/plugins/woocommerce-admin/client/utils/xstate/test/url-handling.test.ts @@ -5,7 +5,7 @@ import * as navigation from '@woocommerce/navigation'; /** * Internal dependencies */ -import { updateQueryParams, createQueryParamsListener } from '../common'; +import { updateQueryParams, createQueryParamsListener } from '../url-handling'; jest.mock( '@woocommerce/navigation', () => ( { getHistory: jest.fn(), diff --git a/plugins/woocommerce-admin/client/launch-your-store/hub/common.ts b/plugins/woocommerce-admin/client/utils/xstate/url-handling.ts similarity index 68% rename from plugins/woocommerce-admin/client/launch-your-store/hub/common.ts rename to plugins/woocommerce-admin/client/utils/xstate/url-handling.ts index e54d37e3d81..c9b7d327d43 100644 --- a/plugins/woocommerce-admin/client/launch-your-store/hub/common.ts +++ b/plugins/woocommerce-admin/client/utils/xstate/url-handling.ts @@ -42,27 +42,21 @@ export const createQueryParamsListener = ( }; }; -type LaunchYourStoreQueryParams = { - sidebar?: string; - content?: string; -}; - -export const updateQueryParams = ( - params: Partial< LaunchYourStoreQueryParams > +export const updateQueryParams = < T extends Record< string, string > >( + params: Partial< T > ) => { - const queryParams = getQuery() as LaunchYourStoreQueryParams; + const queryParams = getQuery() as T; + const changes = Object.entries( params ).reduce( - ( acc: Partial< LaunchYourStoreQueryParams >, [ key, value ] ) => { - // Check if the value is different from the current queryParams. Include if explicitly passed, even if it's undefined. - // This approach assumes that `params` can only have keys that are defined in LaunchYourStoreQueryParams. - if ( - queryParams[ key as keyof LaunchYourStoreQueryParams ] !== value - ) { - acc[ key as keyof LaunchYourStoreQueryParams ] = value; + ( acc: Partial< T >, [ key, value ] ) => { + // Check if the value is different from the current queryParams. + // Include if explicitly passed, even if it's undefined. + if ( queryParams[ key as keyof T ] !== value ) { + acc[ key as keyof T ] = value; } return acc; }, - {} + {} as Partial< T > ); if ( Object.keys( changes ).length > 0 ) { diff --git a/plugins/woocommerce/changelog/dev-refactor-xstate-update-query-params-generic b/plugins/woocommerce/changelog/dev-refactor-xstate-update-query-params-generic new file mode 100644 index 00000000000..d2f049fa0a2 --- /dev/null +++ b/plugins/woocommerce/changelog/dev-refactor-xstate-update-query-params-generic @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +Made XState utils updateQueryParam generic so that it can be reused in other XState machines \ No newline at end of file