2024-03-18 07:44:32 +00:00
/ * *
* External dependencies
* /
2024-04-02 07:16:53 +00:00
import {
ActorRefFrom ,
sendTo ,
setup ,
fromCallback ,
fromPromise ,
assign ,
} from 'xstate5' ;
2024-03-18 07:44:32 +00:00
import React from 'react' ;
import classnames from 'classnames' ;
2024-04-05 01:54:30 +00:00
import { getQuery , navigateTo } from '@woocommerce/navigation' ;
2024-04-05 15:08:23 +00:00
import { OPTIONS_STORE_NAME , TaskListType , TaskType } from '@woocommerce/data' ;
import { dispatch } from '@wordpress/data' ;
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-04-05 01:54:30 +00:00
import { taskClickedAction , getLysTasklist } from './tasklist' ;
2024-03-18 07:44:32 +00:00
export type SidebarMachineContext = {
externalUrl : string | null ;
mainContentMachineRef : ActorRefFrom < typeof mainContentMachine > ;
2024-04-02 07:16:53 +00:00
tasklist? : TaskListType ;
testOrderCount : number ;
removeTestOrders? : boolean ;
2024-04-05 15:08:23 +00:00
launchStoreError ? : {
message : string ;
} ;
2024-03-18 07:44:32 +00:00
} ;
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 }
2024-04-02 07:16:53 +00:00
| { type : 'TASK_CLICKED' ; task : TaskType }
2024-03-18 07:44:32 +00:00
| { type : 'OPEN_WC_ADMIN_URL' ; url : string }
| { type : 'OPEN_WC_ADMIN_URL_IN_CONTENT_AREA' ; url : string }
2024-04-02 07:16:53 +00:00
| { type : 'LAUNCH_STORE' ; removeTestOrders : boolean }
| { type : 'LAUNCH_STORE_SUCCESS' }
| { type : 'POP_BROWSER_STACK' } ;
2024-03-26 02:29:16 +00:00
const sidebarQueryParamListener = fromCallback ( ( { sendBack } ) = > {
return createQueryParamsListener ( 'sidebar' , sendBack ) ;
} ) ;
2024-04-05 15:08:23 +00:00
const launchStoreAction = async ( ) = > {
const results = await dispatch ( OPTIONS_STORE_NAME ) . updateOptions ( {
woocommerce_coming_soon : 'no' ,
} ) ;
if ( results . success ) {
return results ;
}
throw new Error ( JSON . stringify ( results ) ) ;
} ;
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' ) {
2024-04-02 07:16:53 +00:00
navigateTo ( { url : event.url } ) ;
2024-03-18 07:44:32 +00:00
}
} ,
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 ) ;
} ,
2024-04-02 07:16:53 +00:00
taskClicked : ( { event } ) = > {
if ( event . type === 'TASK_CLICKED' ) {
2024-04-05 01:54:30 +00:00
taskClickedAction ( event ) ;
2024-04-02 07:16:53 +00:00
}
} ,
openWcAdminUrl : ( { event } ) = > {
if ( event . type === 'OPEN_WC_ADMIN_URL' ) {
navigateTo ( { url : event.url } ) ;
}
} ,
windowHistoryBack : ( ) = > {
window . history . back ( ) ;
} ,
2024-03-26 02:29:16 +00:00
} ,
guards : {
hasSidebarLocation : (
_ ,
{ sidebarLocation } : { sidebarLocation : string }
) = > {
const { sidebar } = getQuery ( ) as { sidebar? : string } ;
return ! ! sidebar && sidebar === sidebarLocation ;
} ,
} ,
actors : {
sidebarQueryParamListener ,
2024-04-02 07:16:53 +00:00
getTasklist : fromPromise ( getLysTasklist ) ,
2024-04-05 15:08:23 +00:00
updateLaunchStoreOptions : fromPromise ( launchStoreAction ) ,
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 ,
2024-04-02 07:16:53 +00:00
testOrderCount : 0 ,
2024-03-18 07:44:32 +00:00
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 : {
2024-04-02 07:16:53 +00:00
invoke : {
src : 'getTasklist' ,
onDone : {
actions : assign ( {
tasklist : ( { event } ) = > event . output ,
} ) ,
target : 'launchYourStoreHub' ,
} ,
} ,
2024-03-18 07:44:32 +00:00
} ,
launchYourStoreHub : {
2024-04-05 15:08:23 +00:00
id : 'launchYourStoreHub' ,
2024-03-18 07:44:32 +00:00
tags : 'sidebar-visible' ,
meta : {
component : LaunchYourStoreHubSidebar ,
} ,
on : {
LAUNCH_STORE : {
target : '#storeLaunching' ,
} ,
} ,
} ,
} ,
} ,
storeLaunching : {
id : 'storeLaunching' ,
initial : 'launching' ,
states : {
launching : {
2024-04-05 15:08:23 +00:00
entry : assign ( { launchStoreError : undefined } ) , // clear the errors if any from previously
invoke : {
src : 'updateLaunchStoreOptions' ,
onDone : {
2024-03-18 07:44:32 +00:00
target : '#storeLaunchSuccessful' ,
} ,
2024-04-05 15:08:23 +00:00
onError : {
actions : assign ( {
launchStoreError : ( { event } ) = > {
return {
message : JSON.stringify ( event . error ) , // for some reason event.error is an empty object, worth investigating if we decide to use the error message somewhere
} ;
} ,
} ) ,
target : '#launchYourStoreHub' ,
} ,
2024-03-18 07:44:32 +00:00
} ,
} ,
} ,
} ,
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' ,
} ,
2024-04-02 07:16:53 +00:00
TASK_CLICKED : {
actions : 'taskClicked' ,
} ,
OPEN_WC_ADMIN_URL : {
actions : 'openWcAdminUrl' ,
} ,
POP_BROWSER_STACK : {
actions : 'windowHistoryBack' ,
} ,
2024-03-18 07:44:32 +00:00
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 >
) ;
} ;