Implement new users micro survey for project dashboard page on react and non-react version (#11347)

* Implement new users micro survey for project dashboard page on react and non-react version

* Add 'new-users-micro-survey-click' and 'new-users-micro-survey-prompt' new event for the analytics

GitOrigin-RevId: 9aabe931987638b38995d404aa90ac4d40b2f3b5
This commit is contained in:
M Fahru 2023-01-20 06:52:41 -07:00 committed by Copybot
parent 29fbc253fd
commit 8227199dcb
9 changed files with 184 additions and 0 deletions

View file

@ -556,6 +556,26 @@ const ProjectController = {
}
)
},
newUsersMicroSurveyAssignment(cb) {
SplitTestHandler.getAssignment(
req,
res,
'new-users-micro-survey',
(err, assignment) => {
if (err) {
logger.error(
{ err },
'failed to get "new-users-micro-survey" split test assignment'
)
const defaultAssignment = { variant: 'default' }
cb(null, defaultAssignment)
} else {
cb(null, assignment)
}
}
)
},
survey(cb) {
SurveyHandler.getSurvey(userId, (err, survey) => {
if (err) {
@ -578,6 +598,7 @@ const ProjectController = {
user,
userEmailsData,
groupsAndEnterpriseBannerAssignment,
newUsersMicroSurveyAssignment,
userIsMemberOfGroupSubscription,
} = results
@ -718,6 +739,16 @@ const ProjectController = {
!userIsMemberOfGroupSubscription &&
!hasPaidAffiliation
const SEVEN_DAYS = 1000 * 60 * 60 * 24 * 7
const isUserLessThanSevenDaysOld =
user.signUpDate && Date.now() - user.signUpDate.getTime() < SEVEN_DAYS
const showNewUsersMicroSurvey =
Features.hasFeature('saas') &&
newUsersMicroSurveyAssignment.variant === 'enabled' &&
isUserLessThanSevenDaysOld
ProjectController._injectProjectUsers(projects, (error, projects) => {
if (error != null) {
return next(error)
@ -745,6 +776,7 @@ const ProjectController = {
showGroupsAndEnterpriseBanner,
groupsAndEnterpriseBannerVariant:
groupsAndEnterpriseBannerAssignment.variant,
showNewUsersMicroSurvey,
}
const paidUser =

View file

@ -312,6 +312,32 @@ async function projectListReactPage(req, res, next) {
!userIsMemberOfGroupSubscription &&
!hasPaidAffiliation
let newUsersMicroSurveyAssignment
try {
newUsersMicroSurveyAssignment =
await SplitTestHandler.promises.getAssignment(
req,
res,
'new-users-micro-survey'
)
} catch (error) {
logger.error(
{ err: error },
'failed to get "new-users-micro-survey" split test assignment'
)
}
const SEVEN_DAYS = 1000 * 60 * 60 * 24 * 7
const isUserLessThanSevenDaysOld =
user.signUpDate && Date.now() - user.signUpDate.getTime() < SEVEN_DAYS
const showNewUsersMicroSurvey =
Features.hasFeature('saas') &&
(newUsersMicroSurveyAssignment?.variant ?? 'default') === 'enabled' &&
isUserLessThanSevenDaysOld
res.render('project/list-react', {
title: 'your_projects',
usersBestSubscription,
@ -329,6 +355,7 @@ async function projectListReactPage(req, res, next) {
showGroupsAndEnterpriseBanner,
groupsAndEnterpriseBannerVariant:
groupsAndEnterpriseBannerAssignment?.variant ?? 'default',
showNewUsersMicroSurvey,
})
}

View file

@ -27,6 +27,7 @@ block append meta
meta(name="ol-currentUrl" data-type="string" content=currentUrl)
meta(name="ol-showGroupsAndEnterpriseBanner" data-type="boolean" content=showGroupsAndEnterpriseBanner)
meta(name="ol-groupsAndEnterpriseBannerVariant" data-type="string" content=groupsAndEnterpriseBannerVariant)
meta(name="ol-showNewUsersMicroSurvey" data-type="boolean" content=showNewUsersMicroSurvey)
block content
main.content.content-alt.project-list-react#project-list-root

View file

@ -283,3 +283,33 @@ include ../../_mixins/reconfirm_affiliation
button(ng-click="dismiss()").close.pull-right
span(aria-hidden="true") &times;
span.sr-only #{translate("close")}
if showNewUsersMicroSurvey
ul.list-unstyled(
ng-controller="NewUsersMicroSurveyController",
ng-cloak
)
li.notification-entry(
ng-if="!hasDismissedNewUsersMicroSurvey"
event-tracking="new-users-micro-survey-prompt"
event-tracking-mb="true"
event-tracking-trigger="load"
event-segmentation='{"project-dashboard-react": "default"}'
)
.alert.alert-info
.notification-body
| !{translate("help_us_improve_overleaf_by_answering_a_two_question_survey", {}, ['strong'])}
.notification-action
a.pull-right.btn.btn-sm.btn-info(
ng-click="dismiss()"
href="https://docs.google.com/forms/d/e/1FAIpQLSdN23eSbaGkl96-LkNiIW1QCVdhAQEnSGrEhbuuZgNQ5-Qvog/viewform?usp=sf_link"
target="_blank"
event-tracking="new-users-micro-survey-click"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation='{"project-dashboard-react": "default"}'
) #{translate("take_survey")}
.notification-close
button(ng-click="dismiss()").close.pull-right
span(aria-hidden="true") &times;
span.sr-only #{translate("close")}

View file

@ -291,6 +291,7 @@
"have_an_extra_backup": "",
"headers": "",
"help": "",
"help_us_improve_overleaf_by_answering_a_two_question_survey": "",
"hide_outline": "",
"history": "",
"hotkey_add_a_comment": "",
@ -668,6 +669,7 @@
"tags": "",
"tags_slash_folders": "",
"take_short_survey": "",
"take_survey": "",
"template_approved_by_publisher": "",
"templates": "",
"terminated": "",

View file

@ -0,0 +1,72 @@
import { useCallback, useEffect, useState } from 'react'
import Notification from './notification'
import { sendMB } from '../../../../infrastructure/event-tracking'
import getMeta from '../../../../utils/meta'
import customLocalStorage from '../../../../infrastructure/local-storage'
import { Trans, useTranslation } from 'react-i18next'
export default function NewUsersMicroSurvey() {
const { t } = useTranslation()
const showNewUsersMicroSurvey = getMeta(
'ol-showNewUsersMicroSurvey'
) as boolean
const hasDismissedNewUsersMicroSurvey = customLocalStorage.getItem(
'has_dismissed_new_users_micro_survey'
)
// need extra state to close the survey when user clicking the main button
const [show, setShow] = useState(!hasDismissedNewUsersMicroSurvey)
const handleClose = useCallback(() => {
customLocalStorage.setItem('has_dismissed_new_users_micro_survey', true)
}, [])
const handleClickTakeSurvey = useCallback(() => {
customLocalStorage.setItem('has_dismissed_new_users_micro_survey', true)
setShow(false)
sendMB('new-users-micro-survey-click', {
'project-dashboard-react': 'enabled',
})
}, [])
useEffect(() => {
sendMB('new-users-micro-survey-prompt', {
'project-dashboard-react': 'enabled',
})
}, [])
if (hasDismissedNewUsersMicroSurvey || !showNewUsersMicroSurvey || !show) {
return null
}
return (
<Notification bsStyle="info" onDismiss={handleClose}>
<Notification.Body>
<span>
<Trans
i18nKey="help_us_improve_overleaf_by_answering_a_two_question_survey"
components={
/* eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key */
[<strong />]
}
/>
</span>
</Notification.Body>
<Notification.Action>
<a
className="pull-right btn btn-info btn-sm"
href="https://docs.google.com/forms/d/e/1FAIpQLSdN23eSbaGkl96-LkNiIW1QCVdhAQEnSGrEhbuuZgNQ5-Qvog/viewform?usp=sf_link"
rel="noreferrer"
target="_blank"
onClick={handleClickTakeSurvey}
>
{t('take_survey')}
</a>
</Notification.Action>
</Notification>
)
}

View file

@ -3,6 +3,7 @@ import Institution from './groups/institution'
import ConfirmEmail from './groups/confirm-email'
import ReconfirmationInfo from './groups/affiliation/reconfirmation-info'
import GroupsAndEnterpriseBanner from './groups-and-enterprise-banner'
import NewUsersMicroSurvey from './new-users-micro-survey'
function UserNotifications() {
return (
@ -13,6 +14,7 @@ function UserNotifications() {
<ConfirmEmail />
<ReconfirmationInfo />
<GroupsAndEnterpriseBanner />
<NewUsersMicroSurvey />
</ul>
</div>
)

View file

@ -47,6 +47,22 @@ App.controller(
}
)
App.controller(
'NewUsersMicroSurveyController',
function ($scope, localStorage) {
$scope.hasDismissedNewUsersMicroSurvey = localStorage(
'has_dismissed_new_users_micro_survey'
)
$scope.dismiss = () => {
localStorage('has_dismissed_new_users_micro_survey', true)
$scope.hasDismissedNewUsersMicroSurvey = true
}
$scope.newUsersMicroSurveyVariant = getMeta('ol-newUsersMicroSurvey')
}
)
App.controller('ProjectInviteNotificationController', function ($scope, $http) {
// Shortcuts for translation keys
$scope.projectName = $scope.notification.messageOpts.projectName

View file

@ -632,6 +632,7 @@
"help": "Help",
"help_articles_matching": "Help articles matching your subject",
"help_improve_overleaf_fill_out_this_survey": "If you would like to help us improve Overleaf, please take a moment to fill out <0>this survey</0>.",
"help_us_improve_overleaf_by_answering_a_two_question_survey": "Help us improve __appName__ by answering a <0>two question survey</0>.",
"help_us_spread_word": "Help us spread the word about __appName__",
"hide_outline": "Hide File outline",
"history": "History",
@ -1415,6 +1416,7 @@
"tags_slash_folders": "Tags/Folders",
"take_me_home": "Take me home!",
"take_short_survey": "Take a short survey",
"take_survey": "Take Survey",
"tc_everyone": "Everyone",
"tc_guests": "Guests",
"tc_switch_everyone_tip": "Toggle track-changes for everyone",