Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Export calculateProgress method * Onboarding: introduce Wix flow * Introduce util class * Onboarding: create done button component * Implement Wix import logic * Redirect user to the newly created onboarding Wix flow The importer URL will remain the same if the Wix onboarding feature flag is turned off. * Fix issue with getting query params * Handle edge case, don't run import process on the browser's back * Fix issue with showing progress bar value change * Fix type checking issue
- Loading branch information
Showing
10 changed files
with
358 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,158 @@ | ||
import { isEnabled } from '@automattic/calypso-config'; | ||
import React from 'react'; | ||
import { Title } from '@automattic/onboarding'; | ||
import page from 'page'; | ||
import React, { useEffect, useState } from 'react'; | ||
import { connect } from 'react-redux'; | ||
import { LoadingEllipsis } from 'calypso/components/loading-ellipsis'; | ||
import { Interval, EVERY_FIVE_SECONDS } from 'calypso/lib/interval'; | ||
import { decodeURIComponentIfValid } from 'calypso/lib/url'; | ||
import StepWrapper from 'calypso/signup/step-wrapper'; | ||
import { fetchImporterState } from 'calypso/state/imports/actions'; | ||
import { | ||
getImporterStatusForSiteId, | ||
isImporterStatusHydrated, | ||
} from 'calypso/state/imports/selectors'; | ||
import { canCurrentUser } from 'calypso/state/selectors/can-current-user'; | ||
import { getSiteId } from 'calypso/state/sites/selectors'; | ||
import { Importer, QueryObject, ImportJob } from './types'; | ||
import { getImporterTypeForEngine } from './util'; | ||
import WixImporter from './wix'; | ||
|
||
import './style.scss'; | ||
|
||
/* eslint-disable wpcalypso/jsx-classname-namespace */ | ||
|
||
interface Props { | ||
path: string; | ||
stepName: string; | ||
stepSectionName: string; | ||
queryObject: { | ||
temp: string; | ||
}; | ||
queryObject: QueryObject; | ||
siteId: number; | ||
siteSlug: string; | ||
fromSite: string; | ||
canImport: boolean; | ||
isImporterStatusHydrated: boolean; | ||
siteImports: ImportJob[]; | ||
fetchImporterState: ( siteId: number ) => void; | ||
} | ||
|
||
const ImportOnboardingFrom: React.FunctionComponent< Props > = ( props ) => { | ||
const { stepSectionName, queryObject } = props; | ||
const { | ||
stepSectionName, | ||
siteId, | ||
canImport, | ||
siteSlug, | ||
siteImports, | ||
isImporterStatusHydrated, | ||
fromSite, | ||
} = props; | ||
|
||
/** | ||
↓ Fields | ||
*/ | ||
const engine: Importer = stepSectionName.toLowerCase() as Importer; | ||
const [ runImportInitially, setRunImportInitially ] = useState( false ); | ||
const getImportJob = ( engine: Importer ): ImportJob | undefined => { | ||
return siteImports.find( ( x ) => x.type === getImporterTypeForEngine( engine ) ); | ||
}; | ||
|
||
/** | ||
↓ Effects | ||
*/ | ||
useEffect( fetchImporters, [ siteId ] ); | ||
useEffect( checkInitialRunState, [ siteId ] ); | ||
|
||
/** | ||
↓ Methods | ||
*/ | ||
function fetchImporters() { | ||
siteId && props.fetchImporterState( siteId ); | ||
} | ||
|
||
function isLoading() { | ||
return ! isImporterStatusHydrated; | ||
} | ||
|
||
function hasPermission(): boolean { | ||
return canImport; | ||
} | ||
|
||
function checkInitialRunState() { | ||
const searchParams = new URLSearchParams( window.location.search ); | ||
|
||
// run query param indicates that the import process can be run immediately, | ||
// but before proceeding, remove it from the URL path | ||
// because of the browser's back edge case | ||
if ( searchParams.get( 'run' ) === 'true' ) { | ||
setRunImportInitially( true ); | ||
page.replace( props.path.replace( '&run=true', '' ).replace( 'run=true', '' ) ); | ||
} | ||
} | ||
|
||
return ( | ||
<StepWrapper | ||
flowName={ 'import-from' } | ||
hideSkip={ true } | ||
hideBack={ true } | ||
hideNext={ true } | ||
hideFormattedHeader={ true } | ||
stepContent={ | ||
<div className="import__onboarding-page"> | ||
{ stepSectionName === 'wix' && isEnabled( 'gutenboarding/import-from-wix' ) && ( | ||
<WixImporter queryObject={ queryObject } /> | ||
) } | ||
</div> | ||
} | ||
/> | ||
<> | ||
<Interval onTick={ fetchImporters } period={ EVERY_FIVE_SECONDS } /> | ||
|
||
<StepWrapper | ||
flowName={ 'import-from' } | ||
hideSkip={ true } | ||
hideBack={ true } | ||
hideNext={ true } | ||
hideFormattedHeader={ true } | ||
stepContent={ | ||
<div className="import__onboarding-page import-layout__center"> | ||
<div className="import-layout__center"> | ||
{ ( () => { | ||
/** | ||
* Loading screen | ||
*/ | ||
if ( isLoading() ) { | ||
return <LoadingEllipsis />; | ||
} else if ( ! hasPermission() ) { | ||
/** | ||
* Permission screen | ||
*/ | ||
return <Title>You are not authorized to view this page</Title>; | ||
} else if ( engine === 'wix' && isEnabled( 'gutenboarding/import-from-wix' ) ) { | ||
/** | ||
* Wix importer | ||
*/ | ||
return ( | ||
<WixImporter | ||
job={ getImportJob( engine ) } | ||
run={ runImportInitially } | ||
siteId={ siteId } | ||
siteSlug={ siteSlug } | ||
fromSite={ fromSite } | ||
/> | ||
); | ||
} | ||
} )() } | ||
</div> | ||
</div> | ||
} | ||
/> | ||
</> | ||
); | ||
}; | ||
|
||
export default ImportOnboardingFrom; | ||
export default connect( | ||
( state ) => { | ||
const searchParams = new URLSearchParams( window.location.search ); | ||
|
||
const siteSlug = decodeURIComponentIfValid( searchParams.get( 'to' ) ); | ||
const fromSite = decodeURIComponentIfValid( searchParams.get( 'from' ) ); | ||
const siteId = getSiteId( state, siteSlug ) as number; | ||
|
||
return { | ||
siteId, | ||
siteSlug, | ||
fromSite, | ||
siteImports: getImporterStatusForSiteId( state, siteId ), | ||
isImporterStatusHydrated: isImporterStatusHydrated( state ), | ||
canImport: canCurrentUser( state, siteId, 'manage_options' ), | ||
}; | ||
}, | ||
{ | ||
fetchImporterState, | ||
} | ||
)( ImportOnboardingFrom ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,4 +9,8 @@ | |
min-width: 465px; | ||
} | ||
} | ||
|
||
.wpcom__loading-ellipsis { | ||
margin: auto; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
export type Importer = 'wix' | 'medium'; | ||
export type QueryObject = { | ||
from: string; | ||
to: string; | ||
}; | ||
|
||
export interface ImportJob { | ||
importerId: string; | ||
importerState: string; | ||
type: string; | ||
site: { ID: number }; | ||
customData: { [ key: string ]: any }; | ||
errorData: { | ||
type: string; | ||
description: string; | ||
}; | ||
progress: { | ||
page: { completed: number; total: number }; | ||
post: { completed: number; total: number }; | ||
comment: { completed: number; total: number }; | ||
attachment: { completed: number; total: number }; | ||
}; | ||
} | ||
|
||
export interface ImportJobParams { | ||
engine: Importer; | ||
importerStatus: ImportJob; | ||
params: { engine: Importer }; | ||
site: { ID: number }; | ||
targetSiteUrl: string; | ||
supportedContent: string[]; | ||
unsupportedContent: string[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { Importer } from './types'; | ||
|
||
export const getImporterTypeForEngine = ( engine: Importer ) => `importer-type-${ engine }`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { NextButton } from '@automattic/onboarding'; | ||
import { useI18n } from '@wordpress/react-i18n'; | ||
import page from 'page'; | ||
import React from 'react'; | ||
import { ImportJob } from '../types'; | ||
|
||
interface Props { | ||
job: ImportJob; | ||
siteId: number; | ||
siteSlug: string; | ||
resetImport: ( siteId: number, importerId: string ) => void; | ||
} | ||
const DoneButton: React.FunctionComponent< Props > = ( props ) => { | ||
const { __ } = useI18n(); | ||
const { job, siteId, siteSlug, resetImport } = props; | ||
|
||
function onButtonClick() { | ||
redirectToSiteView(); | ||
resetImport( siteId, job.importerId ); | ||
} | ||
|
||
function redirectToSiteView() { | ||
const destination = '/view/' + ( siteSlug || '' ); | ||
page( destination ); | ||
} | ||
|
||
return <NextButton onClick={ onButtonClick }>{ __( 'View site' ) }</NextButton>; | ||
}; | ||
|
||
export default DoneButton; |
Oops, something went wrong.