Adding context property to tasklist tracks event, introducing LayoutContext (#33287)
This commit is contained in:
parent
143d86490d
commit
183ac65c82
|
@ -6,11 +6,9 @@ import { TaskType } from './types';
|
|||
/**
|
||||
* Filters tasks to only visible tasks, taking in account snoozed tasks.
|
||||
*/
|
||||
export function getVisibleTasks( tasks: TaskType[] ) {
|
||||
const nowTimestamp = Date.now();
|
||||
return tasks.filter(
|
||||
export const getVisibleTasks = ( tasks: TaskType[] ) =>
|
||||
tasks.filter(
|
||||
( task ) =>
|
||||
! task.isDismissed &&
|
||||
( ! task.isSnoozed || task.snoozedUntil < nowTimestamp )
|
||||
( ! task.isSnoozed || task.snoozedUntil < Date.now() )
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { lazy, useState } from '@wordpress/element';
|
||||
import { lazy, useState, useContext, useMemo } from '@wordpress/element';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { uniqueId, find } from 'lodash';
|
||||
import { Icon, help as helpIcon, external } from '@wordpress/icons';
|
||||
|
@ -12,6 +12,7 @@ import {
|
|||
OPTIONS_STORE_NAME,
|
||||
useUser,
|
||||
useUserPreferences,
|
||||
getVisibleTasks,
|
||||
} from '@woocommerce/data';
|
||||
import { getHistory } from '@woocommerce/navigation';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
@ -36,6 +37,8 @@ import {
|
|||
import { getUnapprovedReviews } from '../homescreen/activity-panel/reviews/utils';
|
||||
import { ABBREVIATED_NOTIFICATION_SLOT_NAME } from './panels/inbox/abbreviated-notifications-panel';
|
||||
import { getAdminSetting } from '~/utils/admin-settings';
|
||||
import { useActiveSetupTasklist } from '~/tasks';
|
||||
import { LayoutContext } from '~/layout';
|
||||
|
||||
const HelpPanel = lazy( () =>
|
||||
import( /* webpackChunkName: "activity-panels-help" */ './panels/help' )
|
||||
|
@ -61,6 +64,12 @@ export const ActivityPanel = ( { isEmbedded, query } ) => {
|
|||
const { fills } = useSlot( ABBREVIATED_NOTIFICATION_SLOT_NAME );
|
||||
const hasExtendedNotifications = Boolean( fills?.length );
|
||||
const { updateUserPreferences, ...userData } = useUserPreferences();
|
||||
const activeSetupList = useActiveSetupTasklist();
|
||||
const layoutContext = useContext( LayoutContext );
|
||||
const updatedLayoutContext = useMemo(
|
||||
() => layoutContext.getExtendedContext( 'activity-panel' ),
|
||||
[ layoutContext ]
|
||||
);
|
||||
|
||||
const getPreviewSiteBtnTrackData = ( select, getOption ) => {
|
||||
let trackData = {};
|
||||
|
@ -137,6 +146,8 @@ export const ActivityPanel = ( { isEmbedded, query } ) => {
|
|||
requestingTaskListOptions,
|
||||
setupTaskListComplete,
|
||||
setupTaskListHidden,
|
||||
setupTasksCompleteCount,
|
||||
setupTasksCount,
|
||||
previewSiteBtnTrackData,
|
||||
} = useSelect( ( select ) => {
|
||||
const { getOption } = select( OPTIONS_STORE_NAME );
|
||||
|
@ -144,7 +155,10 @@ export const ActivityPanel = ( { isEmbedded, query } ) => {
|
|||
ONBOARDING_STORE_NAME
|
||||
);
|
||||
|
||||
const isSetupTaskListHidden = getTaskList( 'setup' )?.isHidden;
|
||||
const setupList = getTaskList( activeSetupList );
|
||||
|
||||
const isSetupTaskListHidden = setupList?.isHidden;
|
||||
const setupVisibleTasks = getVisibleTasks( setupList?.tasks || [] );
|
||||
const extendedTaskList = getTaskList( 'extended' );
|
||||
|
||||
const thingsToDoCount = getThingsToDoNextCount( extendedTaskList );
|
||||
|
@ -160,8 +174,12 @@ export const ActivityPanel = ( { isEmbedded, query } ) => {
|
|||
requestingTaskListOptions: ! hasFinishedResolution(
|
||||
'getTaskLists'
|
||||
),
|
||||
setupTaskListComplete: getTaskList( 'setup' )?.isComplete,
|
||||
setupTaskListComplete: setupList?.isComplete,
|
||||
setupTaskListHidden: isSetupTaskListHidden,
|
||||
setupTasksCount: setupVisibleTasks.length,
|
||||
setupTasksCompleteCount: setupVisibleTasks.filter(
|
||||
( task ) => task.isComplete
|
||||
).length,
|
||||
isCompletedTask: Boolean(
|
||||
query.task && getTask( query.task )?.isComplete
|
||||
),
|
||||
|
@ -230,7 +248,14 @@ export const ActivityPanel = ( { isEmbedded, query } ) => {
|
|||
const setup = {
|
||||
name: 'setup',
|
||||
title: __( 'Finish setup', 'woocommerce' ),
|
||||
icon: <SetupProgress />,
|
||||
icon: (
|
||||
<SetupProgress
|
||||
setupTasksComplete={ setupTasksCompleteCount }
|
||||
setupCompletePercent={ Math.ceil(
|
||||
( setupTasksCompleteCount / setupTasksCount ) * 100
|
||||
) }
|
||||
/>
|
||||
),
|
||||
visible:
|
||||
currentUserCan( 'manage_woocommerce' ) &&
|
||||
! requestingTaskListOptions &&
|
||||
|
@ -349,55 +374,57 @@ export const ActivityPanel = ( { isEmbedded, query } ) => {
|
|||
const showHelpHighlightTooltip = shouldShowHelpTooltip();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<H id={ headerId } className="screen-reader-text">
|
||||
{ __( 'Store Activity', 'woocommerce' ) }
|
||||
</H>
|
||||
<Section
|
||||
component="aside"
|
||||
id="woocommerce-activity-panel"
|
||||
className="woocommerce-layout__activity-panel"
|
||||
aria-labelledby={ headerId }
|
||||
>
|
||||
<Tabs
|
||||
tabs={ tabs }
|
||||
tabOpen={ isPanelOpen }
|
||||
selectedTab={ currentTab }
|
||||
onTabClick={ ( tab, tabOpen ) => {
|
||||
if ( tab.onClick ) {
|
||||
tab.onClick();
|
||||
return;
|
||||
}
|
||||
<LayoutContext.Provider value={ updatedLayoutContext }>
|
||||
<div>
|
||||
<H id={ headerId } className="screen-reader-text">
|
||||
{ __( 'Store Activity', 'woocommerce' ) }
|
||||
</H>
|
||||
<Section
|
||||
component="aside"
|
||||
id="woocommerce-activity-panel"
|
||||
className="woocommerce-layout__activity-panel"
|
||||
aria-labelledby={ headerId }
|
||||
>
|
||||
<Tabs
|
||||
tabs={ tabs }
|
||||
tabOpen={ isPanelOpen }
|
||||
selectedTab={ currentTab }
|
||||
onTabClick={ ( tab, tabOpen ) => {
|
||||
if ( tab.onClick ) {
|
||||
tab.onClick();
|
||||
return;
|
||||
}
|
||||
|
||||
togglePanel( tab, tabOpen );
|
||||
} }
|
||||
/>
|
||||
<Panel
|
||||
currentTab
|
||||
isPanelOpen={ isPanelOpen }
|
||||
isPanelSwitching={ isPanelSwitching }
|
||||
tab={ find( getTabs(), { name: currentTab } ) }
|
||||
content={ getPanelContent( currentTab ) }
|
||||
closePanel={ () => closePanel() }
|
||||
clearPanel={ () => clearPanel() }
|
||||
/>
|
||||
</Section>
|
||||
{ showHelpHighlightTooltip ? (
|
||||
<HighlightTooltip
|
||||
delay={ 1000 }
|
||||
useAnchor={ true }
|
||||
title={ __( "We're here for help", 'woocommerce' ) }
|
||||
content={ __(
|
||||
'If you have any questions, feel free to explore the WooCommerce docs listed here.',
|
||||
'woocommerce'
|
||||
) }
|
||||
closeButtonText={ __( 'Got it', 'woocommerce' ) }
|
||||
id="activity-panel-tab-help"
|
||||
onClose={ () => closedHelpPanelHighlight() }
|
||||
onShow={ () => recordEvent( 'help_tooltip_view' ) }
|
||||
/>
|
||||
) : null }
|
||||
</div>
|
||||
togglePanel( tab, tabOpen );
|
||||
} }
|
||||
/>
|
||||
<Panel
|
||||
currentTab
|
||||
isPanelOpen={ isPanelOpen }
|
||||
isPanelSwitching={ isPanelSwitching }
|
||||
tab={ find( getTabs(), { name: currentTab } ) }
|
||||
content={ getPanelContent( currentTab ) }
|
||||
closePanel={ () => closePanel() }
|
||||
clearPanel={ () => clearPanel() }
|
||||
/>
|
||||
</Section>
|
||||
{ showHelpHighlightTooltip ? (
|
||||
<HighlightTooltip
|
||||
delay={ 1000 }
|
||||
useAnchor={ true }
|
||||
title={ __( "We're here for help", 'woocommerce' ) }
|
||||
content={ __(
|
||||
'If you have any questions, feel free to explore the WooCommerce docs listed here.',
|
||||
'woocommerce'
|
||||
) }
|
||||
closeButtonText={ __( 'Got it', 'woocommerce' ) }
|
||||
id="activity-panel-tab-help"
|
||||
onClose={ () => closedHelpPanelHighlight() }
|
||||
onShow={ () => recordEvent( 'help_tooltip_view' ) }
|
||||
/>
|
||||
) : null }
|
||||
</div>
|
||||
</LayoutContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import Tasks from '~/tasks';
|
||||
import { Tasks } from '~/tasks';
|
||||
|
||||
type QueryTypeProps = {
|
||||
query: {
|
||||
|
|
|
@ -1,21 +1,38 @@
|
|||
export const SetupProgress = () => (
|
||||
export const SetupProgress = ( {
|
||||
setupTasksComplete,
|
||||
setupCompletePercent,
|
||||
} ) => (
|
||||
<svg
|
||||
className="woocommerce-layout__activity-panel-tab-icon setup-progress"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 25 25"
|
||||
>
|
||||
<path
|
||||
d="M12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20Z"
|
||||
stroke="#DCDCDE"
|
||||
strokeWidth="2"
|
||||
className="setup-progress-ring"
|
||||
d="M 12.476 23.237 C 18.369 23.237 23.146 18.414 23.146 12.464 C 23.146 6.512 18.369 1.687 12.476 1.687 C 6.581 1.687 1.803 6.512 1.803 12.464 C 1.803 18.414 6.581 23.237 12.476 23.237 Z"
|
||||
/>
|
||||
<path
|
||||
d="M4 12V12C4 16.4183 7.58172 20 12 20V20C16.4183 20 20 16.4183 20 12V12C20 7.58172 16.4183 4 12 4V4"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
className="setup-progress-slice"
|
||||
transform="matrix(-0.034188, 0, 0, 0.034134, 38.373184, -8.278505)"
|
||||
d="M 522 607 A 237 237 0 0 1 759 370 L 759 607 Z"
|
||||
fill={ setupTasksComplete > 0 ? 'currentColor' : 'white' }
|
||||
/>
|
||||
<path
|
||||
className="setup-progress-slice"
|
||||
transform="matrix(-0.034188, 0, 0, -0.034134, 38.368454, 33.13131)"
|
||||
d="M 522 607 A 237 237 0 0 1 759 370 L 759 607 Z"
|
||||
fill={ setupCompletePercent >= 50 ? 'currentColor' : 'white' }
|
||||
/>
|
||||
<path
|
||||
className="setup-progress-slice"
|
||||
transform="matrix(0.034188, 0, 0, -0.034134, -13.500516, 33.133827)"
|
||||
d="M 522 607 A 237 237 0 0 1 759 370 L 759 607 Z"
|
||||
fill={ setupCompletePercent >= 75 ? 'currentColor' : 'white' }
|
||||
/>
|
||||
<path
|
||||
className="setup-progress-slice"
|
||||
transform="matrix(0.034188, 0, 0, 0.034134, -13.495783, -8.281025)"
|
||||
d="M 522 607 A 237 237 0 0 1 759 370 L 759 607 Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
|
|
@ -29,11 +29,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
// custom progress icon, requires specific coloring
|
||||
&.setup-progress {
|
||||
path:first-child {
|
||||
stroke: '#DCDCDE';
|
||||
}
|
||||
.setup-progress-slice {
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.setup-progress-ring {
|
||||
stroke-width: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,8 +70,6 @@
|
|||
outline: none;
|
||||
cursor: pointer;
|
||||
background-color: $studio-white;
|
||||
max-width: min-content;
|
||||
min-width: 80px;
|
||||
width: 100%;
|
||||
height: $header-height;
|
||||
color: $gray-700;
|
||||
|
@ -204,16 +203,15 @@
|
|||
}
|
||||
transform: translateX(100%);
|
||||
@include activity-panel-slide();
|
||||
position: fixed;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: #{$header-height + $adminbar-height-mobile};
|
||||
top: 100%;
|
||||
z-index: 1000;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
|
||||
@include breakpoint( '>782px' ) {
|
||||
height: calc(100vh - #{$header-height + $adminbar-height});
|
||||
top: #{$header-height + $adminbar-height};
|
||||
}
|
||||
.has-woocommerce-navigation & {
|
||||
height: calc(100vh - #{$header-height});
|
||||
|
|
|
@ -44,7 +44,9 @@ import { getAdminSetting } from '~/utils/admin-settings';
|
|||
import { ProgressTitle } from '../task-lists';
|
||||
|
||||
const Tasks = lazy( () =>
|
||||
import( /* webpackChunkName: "tasks" */ '../tasks' )
|
||||
import( /* webpackChunkName: "tasks" */ '../tasks' ).then( ( module ) => ( {
|
||||
default: module.Tasks,
|
||||
} ) )
|
||||
);
|
||||
|
||||
const TwoColumnTasks = lazy( () =>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import { SlotFillProvider } from '@wordpress/components';
|
||||
import { compose } from '@wordpress/compose';
|
||||
import { withSelect } from '@wordpress/data';
|
||||
import { Component, lazy, Suspense } from '@wordpress/element';
|
||||
import { Component, lazy, Suspense, createContext } from '@wordpress/element';
|
||||
import {
|
||||
unstable_HistoryRouter as HistoryRouter,
|
||||
Route,
|
||||
|
@ -15,7 +15,7 @@ import {
|
|||
} from 'react-router-dom';
|
||||
import { Children, cloneElement } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { get, isFunction, identity } from 'lodash';
|
||||
import { get, isFunction, identity, memoize } from 'lodash';
|
||||
import { parse } from 'qs';
|
||||
import { getHistory, getQuery } from '@woocommerce/navigation';
|
||||
import {
|
||||
|
@ -51,6 +51,20 @@ const WCPayUsageModal = lazy( () =>
|
|||
)
|
||||
);
|
||||
|
||||
const LayoutContextPrototype = {
|
||||
getExtendedContext( newItem ) {
|
||||
return { ...this, path: [ ...this.path, newItem ] };
|
||||
},
|
||||
toString() {
|
||||
return this.path.join( '/' );
|
||||
},
|
||||
path: [],
|
||||
};
|
||||
|
||||
export const LayoutContext = createContext(
|
||||
LayoutContextPrototype.getExtendedContext( 'root' )
|
||||
);
|
||||
|
||||
export class PrimaryLayout extends Component {
|
||||
render() {
|
||||
const { children } = this.props;
|
||||
|
@ -111,6 +125,13 @@ const LayoutSwitchWrapper = ( props ) => {
|
|||
};
|
||||
|
||||
class _Layout extends Component {
|
||||
memoizedLayoutContext = memoize( ( page ) =>
|
||||
LayoutContextPrototype.getExtendedContext(
|
||||
page?.breadcrumbs[ page.breadcrumbs.length - 1 ]?.toLowerCase() ||
|
||||
'page'
|
||||
)
|
||||
);
|
||||
|
||||
componentDidMount() {
|
||||
this.recordPageViewTrack();
|
||||
}
|
||||
|
@ -195,38 +216,45 @@ class _Layout extends Component {
|
|||
const query = this.getQuery( location && location.search );
|
||||
|
||||
return (
|
||||
<SlotFillProvider>
|
||||
<div className="woocommerce-layout">
|
||||
<Header
|
||||
sections={
|
||||
isFunction( breadcrumbs )
|
||||
? breadcrumbs( this.props )
|
||||
: breadcrumbs
|
||||
}
|
||||
isEmbedded={ isEmbedded }
|
||||
query={ query }
|
||||
/>
|
||||
<TransientNotices />
|
||||
{ ! isEmbedded && (
|
||||
<PrimaryLayout>
|
||||
<div className="woocommerce-layout__main">
|
||||
<Controller { ...restProps } query={ query } />
|
||||
</div>
|
||||
</PrimaryLayout>
|
||||
) }
|
||||
<LayoutContext.Provider
|
||||
value={ this.memoizedLayoutContext( page ) }
|
||||
>
|
||||
<SlotFillProvider>
|
||||
<div className="woocommerce-layout">
|
||||
<Header
|
||||
sections={
|
||||
isFunction( breadcrumbs )
|
||||
? breadcrumbs( this.props )
|
||||
: breadcrumbs
|
||||
}
|
||||
isEmbedded={ isEmbedded }
|
||||
query={ query }
|
||||
/>
|
||||
<TransientNotices />
|
||||
{ ! isEmbedded && (
|
||||
<PrimaryLayout>
|
||||
<div className="woocommerce-layout__main">
|
||||
<Controller
|
||||
{ ...restProps }
|
||||
query={ query }
|
||||
/>
|
||||
</div>
|
||||
</PrimaryLayout>
|
||||
) }
|
||||
|
||||
{ isEmbedded && this.isWCPaySettingsPage() && (
|
||||
<Suspense fallback={ null }>
|
||||
<WCPayUsageModal />
|
||||
</Suspense>
|
||||
{ isEmbedded && this.isWCPaySettingsPage() && (
|
||||
<Suspense fallback={ null }>
|
||||
<WCPayUsageModal />
|
||||
</Suspense>
|
||||
) }
|
||||
</div>
|
||||
<PluginArea scope="woocommerce-admin" />
|
||||
{ window.wcAdminFeatures.navigation && (
|
||||
<PluginArea scope="woocommerce-navigation" />
|
||||
) }
|
||||
</div>
|
||||
<PluginArea scope="woocommerce-admin" />
|
||||
{ window.wcAdminFeatures.navigation && (
|
||||
<PluginArea scope="woocommerce-navigation" />
|
||||
) }
|
||||
<PluginArea scope="woocommerce-tasks" />
|
||||
</SlotFillProvider>
|
||||
<PluginArea scope="woocommerce-tasks" />
|
||||
</SlotFillProvider>
|
||||
</LayoutContext.Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { Tasks } from './tasks';
|
||||
import './fills';
|
||||
import './deprecated-tasks';
|
||||
|
||||
export * from './tasks';
|
||||
export * from './placeholder';
|
||||
export * from './reminder-bar';
|
||||
export * from './hooks/useActiveSetupList';
|
||||
export default Tasks;
|
||||
|
|
|
@ -6,7 +6,8 @@ import { useSelect, useDispatch } from '@wordpress/data';
|
|||
import {
|
||||
ONBOARDING_STORE_NAME,
|
||||
OPTIONS_STORE_NAME,
|
||||
TaskListType,
|
||||
TaskType,
|
||||
getVisibleTasks,
|
||||
} from '@woocommerce/data';
|
||||
import { Button } from '@wordpress/components';
|
||||
import { Link } from '@woocommerce/components';
|
||||
|
@ -112,15 +113,10 @@ export const TasksReminderBar: React.FC< ReminderBarProps > = ( {
|
|||
REMINDER_BAR_HIDDEN_OPTION,
|
||||
] );
|
||||
|
||||
const visibleTasks =
|
||||
taskList?.tasks.filter(
|
||||
( task ) =>
|
||||
! task.isDismissed &&
|
||||
( ! task.isSnoozed || task.snoozedUntil < Date.now() )
|
||||
) || [];
|
||||
const visibleTasks = getVisibleTasks( taskList?.tasks || [] );
|
||||
|
||||
const completedTasks =
|
||||
visibleTasks?.filter( ( task ) => task.isComplete ) || [];
|
||||
visibleTasks.filter( ( task: TaskType ) => task.isComplete ) || [];
|
||||
|
||||
const isResolved = taskListIsResolved && optionIsResolved;
|
||||
|
||||
|
|
|
@ -10,13 +10,14 @@ import {
|
|||
} from '@woocommerce/data';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { TaskItem, useSlot } from '@woocommerce/experimental';
|
||||
import { useCallback } from '@wordpress/element';
|
||||
import { useCallback, useContext } from '@wordpress/element';
|
||||
import { useDispatch } from '@wordpress/data';
|
||||
import { WooOnboardingTaskListItem } from '@woocommerce/onboarding';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { LayoutContext } from '~/layout';
|
||||
import './task-list.scss';
|
||||
|
||||
export type TaskListItemProps = {
|
||||
|
@ -35,6 +36,7 @@ export const TaskListItem: React.FC< TaskListItemProps > = ( {
|
|||
task,
|
||||
} ) => {
|
||||
const { createNotice } = useDispatch( 'core/notices' );
|
||||
const layoutContext = useContext( LayoutContext );
|
||||
|
||||
const {
|
||||
dismissTask,
|
||||
|
@ -117,6 +119,7 @@ export const TaskListItem: React.FC< TaskListItemProps > = ( {
|
|||
const trackClick = () => {
|
||||
recordEvent( 'tasklist_click', {
|
||||
task_name: id,
|
||||
context: layoutContext.toString(),
|
||||
} );
|
||||
|
||||
if ( ! isComplete ) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { __, _n, sprintf } from '@wordpress/i18n';
|
||||
import { useEffect, useRef, useState } from '@wordpress/element';
|
||||
import { useEffect, useRef, useState, useContext } from '@wordpress/element';
|
||||
import { Card, CardHeader } from '@wordpress/components';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { Badge } from '@woocommerce/components';
|
||||
|
@ -21,6 +21,7 @@ import { TaskListItem } from './task-list-item';
|
|||
import { TaskListMenu } from './task-list-menu';
|
||||
import './task-list.scss';
|
||||
import { ProgressHeader } from '~/task-lists/progress-header';
|
||||
import { LayoutContext } from '~/layout';
|
||||
|
||||
export type TaskListProps = TaskListType & {
|
||||
query: {
|
||||
|
@ -51,6 +52,7 @@ export const TaskList: React.FC< TaskListProps > = ( {
|
|||
} );
|
||||
const prevQueryRef = useRef( query );
|
||||
const visibleTasks = getVisibleTasks( tasks );
|
||||
const layoutContext = useContext( LayoutContext );
|
||||
|
||||
const incompleteTasks = tasks.filter(
|
||||
( task ) => ! task.isComplete && ! task.isDismissed
|
||||
|
@ -64,6 +66,7 @@ export const TaskList: React.FC< TaskListProps > = ( {
|
|||
recordEvent( eventPrefix + 'view', {
|
||||
number_tasks: visibleTasks.length,
|
||||
store_connected: profileItems.wccom_connected,
|
||||
context: layoutContext.toString(),
|
||||
} );
|
||||
};
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import { MenuGroup, MenuItem } from '@wordpress/components';
|
||||
import { check } from '@wordpress/icons';
|
||||
import { Fragment, useEffect } from '@wordpress/element';
|
||||
import { Fragment, useEffect, useState } from '@wordpress/element';
|
||||
import { useDispatch, useSelect } from '@wordpress/data';
|
||||
import {
|
||||
ONBOARDING_STORE_NAME,
|
||||
|
@ -33,6 +33,7 @@ import { SectionedTaskListPlaceholder } from '~/two-column-tasks/sectioned-task-
|
|||
|
||||
export type TasksProps = {
|
||||
query: { task?: string };
|
||||
context?: string;
|
||||
};
|
||||
|
||||
function getTaskListComponent( taskListId: string ) {
|
||||
|
@ -155,12 +156,9 @@ export const Tasks: React.FC< TasksProps > = ( { query } ) => {
|
|||
? id.endsWith( 'two_column' )
|
||||
: ! id.endsWith( 'two_column' )
|
||||
)
|
||||
.filter( ( { isVisible }: TaskListType ) => isVisible )
|
||||
.map( ( taskList: TaskListType ) => {
|
||||
const { id, isHidden, isVisible, isToggleable } = taskList;
|
||||
|
||||
if ( ! isVisible ) {
|
||||
return null;
|
||||
}
|
||||
const { id, isHidden, isToggleable } = taskList;
|
||||
|
||||
const TaskListComponent = getTaskListComponent( id );
|
||||
return (
|
||||
|
|
|
@ -144,6 +144,7 @@ describe( 'TaskList', () => {
|
|||
);
|
||||
expect( recordEvent ).toHaveBeenCalledTimes( 1 );
|
||||
expect( recordEvent ).toHaveBeenCalledWith( 'tasklist_view', {
|
||||
context: 'root',
|
||||
number_tasks: 0,
|
||||
store_connected: null,
|
||||
} );
|
||||
|
@ -166,6 +167,7 @@ describe( 'TaskList', () => {
|
|||
);
|
||||
expect( recordEvent ).toHaveBeenCalledTimes( 1 );
|
||||
expect( recordEvent ).toHaveBeenCalledWith( 'extended_tasklist_view', {
|
||||
context: 'root',
|
||||
number_tasks: 0,
|
||||
store_connected: null,
|
||||
} );
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useEffect, useRef, useState } from '@wordpress/element';
|
||||
import { useEffect, useRef, useState, useContext } from '@wordpress/element';
|
||||
import { Panel, PanelBody, PanelRow } from '@wordpress/components';
|
||||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
import { ONBOARDING_STORE_NAME, getVisibleTasks } from '@woocommerce/data';
|
||||
|
@ -20,6 +20,7 @@ import { ProgressHeader } from '~/task-lists/progress-header';
|
|||
import { SectionPanelTitle } from './section-panel-title';
|
||||
import { TaskListItem } from './task-list-item';
|
||||
import { TaskListCompletedHeader } from './completed-header';
|
||||
import { LayoutContext } from '~/layout';
|
||||
|
||||
type PanelBodyProps = Omit< PanelBody.Props, 'title' | 'onToggle' > & {
|
||||
title: string | React.ReactNode | undefined;
|
||||
|
@ -51,6 +52,7 @@ export const SectionedTaskList: React.FC< TaskListProps > = ( {
|
|||
const [ openPanel, setOpenPanel ] = useState< string | null >(
|
||||
sections?.find( ( section ) => ! section.isComplete )?.id || null
|
||||
);
|
||||
const layoutContext = useContext( LayoutContext );
|
||||
|
||||
const prevQueryRef = useRef( query );
|
||||
|
||||
|
@ -64,6 +66,7 @@ export const SectionedTaskList: React.FC< TaskListProps > = ( {
|
|||
recordEvent( `${ eventPrefix }view`, {
|
||||
number_tasks: visibleTasks.length,
|
||||
store_connected: profileItems.wccom_connected,
|
||||
context: layoutContext.toString(),
|
||||
} );
|
||||
};
|
||||
|
||||
|
|
|
@ -5,17 +5,21 @@ import { __ } from '@wordpress/i18n';
|
|||
import { getNewPath, navigateTo } from '@woocommerce/navigation';
|
||||
import {
|
||||
ONBOARDING_STORE_NAME,
|
||||
OPTIONS_STORE_NAME,
|
||||
TaskType,
|
||||
useUserPreferences,
|
||||
} from '@woocommerce/data';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { TaskItem, useSlot } from '@woocommerce/experimental';
|
||||
import { useCallback } from '@wordpress/element';
|
||||
import { useCallback, useContext } from '@wordpress/element';
|
||||
import { useDispatch } from '@wordpress/data';
|
||||
import { WooOnboardingTaskListItem } from '@woocommerce/onboarding';
|
||||
import classnames from 'classnames';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { LayoutContext } from '~/layout';
|
||||
|
||||
export type TaskListItemProps = {
|
||||
task: TaskType;
|
||||
eventPrefix?: string;
|
||||
|
@ -35,6 +39,8 @@ export const TaskListItem: React.FC< TaskListItemProps > = ( {
|
|||
undoSnoozeTask,
|
||||
} = useDispatch( ONBOARDING_STORE_NAME );
|
||||
|
||||
const layoutContext = useContext( LayoutContext );
|
||||
|
||||
const slot = useSlot(
|
||||
`woocommerce_onboarding_task_list_item_${ task.id }`
|
||||
);
|
||||
|
@ -68,6 +74,7 @@ export const TaskListItem: React.FC< TaskListItemProps > = ( {
|
|||
const trackClick = () => {
|
||||
recordEvent( `${ eventPrefix }click`, {
|
||||
task_name: task.id,
|
||||
context: layoutContext.toString(),
|
||||
} );
|
||||
|
||||
if ( ! task.isComplete ) {
|
||||
|
|
|
@ -2,7 +2,13 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useEffect, useRef, useState, createElement } from '@wordpress/element';
|
||||
import {
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
createElement,
|
||||
useContext,
|
||||
} from '@wordpress/element';
|
||||
import { Button, Card } from '@wordpress/components';
|
||||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
import { EllipsisMenu } from '@woocommerce/components';
|
||||
|
@ -29,6 +35,7 @@ import TaskListCompleted from './completed';
|
|||
import { ProgressHeader } from '~/task-lists/progress-header';
|
||||
import { TaskListItemTwoColumn } from './task-list-item-two-column';
|
||||
import { TaskListCompletedHeader } from './completed-header';
|
||||
import { LayoutContext } from '~/layout';
|
||||
|
||||
export type TaskListProps = TaskListType & {
|
||||
eventName?: string;
|
||||
|
@ -71,6 +78,7 @@ export const TaskList: React.FC< TaskListProps > = ( {
|
|||
} >( {} );
|
||||
const [ activeTaskId, setActiveTaskId ] = useState( '' );
|
||||
const [ showDismissModal, setShowDismissModal ] = useState( false );
|
||||
const layoutContext = useContext( LayoutContext );
|
||||
|
||||
const prevQueryRef = useRef( query );
|
||||
|
||||
|
@ -83,6 +91,7 @@ export const TaskList: React.FC< TaskListProps > = ( {
|
|||
recordEvent( `${ listEventPrefix }view`, {
|
||||
number_tasks: visibleTasks.length,
|
||||
store_connected: profileItems.wccom_connected,
|
||||
context: layoutContext.toString(),
|
||||
} );
|
||||
};
|
||||
|
||||
|
@ -179,6 +188,7 @@ export const TaskList: React.FC< TaskListProps > = ( {
|
|||
const trackClick = ( task: TaskType ) => {
|
||||
recordEvent( `${ listEventPrefix }click`, {
|
||||
task_name: task.id,
|
||||
context: layoutContext.toString(),
|
||||
} );
|
||||
};
|
||||
|
||||
|
|
|
@ -148,6 +148,7 @@ describe( 'TaskList', () => {
|
|||
);
|
||||
expect( recordEvent ).toHaveBeenCalledTimes( 1 );
|
||||
expect( recordEvent ).toHaveBeenCalledWith( 'tasklist_view', {
|
||||
context: 'root',
|
||||
number_tasks: 0,
|
||||
store_connected: null,
|
||||
} );
|
||||
|
@ -170,6 +171,7 @@ describe( 'TaskList', () => {
|
|||
);
|
||||
expect( recordEvent ).toHaveBeenCalledTimes( 1 );
|
||||
expect( recordEvent ).toHaveBeenCalledWith( 'tasklist_view', {
|
||||
context: 'root',
|
||||
number_tasks: 0,
|
||||
store_connected: null,
|
||||
} );
|
||||
|
@ -193,6 +195,7 @@ describe( 'TaskList', () => {
|
|||
);
|
||||
expect( recordEvent ).toHaveBeenCalledTimes( 1 );
|
||||
expect( recordEvent ).toHaveBeenCalledWith( 'extended_tasklist_view', {
|
||||
context: 'root',
|
||||
number_tasks: 0,
|
||||
store_connected: null,
|
||||
} );
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Adding property to tasks tracks events to indicate context.
|
|
@ -171,7 +171,7 @@ class TaskList {
|
|||
* @return bool
|
||||
*/
|
||||
public function is_visible() {
|
||||
if ( ! $this->visible ) {
|
||||
if ( ! $this->visible || ! count( $this->get_viewable_tasks() ) > 0 ) {
|
||||
return false;
|
||||
}
|
||||
return ! $this->is_hidden();
|
||||
|
|
|
@ -104,7 +104,6 @@ class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case {
|
|||
* Test getting a customers default token, when there no token is expictly set.
|
||||
* This should be the "first created".
|
||||
* @see WC_Payment_Token::create()
|
||||
* @group failing
|
||||
* @since 2.6.0
|
||||
*/
|
||||
public function test_wc_get_customer_default_token_returns_first_created_when_no_default_token_set() {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
require_once __DIR__ . '/test-task.php';
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\OnboardingTasks\TaskList;
|
||||
use Automattic\WooCommerce\Admin\Features\OnboardingTasks\Task;
|
||||
|
||||
/**
|
||||
* class WC_Admin_Tests_OnboardingTasks_TaskList
|
||||
|
@ -89,6 +90,13 @@ class WC_Admin_Tests_OnboardingTasks_TaskList extends WC_Unit_Test_Case {
|
|||
* Tests that lists can be hidden.
|
||||
*/
|
||||
public function test_visible() {
|
||||
$this->assertFalse( $this->list->is_visible() );
|
||||
$this->list->add_task(
|
||||
new TestTask(
|
||||
new TaskList(),
|
||||
array( 'id' => 'my-task' )
|
||||
)
|
||||
);
|
||||
$this->assertTrue( $this->list->is_visible() );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue