Merge pull request #32914 from woocommerce/add/32811-import-prdocuts-tracks
Add tracks for experimental import products task
This commit is contained in:
commit
c4c2d160ff
|
@ -7,6 +7,7 @@ import ReblogIcon from 'gridicons/dist/reblog';
|
||||||
import { getAdminLink } from '@woocommerce/settings';
|
import { getAdminLink } from '@woocommerce/settings';
|
||||||
import interpolateComponents from '@automattic/interpolate-components';
|
import interpolateComponents from '@automattic/interpolate-components';
|
||||||
import { ExternalLink } from '@wordpress/components';
|
import { ExternalLink } from '@wordpress/components';
|
||||||
|
import { recordEvent } from '@woocommerce/tracks';
|
||||||
|
|
||||||
export const importTypes = [
|
export const importTypes = [
|
||||||
{
|
{
|
||||||
|
@ -20,6 +21,8 @@ export const importTypes = [
|
||||||
href: getAdminLink(
|
href: getAdminLink(
|
||||||
'edit.php?post_type=product&page=product_importer&wc_onboarding_active_task=products'
|
'edit.php?post_type=product&page=product_importer&wc_onboarding_active_task=products'
|
||||||
),
|
),
|
||||||
|
onClick: () =>
|
||||||
|
recordEvent( 'tasklist_add_product', { method: 'import' } ),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'from-cart2cart' as const,
|
key: 'from-cart2cart' as const,
|
||||||
|
@ -37,5 +40,7 @@ export const importTypes = [
|
||||||
},
|
},
|
||||||
} ),
|
} ),
|
||||||
before: <ReblogIcon />,
|
before: <ReblogIcon />,
|
||||||
|
onClick: () =>
|
||||||
|
recordEvent( 'tasklist_add_product', { method: 'migrate' } ),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -6,8 +6,9 @@ import { registerPlugin } from '@wordpress/plugins';
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { Icon, chevronUp, chevronDown } from '@wordpress/icons';
|
import { Icon, chevronUp, chevronDown } from '@wordpress/icons';
|
||||||
import { Button } from '@wordpress/components';
|
import { Button } from '@wordpress/components';
|
||||||
import { useState } from '@wordpress/element';
|
import { useMemo, useState } from '@wordpress/element';
|
||||||
import { getAdminLink } from '@woocommerce/settings';
|
import { getAdminLink } from '@woocommerce/settings';
|
||||||
|
import { recordEvent } from '@woocommerce/tracks';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -20,9 +21,23 @@ import useProductTypeListItems from '../experimental-products/use-product-types-
|
||||||
import { getProductTypes } from '../experimental-products/utils';
|
import { getProductTypes } from '../experimental-products/utils';
|
||||||
import LoadSampleProductModal from '../components/load-sample-product-modal';
|
import LoadSampleProductModal from '../components/load-sample-product-modal';
|
||||||
import useLoadSampleProducts from '../components/use-load-sample-products';
|
import useLoadSampleProducts from '../components/use-load-sample-products';
|
||||||
|
import useRecordCompletionTime from '../use-record-completion-time';
|
||||||
|
|
||||||
const Products = () => {
|
export const Products = () => {
|
||||||
const [ showStacks, setStackVisibility ] = useState< boolean >( false );
|
const [ showStacks, setStackVisibility ] = useState< boolean >( false );
|
||||||
|
const { recordCompletionTime } = useRecordCompletionTime( 'products' );
|
||||||
|
|
||||||
|
const importTypesWithTimeRecord = useMemo(
|
||||||
|
() =>
|
||||||
|
importTypes.map( ( importType ) => ( {
|
||||||
|
...importType,
|
||||||
|
onClick: () => {
|
||||||
|
importType.onClick();
|
||||||
|
recordCompletionTime();
|
||||||
|
},
|
||||||
|
} ) ),
|
||||||
|
[ recordCompletionTime ]
|
||||||
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
loadSampleProduct,
|
loadSampleProduct,
|
||||||
|
@ -32,20 +47,34 @@ const Products = () => {
|
||||||
'edit.php?post_type=product&wc_onboarding_active_task=products'
|
'edit.php?post_type=product&wc_onboarding_active_task=products'
|
||||||
),
|
),
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
const productTypeListItems = useProductTypeListItems(
|
||||||
|
getProductTypes( [ 'subscription' ] ),
|
||||||
|
{
|
||||||
|
onClick: recordCompletionTime,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const StacksComponent = (
|
const StacksComponent = (
|
||||||
<Stacks
|
<Stacks
|
||||||
items={ useProductTypeListItems(
|
items={ productTypeListItems }
|
||||||
getProductTypes( [ 'subscription' ] )
|
|
||||||
) }
|
|
||||||
onClickLoadSampleProduct={ loadSampleProduct }
|
onClickLoadSampleProduct={ loadSampleProduct }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="woocommerce-task-import-products">
|
<div className="woocommerce-task-import-products">
|
||||||
<h1>{ __( 'Import your products', 'woocommerce' ) }</h1>
|
<h1>{ __( 'Import your products', 'woocommerce' ) }</h1>
|
||||||
<CardList items={ importTypes } />
|
<CardList items={ importTypesWithTimeRecord } />
|
||||||
<div className="woocommerce-task-import-products-stacks">
|
<div className="woocommerce-task-import-products-stacks">
|
||||||
<Button onClick={ () => setStackVisibility( ! showStacks ) }>
|
<Button
|
||||||
|
onClick={ () => {
|
||||||
|
recordEvent(
|
||||||
|
'tasklist_add_product_from_scratch_click'
|
||||||
|
);
|
||||||
|
setStackVisibility( ! showStacks );
|
||||||
|
} }
|
||||||
|
>
|
||||||
{ __( 'Or add your products from scratch', 'woocommerce' ) }
|
{ __( 'Or add your products from scratch', 'woocommerce' ) }
|
||||||
<Icon icon={ showStacks ? chevronUp : chevronDown } />
|
<Icon icon={ showStacks ? chevronUp : chevronDown } />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { render, waitFor } from '@testing-library/react';
|
||||||
|
import { recordEvent } from '@woocommerce/tracks';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { Products } from '../';
|
||||||
|
|
||||||
|
jest.mock( '@woocommerce/tracks', () => ( { recordEvent: jest.fn() } ) );
|
||||||
|
|
||||||
|
describe( 'Products', () => {
|
||||||
|
beforeEach( () => {
|
||||||
|
( recordEvent as jest.Mock ).mockClear();
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'should fire "tasklist_add_product_from_scratch_click" event when the button clicked', async () => {
|
||||||
|
const { getByRole } = render( <Products /> );
|
||||||
|
|
||||||
|
userEvent.click(
|
||||||
|
getByRole( 'button', { name: 'Or add your products from scratch' } )
|
||||||
|
);
|
||||||
|
await waitFor( () =>
|
||||||
|
expect( recordEvent ).toHaveBeenCalledWith(
|
||||||
|
'tasklist_add_product_from_scratch_click'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'should fire "tasklist_add_product" event when the csv option clicked', async () => {
|
||||||
|
const { getByRole } = render( <Products /> );
|
||||||
|
|
||||||
|
userEvent.click(
|
||||||
|
getByRole( 'menuitem', {
|
||||||
|
name:
|
||||||
|
'FROM A CSV FILE Import all products at once by uploading a CSV file.',
|
||||||
|
} )
|
||||||
|
);
|
||||||
|
await waitFor( () =>
|
||||||
|
expect( recordEvent ).toHaveBeenCalledWith(
|
||||||
|
'tasklist_add_product',
|
||||||
|
{
|
||||||
|
method: 'import',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'should fire "tasklist_add_product" event when the cart2cart option clicked', async () => {
|
||||||
|
const { getByRole } = render( <Products /> );
|
||||||
|
|
||||||
|
userEvent.click(
|
||||||
|
getByRole( 'menuitem', {
|
||||||
|
name:
|
||||||
|
'FROM CART2CART Migrate all store data like products, customers, and orders in no time with this 3rd party plugin. Learn more (opens in a new tab)',
|
||||||
|
} )
|
||||||
|
);
|
||||||
|
await waitFor( () =>
|
||||||
|
expect( recordEvent ).toHaveBeenCalledWith(
|
||||||
|
'tasklist_add_product',
|
||||||
|
{
|
||||||
|
method: 'migrate',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'should fire "task_completion_time" event when an option clicked', async () => {
|
||||||
|
Object.defineProperty( window, 'performance', {
|
||||||
|
value: {
|
||||||
|
now: jest
|
||||||
|
.fn()
|
||||||
|
.mockReturnValueOnce( 0 )
|
||||||
|
.mockReturnValueOnce( 1000 ),
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
const { getByRole } = render( <Products /> );
|
||||||
|
|
||||||
|
userEvent.click(
|
||||||
|
getByRole( 'menuitem', {
|
||||||
|
name:
|
||||||
|
'FROM A CSV FILE Import all products at once by uploading a CSV file.',
|
||||||
|
} )
|
||||||
|
);
|
||||||
|
await waitFor( () =>
|
||||||
|
expect( recordEvent ).toHaveBeenCalledWith(
|
||||||
|
'task_completion_time',
|
||||||
|
{
|
||||||
|
task_name: 'products',
|
||||||
|
time: 1000,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
} );
|
|
@ -9,14 +9,26 @@ import { useMemo } from '@wordpress/element';
|
||||||
import useCreateProductByType from './use-create-product-by-type';
|
import useCreateProductByType from './use-create-product-by-type';
|
||||||
import { ProductType } from './constants';
|
import { ProductType } from './constants';
|
||||||
|
|
||||||
const useProductTypeListItems = ( _productTypes: ProductType[] ) => {
|
const useProductTypeListItems = (
|
||||||
|
_productTypes: ProductType[],
|
||||||
|
{
|
||||||
|
onClick,
|
||||||
|
}: {
|
||||||
|
onClick?: () => void;
|
||||||
|
} = {}
|
||||||
|
) => {
|
||||||
const { createProductByType } = useCreateProductByType();
|
const { createProductByType } = useCreateProductByType();
|
||||||
|
|
||||||
const productTypes = useMemo(
|
const productTypes = useMemo(
|
||||||
() =>
|
() =>
|
||||||
_productTypes.map( ( productType ) => ( {
|
_productTypes.map( ( productType ) => ( {
|
||||||
...productType,
|
...productType,
|
||||||
onClick: () => createProductByType( productType.key ),
|
onClick: () => {
|
||||||
|
createProductByType( productType.key );
|
||||||
|
if ( typeof onClick === 'function' ) {
|
||||||
|
onClick();
|
||||||
|
}
|
||||||
|
},
|
||||||
} ) ),
|
} ) ),
|
||||||
[ createProductByType ]
|
[ createProductByType ]
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { useRef } from '@wordpress/element';
|
||||||
|
import { recordEvent } from '@woocommerce/tracks';
|
||||||
|
|
||||||
|
const useRecordCompletionTime = ( taskName: string, startTime?: number ) => {
|
||||||
|
const _startTime = useRef( startTime || window.performance.now() );
|
||||||
|
|
||||||
|
const recordCompletionTime = () => {
|
||||||
|
recordEvent( 'task_completion_time', {
|
||||||
|
task_name: taskName,
|
||||||
|
time: window.performance.now() - _startTime.current,
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
recordCompletionTime,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useRecordCompletionTime;
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: add
|
||||||
|
|
||||||
|
Add track events for experimental import products task
|
Loading…
Reference in New Issue