Skip to content

Commit

Permalink
Add verification & continue anyway path In site migration credentials…
Browse files Browse the repository at this point in the history
… form, change error message area on top (#94869)

* Add new properties in types

* Move hooks, add additional error handling

* New error section on top, continue anyway button

* Fix style of error section

* Don't show verifying credentials when requesting anyway

* Add tests for Continue button states

* Test Continue Anyways button requests with proper payload

* Update client/landing/stepper/declarative-flow/internals/steps-repository/site-migration-credentials/components/credentials-form.tsx

Co-authored-by: Miroslav Mitev <m1r0@users.noreply.github.com>

* Change name of requestInAnywayMode variable

---------

Co-authored-by: Miroslav Mitev <m1r0@users.noreply.github.com>
  • Loading branch information
Imran92 and m1r0 authored Sep 26, 2024
1 parent 814235d commit 37fea76
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { useIsEnglishLocale } from '@automattic/i18n-utils';
import { NextButton } from '@automattic/onboarding';
import { useTranslate } from 'i18n-calypso';
import { FC } from 'react';
import Banner from 'calypso/components/banner';
import Notice from 'calypso/components/notice';
import { useQuery } from 'calypso/landing/stepper/hooks/use-query';
import { useCredentialsForm } from '../use-credentials-form';
import { useCredentialsForm } from '../hooks/use-credentials-form';
import { AccessMethodPicker } from './access-method-picker';
import { BackupFileField } from './backup-file-field';
import { ErrorMessage } from './error-message';
Expand All @@ -29,21 +29,29 @@ export const CredentialsForm: FC< CredentialsFormProps > = ( { onSubmit, onSkip
isPending,
submitHandler,
importSiteQueryParam,
getContinueButtonText,
} = useCredentialsForm( onSubmit );

const queryError = useQuery().get( 'error' ) || null;

let errorMessage;
if ( isEnglishLocale && errors.root && errors.root.type !== 'manual' && errors.root.message ) {
errorMessage = errors.root.message;
} else if ( queryError === 'ticket-creation' ) {
errorMessage = translate(
'We ran into a problem submitting your details. Please try again shortly.'
);
}
return (
<form className="site-migration-credentials__form" onSubmit={ handleSubmit( submitHandler ) }>
{ queryError === 'ticket-creation' && (
<Banner
className="site-migration-credentials__error-banner"
showIcon={ false }
title=""
description={ translate(
'We ran into a problem submitting your details. Please try again shortly.'
) }
></Banner>
{ errorMessage && (
<Notice
className="site-migration-credentials__error-notice"
status="is-warning"
showDismiss={ false }
>
{ errorMessage }
</Notice>
) }
<div className="site-migration-credentials__content">
<AccessMethodPicker control={ control } />
Expand All @@ -66,11 +74,13 @@ export const CredentialsForm: FC< CredentialsFormProps > = ( { onSubmit, onSkip

<SpecialInstructions control={ control } errors={ errors } />

<ErrorMessage error={ errors.root } />
<ErrorMessage
error={ errors.root && errors.root.type === 'manual' ? errors.root : undefined }
/>

<div className="site-migration-credentials__submit">
<NextButton disabled={ isPending } type="submit">
{ translate( 'Continue' ) }
{ getContinueButtonText() }
</NextButton>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { useEffect } from 'react';
import { useIsEnglishLocale } from '@automattic/i18n-utils';
import { useTranslate } from 'i18n-calypso';
import { useCallback, useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { useQuery } from 'calypso/landing/stepper/hooks/use-query';
import { recordTracksEvent } from 'calypso/lib/analytics/tracks';
import { useFormErrorMapping } from './hooks/use-form-error-mapping';
import { CredentialsFormData } from './types';
import { CredentialsFormData } from '../types';
import { useFormErrorMapping } from './use-form-error-mapping';
import { useSiteMigrationCredentialsMutation } from './use-site-migration-credentials-mutation';

export const useCredentialsForm = ( onSubmit: () => void ) => {
const importSiteQueryParam = useQuery().get( 'from' ) || '';
const [ canBypassVerification, setCanBypassVerification ] = useState( false );
const translate = useTranslate();
const isEnglishLocale = useIsEnglishLocale();

const {
isPending,
mutate: requestAutomatedMigration,
Expand Down Expand Up @@ -49,22 +55,48 @@ export const useCredentialsForm = ( onSubmit: () => void ) => {
}, [ isSuccess, onSubmit ] );

useEffect( () => {
if ( error ) {
recordTracksEvent( 'calypso_site_migration_automated_request_error' );
if ( ! error ) {
return;
}

recordTracksEvent( 'calypso_site_migration_automated_request_error' );

const { code } = error;

const anywayModeErrors = [ 'automated_migration_tools_login_and_get_cookies_test_failed' ];

if ( anywayModeErrors.includes( code ) ) {
setCanBypassVerification( true );
}
}, [ error ] );

useEffect( () => {
const { unsubscribe } = watch( () => {
clearErrors( 'root' );
setCanBypassVerification( false );
} );
return () => unsubscribe();
}, [ watch, clearErrors ] );

const submitHandler = ( data: CredentialsFormData ) => {
requestAutomatedMigration( data );
requestAutomatedMigration( {
...data,
bypassVerification: canBypassVerification || ! isEnglishLocale,
} );
};

const getContinueButtonText = useCallback( () => {
if ( isEnglishLocale && isPending && ! canBypassVerification ) {
return translate( 'Verifying credentials' );
}

if ( isEnglishLocale && canBypassVerification ) {
return translate( 'Continue anyways' );
}

return translate( 'Continue' );
}, [ isPending, canBypassVerification, isEnglishLocale, translate ] );

return {
formState: { errors },
control,
Expand All @@ -74,5 +106,6 @@ export const useCredentialsForm = ( onSubmit: () => void ) => {
isPending,
submitHandler,
importSiteQueryParam,
getContinueButtonText,
};
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useIsEnglishLocale } from '@automattic/i18n-utils';
import { useTranslate } from 'i18n-calypso';
import { useCallback, useMemo } from 'react';
import { FieldErrors } from 'react-hook-form';
Expand All @@ -16,6 +17,7 @@ export const useFormErrorMapping = (
variables?: CredentialsFormData | null
): FieldErrors< CredentialsFormData > | undefined => {
const translate = useTranslate();
const isEnglishLocale = useIsEnglishLocale();

const fieldMapping: Record< string, { type: string; message: string } | null > = useMemo(
() => ( {
Expand All @@ -27,6 +29,32 @@ export const useFormErrorMapping = (
[ translate ]
);

const getCredentialsErrorMessage = useCallback(
( errorCode: any ) => {
switch ( errorCode ) {
case 404:
return {
from_url: {
type: 'manual',
message: translate( 'Check your site address.' ),
},
};
default:
return {
username: {
type: 'manual',
message: translate( 'Check your username.' ),
},
password: {
type: 'manual',
message: translate( 'Check your password.' ),
},
};
}
},
[ translate ]
);

const getTranslatedMessage = useCallback(
( key: string ) => {
return (
Expand All @@ -52,6 +80,22 @@ export const useFormErrorMapping = (
};
}

if (
isEnglishLocale &&
code === 'automated_migration_tools_login_and_get_cookies_test_failed'
) {
const errors = {
root: {
type: 'special',
message: translate(
'We could not verify your credentials. Can you double check your account information and try again?'
),
},
...getCredentialsErrorMessage( data?.response_code ),
};
return errors;
}

if ( code !== 'rest_invalid_param' || ! data?.params ) {
return { root: { type: 'manual', message } };
}
Expand All @@ -69,7 +113,7 @@ export const useFormErrorMapping = (
{} as Record< string, { type: string; message: string } >
);
},
[ getTranslatedMessage, translate ]
[ getTranslatedMessage, translate, getCredentialsErrorMessage, isEnglishLocale ]
);

return useMemo( () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMutation, UseMutationOptions } from '@tanstack/react-query';
import wpcomRequest from 'wpcom-proxy-request';
import { useSiteSlugParam } from 'calypso/landing/stepper/hooks/use-site-slug-param';
import { ApiError, CredentialsFormData } from './types';
import { ApiError, CredentialsFormData } from '../types';

interface AutomatedMigrationAPIResponse {
success: boolean;
Expand All @@ -15,6 +15,7 @@ interface AutomatedMigrationBody {
password?: string;
backup_file_location?: string;
notes?: string;
bypass_verification?: boolean;
}

export const useSiteMigrationCredentialsMutation = <
Expand All @@ -33,6 +34,7 @@ export const useSiteMigrationCredentialsMutation = <
notes,
migrationType,
backupFileLocation,
bypassVerification,
}: CredentialsFormData ) => {
let body: AutomatedMigrationBody = {
migration_type: migrationType,
Expand All @@ -46,6 +48,7 @@ export const useSiteMigrationCredentialsMutation = <
from_url,
username,
password,
bypass_verification: bypassVerification,
};
} else {
// In case of backup, we need to send the backup file location.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,19 @@
margin-bottom: 60px;
}

.site-migration-credentials__content,
.site-migration-credentials__error-banner {
&__error-notice.notice .notice__icon-wrapper svg.notice__icon {
fill: var(--color-text-inverted);
}

&__error-notice,
&__content,
&__error-banner {
margin: 0 auto 16px;
max-width: 500px;
}

.site-migration-credentials__content,
.site-migration-credentials__error-banner {
@media (min-width: $break-mobile) {
margin-bottom: 16px;
}
Expand Down
Loading

0 comments on commit 37fea76

Please sign in to comment.