2024-03-18 07:44:32 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
2024-03-26 02:29:16 +00:00
|
|
|
import { ActorRefFrom, sendTo, setup, fromCallback } from 'xstate5';
|
2024-03-18 07:44:32 +00:00
|
|
|
import React from 'react';
|
|
|
|
import classnames from 'classnames';
|
2024-03-26 02:29:16 +00:00
|
|
|
import { getQuery } from '@woocommerce/navigation';
|
2024-03-18 07:44:32 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import { LaunchYourStoreHubSidebar } from './components/launch-store-hub';
|
|
|
|
import type { LaunchYourStoreComponentProps } from '..';
|
|
|
|
import type { mainContentMachine } from '../main-content/xstate';
|
2024-03-26 02:29:16 +00:00
|
|
|
import { updateQueryParams, createQueryParamsListener } from '../common';
|
2024-03-18 07:44:32 +00:00
|
|
|
|
|
|
|
export type SidebarMachineContext = {
|
|
|
|
externalUrl: string | null;
|
|
|
|
mainContentMachineRef: ActorRefFrom< typeof mainContentMachine >;
|
|
|
|
};
|
|
|
|
export type SidebarComponentProps = LaunchYourStoreComponentProps & {
|
|
|
|
context: SidebarMachineContext;
|
|
|
|
};
|
|
|
|
export type SidebarMachineEvents =
|
2024-03-26 02:29:16 +00:00
|
|
|
| { type: 'EXTERNAL_URL_UPDATE' }
|
2024-03-18 07:44:32 +00:00
|
|
|
| { type: 'OPEN_EXTERNAL_URL'; url: string }
|
|
|
|
| { type: 'OPEN_WC_ADMIN_URL'; url: string }
|
|
|
|
| { type: 'OPEN_WC_ADMIN_URL_IN_CONTENT_AREA'; url: string }
|
|
|
|
| { type: 'LAUNCH_STORE' }
|
|
|
|
| { type: 'LAUNCH_STORE_SUCCESS' };
|
2024-03-26 02:29:16 +00:00
|
|
|
|
|
|
|
const sidebarQueryParamListener = fromCallback( ( { sendBack } ) => {
|
|
|
|
return createQueryParamsListener( 'sidebar', sendBack );
|
|
|
|
} );
|
|
|
|
|
2024-03-18 07:44:32 +00:00
|
|
|
export const sidebarMachine = setup( {
|
|
|
|
types: {} as {
|
|
|
|
context: SidebarMachineContext;
|
|
|
|
events: SidebarMachineEvents;
|
|
|
|
input: {
|
|
|
|
mainContentMachineRef: ActorRefFrom< typeof mainContentMachine >;
|
|
|
|
};
|
|
|
|
},
|
|
|
|
actions: {
|
|
|
|
openExternalUrl: ( { event } ) => {
|
|
|
|
if ( event.type === 'OPEN_EXTERNAL_URL' ) {
|
|
|
|
window.open( event.url, '_self' );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
showLaunchStoreSuccessPage: sendTo(
|
|
|
|
( { context } ) => context.mainContentMachineRef,
|
|
|
|
{ type: 'SHOW_LAUNCH_STORE_SUCCESS' }
|
|
|
|
),
|
|
|
|
showLoadingPage: sendTo(
|
|
|
|
( { context } ) => context.mainContentMachineRef,
|
|
|
|
{ type: 'SHOW_LOADING' }
|
|
|
|
),
|
2024-03-26 02:29:16 +00:00
|
|
|
updateQueryParams: (
|
|
|
|
_,
|
|
|
|
params: { sidebar?: string; content?: string }
|
|
|
|
) => {
|
|
|
|
updateQueryParams( params );
|
|
|
|
},
|
|
|
|
},
|
|
|
|
guards: {
|
|
|
|
hasSidebarLocation: (
|
|
|
|
_,
|
|
|
|
{ sidebarLocation }: { sidebarLocation: string }
|
|
|
|
) => {
|
|
|
|
const { sidebar } = getQuery() as { sidebar?: string };
|
|
|
|
return !! sidebar && sidebar === sidebarLocation;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
actors: {
|
|
|
|
sidebarQueryParamListener,
|
2024-03-18 07:44:32 +00:00
|
|
|
},
|
|
|
|
} ).createMachine( {
|
|
|
|
id: 'sidebar',
|
2024-03-26 02:29:16 +00:00
|
|
|
initial: 'navigate',
|
2024-03-18 07:44:32 +00:00
|
|
|
context: ( { input } ) => ( {
|
|
|
|
externalUrl: null,
|
|
|
|
mainContentMachineRef: input.mainContentMachineRef,
|
|
|
|
} ),
|
2024-03-26 02:29:16 +00:00
|
|
|
invoke: {
|
|
|
|
id: 'sidebarQueryParamListener',
|
|
|
|
src: 'sidebarQueryParamListener',
|
|
|
|
},
|
2024-03-18 07:44:32 +00:00
|
|
|
states: {
|
2024-03-26 02:29:16 +00:00
|
|
|
navigate: {
|
|
|
|
always: [
|
|
|
|
{
|
|
|
|
guard: {
|
|
|
|
type: 'hasSidebarLocation',
|
|
|
|
params: { sidebarLocation: 'hub' },
|
|
|
|
},
|
|
|
|
target: 'launchYourStoreHub',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
guard: {
|
|
|
|
type: 'hasSidebarLocation',
|
|
|
|
params: { sidebarLocation: 'launch-success' },
|
|
|
|
},
|
|
|
|
target: 'storeLaunchSuccessful',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
target: 'launchYourStoreHub',
|
|
|
|
},
|
|
|
|
],
|
2024-03-18 07:44:32 +00:00
|
|
|
},
|
|
|
|
launchYourStoreHub: {
|
|
|
|
initial: 'preLaunchYourStoreHub',
|
|
|
|
states: {
|
|
|
|
preLaunchYourStoreHub: {
|
|
|
|
always: 'launchYourStoreHub',
|
|
|
|
// do async stuff here such as retrieving task statuses
|
|
|
|
},
|
|
|
|
launchYourStoreHub: {
|
|
|
|
tags: 'sidebar-visible',
|
|
|
|
meta: {
|
|
|
|
component: LaunchYourStoreHubSidebar,
|
|
|
|
},
|
|
|
|
on: {
|
|
|
|
LAUNCH_STORE: {
|
|
|
|
target: '#storeLaunching',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
storeLaunching: {
|
|
|
|
id: 'storeLaunching',
|
|
|
|
initial: 'launching',
|
|
|
|
states: {
|
|
|
|
launching: {
|
|
|
|
tags: 'fullscreen',
|
|
|
|
entry: { type: 'showLoadingPage' },
|
|
|
|
on: {
|
|
|
|
LAUNCH_STORE_SUCCESS: {
|
|
|
|
target: '#storeLaunchSuccessful',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
storeLaunchSuccessful: {
|
|
|
|
id: 'storeLaunchSuccessful',
|
|
|
|
tags: 'fullscreen',
|
2024-03-26 02:29:16 +00:00
|
|
|
entry: [
|
|
|
|
{
|
|
|
|
type: 'updateQueryParams',
|
|
|
|
params: {
|
|
|
|
sidebar: 'launch-success',
|
|
|
|
content: 'launch-store-success',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{ type: 'showLaunchStoreSuccessPage' },
|
|
|
|
],
|
2024-03-18 07:44:32 +00:00
|
|
|
},
|
|
|
|
openExternalUrl: {
|
|
|
|
id: 'openExternalUrl',
|
|
|
|
tags: 'sidebar-visible', // unintuitive but it prevents a layout shift just before leaving
|
|
|
|
entry: [ 'openExternalUrl' ],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
on: {
|
2024-03-26 02:29:16 +00:00
|
|
|
EXTERNAL_URL_UPDATE: {
|
|
|
|
target: '.navigate',
|
|
|
|
},
|
2024-03-18 07:44:32 +00:00
|
|
|
OPEN_EXTERNAL_URL: {
|
|
|
|
target: '#openExternalUrl',
|
|
|
|
},
|
|
|
|
OPEN_WC_ADMIN_URL: {},
|
|
|
|
OPEN_WC_ADMIN_URL_IN_CONTENT_AREA: {},
|
|
|
|
},
|
|
|
|
} );
|
|
|
|
export const SidebarContainer = ( {
|
|
|
|
children,
|
|
|
|
className,
|
|
|
|
}: {
|
|
|
|
children: React.ReactNode;
|
|
|
|
className?: string;
|
|
|
|
} ) => {
|
|
|
|
return (
|
|
|
|
<div
|
|
|
|
className={ classnames(
|
|
|
|
'launch-your-store-layout__sidebar',
|
|
|
|
className
|
|
|
|
) }
|
|
|
|
>
|
|
|
|
{ children }
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|