Skip to content

Commit

Permalink
Launchpad: Update my home controller redirection to use launchpadChec…
Browse files Browse the repository at this point in the history
…klist API (Automattic#76164)

* Update my home controller to use launchpadChecklist API

* Add launchpad checklist api to launchpad step component

* Update useLaunchpadChecklist hook
  • Loading branch information
agrullon95 authored Apr 26, 2023
1 parent 0f237e2 commit df2b982
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useEffect } from '@wordpress/element';
import { getQueryArg } from '@wordpress/url';
import { useTranslate } from 'i18n-calypso';
import { useSelector, useDispatch } from 'react-redux';
import { useLaunchpadChecklist } from 'calypso/../packages/help-center/src/hooks/use-launchpad-checklist';
import DocumentHead from 'calypso/components/data/document-head';
import FormattedHeader from 'calypso/components/formatted-header';
import { useLaunchpad } from 'calypso/data/sites/use-launchpad';
Expand All @@ -18,7 +19,6 @@ import { successNotice } from 'calypso/state/notices/actions';
import { useQuery } from '../../../../hooks/use-query';
import StepContent from './step-content';
import { areLaunchpadTasksCompleted } from './task-helper';
import { launchpadFlowTasks } from './tasks';
import type { Step } from '../../types';
import type { SiteSelect } from '@automattic/data-stores';

