From ad78576cf428b27283baf6c900b669ca1f83ecd4 Mon Sep 17 00:00:00 2001 From: Matt Sherman Date: Wed, 18 Nov 2020 15:53:52 -0500 Subject: [PATCH] Record Tracks events when CES notice/snackbar and modal is viewed (https://github.com/woocommerce/woocommerce-admin/pull/5648) --- .../customer-effort-score-tracks.js | 50 ++++++++++++++----- .../customer-effort-score/src/index.js | 47 ++++++++++------- 2 files changed, 68 insertions(+), 29 deletions(-) diff --git a/plugins/woocommerce-admin/client/customer-effort-score-tracks/customer-effort-score-tracks.js b/plugins/woocommerce-admin/client/customer-effort-score-tracks/customer-effort-score-tracks.js index 313bef7fe96..a7166924e70 100644 --- a/plugins/woocommerce-admin/client/customer-effort-score-tracks/customer-effort-score-tracks.js +++ b/plugins/woocommerce-admin/client/customer-effort-score-tracks/customer-effort-score-tracks.js @@ -43,7 +43,7 @@ function CustomerEffortScoreTracks( { updateOptions, createNotice, } ) { - const [ shown, setShown ] = useState( false ); + const [ modalShown, setModalShown ] = useState( false ); if ( resolving ) { return null; @@ -54,18 +54,42 @@ function CustomerEffortScoreTracks( { return null; } - if ( cesShownForActions.indexOf( action ) !== -1 && ! shown ) { + // We only want to return null early if the modal was already shown + // for this action *before* this component was initially instantiated. + // + // We want to make sure we still render CustomerEffortScore below + // (we don't want to return null early), if the modal was shown for this + // instantiation, so that the component doesn't go away while we are + // still showing it. + if ( cesShownForActions.indexOf( action ) !== -1 && ! modalShown ) { return null; } - const openedCallback = () => { - // Use the `shown` state value to only update the shown_for_actions - // option once. - if ( shown ) { - return; - } + const onNoticeShown = () => { + recordEvent( 'ces_snackbar_view', { + action, + store_age: storeAge, + ...trackProps, + } ); + }; + + const onNoticeDismissed = () => { + recordEvent( 'ces_snackbar_dismiss', { + action, + store_age: storeAge, + ...trackProps, + } ); + }; + + const onModalShown = () => { + setModalShown( true ); + + recordEvent( 'ces_view', { + action, + store_age: storeAge, + ...trackProps, + } ); - setShown( true ); updateOptions( { [ SHOWN_FOR_ACTIONS_OPTION_NAME ]: [ action, @@ -74,7 +98,7 @@ function CustomerEffortScoreTracks( { } ); }; - const trackCallback = ( score ) => { + const recordScore = ( score ) => { recordEvent( 'ces_feedback', { action, score, @@ -86,9 +110,11 @@ function CustomerEffortScoreTracks( { return ( { setVisible( true ); - - openedCallback(); + onModalShownCallback(); }, }, ], icon, explicitDismiss: true, - onDismiss: openedCallback, + onDismiss: onNoticeDismissedCallback, } ); setShouldCreateNotice( false ); + onNoticeShownCallback(); + return null; } @@ -62,7 +67,7 @@ function CustomerEffortScore( { setScore( 3 ); // TODO let this happen in the UI setVisible( false ); - trackCallback( score ); + recordScoreCallback( score ); } return ( @@ -74,9 +79,9 @@ function CustomerEffortScore( { CustomerEffortScore.propTypes = { /** - * The function to call when the modal is actioned. + * The function to call to record the score. */ - trackCallback: PropTypes.func.isRequired, + recordScoreCallback: PropTypes.func.isRequired, /** * The label displayed in the modal. */ @@ -86,9 +91,17 @@ CustomerEffortScore.propTypes = { */ createNotice: PropTypes.func.isRequired, /** - * Callback executed when the modal is opened. + * The function to call when the notice is shown. */ - openedCallback: PropTypes.func, + onNoticeShownCallback: PropTypes.func, + /** + * The function to call when the notice is dismissed. + */ + onNoticeDismissedCallback: PropTypes.func, + /** + * The function to call when the modal is shown. + */ + onModalShownCallback: PropTypes.func, /** * Icon (React component) to be displayed. */