Merge pull request #32944 from woocommerce/add/tracks-experimental-products
Add tracks for experimental products page
This commit is contained in:
commit
2c5f47a91d
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: Add
|
||||
|
||||
Changed task_view experimental_product key to variant (technically a breaking change but since it was introduced in the same version it is fine) #32944
|
|
@ -8,7 +8,7 @@ import { Slot, Fill } from '@wordpress/components';
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { isProductTaskExperimentTreatment } from './use-product-layout-experiment';
|
||||
import { getProductLayoutExperiment } from './use-product-layout-experiment';
|
||||
|
||||
export const trackView = async ( taskId ) => {
|
||||
const activePlugins = wp.data
|
||||
|
@ -25,9 +25,7 @@ export const trackView = async ( taskId ) => {
|
|||
|
||||
recordEvent( 'task_view', {
|
||||
task_name: taskId,
|
||||
experimental_products:
|
||||
window.wcAdminFeatures[ 'experimental-products-task' ] &&
|
||||
( await isProductTaskExperimentTreatment() ),
|
||||
variant: await getProductLayoutExperiment(),
|
||||
wcs_installed: installedPlugins.includes( 'woocommerce-services' ),
|
||||
wcs_active: activePlugins.includes( 'woocommerce-services' ),
|
||||
jetpack_installed: installedPlugins.includes( 'jetpack' ),
|
||||
|
|
|
@ -7,6 +7,12 @@ import apiFetch from '@wordpress/api-fetch';
|
|||
import { WC_ADMIN_NAMESPACE } from '@woocommerce/data';
|
||||
import { useDispatch } from '@wordpress/data';
|
||||
import { useState } from '@wordpress/element';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import useRecordCompletionTime from '../use-record-completion-time';
|
||||
|
||||
type UseLoadSampleProductsProps = {
|
||||
redirectUrlAfterSuccess: string;
|
||||
|
@ -17,8 +23,13 @@ const useLoadSampleProducts = ( {
|
|||
}: UseLoadSampleProductsProps ) => {
|
||||
const [ isRequesting, setIsRequesting ] = useState< boolean >( false );
|
||||
const { createNotice } = useDispatch( 'core/notices' );
|
||||
const { recordCompletionTime } = useRecordCompletionTime( 'products' );
|
||||
|
||||
const loadSampleProduct = async () => {
|
||||
recordEvent( 'tasklist_add_product', {
|
||||
method: 'sample_product',
|
||||
} );
|
||||
recordCompletionTime();
|
||||
setIsRequesting( true );
|
||||
try {
|
||||
await apiFetch( {
|
||||
|
|
|
@ -50,6 +50,7 @@ export const Products = () => {
|
|||
|
||||
const productTypeListItems = useProductTypeListItems(
|
||||
getProductTypes( [ 'subscription' ] ),
|
||||
[],
|
||||
{
|
||||
onClick: recordCompletionTime,
|
||||
}
|
||||
|
|
|
@ -73,6 +73,8 @@ describe( 'Products', () => {
|
|||
now: jest
|
||||
.fn()
|
||||
.mockReturnValueOnce( 0 )
|
||||
.mockReturnValueOnce( 1000 )
|
||||
.mockReturnValueOnce( 0 )
|
||||
.mockReturnValueOnce( 1000 ),
|
||||
},
|
||||
} );
|
||||
|
@ -84,14 +86,21 @@ describe( 'Products', () => {
|
|||
'FROM A CSV FILE Import all products at once by uploading a CSV file.',
|
||||
} )
|
||||
);
|
||||
await waitFor( () =>
|
||||
expect( recordEvent ).toHaveBeenCalledWith(
|
||||
await waitFor( () => {
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
'tasklist_add_product',
|
||||
{ method: 'import' }
|
||||
);
|
||||
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
'task_completion_time',
|
||||
{
|
||||
task_name: 'products',
|
||||
time: '0-2s',
|
||||
}
|
||||
)
|
||||
);
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -6,6 +6,7 @@ import { Text } from '@woocommerce/experimental';
|
|||
import { Link } from '@woocommerce/components';
|
||||
import interpolateComponents from '@automattic/interpolate-components';
|
||||
import { getAdminLink } from '@woocommerce/settings';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -13,6 +14,7 @@ import { getAdminLink } from '@woocommerce/settings';
|
|||
import { ProductType } from './constants';
|
||||
import CardList from '../experimental-import-products/CardList';
|
||||
import './card-layout.scss';
|
||||
import useRecordCompletionTime from '../use-record-completion-time';
|
||||
|
||||
type CardProps = {
|
||||
items: ( ProductType & {
|
||||
|
@ -21,6 +23,8 @@ type CardProps = {
|
|||
};
|
||||
|
||||
const CardLayout: React.FC< CardProps > = ( { items } ) => {
|
||||
const { recordCompletionTime } = useRecordCompletionTime( 'products' );
|
||||
|
||||
return (
|
||||
<div className="woocommerce-products-card-layout">
|
||||
<Text className="woocommerce-products-card-layout__description">
|
||||
|
@ -32,6 +36,10 @@ const CardLayout: React.FC< CardProps > = ( { items } ) => {
|
|||
sbLink: (
|
||||
<Link
|
||||
onClick={ () => {
|
||||
recordEvent( 'tasklist_add_product', {
|
||||
method: 'manually',
|
||||
} );
|
||||
recordCompletionTime();
|
||||
window.location = getAdminLink(
|
||||
'post-new.php?post_type=product&wc_onboarding_active_task=products&tutorial=true'
|
||||
);
|
||||
|
|
|
@ -7,8 +7,16 @@ import { Text } from '@woocommerce/experimental';
|
|||
import { ExternalLink } from '@wordpress/components';
|
||||
import { Link } from '@woocommerce/components';
|
||||
import { getAdminLink } from '@woocommerce/settings';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import useRecordCompletionTime from '../use-record-completion-time';
|
||||
|
||||
const Footer: React.FC = () => {
|
||||
const { recordCompletionTime } = useRecordCompletionTime( 'products' );
|
||||
|
||||
return (
|
||||
<div className="woocommerce-products-footer">
|
||||
<Text className="woocommerce-products-footer__selling-somewhere-else">
|
||||
|
@ -23,6 +31,10 @@ const Footer: React.FC = () => {
|
|||
importCSVLink: (
|
||||
<Link
|
||||
onClick={ () => {
|
||||
recordEvent( 'tasklist_add_product', {
|
||||
method: 'import',
|
||||
} );
|
||||
recordCompletionTime();
|
||||
window.location = getAdminLink(
|
||||
'edit.php?post_type=product&page=product_importer&wc_onboarding_active_task=products'
|
||||
);
|
||||
|
@ -36,6 +48,12 @@ const Footer: React.FC = () => {
|
|||
),
|
||||
_3rdLink: (
|
||||
<ExternalLink
|
||||
onClick={ () => {
|
||||
recordEvent( 'tasklist_add_product', {
|
||||
method: 'migrate',
|
||||
} );
|
||||
recordCompletionTime();
|
||||
} }
|
||||
href="https://woocommerce.com/products/cart2cart/?utm_medium=product"
|
||||
type="external"
|
||||
>
|
||||
|
|
|
@ -26,6 +26,7 @@ import CardLayout from './card-layout';
|
|||
import { LoadSampleProductType } from './constants';
|
||||
import LoadSampleProductModal from '../components/load-sample-product-modal';
|
||||
import useLoadSampleProducts from '../components/use-load-sample-products';
|
||||
import useRecordCompletionTime from '../use-record-completion-time';
|
||||
|
||||
const getOnboardingProductType = (): string[] => {
|
||||
const onboardingData = getAdminSetting( 'onboarding' );
|
||||
|
@ -57,11 +58,28 @@ export const Products = () => {
|
|||
experimentLayout,
|
||||
] = useProductTaskExperiment();
|
||||
|
||||
const productTypes = useProductTypeListItems( getProductTypes() );
|
||||
const surfacedProductTypeKeys = getSurfacedProductTypeKeys(
|
||||
getOnboardingProductType()
|
||||
);
|
||||
|
||||
const productTypes = useProductTypeListItems(
|
||||
getProductTypes(),
|
||||
surfacedProductTypeKeys
|
||||
);
|
||||
const { recordCompletionTime } = useRecordCompletionTime( 'products' );
|
||||
|
||||
const productTypesWithTimeRecord = useMemo(
|
||||
() =>
|
||||
productTypes.map( ( productType ) => ( {
|
||||
...productType,
|
||||
onClick: () => {
|
||||
productType.onClick();
|
||||
recordCompletionTime();
|
||||
},
|
||||
} ) ),
|
||||
[ recordCompletionTime ]
|
||||
);
|
||||
|
||||
const {
|
||||
loadSampleProduct,
|
||||
isLoadingSampleProducts,
|
||||
|
@ -72,12 +90,13 @@ export const Products = () => {
|
|||
} );
|
||||
|
||||
const visibleProductTypes = useMemo( () => {
|
||||
const surfacedProductTypes = productTypes.filter( ( productType ) =>
|
||||
const surfacedProductTypes = productTypesWithTimeRecord.filter(
|
||||
( productType ) =>
|
||||
surfacedProductTypeKeys.includes( productType.key )
|
||||
);
|
||||
if ( isExpanded ) {
|
||||
// To show product types in same order, we need to push the other product types to the end.
|
||||
productTypes.forEach(
|
||||
productTypesWithTimeRecord.forEach(
|
||||
( productType ) =>
|
||||
! surfacedProductTypes.includes( productType ) &&
|
||||
surfacedProductTypes.push( productType )
|
||||
|
|
|
@ -6,12 +6,14 @@ import { List, Link } from '@woocommerce/components';
|
|||
import { Text } from '@woocommerce/experimental';
|
||||
import interpolateComponents from '@automattic/interpolate-components';
|
||||
import { getAdminLink } from '@woocommerce/settings';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { ProductType } from './constants';
|
||||
import './stack.scss';
|
||||
import useRecordCompletionTime from '../use-record-completion-time';
|
||||
|
||||
type StackProps = {
|
||||
items: ( ProductType & {
|
||||
|
@ -26,6 +28,8 @@ const Stack: React.FC< StackProps > = ( {
|
|||
onClickLoadSampleProduct,
|
||||
showOtherOptions = true,
|
||||
} ) => {
|
||||
const { recordCompletionTime } = useRecordCompletionTime( 'products' );
|
||||
|
||||
return (
|
||||
<div className="woocommerce-products-stack">
|
||||
<List items={ items } />
|
||||
|
@ -40,6 +44,10 @@ const Stack: React.FC< StackProps > = ( {
|
|||
sbLink: (
|
||||
<Link
|
||||
onClick={ () => {
|
||||
recordEvent( 'tasklist_add_product', {
|
||||
method: 'manually',
|
||||
} );
|
||||
recordCompletionTime();
|
||||
window.location = getAdminLink(
|
||||
'post-new.php?post_type=product&wc_onboarding_active_task=products&tutorial=true'
|
||||
);
|
||||
|
@ -56,6 +64,7 @@ const Stack: React.FC< StackProps > = ( {
|
|||
href=""
|
||||
type="wc-admin"
|
||||
onClick={ () => {
|
||||
recordCompletionTime();
|
||||
onClickLoadSampleProduct();
|
||||
return false;
|
||||
} }
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { render } from '@testing-library/react';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -9,7 +10,11 @@ import { render } from '@testing-library/react';
|
|||
import CardLayout from '../card-layout';
|
||||
import { productTypes } from '../constants';
|
||||
|
||||
jest.mock( '@woocommerce/tracks', () => ( { recordEvent: jest.fn() } ) );
|
||||
describe( 'CardLayout', () => {
|
||||
beforeEach( () => {
|
||||
( recordEvent as jest.Mock ).mockClear();
|
||||
} );
|
||||
it( 'should render all products types in CardLayout', () => {
|
||||
const { queryByText, queryAllByRole } = render(
|
||||
<CardLayout
|
||||
|
@ -26,4 +31,28 @@ describe( 'CardLayout', () => {
|
|||
|
||||
expect( queryAllByRole( 'link' ) ).toHaveLength( 1 );
|
||||
} );
|
||||
|
||||
it( 'start blank link should fire the tasklist_add_product and completion events', () => {
|
||||
const { getByText } = render(
|
||||
<CardLayout
|
||||
items={ [
|
||||
{
|
||||
...productTypes[ 0 ],
|
||||
onClick: () => {},
|
||||
},
|
||||
] }
|
||||
/>
|
||||
);
|
||||
fireEvent.click( getByText( 'Start blank' ) );
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
'tasklist_add_product',
|
||||
{ method: 'manually' }
|
||||
);
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
'task_completion_time',
|
||||
{ task_name: 'products', time: '0-2s' }
|
||||
);
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { render } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
jest.mock( '@woocommerce/tracks', () => ( { recordEvent: jest.fn() } ) );
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -9,8 +13,41 @@ import { render } from '@testing-library/react';
|
|||
import Footer from '../footer';
|
||||
|
||||
describe( 'Footer', () => {
|
||||
beforeEach( () => {
|
||||
( recordEvent as jest.Mock ).mockClear();
|
||||
} );
|
||||
it( 'should render footer with two links', () => {
|
||||
const { queryAllByRole } = render( <Footer /> );
|
||||
expect( queryAllByRole( 'link' ) ).toHaveLength( 2 );
|
||||
} );
|
||||
|
||||
it( 'clicking on import CSV should fire event tasklist_add_product with method:import and task_completion_time', () => {
|
||||
const { getByText } = render( <Footer /> );
|
||||
userEvent.click( getByText( 'Import your products from a CSV file' ) );
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
'tasklist_add_product',
|
||||
{ method: 'import' }
|
||||
);
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
'task_completion_time',
|
||||
{ task_name: 'products', time: '0-2s' }
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'clicking on start blank should fire event tasklist_add_product with method:migrate and task_completion_time', () => {
|
||||
const { getByText } = render( <Footer /> );
|
||||
userEvent.click( getByText( 'use a 3rd party migration plugin' ) );
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
'tasklist_add_product',
|
||||
{ method: 'migrate' }
|
||||
);
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
'task_completion_time',
|
||||
{ task_name: 'products', time: '0-2s' }
|
||||
);
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import { render, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { useProductTaskExperiment } from '@woocommerce/onboarding';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -25,6 +26,12 @@ jest.mock( '@woocommerce/onboarding', () => ( {
|
|||
useProductTaskExperiment: jest.fn().mockReturnValue( [ false, 'stacked' ] ),
|
||||
} ) );
|
||||
|
||||
jest.mock( '../use-create-product-by-type', () => ( {
|
||||
useCreateProductByType: jest
|
||||
.fn()
|
||||
.mockReturnValue( { createProductByType: jest.fn() } ),
|
||||
} ) );
|
||||
|
||||
global.fetch = jest.fn().mockImplementation( () =>
|
||||
Promise.resolve( {
|
||||
json: () => Promise.resolve( {} ),
|
||||
|
@ -32,6 +39,8 @@ global.fetch = jest.fn().mockImplementation( () =>
|
|||
} )
|
||||
);
|
||||
|
||||
jest.mock( '@woocommerce/tracks', () => ( { recordEvent: jest.fn() } ) );
|
||||
|
||||
describe( 'Products', () => {
|
||||
beforeEach( () => {
|
||||
jest.clearAllMocks();
|
||||
|
@ -65,6 +74,70 @@ describe( 'Products', () => {
|
|||
expect( queryByText( 'View more product types' ) ).toBeInTheDocument();
|
||||
} );
|
||||
|
||||
it( 'clicking on suggested product should fire event tasklist_product_template_selection with is_suggested:true and task_completion_time', () => {
|
||||
( getAdminSetting as jest.Mock ).mockImplementation( () => ( {
|
||||
profile: {
|
||||
product_types: [ 'downloads' ],
|
||||
},
|
||||
} ) );
|
||||
const { getByRole } = render( <Products /> );
|
||||
|
||||
userEvent.click(
|
||||
getByRole( 'menuitem', {
|
||||
name:
|
||||
'Digital product A digital product like service, downloadable book, music or video.',
|
||||
} )
|
||||
);
|
||||
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
'tasklist_product_template_selection',
|
||||
{ is_suggested: true, product_type: 'digital' }
|
||||
);
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
'task_completion_time',
|
||||
{ task_name: 'products', time: '0-2s' }
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'clicking on not-suggested product should fire event tasklist_product_template_selection with is_suggested:false and task_completion_time', async () => {
|
||||
( getAdminSetting as jest.Mock ).mockImplementation( () => ( {
|
||||
profile: {
|
||||
product_types: [ 'downloads' ],
|
||||
},
|
||||
} ) );
|
||||
const { queryByText, getByRole, queryByRole } = render( <Products /> );
|
||||
|
||||
expect( queryByText( 'View more product types' ) ).toBeInTheDocument();
|
||||
|
||||
userEvent.click(
|
||||
getByRole( 'button', { name: 'View more product types' } )
|
||||
);
|
||||
|
||||
await waitFor( () =>
|
||||
expect( queryByRole( 'menu' )?.childElementCount ).toBe(
|
||||
productTypes.length
|
||||
)
|
||||
);
|
||||
userEvent.click(
|
||||
getByRole( 'menuitem', {
|
||||
name: 'Grouped product A collection of related products.',
|
||||
} )
|
||||
);
|
||||
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
'tasklist_product_template_selection',
|
||||
{ is_suggested: false, product_type: 'grouped' }
|
||||
);
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
'task_completion_time',
|
||||
{ task_name: 'products', time: '0-2s' }
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'should render all products type when clicking view more button', async () => {
|
||||
( getAdminSetting as jest.Mock ).mockImplementation( () => ( {
|
||||
profile: {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*/
|
||||
import { render, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -10,7 +11,13 @@ import userEvent from '@testing-library/user-event';
|
|||
import Stack from '../stack';
|
||||
import { productTypes } from '../constants';
|
||||
|
||||
jest.mock( '@woocommerce/tracks', () => ( { recordEvent: jest.fn() } ) );
|
||||
|
||||
describe( 'Stack', () => {
|
||||
beforeEach( () => {
|
||||
( recordEvent as jest.Mock ).mockClear();
|
||||
} );
|
||||
|
||||
it( 'should render stack with given product type and two links', () => {
|
||||
const { queryByText, queryAllByRole } = render(
|
||||
<Stack
|
||||
|
@ -63,5 +70,38 @@ describe( 'Stack', () => {
|
|||
getByRole( 'link', { name: 'Load Sample Products' } )
|
||||
);
|
||||
await waitFor( () => expect( onClickLoadSampleProduct ).toBeCalled() );
|
||||
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
'task_completion_time',
|
||||
{ task_name: 'products', time: '0-2s' }
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'should fire the tasklist_add_product and task_completion_time events when the "Start Blank" link is clicked', async () => {
|
||||
const onClickLoadSampleProduct = jest.fn();
|
||||
const { getByRole } = render(
|
||||
<Stack
|
||||
onClickLoadSampleProduct={ onClickLoadSampleProduct }
|
||||
items={ [
|
||||
{
|
||||
...productTypes[ 0 ],
|
||||
onClick: () => {},
|
||||
},
|
||||
] }
|
||||
/>
|
||||
);
|
||||
|
||||
userEvent.click( getByRole( 'link', { name: 'Start Blank' } ) );
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
'tasklist_add_product',
|
||||
{ method: 'manually' }
|
||||
);
|
||||
expect( recordEvent ).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
'task_completion_time',
|
||||
{ task_name: 'products', time: '0-2s' }
|
||||
);
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -12,7 +12,7 @@ import { useState } from '@wordpress/element';
|
|||
import { ProductTypeKey } from './constants';
|
||||
import { createNoticesFromResponse } from '../../../lib/notices';
|
||||
|
||||
const useCreateProductByType = () => {
|
||||
export const useCreateProductByType = () => {
|
||||
const { createProductFromTemplate } = useDispatch( ITEMS_STORE_NAME );
|
||||
const [ isRequesting, setIsRequesting ] = useState< boolean >( false );
|
||||
|
||||
|
@ -54,5 +54,3 @@ const useCreateProductByType = () => {
|
|||
isRequesting,
|
||||
};
|
||||
};
|
||||
|
||||
export default useCreateProductByType;
|
||||
|
|
|
@ -2,15 +2,17 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { useMemo } from '@wordpress/element';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import useCreateProductByType from './use-create-product-by-type';
|
||||
import { ProductType } from './constants';
|
||||
import { useCreateProductByType } from './use-create-product-by-type';
|
||||
import { ProductType, ProductTypeKey } from './constants';
|
||||
|
||||
const useProductTypeListItems = (
|
||||
_productTypes: ProductType[],
|
||||
suggestedProductTypes: ProductTypeKey[] = [],
|
||||
{
|
||||
onClick,
|
||||
}: {
|
||||
|
@ -25,6 +27,12 @@ const useProductTypeListItems = (
|
|||
...productType,
|
||||
onClick: () => {
|
||||
createProductByType( productType.key );
|
||||
recordEvent( 'tasklist_product_template_selection', {
|
||||
product_type: productType.key,
|
||||
is_suggested: suggestedProductTypes.includes(
|
||||
productType.key
|
||||
),
|
||||
} );
|
||||
if ( typeof onClick === 'function' ) {
|
||||
onClick();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: Add
|
||||
|
||||
Added events for experimental products page #32944
|
Loading…
Reference in New Issue