Expand All @@ -37,14 +37,18 @@ const Launchpad: Step = ( { navigation, flow }: LaunchpadProps ) => {
const site = useSite();
const {
isError: launchpadFetchError,
data: { launchpad_screen: launchpadScreenOption, checklist_statuses, site_intent },
data: { launchpad_screen: launchpadScreenOption, site_intent: siteIntentOption },
} = useLaunchpad( siteSlug );
const isSiteLaunched = site?.launch_status === 'launched' || false;
const recordSignupComplete = useRecordSignupComplete( flow );
const dispatch = useDispatch();
const { saveSiteSettings } = useWPDispatch( SITE_STORE );
const isLoggedIn = useSelector( isUserLoggedIn );

const {
data: { checklist: launchpadChecklist },
} = useLaunchpadChecklist( siteSlug, siteIntentOption );

const fetchingSiteError = useSelect(
( select ) => ( select( SITE_STORE ) as SiteSelect ).getFetchingSiteError(),
[]
Expand All @@ -65,14 +69,7 @@ const Launchpad: Step = ( { navigation, flow }: LaunchpadProps ) => {
redirectToSiteHome( siteSlug, flow );
}

if (
areLaunchpadTasksCompleted(
site_intent,
launchpadFlowTasks,
checklist_statuses,
isSiteLaunched
)
) {
if ( areLaunchpadTasksCompleted( launchpadChecklist, isSiteLaunched ) ) {
saveSiteSettings( site?.ID, { launchpad_screen: 'off' } );
redirectToSiteHome( siteSlug, flow );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { recordTracksEvent } from 'calypso/lib/analytics/tracks';
import { isVideoPressFlow } from 'calypso/signup/utils';
import { ONBOARD_STORE, SITE_STORE } from '../../../../stores';
import { launchpadFlowTasks } from './tasks';
import { LaunchpadFlowTaskList, LaunchpadStatuses, Task } from './types';
import { LaunchpadChecklist, LaunchpadStatuses, Task } from './types';
import type { SiteDetails } from '@automattic/data-stores';
/**
* Some attributes of these enhanced tasks will soon be fetched through a WordPress REST
Expand Down Expand Up @@ -416,28 +416,25 @@ export function getArrayOfFilteredTasks(
* This is used to as a fallback check to determine if the full
* screen launchpad should be shown or not.
*
* @param {string} siteIntent - The value of a site's site_intent option
* @param {LaunchpadStatuses} checklist_statuses - The value of a site's checklist_statuses option
* @param {LaunchpadChecklist} checklist - The list of tasks for a site's launchpad
* @param {boolean} isSiteLaunched - The value of a site's is_launched option
* @param {LaunchpadFlowTaskList} launchpadFlowTasks - The list of tasks for each site_intent
* @returns {boolean} - True if the final task for the given site_intent is completed
* @returns {boolean} - True if the final task for the given site checklist is completed
*/
export function areLaunchpadTasksCompleted(
site_intent: string,
launchpadFlowTasks: LaunchpadFlowTaskList,
checklist_statuses: LaunchpadStatuses,
checklist: LaunchpadChecklist,
isSiteLaunched: boolean
) {
if ( ! site_intent ) {
if ( ! Array.isArray( checklist ) ) {
return false;
}

const lastTask =
launchpadFlowTasks[ site_intent ][ launchpadFlowTasks[ site_intent ].length - 1 ];
const lastTask = checklist[ checklist.length - 1 ];

// If last task is site_launched, return true if site is launched OR site_launch task is completed
// Else return the status of the last task (will be false if task is not in checklist_statuses)
return lastTask === 'site_launched'
? isSiteLaunched || Boolean( checklist_statuses[ lastTask ] )
: Boolean( checklist_statuses[ lastTask as keyof LaunchpadStatuses ] );
// If last task is site_launched and if site is launched, return true
// Else return the status of the last task
if ( lastTask?.id === 'site_launched' && isSiteLaunched ) {
return true;
}

return lastTask?.completed;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export interface Task {
warning?: boolean;
}

export type LaunchpadChecklist = Task[];

export interface LaunchpadFlowTaskList {
[ string: string ]: string[];
}
Expand Down
21 changes: 11 additions & 10 deletions client/my-sites/customer-home/controller.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { isEcommerce } from '@automattic/calypso-products/src';
import page from 'page';
import { fetchLaunchpadChecklist } from 'calypso/../packages/help-center/src/hooks/use-launchpad-checklist';
import { fetchLaunchpad } from 'calypso/data/sites/use-launchpad';
import { areLaunchpadTasksCompleted } from 'calypso/landing/stepper/declarative-flow/internals/steps-repository/launchpad/task-helper';
import { launchpadFlowTasks } from 'calypso/landing/stepper/declarative-flow/internals/steps-repository/launchpad/tasks';
import { getQueryArgs } from 'calypso/lib/query-args';
import { fetchSitePlugins } from 'calypso/state/plugins/installed/actions';
import { getPluginOnSite } from 'calypso/state/plugins/installed/selectors';
Expand Down Expand Up @@ -47,21 +47,22 @@ export async function maybeRedirect( context, next ) {
const isSiteLaunched = site?.launch_status === 'launched' || false;

try {
const { launchpad_screen, checklist_statuses, site_intent } = await fetchLaunchpad( slug );
const { launchpad_screen: launchpadScreenOption, site_intent: siteIntentOption } =
await fetchLaunchpad( slug );
// We can remove this fetchLaunchpadChecklist call once we add the checklist data into the launchpad endpoint
const { checklist: launchpadChecklist } = await fetchLaunchpadChecklist(
slug,
siteIntentOption
);
if (
launchpad_screen === 'full' &&
! areLaunchpadTasksCompleted(
site_intent,
launchpadFlowTasks,
checklist_statuses,
isSiteLaunched
)
launchpadScreenOption === 'full' &&
! areLaunchpadTasksCompleted( launchpadChecklist, isSiteLaunched )
) {
// The new stepper launchpad onboarding flow isn't registered within the "page"
// client-side router, so page.redirect won't work. We need to use the
// traditional window.location Web API.
const verifiedParam = getQueryArgs()?.verified;
redirectToLaunchpad( slug, site_intent, verifiedParam );
redirectToLaunchpad( slug, siteIntentOption, verifiedParam );
return;
}
} catch ( error ) {}
Expand Down
60 changes: 60 additions & 0 deletions packages/help-center/src/hooks/use-launchpad-checklist.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import apiFetch from '@wordpress/api-fetch';
import { useQuery } from 'react-query';
import wpcomRequest, { canAccessWpcomApis } from 'wpcom-proxy-request';

interface APIFetchOptions {
global: boolean;
path: string;
}

interface Task {
id: string;
completed: boolean;
disabled: boolean;
title?: string;
subtitle?: string;
badgeText?: string;
actionDispatch?: () => void;
isLaunchTask?: boolean;
warning?: boolean;
}

interface LaunchpadTasks {
checklist: Task[];
}

export const fetchLaunchpadChecklist = (
siteSlug: string | null,
siteIntent: string
): Promise< LaunchpadTasks > => {
const slug = encodeURIComponent( siteSlug as string );

return canAccessWpcomApis()
? wpcomRequest( {
path: `sites/${ slug }/launchpad/checklist?checklist_slug=${ siteIntent }`,
apiNamespace: 'wpcom/v2/',
apiVersion: '2',
} )
: apiFetch( {
global: true,
path: `sites/${ slug }/launchpad/checklist?checklist_slug=${ siteIntent }`,
} as APIFetchOptions );
};

export const useLaunchpadChecklist = ( siteSlug: string | null, siteIntent: string ) => {
const key = [ 'launchpad-checklist', siteSlug ];
const queryResult = useQuery( key, () => fetchLaunchpadChecklist( siteSlug, siteIntent ), {
retry: 3,
initialData: {
checklist: [],
},
} );

// Typescript is returning the type "T | undefined" for useQuery,
// regardless of initialData or placeholderData. Because of this, we
// need to narrow the return type ourselves, which is why we have
// the ternary we do below.
// https://github.com/TanStack/query/discussions/1331#discussioncomment-809549
const data = queryResult.isSuccess ? queryResult.data : { checklist: [] };
return { ...queryResult, data };
};

0 comments on commit df2b982

Please sign in to comment.