diff --git a/client/data/site-migration/use-update-migration-status.ts b/client/data/site-migration/use-update-migration-status.ts
index 3838dbf179216..cdc9aa9fc50e0 100644
--- a/client/data/site-migration/use-update-migration-status.ts
+++ b/client/data/site-migration/use-update-migration-status.ts
@@ -20,7 +20,11 @@ export const useUpdateMigrationStatus = () => {
} ),
} );
- const { mutate: updateMigrationStatusMutate, ...updateStatusMutationRest } = updateStatusMutation;
+ const {
+ mutate: updateMigrationStatusMutate,
+ mutateAsync: updateMigrationStatusMutateAsync,
+ ...updateStatusMutationRest
+ } = updateStatusMutation;
const updateMigrationStatus = useCallback(
( targetBlogId: SiteId, statusSticker: string ) =>
@@ -28,5 +32,11 @@ export const useUpdateMigrationStatus = () => {
[ updateMigrationStatusMutate ]
);
- return { updateMigrationStatus, updateStatusMutationRest };
+ const updateMigrationStatusAsync = useCallback(
+ ( targetBlogId: SiteId, statusSticker: string ) =>
+ updateMigrationStatusMutateAsync( { targetBlogId, statusSticker } ),
+ [ updateMigrationStatusMutateAsync ]
+ );
+
+ return { updateMigrationStatus, updateMigrationStatusAsync, updateStatusMutationRest };
};
diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/index.tsx b/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/index.tsx
index f0ae72294280c..7324908b60c8e 100644
--- a/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/index.tsx
+++ b/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/index.tsx
@@ -1,8 +1,9 @@
import { StepContainer } from '@automattic/onboarding';
import { useTranslate } from 'i18n-calypso';
-import { FC, useMemo } from 'react';
+import { FC, useMemo, useState } from 'react';
import DocumentHead from 'calypso/components/data/document-head';
import FormattedHeader from 'calypso/components/formatted-header';
+import { LoadingEllipsis } from 'calypso/components/loading-ellipsis';
import { useAnalyzeUrlQuery } from 'calypso/data/site-profiler/use-analyze-url-query';
import { useHostingProviderQuery } from 'calypso/data/site-profiler/use-hosting-provider-query';
import { HOW_TO_MIGRATE_OPTIONS } from 'calypso/landing/stepper/constants';
@@ -62,7 +63,20 @@ const SiteMigrationHowToMigrate: FC< Props > = ( props ) => {
urlData
);
- const { setPendingMigration } = usePendingMigrationStatus( { onSubmit: navigation.submit } );
+ const { setPendingMigration, isLoading: isUpdatingMigrationStatus } = usePendingMigrationStatus( {
+ onSubmit: navigation.submit,
+ } );
+
+ const [ isSubmitting, setIsSubmitting ] = useState( false );
+ const handleClick = async ( value: string ) => {
+ setIsSubmitting( true );
+
+ try {
+ await setPendingMigration( value );
+ } finally {
+ setIsSubmitting( false );
+ }
+ };
const hostingProviderSlug = hostingProviderData?.hosting_provider?.slug;
const shouldDisplayHostIdentificationMessage =
@@ -70,20 +84,21 @@ const SiteMigrationHowToMigrate: FC< Props > = ( props ) => {
hostingProviderSlug !== 'unknown' &&
hostingProviderSlug !== 'automattic';
- const stepContent = (
- <>
+ const stepContent =
+ isSubmitting || isUpdatingMigrationStatus ? (
+
+ ) : (
{ options.map( ( option, i ) => (
setPendingMigration( option.value ) }
+ onClick={ () => handleClick( option.value ) }
/>
) ) }
- >
- );
+ );
const platformText = shouldDisplayHostIdentificationMessage
? translate( 'Your WordPress site is hosted with %(hostingProviderName)s.', {
diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/style.scss b/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/style.scss
index fa615325a8a8e..7f28d87751bd9 100644
--- a/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/style.scss
+++ b/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/style.scss
@@ -43,4 +43,9 @@
.how-to-migrate__description {
color: var(--studio-gray-60);
}
+
+ .how-to-migrate__loader {
+ display: block;
+ margin: 0 auto;
+ }
}
diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/test/index.tsx b/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/test/index.tsx
index 462bb5a70898c..cff9de56ba18a 100644
--- a/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/test/index.tsx
+++ b/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/test/index.tsx
@@ -1,7 +1,7 @@
/**
* @jest-environment jsdom
*/
-import { fireEvent } from '@testing-library/react';
+import { act, fireEvent } from '@testing-library/react';
import React from 'react';
import { useUpdateMigrationStatus } from 'calypso/data/site-migration/use-update-migration-status';
import { RenderStepOptions, mockStepProps, renderStep } from '../../test/helpers';
@@ -47,6 +47,8 @@ describe( 'SiteMigrationHowToMigrate', () => {
mockUpdateMigrationStatus = jest.fn();
( useUpdateMigrationStatus as jest.Mock ).mockReturnValue( {
updateMigrationStatus: mockUpdateMigrationStatus,
+ updateMigrationStatusAsync: mockUpdateMigrationStatus,
+ updateStatusMutationRest: {},
} );
} );
@@ -56,11 +58,14 @@ describe( 'SiteMigrationHowToMigrate', () => {
expect( mockUpdateMigrationStatus ).toHaveBeenCalledWith( siteId, 'migration-pending' );
} );
- it( 'should call updateMigrationStatus with correct value for DIFM option', () => {
+ it( 'should call updateMigrationStatus with correct value for DIFM option', async () => {
const { getByText } = render( { navigation: { submit: mockSubmit } } );
const optionButton = getByText( 'Do it for me' );
- fireEvent.click( optionButton );
+
+ await act( async () => {
+ await fireEvent.click( optionButton );
+ } );
// Check the last call value
const lastCallValue =
@@ -68,11 +73,14 @@ describe( 'SiteMigrationHowToMigrate', () => {
expect( lastCallValue ).toBe( 'migration-pending-difm' );
} );
- it( 'should call updateMigrationStatus with correct value for DIY option', () => {
+ it( 'should call updateMigrationStatus with correct value for DIY option', async () => {
const { getByText } = render( { navigation: { submit: mockSubmit } } );
const optionButton = getByText( "I'll do it myself" );
- fireEvent.click( optionButton );
+
+ await act( async () => {
+ await fireEvent.click( optionButton );
+ } );
// Check the last call value
const lastCallValue =
@@ -80,20 +88,26 @@ describe( 'SiteMigrationHowToMigrate', () => {
expect( lastCallValue ).toBe( 'migration-pending-diy' );
} );
- it( 'should call submit with correct value when DIFM option is clicked', () => {
+ it( 'should call submit with correct value when DIFM option is clicked', async () => {
const { getByText } = render( { navigation: { submit: mockSubmit } } );
const optionButton = getByText( 'Do it for me' );
- fireEvent.click( optionButton );
+
+ await act( async () => {
+ await fireEvent.click( optionButton );
+ } );
expect( mockSubmit ).toHaveBeenCalledWith( { destination: 'upgrade', how: 'difm' } );
} );
- it( 'should call submit with correct value for DIY option', () => {
+ it( 'should call submit with correct value for DIY option', async () => {
const { getByText } = render( { navigation: { submit: mockSubmit } } );
const optionButton = getByText( "I'll do it myself" );
- fireEvent.click( optionButton );
+
+ await act( async () => {
+ await fireEvent.click( optionButton );
+ } );
expect( mockSubmit ).toHaveBeenCalledWith( { destination: 'upgrade', how: 'myself' } );
} );
diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/use-pending-migration-status.ts b/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/use-pending-migration-status.ts
index 8298129f1898d..abf1c886ee785 100644
--- a/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/use-pending-migration-status.ts
+++ b/client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-how-to-migrate/use-pending-migration-status.ts
@@ -18,7 +18,16 @@ const usePendingMigrationStatus = ( { onSubmit }: PendingMigrationStatusProps )
? true
: false;
- const { updateMigrationStatus } = useUpdateMigrationStatus();
+ const {
+ updateMigrationStatus,
+ updateMigrationStatusAsync,
+ updateStatusMutationRest: {
+ isIdle: isMigrationStatusUpdateIdle,
+ isPending: isMigrationStatusUpdatePending,
+ },
+ } = useUpdateMigrationStatus();
+
+ const isLoading = isMigrationStatusUpdateIdle || isMigrationStatusUpdatePending;
// Register pending migration status when loading the step.
useEffect( () => {
@@ -27,11 +36,11 @@ const usePendingMigrationStatus = ( { onSubmit }: PendingMigrationStatusProps )
}
}, [ siteId, updateMigrationStatus ] );
- const setPendingMigration = ( how: string ) => {
+ const setPendingMigration = async ( how: string ) => {
const destination = canInstallPlugins ? 'migrate' : 'upgrade';
if ( siteId ) {
const parsedHow = how === HOW_TO_MIGRATE_OPTIONS.DO_IT_MYSELF ? 'diy' : how;
- updateMigrationStatus( siteId, `migration-pending-${ parsedHow }` );
+ await updateMigrationStatusAsync( siteId, `migration-pending-${ parsedHow }` );
}
if ( onSubmit ) {
@@ -39,7 +48,7 @@ const usePendingMigrationStatus = ( { onSubmit }: PendingMigrationStatusProps )
}
};
- return { setPendingMigration };
+ return { setPendingMigration, isLoading };
};
export default usePendingMigrationStatus;