Merge pull request #32320 from woocommerce/add/32161_reminder_bar
Add reminder bar for task list experiment
This commit is contained in:
commit
eb081aa9fa
|
@ -12,12 +12,14 @@ export type TaskType = {
|
|||
snoozedUntil: number;
|
||||
time: string;
|
||||
title: string;
|
||||
isVisited?: boolean;
|
||||
};
|
||||
|
||||
export type TaskListType = {
|
||||
id: string;
|
||||
isCollapsible?: boolean;
|
||||
isComplete: boolean;
|
||||
isHidden: boolean;
|
||||
isExpandable?: boolean;
|
||||
tasks: TaskType[];
|
||||
title: string;
|
||||
|
|
|
@ -2,6 +2,23 @@
|
|||
|
||||
## Unreleased
|
||||
|
||||
### Display Reminder Bar while completing the primary task list
|
||||
|
||||
1. Checkout branch on a fresh site (if your store is > 4 weeks old it will automatically hide the reminder bar)
|
||||
2. Complete the onboarding wizard with standard options.
|
||||
3. Complete a single step of the primary task list.
|
||||
4. You should _not_ see the reminder bar on the Homescreen or any other page related to the tasks. You _should_ see it everywhere else.
|
||||
5. Go to a non-task related page, such as _Orders_, and you should see the bar appear above the header. Ensure the copy starts with "You're doing great!"
|
||||
6. Click the "Continue Setup" link, which should redirect you to the Homescreen.
|
||||
7. Complete all but one task remaining.
|
||||
8. Go back to the _Orders_ page to view the reminder bar. It should appear similar but have different copy, starting with "Almost there."
|
||||
9. Click the "Finish setup" link to ensure that it returns you to the homescreen.
|
||||
10. Hide the list by clicking the '...' menu, and then return to the _Orders_ page. The bar should now be hidden.
|
||||
11. Re-enable task list by going to Orders -> Help -> Setup Wizard -> Task List -> Enable.
|
||||
12. The reminder bar should now appear when viewing the _Orders_ page.
|
||||
13. Complete the task list.
|
||||
14. The reminder bar will no longer display on the _Orders_ page.
|
||||
|
||||
### Display WCPay task when installed via subscriptions option on profiler
|
||||
|
||||
1. Start with a fresh install.
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: Add
|
||||
|
||||
Adding reminder bar for primary task list experiment(s). #32320
|
|
@ -18,6 +18,7 @@ import {
|
|||
WooHeaderItem,
|
||||
WooHeaderPageTitle,
|
||||
} from './utils';
|
||||
import { TasksReminderBar } from '../tasks';
|
||||
|
||||
export const PAGE_TITLE_FILTER = 'woocommerce_admin_header_page_title';
|
||||
|
||||
|
@ -92,8 +93,17 @@ export const Header = ( { sections, isEmbedded = false, query } ) => {
|
|||
}
|
||||
}, [ isEmbedded, sections, siteTitle ] );
|
||||
|
||||
const tasksReminderFeature =
|
||||
window.wcAdminFeatures[ 'tasklist-setup-experiment-1' ];
|
||||
|
||||
return (
|
||||
<div className={ className } ref={ headerElement }>
|
||||
{ tasksReminderFeature && (
|
||||
<TasksReminderBar
|
||||
pageTitle={ pageTitle }
|
||||
updateBodyMargin={ updateBodyMargin }
|
||||
/>
|
||||
) }
|
||||
<div className="woocommerce-layout__header-wrapper">
|
||||
<WooHeaderNavigationItem.Slot
|
||||
fillProps={ { isEmbedded, query } }
|
||||
|
|
|
@ -6,4 +6,5 @@ import './fills';
|
|||
import './deprecated-tasks';
|
||||
|
||||
export * from './placeholder';
|
||||
export * from './reminder-bar';
|
||||
export default Tasks;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export * from './reminder-bar';
|
|
@ -0,0 +1,29 @@
|
|||
.woocommerce-layout__header-tasks-reminder-bar {
|
||||
height: 40px;
|
||||
background-color: #007cba;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
}
|
||||
|
||||
button {
|
||||
&:hover {
|
||||
opacity: 0.7;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
import {
|
||||
ONBOARDING_STORE_NAME,
|
||||
OPTIONS_STORE_NAME,
|
||||
TaskListType,
|
||||
} from '@woocommerce/data';
|
||||
import { Button } from '@wordpress/components';
|
||||
import { Link } from '@woocommerce/components';
|
||||
import { getAdminLink } from '@woocommerce/settings';
|
||||
import { close as closeIcon } from '@wordpress/icons';
|
||||
import interpolateComponents from '@automattic/interpolate-components';
|
||||
import { useEffect } from '@wordpress/element';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import './reminder-bar.scss';
|
||||
|
||||
type ReminderBarProps = {
|
||||
taskListId: string;
|
||||
pageTitle: string;
|
||||
updateBodyMargin: () => void;
|
||||
};
|
||||
|
||||
type ReminderTextProps = {
|
||||
remainingCount: number;
|
||||
};
|
||||
|
||||
const REMINDER_BAR_HIDDEN_OPTION = 'woocommerce_task_list_reminder_bar_hidden';
|
||||
|
||||
const ReminderText: React.FC< ReminderTextProps > = ( { remainingCount } ) => {
|
||||
const translationText =
|
||||
remainingCount === 1
|
||||
? /* translators: 1: remaining tasks count */
|
||||
__(
|
||||
'🎉 Almost there. Only {{strongText}}%1$d step left{{/strongText}} get your store up and running. {{setupLink}}Finish setup{{/setupLink}}',
|
||||
'woocommerce-admin'
|
||||
)
|
||||
: /* translators: 1: remaining tasks count */
|
||||
__(
|
||||
"🚀 You're doing great! {{strongText}}%1$d steps left{{/strongText}} to get your store up and running. {{setupLink}}Continue setup{{/setupLink}}",
|
||||
'woocommerce-admin'
|
||||
);
|
||||
|
||||
return (
|
||||
<p>
|
||||
{ interpolateComponents( {
|
||||
mixedString: sprintf( translationText, remainingCount ),
|
||||
components: {
|
||||
strongText: <strong />,
|
||||
setupLink: (
|
||||
<Link
|
||||
href={ getAdminLink( 'admin.php?page=wc-admin' ) }
|
||||
type="wp-admin"
|
||||
/>
|
||||
),
|
||||
},
|
||||
} ) }
|
||||
</p>
|
||||
);
|
||||
};
|
||||
|
||||
export const TasksReminderBar: React.FC< ReminderBarProps > = ( {
|
||||
taskListId = 'setup_experiment_1',
|
||||
pageTitle,
|
||||
updateBodyMargin,
|
||||
} ) => {
|
||||
const { updateOptions } = useDispatch( OPTIONS_STORE_NAME );
|
||||
const {
|
||||
remainingCount,
|
||||
loading,
|
||||
taskListHidden,
|
||||
taskListComplete,
|
||||
reminderBarHidden,
|
||||
completedTasksCount,
|
||||
} = useSelect( ( select ) => {
|
||||
const {
|
||||
getTaskList,
|
||||
hasFinishedResolution: onboardingHasFinishedResolution,
|
||||
} = select( ONBOARDING_STORE_NAME );
|
||||
const {
|
||||
getOption,
|
||||
hasFinishedResolution: optionHasFinishedResolution,
|
||||
} = select( OPTIONS_STORE_NAME );
|
||||
const reminderBarHiddenOption = getOption( REMINDER_BAR_HIDDEN_OPTION );
|
||||
const taskList: TaskListType = getTaskList( taskListId );
|
||||
const taskListIsResolved = onboardingHasFinishedResolution(
|
||||
'getTaskList',
|
||||
[ taskListId ]
|
||||
);
|
||||
const optionIsResolved = optionHasFinishedResolution( 'getOption', [
|
||||
REMINDER_BAR_HIDDEN_OPTION,
|
||||
] );
|
||||
|
||||
const visibleTasks = taskList?.tasks.filter(
|
||||
( task ) =>
|
||||
! task.isDismissed &&
|
||||
( ! task.isSnoozed || task.snoozedUntil < Date.now() )
|
||||
);
|
||||
|
||||
const completedTasks = (visibleTasks?.filter(
|
||||
( task ) => task.isComplete
|
||||
) || []);
|
||||
|
||||
const isResolved = taskListIsResolved && optionIsResolved;
|
||||
|
||||
return {
|
||||
reminderBarHidden: reminderBarHiddenOption === 'yes',
|
||||
taskListHidden: isResolved ? taskList.isHidden : false,
|
||||
taskListComplete: isResolved ? taskList.isComplete : false,
|
||||
loading: ! isResolved,
|
||||
completedTasksCount: completedTasks.length,
|
||||
remainingCount: isResolved
|
||||
? visibleTasks?.length - completedTasks.length
|
||||
: null,
|
||||
};
|
||||
} );
|
||||
|
||||
const hideReminderBar =
|
||||
loading ||
|
||||
taskListHidden ||
|
||||
taskListComplete ||
|
||||
reminderBarHidden ||
|
||||
completedTasksCount === 0 ||
|
||||
[ 'Home', 'Shipping', 'Tax', 'Payments' ].includes( pageTitle );
|
||||
|
||||
useEffect( () => {
|
||||
updateBodyMargin();
|
||||
}, [ hideReminderBar, updateBodyMargin ] );
|
||||
|
||||
if ( hideReminderBar ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="woocommerce-layout__header-tasks-reminder-bar">
|
||||
<ReminderText remainingCount={ remainingCount } />
|
||||
<Button
|
||||
isSmall
|
||||
onClick={ () =>
|
||||
updateOptions( {
|
||||
[ REMINDER_BAR_HIDDEN_OPTION ]: 'yes',
|
||||
} )
|
||||
}
|
||||
icon={ closeIcon }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -6,6 +6,8 @@
|
|||
namespace Automattic\WooCommerce\Admin\Features\OnboardingTasks;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\OnboardingTasks\Task;
|
||||
use Automattic\WooCommerce\Admin\WCAdminHelper;
|
||||
|
||||
|
||||
/**
|
||||
* Task List class.
|
||||
|
@ -26,6 +28,11 @@ class TaskList {
|
|||
*/
|
||||
const COMPLETED_OPTION = 'woocommerce_task_list_completed_lists';
|
||||
|
||||
/**
|
||||
* Option name of hidden reminder bar.
|
||||
*/
|
||||
const REMINDER_BAR_HIDDEN_OPTION = 'woocommerce_task_list_reminder_bar_hidden';
|
||||
|
||||
/**
|
||||
* ID.
|
||||
*
|
||||
|
@ -114,6 +121,8 @@ class TaskList {
|
|||
$task = new $class( $this );
|
||||
$this->add_task( $task );
|
||||
}
|
||||
|
||||
$this->possibly_remove_reminder_bar();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -311,6 +320,20 @@ class TaskList {
|
|||
return $this->get_list_id() . '_tasklist_' . $event_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove reminder bar four weeks after store creation.
|
||||
*/
|
||||
public static function possibly_remove_reminder_bar() {
|
||||
$bar_hidden = get_option( self::REMINDER_BAR_HIDDEN_OPTION, 'no' );
|
||||
$active_for_four_weeks = WCAdminHelper::is_wc_admin_active_for( WEEK_IN_SECONDS * 4 );
|
||||
|
||||
if ( 'yes' === $bar_hidden || ! $active_for_four_weeks ) {
|
||||
return;
|
||||
}
|
||||
|
||||
update_option( self::REMINDER_BAR_HIDDEN_OPTION, 'yes' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list for use in JSON.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue