/** * External dependencies */ import { createMachine } from 'xstate'; import { getQuery } from '@woocommerce/navigation'; /** * Internal dependencies */ import { ApiCallLoader, AssembleHubLoader } from './pages/ApiCallLoader'; import { FlowType } from '../types'; import { DesignWithoutAIStateMachineContext } from './types'; import { services } from './services'; import { actions } from './actions'; export const hasStepInUrl = ( _ctx: unknown, _evt: unknown, { cond }: { cond: unknown } ) => { const { path = '' } = getQuery() as { path: string }; const pathFragments = path.split( '/' ); return ( pathFragments[ 2 ] === // [0] '', [1] 'customize-store', [2] design step slug ( cond as { step: string | undefined } ).step ); }; export type DesignWithoutAIStateMachineEvents = | { type: 'EXTERNAL_URL_UPDATE' } | { type: 'NO_AI_FLOW_ERROR'; payload: { hasError: boolean } }; export const designWithNoAiStateMachineDefinition = createMachine( { id: 'designWithoutAI', predictableActionArguments: true, preserveActionOrder: true, schema: { context: {} as DesignWithoutAIStateMachineContext, events: {} as DesignWithoutAIStateMachineEvents, }, invoke: { src: 'browserPopstateHandler', }, on: { EXTERNAL_URL_UPDATE: { target: 'navigate', }, }, context: { startLoadingTime: null, flowType: FlowType.noAI, apiCallLoader: { hasErrors: false, }, }, initial: 'navigate', states: { navigate: { always: [ { cond: { type: 'hasStepInUrl', step: 'design', }, target: 'preAssembleSite', }, ], }, preAssembleSite: { initial: 'preApiCallLoader', id: 'preAssembleSite', states: { preApiCallLoader: { meta: { // @todo: Move the current component in a common folder or create a new one dedicated to this flow. component: ApiCallLoader, }, type: 'parallel', states: { installAndActivateTheme: { initial: 'pending', states: { pending: { invoke: { src: 'installAndActivateTheme', onDone: { target: 'success', }, onError: { actions: 'redirectToIntroWithError', }, }, }, success: { type: 'final' }, }, }, assembleSite: { initial: 'pending', states: { pending: { invoke: { src: 'assembleSite', onDone: { target: 'success', }, onError: { actions: 'redirectToIntroWithError', }, }, }, success: { type: 'final', }, }, }, createProducts: { initial: 'pending', states: { pending: { invoke: { src: 'createProducts', onDone: { target: 'success', }, onError: { actions: 'redirectToIntroWithError', }, }, }, success: { type: 'final', }, }, }, }, onDone: { target: '#designWithoutAI.showAssembleHub', }, }, }, }, showAssembleHub: { id: 'showAssembleHub', meta: { component: AssembleHubLoader, }, entry: [ 'redirectToAssemblerHub' ], type: 'final', }, }, }, { actions, services, guards: { hasStepInUrl, }, } );