2020-12-03 21:16:04 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import { __ } from '@wordpress/i18n';
|
2021-04-27 15:23:34 +00:00
|
|
|
import { useEffect, useRef } from '@wordpress/element';
|
2021-01-07 23:57:09 +00:00
|
|
|
import { Button, Card, CardBody, CardHeader } from '@wordpress/components';
|
2021-04-27 15:23:34 +00:00
|
|
|
import { useSelect, useDispatch } from '@wordpress/data';
|
2020-12-03 21:16:04 +00:00
|
|
|
import {
|
2021-04-27 15:23:34 +00:00
|
|
|
EllipsisMenu,
|
|
|
|
Badge,
|
|
|
|
__experimentalList as List,
|
|
|
|
} from '@woocommerce/components';
|
|
|
|
import { updateQueryString } from '@woocommerce/navigation';
|
|
|
|
import { OPTIONS_STORE_NAME, ONBOARDING_STORE_NAME } from '@woocommerce/data';
|
2020-12-03 21:16:04 +00:00
|
|
|
import { recordEvent } from '@woocommerce/tracks';
|
2021-01-07 23:57:09 +00:00
|
|
|
import { Text } from '@woocommerce/experimental';
|
2020-12-03 21:16:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
2021-04-27 15:23:34 +00:00
|
|
|
import { TaskItem } from './task-item';
|
|
|
|
|
|
|
|
export const TaskList = ( {
|
|
|
|
query,
|
|
|
|
name = 'task_list',
|
|
|
|
isComplete,
|
|
|
|
dismissedTasks,
|
|
|
|
tasks,
|
|
|
|
trackedCompletedTasks: totalTrackedCompletedTasks,
|
|
|
|
title: listTitle,
|
|
|
|
} ) => {
|
|
|
|
const { createNotice } = useDispatch( 'core/notices' );
|
|
|
|
const { updateOptions } = useDispatch( OPTIONS_STORE_NAME );
|
|
|
|
const { profileItems } = useSelect( ( select ) => {
|
|
|
|
const { getProfileItems } = select( ONBOARDING_STORE_NAME );
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
return {
|
|
|
|
profileItems: getProfileItems(),
|
|
|
|
};
|
|
|
|
} );
|
|
|
|
|
|
|
|
const prevQueryRef = useRef( query );
|
|
|
|
useEffect( () => {
|
|
|
|
recordTaskListView();
|
|
|
|
}, [] );
|
|
|
|
|
|
|
|
useEffect( () => {
|
|
|
|
const { task: prevTask } = prevQueryRef.current;
|
2020-12-03 21:16:04 +00:00
|
|
|
const { task } = query;
|
|
|
|
|
|
|
|
if ( prevTask !== task ) {
|
|
|
|
window.document.documentElement.scrollTop = 0;
|
2021-04-27 15:23:34 +00:00
|
|
|
prevQueryRef.current = query;
|
2020-12-03 21:16:04 +00:00
|
|
|
}
|
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
possiblyCompleteTaskList();
|
|
|
|
possiblyTrackCompletedTasks();
|
|
|
|
}, [ query ] );
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
const possiblyCompleteTaskList = () => {
|
2021-01-27 18:40:02 +00:00
|
|
|
const taskListVariableName = `woocommerce_${ name }_complete`;
|
|
|
|
const taskListToComplete = isComplete
|
|
|
|
? { [ taskListVariableName ]: 'no' }
|
|
|
|
: { [ taskListVariableName ]: 'yes' };
|
|
|
|
if ( name === 'task_list' ) {
|
|
|
|
taskListToComplete.woocommerce_default_homepage_layout =
|
|
|
|
'two_columns';
|
|
|
|
}
|
2020-12-03 21:16:04 +00:00
|
|
|
|
|
|
|
if (
|
2021-04-27 15:23:34 +00:00
|
|
|
( ! getIncompleteTasks().length && ! isComplete ) ||
|
|
|
|
( getIncompleteTasks().length && isComplete )
|
2020-12-03 21:16:04 +00:00
|
|
|
) {
|
|
|
|
updateOptions( {
|
|
|
|
...taskListToComplete,
|
|
|
|
} );
|
|
|
|
}
|
2021-04-27 15:23:34 +00:00
|
|
|
};
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
const getCompletedTaskKeys = () => {
|
|
|
|
return getVisibleTasks()
|
2020-12-03 21:16:04 +00:00
|
|
|
.filter( ( task ) => task.completed )
|
|
|
|
.map( ( task ) => task.key );
|
2021-04-27 15:23:34 +00:00
|
|
|
};
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
const getIncompleteTasks = () => {
|
2021-01-27 18:40:02 +00:00
|
|
|
return tasks.filter(
|
2020-12-03 21:16:04 +00:00
|
|
|
( task ) =>
|
|
|
|
task.visible &&
|
|
|
|
! task.completed &&
|
|
|
|
! dismissedTasks.includes( task.key )
|
|
|
|
);
|
2021-04-27 15:23:34 +00:00
|
|
|
};
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
const getTrackedIncompletedTasks = (
|
|
|
|
partialCompletedTasks,
|
|
|
|
allTrackedTask
|
|
|
|
) => {
|
|
|
|
return getVisibleTasks()
|
2021-01-27 18:40:02 +00:00
|
|
|
.filter(
|
|
|
|
( task ) =>
|
|
|
|
allTrackedTask.includes( task.key ) &&
|
|
|
|
! partialCompletedTasks.includes( task.key )
|
|
|
|
)
|
|
|
|
.map( ( task ) => task.key );
|
2021-04-27 15:23:34 +00:00
|
|
|
};
|
2021-01-27 18:40:02 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
const possiblyTrackCompletedTasks = () => {
|
|
|
|
const completedTaskKeys = getCompletedTaskKeys();
|
|
|
|
const trackedCompletedTasks = getTrackedCompletedTasks(
|
2020-12-03 21:16:04 +00:00
|
|
|
completedTaskKeys,
|
|
|
|
totalTrackedCompletedTasks
|
|
|
|
);
|
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
const trackedIncompleteTasks = getTrackedIncompletedTasks(
|
2021-01-27 18:40:02 +00:00
|
|
|
trackedCompletedTasks,
|
|
|
|
totalTrackedCompletedTasks
|
|
|
|
);
|
|
|
|
|
2020-12-03 21:16:04 +00:00
|
|
|
if (
|
2021-04-27 15:23:34 +00:00
|
|
|
shouldUpdateCompletedTasks(
|
2020-12-03 21:16:04 +00:00
|
|
|
trackedCompletedTasks,
|
2021-01-27 18:40:02 +00:00
|
|
|
trackedIncompleteTasks,
|
2020-12-03 21:16:04 +00:00
|
|
|
completedTaskKeys
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
updateOptions( {
|
2021-04-27 15:23:34 +00:00
|
|
|
woocommerce_task_list_tracked_completed_tasks: getTasksForUpdate(
|
2021-01-27 18:40:02 +00:00
|
|
|
completedTaskKeys,
|
|
|
|
totalTrackedCompletedTasks,
|
|
|
|
trackedIncompleteTasks
|
|
|
|
),
|
2020-12-03 21:16:04 +00:00
|
|
|
} );
|
|
|
|
}
|
2021-04-27 15:23:34 +00:00
|
|
|
};
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
const dismissTask = ( { key, onDismiss } ) => {
|
2020-12-03 21:16:04 +00:00
|
|
|
createNotice( 'success', __( 'Task dismissed' ), {
|
|
|
|
actions: [
|
|
|
|
{
|
|
|
|
label: __( 'Undo', 'woocommerce-admin' ),
|
2021-04-27 15:23:34 +00:00
|
|
|
onClick: () => undoDismissTask( key ),
|
2020-12-03 21:16:04 +00:00
|
|
|
},
|
|
|
|
],
|
|
|
|
} );
|
|
|
|
|
|
|
|
recordEvent( 'tasklist_dismiss_task', { task_name: key } );
|
|
|
|
|
|
|
|
updateOptions( {
|
|
|
|
woocommerce_task_list_dismissed_tasks: [ ...dismissedTasks, key ],
|
|
|
|
} );
|
|
|
|
if ( onDismiss ) {
|
|
|
|
onDismiss();
|
|
|
|
}
|
2021-04-27 15:23:34 +00:00
|
|
|
};
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
const undoDismissTask = ( key ) => {
|
2020-12-03 21:16:04 +00:00
|
|
|
const updatedDismissedTasks = dismissedTasks.filter(
|
|
|
|
( task ) => task !== key
|
|
|
|
);
|
|
|
|
|
|
|
|
updateOptions( {
|
|
|
|
woocommerce_task_list_dismissed_tasks: updatedDismissedTasks,
|
|
|
|
} );
|
2021-04-27 15:23:34 +00:00
|
|
|
};
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
const getVisibleTasks = () => {
|
2020-12-03 21:16:04 +00:00
|
|
|
return tasks.filter(
|
|
|
|
( task ) => task.visible && ! dismissedTasks.includes( task.key )
|
|
|
|
);
|
2021-04-27 15:23:34 +00:00
|
|
|
};
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
const recordTaskListView = () => {
|
|
|
|
if ( query.task ) {
|
2020-12-03 21:16:04 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-04-16 13:29:54 +00:00
|
|
|
const isCoreTaskList = name === 'task_list';
|
|
|
|
const taskListName = isCoreTaskList ? 'tasklist' : 'extended_tasklist';
|
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
const visibleTasks = getVisibleTasks();
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-16 13:29:54 +00:00
|
|
|
recordEvent( `${ taskListName }_view`, {
|
2021-04-27 15:23:34 +00:00
|
|
|
number_tasks: visibleTasks.length,
|
2020-12-03 21:16:04 +00:00
|
|
|
store_connected: profileItems.wccom_connected,
|
|
|
|
} );
|
2021-04-27 15:23:34 +00:00
|
|
|
};
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
const hideTaskCard = ( action ) => {
|
2021-01-27 18:40:02 +00:00
|
|
|
const isCoreTaskList = name === 'task_list';
|
|
|
|
const taskListName = isCoreTaskList ? 'tasklist' : 'extended_tasklist';
|
|
|
|
const updateOptionsParams = {
|
|
|
|
[ `woocommerce_${ name }_hidden` ]: 'yes',
|
|
|
|
};
|
|
|
|
if ( isCoreTaskList ) {
|
|
|
|
updateOptionsParams.woocommerce_task_list_prompt_shown = true;
|
|
|
|
updateOptionsParams.woocommerce_default_homepage_layout =
|
|
|
|
'two_columns';
|
|
|
|
}
|
|
|
|
|
|
|
|
recordEvent( `${ taskListName }_completed`, {
|
2020-12-03 21:16:04 +00:00
|
|
|
action,
|
2021-04-27 15:23:34 +00:00
|
|
|
completed_task_count: getCompletedTaskKeys().length,
|
|
|
|
incomplete_task_count: getIncompleteTasks().length,
|
2020-12-03 21:16:04 +00:00
|
|
|
} );
|
2021-01-27 18:40:02 +00:00
|
|
|
updateOptions( {
|
|
|
|
...updateOptionsParams,
|
2020-12-03 21:16:04 +00:00
|
|
|
} );
|
2021-04-27 15:23:34 +00:00
|
|
|
};
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
const renderMenu = () => {
|
2020-12-03 21:16:04 +00:00
|
|
|
return (
|
|
|
|
<div className="woocommerce-card__menu woocommerce-card__header-item">
|
|
|
|
<EllipsisMenu
|
|
|
|
label={ __( 'Task List Options', 'woocommerce-admin' ) }
|
|
|
|
renderContent={ () => (
|
|
|
|
<div className="woocommerce-task-card__section-controls">
|
|
|
|
<Button
|
2021-04-27 15:23:34 +00:00
|
|
|
onClick={ () => hideTaskCard( 'remove_card' ) }
|
2020-12-03 21:16:04 +00:00
|
|
|
>
|
|
|
|
{ __( 'Hide this', 'woocommerce-admin' ) }
|
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
) }
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
);
|
2021-04-27 15:23:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const listTasks = getVisibleTasks().map( ( task ) => {
|
|
|
|
if ( ! task.onClick ) {
|
|
|
|
task.onClick = ( e ) => {
|
|
|
|
if ( e.target.nodeName === 'A' ) {
|
|
|
|
// This is a nested link, so don't activate this task.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
updateQueryString( { task: task.key } );
|
|
|
|
};
|
|
|
|
}
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
return task;
|
|
|
|
} );
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
if ( ! listTasks.length ) {
|
|
|
|
return <div className="woocommerce-task-dashboard__container"></div>;
|
|
|
|
}
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<div className="woocommerce-task-dashboard__container">
|
|
|
|
<Card
|
|
|
|
size="large"
|
|
|
|
className="woocommerce-task-card woocommerce-homescreen-card"
|
2020-12-03 21:16:04 +00:00
|
|
|
>
|
2021-04-27 15:23:34 +00:00
|
|
|
<CardHeader size="medium">
|
|
|
|
<div className="wooocommerce-task-card__header">
|
|
|
|
<Text variant="title.small">{ listTitle }</Text>
|
|
|
|
<Badge count={ getIncompleteTasks().length } />
|
2020-12-03 21:16:04 +00:00
|
|
|
</div>
|
2021-04-27 15:23:34 +00:00
|
|
|
{ renderMenu() }
|
|
|
|
</CardHeader>
|
|
|
|
<CardBody>
|
|
|
|
<List animation="slide-right">
|
|
|
|
{ listTasks.map( ( task ) => (
|
|
|
|
<TaskItem
|
|
|
|
key={ task.key }
|
|
|
|
title={ task.title }
|
|
|
|
completed={ task.completed }
|
|
|
|
content={ task.content }
|
|
|
|
onClick={ task.onClick }
|
|
|
|
isDismissable={ task.isDismissable }
|
|
|
|
onDismiss={ () => dismissTask( task ) }
|
|
|
|
time={ task.time }
|
|
|
|
/>
|
|
|
|
) ) }
|
|
|
|
</List>
|
|
|
|
</CardBody>
|
|
|
|
</Card>
|
|
|
|
</div>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
function shouldUpdateCompletedTasks( tasks, untrackedTasks, completedTasks ) {
|
|
|
|
if ( untrackedTasks.length > 0 ) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if ( completedTasks.length === 0 ) {
|
|
|
|
return false;
|
2020-12-03 21:16:04 +00:00
|
|
|
}
|
2021-04-27 15:23:34 +00:00
|
|
|
return ! completedTasks.every(
|
|
|
|
( taskName ) => tasks.indexOf( taskName ) >= 0
|
|
|
|
);
|
2020-12-03 21:16:04 +00:00
|
|
|
}
|
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
function getTrackedCompletedTasks( completedTasks, trackedTasks ) {
|
|
|
|
if ( ! trackedTasks ) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
return completedTasks.filter( ( taskName ) =>
|
|
|
|
trackedTasks.includes( taskName )
|
|
|
|
);
|
|
|
|
}
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
function getTasksForUpdate(
|
|
|
|
completedTaskKeys,
|
|
|
|
totalTrackedCompletedTasks,
|
|
|
|
trackedIncompleteTasks
|
|
|
|
) {
|
|
|
|
const mergedLists = [
|
|
|
|
...new Set( [ ...completedTaskKeys, ...totalTrackedCompletedTasks ] ),
|
|
|
|
];
|
|
|
|
return mergedLists.filter(
|
|
|
|
( taskName ) => ! trackedIncompleteTasks.includes( taskName )
|
|
|
|
);
|
|
|
|
}
|
2020-12-03 21:16:04 +00:00
|
|
|
|
2021-04-27 15:23:34 +00:00
|
|
|
export default TaskList;
|