Merge pull request #32473 from woocommerce/feature/32164_new_task_list_loading_placeholder

New task list loading placeholder for experiment 1
This commit is contained in:
louwie17 2022-04-08 09:55:45 -03:00 committed by GitHub
commit f7937593e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 109 additions and 97 deletions

View File

@ -42,6 +42,7 @@ import { WelcomeModal } from './welcome-modal';
import { useHeadercardExperimentHook } from './hooks/use-headercard-experiment-hook';
import './style.scss';
import '../dashboard/style.scss';
import { getAdminSetting } from '~/utils/admin-settings';
const Tasks = lazy( () =>
import( /* webpackChunkName: "tasks" */ '../tasks' )
@ -285,8 +286,7 @@ export default compose(
const { getOption, hasFinishedResolution } = select(
OPTIONS_STORE_NAME
);
const { getTaskList, getTaskLists } = select( ONBOARDING_STORE_NAME );
const taskLists = getTaskLists();
const { getTaskList } = select( ONBOARDING_STORE_NAME );
const welcomeFromCalypsoModalDismissed =
getOption( WELCOME_FROM_CALYPSO_MODAL_DISMISSED_OPTION_NAME ) !==
@ -337,7 +337,7 @@ export default compose(
shouldShowWelcomeModal,
shouldShowWelcomeFromCalypsoModal,
isTaskListHidden: getTaskList( 'setup' )?.isHidden,
hasTaskList: !! taskLists.find( ( list ) => list.isVisible ),
hasTaskList: getAdminSetting( 'visibleTaskListIds', [] ).length > 0,
taskListComplete: getTaskList( 'setup' )?.isComplete,
installTimestamp,
installTimestampHasResolved,

View File

@ -15,7 +15,7 @@ import { ONBOARDING_STORE_NAME, PLUGINS_STORE_NAME } from '@woocommerce/data';
import CartModal from '../../dashboard/components/cart-modal';
import { getCategorizedOnboardingProducts } from '../../dashboard/utils';
const PurchaseTaskItem = () => {
const PurchaseTaskItem = ( { defaultTaskItem } ) => {
const [ cartModalOpen, setCartModalOpen ] = useState( false );
const { installedPlugins, productTypes, profileItems } = useSelect(
@ -47,25 +47,32 @@ const PurchaseTaskItem = () => {
installedPlugins
);
const { remainingProducts } = groupedProducts;
const DefaultTaskItem = defaultTaskItem;
return (
<>
<DefaultTaskItem
onClick={ () => {
if ( remainingProducts.length ) {
toggleCartModal();
}
} }
/>
{ cartModalOpen && (
<CartModal
onClose={ () => toggleCartModal() }
onClickPurchaseLater={ () => toggleCartModal() }
/>
) }
</>
);
};
const PurchaseTaskItemFill = () => {
return (
<WooOnboardingTaskListItem id="purchase">
{ ( { defaultTaskItem: DefaultTaskItem } ) => (
<>
<DefaultTaskItem
onClick={ () => {
if ( remainingProducts.length ) {
toggleCartModal();
}
} }
/>
{ cartModalOpen && (
<CartModal
onClose={ () => toggleCartModal() }
onClickPurchaseLater={ () => toggleCartModal() }
/>
) }
</>
{ ( { defaultTaskItem } ) => (
<PurchaseTaskItem defaultTaskItem={ defaultTaskItem } />
) }
</WooOnboardingTaskListItem>
);
@ -73,5 +80,5 @@ const PurchaseTaskItem = () => {
registerPlugin( 'woocommerce-admin-task-purchase', {
scope: 'woocommerce-tasks',
render: PurchaseTaskItem,
render: PurchaseTaskItemFill,
} );

View File

@ -4,7 +4,7 @@
import { __ } from '@wordpress/i18n';
import { MenuGroup, MenuItem } from '@wordpress/components';
import { check } from '@wordpress/icons';
import { Fragment, useEffect, lazy, Suspense } from '@wordpress/element';
import { Fragment, useEffect } from '@wordpress/element';
import { useDispatch, useSelect } from '@wordpress/data';
import { ONBOARDING_STORE_NAME, OPTIONS_STORE_NAME } from '@woocommerce/data';
import { useExperiment } from '@woocommerce/explat';
@ -15,29 +15,19 @@ import { recordEvent } from '@woocommerce/tracks';
*/
import { DisplayOption } from '~/activity-panel/display-options';
import { Task } from './task';
import { TasksPlaceholder } from './placeholder';
import { TasksPlaceholder, TasksPlaceholderProps } from './placeholder';
import './tasks.scss';
import { TaskListProps } from './task-list';
import { TaskListProps, TaskList } from './task-list';
import { TaskList as TwoColumnTaskList } from '../two-column-tasks/task-list';
import TwoColumnTaskListPlaceholder from '../two-column-tasks/placeholder';
import '../two-column-tasks/style.scss';
import { getAdminSetting } from '~/utils/admin-settings';
export type TasksProps = {
query: { task?: string };
};
const TaskList = lazy(
() => import( /* webpackChunkName: "task-list" */ './task-list' )
);
const TwoColumnTaskList = lazy(
() =>
import(
/* webpackChunkName: "two-column-task-list" */ '../two-column-tasks/task-list'
)
);
function getTaskListComponent(
taskListId: string
): React.LazyExoticComponent< React.FC< TaskListProps > > {
function getTaskListComponent( taskListId: string ): React.FC< TaskListProps > {
switch ( taskListId ) {
case 'setup_experiment_1':
return TwoColumnTaskList;
@ -46,6 +36,17 @@ function getTaskListComponent(
}
}
function getTaskListPlaceholderComponent(
taskListId: string
): React.FC< TasksPlaceholderProps > {
switch ( taskListId ) {
case 'setup_experiment_1':
return TwoColumnTaskListPlaceholder;
default:
return TasksPlaceholder;
}
}
export const Tasks: React.FC< TasksProps > = ( { query } ) => {
const { task } = query;
const { hideTaskList } = useDispatch( ONBOARDING_STORE_NAME );
@ -56,9 +57,9 @@ export const Tasks: React.FC< TasksProps > = ( { query } ) => {
const { isResolving, taskLists } = useSelect( ( select ) => {
return {
isResolving: select( ONBOARDING_STORE_NAME ).isResolving(
'getTaskLists'
),
isResolving: ! select(
ONBOARDING_STORE_NAME
).hasFinishedResolution( 'getTaskLists' ),
taskLists: select( ONBOARDING_STORE_NAME ).getTaskLists(),
};
} );
@ -108,8 +109,13 @@ export const Tasks: React.FC< TasksProps > = ( { query } ) => {
return null;
}
const taskListIds = getAdminSetting( 'visibleTaskListIds', [] );
const TaskListPlaceholderComponent = getTaskListPlaceholderComponent(
taskListIds[ 0 ]
);
if ( isResolving ) {
return <TasksPlaceholder query={ query } />;
return <TaskListPlaceholderComponent query={ query } />;
}
if ( currentTask ) {
@ -121,7 +127,7 @@ export const Tasks: React.FC< TasksProps > = ( { query } ) => {
}
if ( isLoadingExperiment ) {
return <TasksPlaceholder query={ query } />;
return <TaskListPlaceholderComponent query={ query } />;
}
return taskLists
@ -131,17 +137,7 @@ export const Tasks: React.FC< TasksProps > = ( { query } ) => {
: ! id.endsWith( 'two_column' )
)
.map( ( taskList ) => {
const {
id,
eventPrefix,
isComplete,
isHidden,
isVisible,
isToggleable,
title,
tasks,
displayProgressHeader,
} = taskList;
const { id, isHidden, isVisible, isToggleable } = taskList;
if ( ! isVisible ) {
return null;
@ -151,22 +147,14 @@ export const Tasks: React.FC< TasksProps > = ( { query } ) => {
return (
<Fragment key={ id }>
<Suspense fallback={ null }>
<TaskListComponent
id={ id }
eventPrefix={ eventPrefix }
isComplete={ isComplete }
isExpandable={
experimentAssignment?.variationName ===
'treatment'
}
query={ query }
tasks={ tasks }
title={ title }
twoColumns={ false }
displayProgressHeader={ displayProgressHeader }
/>
</Suspense>
<TaskListComponent
isExpandable={
experimentAssignment?.variationName === 'treatment'
}
query={ query }
twoColumns={ false }
{ ...taskList }
/>
{ isToggleable && (
<DisplayOption>
<MenuGroup

View File

@ -27,10 +27,13 @@ jest.mock( '@wordpress/data', () => {
jest.mock( '@woocommerce/explat' );
jest.mock( '@woocommerce/tracks' );
jest.mock( '../task-list', () => ( { id } ) => <div>task-list:{ id }</div> );
jest.mock( '../../two-column-tasks/task-list', () => ( { id } ) => (
<div>two-column-list:{ id }</div>
) );
jest.mock( '../task-list', () => ( {
TaskList: ( { id } ) => <div>task-list:{ id }</div>,
} ) );
jest.mock( '../../two-column-tasks/task-list', () => ( {
TaskList: ( { id } ) => <div>two-column-list:{ id }</div>,
} ) );
jest.mock( '../task', () => ( {
Task: ( { query } ) => <div>task:{ query.task }</div>,

View File

@ -3,7 +3,7 @@
*/
import { __ } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';
import { ONBOARDING_STORE_NAME, OPTIONS_STORE_NAME } from '@woocommerce/data';
import { ONBOARDING_STORE_NAME } from '@woocommerce/data';
/**
* Internal dependencies
@ -14,25 +14,7 @@ import TaskList from './task-list';
import TaskListPlaceholder from './placeholder';
import { Task } from '../tasks/task';
const taskDashboardSelect = ( select ) => {
const { getOption, hasFinishedResolution } = select( OPTIONS_STORE_NAME );
return {
keepCompletedTaskList: getOption(
'woocommerce_task_list_keep_completed'
),
isResolving: ! hasFinishedResolution( 'getOption', [
'woocommerce_task_list_keep_completed',
] ),
};
};
const TaskDashboard = ( { query, twoColumns } ) => {
const {
keepCompletedTaskList,
isResolving: isResolvingOptions,
} = useSelect( taskDashboardSelect );
const { task } = query;
const { isResolving, taskLists } = useSelect( ( select ) => {
@ -72,7 +54,7 @@ const TaskDashboard = ( { query, twoColumns } ) => {
return null;
}
if ( isResolving || isResolvingOptions || ! taskLists[ 0 ] ) {
if ( isResolving || ! taskLists[ 0 ] ) {
return <TaskListPlaceholder twoColumns={ twoColumns } />;
}
@ -104,7 +86,7 @@ const TaskDashboard = ( { query, twoColumns } ) => {
id={ taskList.id }
eventName="tasklist"
twoColumns={ twoColumns }
keepCompletedTaskList={ keepCompletedTaskList }
keepCompletedTaskList={ taskList.keepCompletedTaskList }
dismissedTasks={ dismissedTasks || [] }
isComplete={ isTaskListComplete }
query={ query }

View File

@ -8,7 +8,15 @@ import classnames from 'classnames';
*/
import './style.scss';
const TaskListPlaceholder = ( props ) => {
type TasksPlaceholderProps = {
numTasks?: number;
twoColumns?: boolean;
query: {
task?: string;
};
};
const TaskListPlaceholder: React.FC< TasksPlaceholderProps > = ( props ) => {
const { numTasks = 5, twoColumns = false } = props;
return (

View File

@ -329,6 +329,15 @@ class TaskList {
return $this->get_list_id() . '_tasklist_' . $event_name;
}
/**
* Returns option to keep completed task list.
*
* @return string
*/
public function get_keep_completed_task_list() {
return get_option( 'woocommerce_task_list_keep_completed', 'no' );
}
/**
* Remove reminder bar four weeks after store creation.
*/
@ -364,6 +373,7 @@ class TaskList {
),
'eventPrefix' => $this->prefix_event( '' ),
'displayProgressHeader' => $this->display_progress_header,
'keepCompletedTaskList' => $this->get_keep_completed_task_list(),
);
}
}

View File

@ -70,6 +70,7 @@ class TaskLists {
self::init_default_lists();
add_action( 'admin_init', array( __CLASS__, 'set_active_task' ), 5 );
add_action( 'init', array( __CLASS__, 'init_tasks' ) );
add_filter( 'woocommerce_admin_shared_settings', array( __CLASS__, 'task_list_preloaded_settings' ), 20 );
}
/**
@ -321,7 +322,7 @@ class TaskLists {
return array_filter(
self::get_lists(),
function ( $task_list ) {
return ! $task_list->is_hidden();
return $task_list->is_visible();
}
);
}
@ -373,4 +374,17 @@ class TaskLists {
return null;
}
/**
* Add visible list ids to component settings.
*
* @param array $settings Component settings.
*
* @return array
*/
public static function task_list_preloaded_settings( $settings ) {
$settings['visibleTaskListIds'] = array_keys( self::get_visible() );
return $settings;
}
}