-
Notifications
You must be signed in to change notification settings - Fork 22
Add CES prompts for initial setup and campaign creation #1152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@ianlin , I converted your PR to draft, since it is still "work in progress". You can create a draft PR without needing to specify "WIP" in the PR title. When the PR is ready for review, just add the reviewers and click on the "Ready for review" button. 🙂 |
@ecgan TIL, thank you! 😄 |
Since this logic will also be used for the CES prompt component in the upcoming implementaion.
Requirement: 1. Display it when the user enters product feed for the first time after setting up 2. However, don't display it unless the success modal is not shown. I.e. dismiss the success modal will display the CES prompt Displaying Logic: - When the user finishes setting up, they will be in the product feed page and the success modal is shown - There are 2 scenarios: - If the user dismiss the success modal, the CES prmopt will be displayed - If the user clicks "Manage and edit your product feed in WooCommerce" and goes to the product feed page in a new tab, the CES prompt will be displayed in the new tab - If the user dismisses the CES prompt or clicks "Give feedback" on the prompt, the CES prompt in the original tab will not be shown when the success modal is dismissed - But if the user does not dismiss the CES prompt or clicks "Give feedback" on the prompt in the new tab, the CES prompt in the original tab will be shown when the success modal is dismissed
5772004
to
0ff1b0f
Compare
- DB options: woocommerce_allow_tracking - wp-admin settings: WooCommerce -> Settings -> Advanced -> WooCommerce.com -> Enable tracking - Frontend checks `window.wcTracks.isEnabled`
Note: CES = Customer Effort Score
And make it more general so it can be a shared component
This is rather simple. This prompt should appear immediately after user successfully completes Ads creation flow and clicks "Got it" in the success modal.
f6ff5ee
to
9b6a811
Compare
const handleGotItClick = useCallback( | ||
( e ) => { | ||
handleCloseWithAction( e ); | ||
setCESPromptOpen( true ); | ||
}, | ||
[ setCESPromptOpen ] | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ / 💅
What i the rationale behind using handleGotItClick
separated. Instead of adding
if ( action === CTA_CREATE_ANOTHER_CAMPAIGN ) {
getHistory().push( getCreateCampaignUrl() );
}
if ( action === CTA_CONFIRM) {
setCESPromptOpen( true );
}
I guess is something related to the UseCallback? Not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think originally my thought was: the handleCloseWithAction
is defined outside of the component GuideImplementation
, we will need to pass the function prop setCESPromptOpen()
to it and I think it could be inflexible if we have more custom actions. But I agree with you that using handleCloseWithAction
to handle multiple actions would be better than using a separated handleGotItClick
. What do you think if we move handleCloseWithAction
inside the component so it can use the function prop setCESPromptOpen()
directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohhh, understood, didn't show that one. Thanks for the explanation.
What do you think if we move handleCloseWithAction inside the component
Would be interesting to know why it is outside, wondering if there is an important reason for it, maybe @eason9487 knows.
I would go ahead with your current solution and the maybe refactor after knowing that. It's 100% a non blocking issue. Since I don't want to block the PR I rely on you for the final decision regarding this. Again, looks good now as it's.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those click handlers were not dependent on props and states, so to avoid their references changing all the time, I put them outside then. It's ok to move them inside the component.
💅
BTW, I'd suggest adding a callback prop, such as onGuideRequestClose( action )
, to this component and moving the process of handleCloseWithAction
handler to the upper component. Therefore, it could decouple the <CustomerEffortScorePrompt>
from this guide, and the logic of the opening/closing this guide could also be centralized on the outside. In this way, as with product feed index, the similar logic is implemented at dashboard index.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eason9487 Great suggestion. Added in bc3aaef 739e897.
Going to the page Behaviour and visual testing these for now and looks good ✅
|
🚧 I could not complete the test instructions successfully (I take as granted that Followed steps:
Screen.Recording.2021-12-17.at.16.19.15.mov |
|
🚧 /❓ In product feed, context was In campaigns setup, context was I guess we should maintain consistency between them. Since it's exactly the same context. Thoughts? |
Nice work @ianlin ❤️ |
Reason to change: There was a bug - Success modal is displayed, CES prompt is not shown - Open a new tab to the product feed page, CES prompt is shown - Go back to the original tab and dismiss the success modal, the CES prmopt is shown, which is what we don't want. To solve it, moving `removeCESPromptFlagFromLocal` from `onNoticeDismissed` and `onModalShown` to only `onNoticeShown` is not enough, as it leads to another problem: - Success modal is displayed, CES prompt is not shown - Open a new tab to the product feed page, CES prompt is shown - Click `Give feedback` but the CES modal is not displayed This is because we change to remove the CES flag from local storage when the CES prompt is shown. When it happens the ProductFeed will re-render and the CES prmopt will not be rendered because the flag was removed. Then clicking `Give feedback` won't render the modal. To solve this we add a component state `canCESPromptOpen` in ProductFeed component, rather than check the local storage flag directly. Then we add the logic to update the `canCESPromptOpen` state only when its value is false.
Good catch as well! I have updated this in 07d85e4. To explain this: Originally the
This is because we change to remove the CES flag from local storage when the CES prompt is shown. When it happens the ProductFeed will re-render and the CES prmopt will not be rendered because the flag was removed. Then clicking To solve this we add a component state Here's the video to demonstrate the fixed behaviour: Screen.Recording.2021-12-20.at.18.04.59.mov |
* @param {string} props.label Text to be displayed in the CES notice and modal. | ||
* @return {JSX.Element} Rendered element. | ||
*/ | ||
const CustomerEffortScorePrompt = ( { eventContext, label } ) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💅 Non blocking
I guess we can add here
if ( ! isWCTracksEnabled() ) return null;
Since it is a common check for all the prompts, right?
And then remove them in js/src/dashboard/campaign-creation-success-guide/index.js
and js/src/product-feed/index.js
/** | ||
* CES feedback recorded | ||
* | ||
* @event gla_ces_feedback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @event gla_ces_feedback | |
* @event gla_ces_feedback | |
* @property {number} score The provided feedback score. | |
* @property {string} comments If a comment is provided. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💅
isOpen={ isOpen } | ||
setCESPromptOpen={ setCESPromptOpen } | ||
/> | ||
{ isCESPromptOpen && wcTracksEnabled && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💅
See my previous comment regarding isWCTracksEnabled();
|
||
const wcTracksEnabled = isWCTracksEnabled(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💅
See comment regarding isWCTracksEnabled();
|
||
const localStorage = { | ||
get( key ) { | ||
return localStorageExists ? window.localStorage.getItem( key ) : null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💅 What do you think about...
return window?.localStorage?.getItem( key )
or return window?.localStorage?.getItem( key ) ?? null
(in case we need null as return for a reason).
That way we can remove both conditionals and the localStorageExists computed function
} ); | ||
} ); | ||
|
||
describe( 'And both canCESPromptOpenLocal and wcTracksEnabled are true', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💅
RE- comments regarding isWCTracksEnabled
It will also simplify the test. We can have a separated test for the CESPrompt checking that and here only test LocalStorage / SubmissionSuccessGuide
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ LGTM. Good work!
All the blocking issues were addressed and this PR looks good for me
Prompt 1 test ✅
Prompt 1.2 test ✅
Prompt 2 thank test ✅
Unit tests ✅
💅 Just a few pending comments out there
624373a
to
bc62333
Compare
Changes proposed in this Pull Request:
Closes #882.
This PR implements two CES prompts that will displayed when the user
Prompt 1: successfully completes initial setup flow and enters the product feed page for the first time
Prompt 2: successfully completes Ads creation flow and clicks "Got it" in the success modal.
Implementation Details
Prompt 1
This can be split into two requirements:
When the user sees the success modal, there are different paths that they can go:
X
button, clicking anywhere outside of the modal, or clickingMaybe later
button.Manage and edit your product feed in WooCommerce
.a. Eventually the user will go to the product feed page by clicking it, so the behaviour will be just like the point 2 above
In oder to fulfil the requirements above, we need to store a flag
gla-can-onboarding-setup-ces-prompt-open
in the local storage to help us to decide when can we display the CES prompt. The flows will be like this:Flow 1 (Video 1)
gla-can-onboarding-setup-ces-prompt-open
totrue
(actually any value is fine)gla-can-onboarding-setup-ces-prompt-open
from the local storageFlow 2 (Video 2)
gla-can-onboarding-setup-ces-prompt-open
totrue
gla-can-onboarding-setup-ces-prompt-open
Prompt 2
Prompt 2 is simpler, the prompt will only be shown when the user clicks on "Got it" of the campaign creation success modal, so we don't need the flag in local storage.
(Video 3)
(Video 4)
Screenshots:
Video 1 - Dismiss success modal and show the CES prompt
ces-dismiss-success-modal.mov
Video 2 - Go to product feed in a new tab
ces-product-feed-new-tab.mov
Video 3 - Click "Got it" on the campaign creation success modal and show the CES
ces-campaign-got-it.mov
Video 4 - Dismiss the campaign creation success modal and the CES won't show
ces-campaign-dismiss.mov
Detailed test instructions:
Prompt 1, Flow 1
/wp-admin/admin.php?page=wc-admin&path=/google/product-feed&guide=submission-success
localStorage.setItem('debug', 'wc-admin*')
in your web's dev consolePrompt 1, Flow 2
Follow the first three steps aboveFollow the first two steps above (thanks @puntope)Manage and edit your product feed in WooCommerce
Prompt 2
/wp-admin/admin.php?page=wc-admin&path=/google/dashboard&guide=campaign-creation-success
Changelog entry