2021-09-01 21:28:24 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import { __ } from '@wordpress/i18n';
|
2022-06-01 17:10:20 +00:00
|
|
|
import { getNewPath, navigateTo } from '@woocommerce/navigation';
|
2021-09-01 21:28:24 +00:00
|
|
|
import {
|
|
|
|
ONBOARDING_STORE_NAME,
|
|
|
|
TaskType,
|
|
|
|
useUserPreferences,
|
|
|
|
} from '@woocommerce/data';
|
|
|
|
import { recordEvent } from '@woocommerce/tracks';
|
2021-09-21 19:33:44 +00:00
|
|
|
import { TaskItem, useSlot } from '@woocommerce/experimental';
|
2023-04-25 22:17:33 +00:00
|
|
|
import { useCallback, useEffect } from '@wordpress/element';
|
2021-09-01 21:28:24 +00:00
|
|
|
import { useDispatch } from '@wordpress/data';
|
2021-09-21 19:33:44 +00:00
|
|
|
import { WooOnboardingTaskListItem } from '@woocommerce/onboarding';
|
2023-04-25 22:17:33 +00:00
|
|
|
import { useLayoutContext } from '@woocommerce/admin-layout';
|
2021-09-01 21:28:24 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import './task-list.scss';
|
|
|
|
|
|
|
|
export type TaskListItemProps = {
|
|
|
|
isExpandable: boolean;
|
|
|
|
isExpanded: boolean;
|
|
|
|
setExpandedTask: ( id: string ) => void;
|
2022-04-20 08:48:53 +00:00
|
|
|
task: TaskType & {
|
|
|
|
onClick?: () => void;
|
|
|
|
};
|
2021-09-01 21:28:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
export const TaskListItem: React.FC< TaskListItemProps > = ( {
|
|
|
|
isExpandable = false,
|
|
|
|
isExpanded = false,
|
|
|
|
setExpandedTask,
|
|
|
|
task,
|
|
|
|
} ) => {
|
|
|
|
const { createNotice } = useDispatch( 'core/notices' );
|
2023-04-25 22:17:33 +00:00
|
|
|
const { layoutString } = useLayoutContext();
|
2021-09-21 19:33:44 +00:00
|
|
|
|
2021-09-01 21:28:24 +00:00
|
|
|
const {
|
|
|
|
dismissTask,
|
|
|
|
snoozeTask,
|
|
|
|
undoDismissTask,
|
|
|
|
undoSnoozeTask,
|
2022-03-21 13:52:04 +00:00
|
|
|
visitedTask,
|
2021-09-01 21:28:24 +00:00
|
|
|
} = useDispatch( ONBOARDING_STORE_NAME );
|
|
|
|
const userPreferences = useUserPreferences();
|
|
|
|
|
|
|
|
const {
|
|
|
|
actionLabel,
|
|
|
|
actionUrl,
|
|
|
|
content,
|
|
|
|
id,
|
|
|
|
isComplete,
|
|
|
|
isDismissable,
|
2021-09-29 17:55:44 +00:00
|
|
|
isSnoozeable,
|
2021-09-01 21:28:24 +00:00
|
|
|
time,
|
|
|
|
title,
|
2023-09-07 13:43:18 +00:00
|
|
|
badge,
|
2021-10-01 18:46:23 +00:00
|
|
|
level,
|
|
|
|
additionalInfo,
|
2022-11-15 10:12:17 +00:00
|
|
|
recordViewEvent,
|
2021-09-01 21:28:24 +00:00
|
|
|
} = task;
|
|
|
|
|
2022-11-15 10:12:17 +00:00
|
|
|
useEffect( () => {
|
|
|
|
if ( recordViewEvent ) {
|
|
|
|
recordEvent( 'tasklist_item_view', {
|
|
|
|
task_name: id,
|
|
|
|
is_complete: isComplete,
|
2023-04-25 22:17:33 +00:00
|
|
|
context: layoutString,
|
2022-11-15 10:12:17 +00:00
|
|
|
} );
|
|
|
|
}
|
|
|
|
// run the effect only when component mounts
|
|
|
|
// eslint-disable-next-line
|
|
|
|
}, [] );
|
|
|
|
|
2021-09-21 19:33:44 +00:00
|
|
|
const slot = useSlot( `woocommerce_onboarding_task_list_item_${ id }` );
|
|
|
|
const hasFills = Boolean( slot?.fills?.length );
|
|
|
|
|
2021-09-01 21:28:24 +00:00
|
|
|
const onDismiss = useCallback( () => {
|
2021-09-29 17:55:44 +00:00
|
|
|
dismissTask( id );
|
2022-07-08 10:37:30 +00:00
|
|
|
createNotice( 'success', __( 'Task dismissed', 'woocommerce' ), {
|
2021-09-01 21:28:24 +00:00
|
|
|
actions: [
|
|
|
|
{
|
2022-03-30 09:00:04 +00:00
|
|
|
label: __( 'Undo', 'woocommerce' ),
|
2021-09-01 21:28:24 +00:00
|
|
|
onClick: () => undoDismissTask( id ),
|
|
|
|
},
|
|
|
|
],
|
|
|
|
} );
|
|
|
|
}, [ id ] );
|
|
|
|
|
|
|
|
const onSnooze = useCallback( () => {
|
2021-09-29 17:55:44 +00:00
|
|
|
snoozeTask( id );
|
2021-09-01 21:28:24 +00:00
|
|
|
createNotice(
|
|
|
|
'success',
|
2022-03-30 09:00:04 +00:00
|
|
|
__( 'Task postponed until tomorrow', 'woocommerce' ),
|
2021-09-01 21:28:24 +00:00
|
|
|
{
|
|
|
|
actions: [
|
|
|
|
{
|
2022-03-30 09:00:04 +00:00
|
|
|
label: __( 'Undo', 'woocommerce' ),
|
2021-09-01 21:28:24 +00:00
|
|
|
onClick: () => undoSnoozeTask( id ),
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}, [ id ] );
|
|
|
|
|
|
|
|
const getTaskStartedCount = () => {
|
|
|
|
const trackedStartedTasks =
|
|
|
|
userPreferences.task_list_tracked_started_tasks;
|
|
|
|
if ( ! trackedStartedTasks || ! trackedStartedTasks[ id ] ) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return trackedStartedTasks[ id ];
|
|
|
|
};
|
|
|
|
|
|
|
|
// @todo This would be better as a task endpoint that handles updating the count.
|
|
|
|
const updateTrackStartedCount = () => {
|
|
|
|
const newCount = getTaskStartedCount() + 1;
|
|
|
|
const trackedStartedTasks =
|
|
|
|
userPreferences.task_list_tracked_started_tasks || {};
|
|
|
|
|
2022-03-21 13:52:04 +00:00
|
|
|
visitedTask( id );
|
2021-09-01 21:28:24 +00:00
|
|
|
userPreferences.updateUserPreferences( {
|
|
|
|
task_list_tracked_started_tasks: {
|
|
|
|
...( trackedStartedTasks || {} ),
|
|
|
|
[ id ]: newCount,
|
|
|
|
},
|
|
|
|
} );
|
|
|
|
};
|
|
|
|
|
2021-09-21 19:33:44 +00:00
|
|
|
const trackClick = () => {
|
2021-09-01 21:28:24 +00:00
|
|
|
recordEvent( 'tasklist_click', {
|
|
|
|
task_name: id,
|
2023-04-25 22:17:33 +00:00
|
|
|
context: layoutString,
|
2021-09-01 21:28:24 +00:00
|
|
|
} );
|
|
|
|
|
|
|
|
if ( ! isComplete ) {
|
|
|
|
updateTrackStartedCount();
|
|
|
|
}
|
2021-09-21 19:33:44 +00:00
|
|
|
};
|
2021-09-01 21:28:24 +00:00
|
|
|
|
2021-09-21 19:33:44 +00:00
|
|
|
const onClickDefault = useCallback( () => {
|
2021-09-01 21:28:24 +00:00
|
|
|
if ( actionUrl ) {
|
2022-06-01 17:10:20 +00:00
|
|
|
navigateTo( {
|
|
|
|
url: actionUrl,
|
|
|
|
} );
|
2021-09-01 21:28:24 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-06-01 17:10:20 +00:00
|
|
|
navigateTo( { url: getNewPath( { task: id }, '/', {} ) } );
|
2021-09-01 21:28:24 +00:00
|
|
|
}, [ id, isComplete, actionUrl ] );
|
|
|
|
|
2021-09-21 19:33:44 +00:00
|
|
|
const taskItemProps = {
|
|
|
|
expandable: isExpandable,
|
|
|
|
expanded: isExpandable && isExpanded,
|
|
|
|
completed: isComplete,
|
2021-09-29 17:55:44 +00:00
|
|
|
onSnooze: isSnoozeable && onSnooze,
|
2021-09-21 19:33:44 +00:00
|
|
|
onDismiss: isDismissable && onDismiss,
|
|
|
|
};
|
|
|
|
|
|
|
|
const DefaultTaskItem = useCallback(
|
|
|
|
( props ) => {
|
|
|
|
const onClickActions = () => {
|
|
|
|
trackClick();
|
|
|
|
|
|
|
|
if ( props.onClick ) {
|
|
|
|
return props.onClick();
|
|
|
|
}
|
|
|
|
|
|
|
|
return onClickDefault();
|
|
|
|
};
|
|
|
|
return (
|
|
|
|
<TaskItem
|
|
|
|
key={ id }
|
|
|
|
title={ title }
|
2023-09-07 13:43:18 +00:00
|
|
|
badge={ badge }
|
2021-09-21 19:33:44 +00:00
|
|
|
content={ content }
|
2021-10-01 18:46:23 +00:00
|
|
|
additionalInfo={ additionalInfo }
|
2021-09-21 19:33:44 +00:00
|
|
|
time={ time }
|
|
|
|
action={ onClickActions }
|
2021-10-01 18:46:23 +00:00
|
|
|
level={ level }
|
2021-09-21 19:33:44 +00:00
|
|
|
actionLabel={ actionLabel }
|
|
|
|
{ ...taskItemProps }
|
|
|
|
{ ...props }
|
|
|
|
onClick={
|
|
|
|
! isExpandable || isComplete
|
|
|
|
? onClickActions
|
|
|
|
: () => setExpandedTask( id )
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
},
|
2023-09-07 13:43:18 +00:00
|
|
|
[
|
|
|
|
id,
|
|
|
|
title,
|
|
|
|
badge,
|
|
|
|
content,
|
|
|
|
time,
|
|
|
|
actionLabel,
|
|
|
|
isExpandable,
|
|
|
|
isComplete,
|
|
|
|
]
|
2021-09-21 19:33:44 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
return hasFills ? (
|
|
|
|
<WooOnboardingTaskListItem.Slot
|
|
|
|
id={ id }
|
|
|
|
fillProps={ {
|
|
|
|
defaultTaskItem: DefaultTaskItem,
|
|
|
|
isComplete,
|
|
|
|
...taskItemProps,
|
|
|
|
} }
|
2021-09-01 21:28:24 +00:00
|
|
|
/>
|
2021-09-21 19:33:44 +00:00
|
|
|
) : (
|
2021-10-06 18:47:41 +00:00
|
|
|
<DefaultTaskItem onClick={ task.onClick } />
|
2021-09-01 21:28:24 +00:00
|
|
|
);
|
|
|
|
};
|