Jelajahi Sumber

Merge pull request #11078 from overleaf/jel-features-page-analytics

[web] Add analytics to React dash features link

GitOrigin-RevId: 5f62af1af3854b1443734cda6b97334e6eb42711
Jessica Lawshe 3 tahun lalu
induk
melakukan
bd3b9007c8

+ 15 - 1
services/web/frontend/js/features/project-list/components/current-plan-widget/commons-plan.tsx

@@ -1,6 +1,8 @@
 import { useTranslation, Trans } from 'react-i18next'
 import { CommonsPlanSubscription } from '../../../../../../types/project/dashboard/subscription'
 import Tooltip from '../../../../shared/components/tooltip'
+import getMeta from '../../../../utils/meta'
+import * as eventTracking from '../../../../infrastructure/event-tracking'
 
 type CommonsPlanProps = Pick<
   CommonsPlanSubscription,
@@ -16,6 +18,14 @@ function CommonsPlan({
   const currentPlanLabel = (
     <Trans i18nKey="premium_plan_label" components={{ b: <strong /> }} />
   )
+  const featuresPageVariant = getMeta('ol-splitTestVariants')?.['features-page']
+
+  function handleLinkClick() {
+    eventTracking.sendMB('features-page-link', {
+      splitTest: 'features-page',
+      splitTestVariant: featuresPageVariant,
+    })
+  }
 
   return (
     <>
@@ -28,7 +38,11 @@ function CommonsPlan({
         id="commons-plan"
         overlayProps={{ placement: 'bottom' }}
       >
-        <a href={featuresPageURL} className="current-plan-label hidden-xs">
+        <a
+          href={featuresPageURL}
+          className="current-plan-label hidden-xs"
+          onClick={handleLinkClick}
+        >
           {currentPlanLabel} <span className="info-badge" />
         </a>
       </Tooltip>

+ 14 - 1
services/web/frontend/js/features/project-list/components/current-plan-widget/free-plan.tsx

@@ -3,6 +3,7 @@ import { Button } from 'react-bootstrap'
 import { FreePlanSubscription } from '../../../../../../types/project/dashboard/subscription'
 import Tooltip from '../../../../shared/components/tooltip'
 import * as eventTracking from '../../../../infrastructure/event-tracking'
+import getMeta from '../../../../utils/meta'
 
 type FreePlanProps = Pick<FreePlanSubscription, 'featuresPageURL'>
 
@@ -16,6 +17,14 @@ function FreePlan({ featuresPageURL }: FreePlanProps) {
     eventTracking.sendMB('upgrade-button-click', { source: 'dashboard-top' })
   }
 
+  const featuresPageVariant = getMeta('ol-splitTestVariants')?.['features-page']
+  function handleLinkClick() {
+    eventTracking.sendMB('features-page-link', {
+      splitTest: 'features-page',
+      splitTestVariant: featuresPageVariant,
+    })
+  }
+
   return (
     <>
       <span className="current-plan-label visible-xs">{currentPlanLabel}</span>
@@ -24,7 +33,11 @@ function FreePlan({ featuresPageURL }: FreePlanProps) {
         id="free-plan"
         overlayProps={{ placement: 'bottom' }}
       >
-        <a href={featuresPageURL} className="current-plan-label hidden-xs">
+        <a
+          href={featuresPageURL}
+          className="current-plan-label hidden-xs"
+          onClick={handleLinkClick}
+        >
           {currentPlanLabel} <span className="info-badge" />
         </a>
       </Tooltip>{' '}

+ 15 - 1
services/web/frontend/js/features/project-list/components/current-plan-widget/group-plan.tsx

@@ -1,6 +1,8 @@
 import { useTranslation, Trans } from 'react-i18next'
 import { GroupPlanSubscription } from '../../../../../../types/project/dashboard/subscription'
 import Tooltip from '../../../../shared/components/tooltip'
+import getMeta from '../../../../utils/meta'
+import * as eventTracking from '../../../../infrastructure/event-tracking'
 
 type GroupPlanProps = Pick<
   GroupPlanSubscription,
@@ -29,6 +31,14 @@ function GroupPlan({
       <Trans i18nKey="premium_plan_label" components={{ b: <strong /> }} />
     )
 
+  const featuresPageVariant = getMeta('ol-splitTestVariants')?.['features-page']
+  function handleLinkClick() {
+    eventTracking.sendMB('features-page-link', {
+      splitTest: 'features-page',
+      splitTestVariant: featuresPageVariant,
+    })
+  }
+
   return (
     <>
       <span className="current-plan-label visible-xs">{currentPlanLabel}</span>
@@ -44,7 +54,11 @@ function GroupPlan({
         id="group-plan"
         overlayProps={{ placement: 'bottom' }}
       >
-        <a href={featuresPageURL} className="current-plan-label hidden-xs">
+        <a
+          href={featuresPageURL}
+          className="current-plan-label hidden-xs"
+          onClick={handleLinkClick}
+        >
           {currentPlanLabel} <span className="info-badge" />
         </a>
       </Tooltip>

+ 15 - 1
services/web/frontend/js/features/project-list/components/current-plan-widget/individual-plan.tsx

@@ -1,6 +1,8 @@
 import { useTranslation, Trans } from 'react-i18next'
 import { IndividualPlanSubscription } from '../../../../../../types/project/dashboard/subscription'
 import Tooltip from '../../../../shared/components/tooltip'
+import getMeta from '../../../../utils/meta'
+import * as eventTracking from '../../../../infrastructure/event-tracking'
 
 type IndividualPlanProps = Pick<
   IndividualPlanSubscription,
@@ -28,6 +30,14 @@ function IndividualPlan({
       <Trans i18nKey="premium_plan_label" components={{ b: <strong /> }} />
     )
 
+  const featuresPageVariant = getMeta('ol-splitTestVariants')?.['features-page']
+  function handleLinkClick() {
+    eventTracking.sendMB('features-page-link', {
+      splitTest: 'features-page',
+      splitTestVariant: featuresPageVariant,
+    })
+  }
+
   return (
     <>
       <span className="current-plan-label visible-xs">{currentPlanLabel}</span>
@@ -36,7 +46,11 @@ function IndividualPlan({
         id="individual-plan"
         overlayProps={{ placement: 'bottom' }}
       >
-        <a href={featuresPageURL} className="current-plan-label hidden-xs">
+        <a
+          href={featuresPageURL}
+          className="current-plan-label hidden-xs"
+          onClick={handleLinkClick}
+        >
           {currentPlanLabel} <span className="info-badge" />
         </a>
       </Tooltip>

+ 4 - 0
services/web/frontend/js/infrastructure/event-tracking.js

@@ -27,6 +27,10 @@ export function sendOnce(category, action, label, value) {
 }
 
 export function sendMB(key, segmentation = {}) {
+  if (!segmentation.page) {
+    segmentation.page = window.location.pathname
+  }
+
   sendBeacon(key, segmentation)
 
   if (typeof window.gtag !== 'function') return

+ 1 - 0
services/web/test/frontend/features/editor-navigation-toolbar/components/layout-dropdown-button.test.js

@@ -136,6 +136,7 @@ describe('<LayoutDropdownButton />', function () {
       sinon.assert.calledWith(sendMBSpy, 'project-layout-change', {
         layout: 'flat',
         view: 'editor',
+        page: '/detacher',
       })
     })
 

+ 20 - 1
services/web/test/frontend/features/project-list/components/current-plan-widget.test.tsx

@@ -52,6 +52,7 @@ describe('<CurrentPlanWidget />', function () {
       expect(sendMBSpy).to.be.calledOnce
       expect(sendMBSpy).calledWith('upgrade-button-click', {
         source: 'dashboard-top',
+        page: '/',
       })
     })
   })
@@ -245,6 +246,8 @@ describe('<CurrentPlanWidget />', function () {
   })
 
   describe('features page split test', function () {
+    let sendMBSpy: sinon.SinonSpy
+
     const variants = [
       { name: 'default', link: '/learn/how-to/Overleaf_premium_features' },
       { name: 'new', link: '/about/features-overview' },
@@ -279,6 +282,14 @@ describe('<CurrentPlanWidget />', function () {
       },
     ]
 
+    beforeEach(function () {
+      sendMBSpy = sinon.spy(eventTracking, 'sendMB')
+    })
+
+    afterEach(function () {
+      sendMBSpy.restore()
+    })
+
     for (const variant of variants) {
       describe(`${variant.name} variant`, function () {
         beforeEach(function () {
@@ -291,7 +302,7 @@ describe('<CurrentPlanWidget />', function () {
         })
 
         for (const plan of plans) {
-          it(`links to ${variant.name} features page on ${plan.type} plan`, function () {
+          it(`links to ${variant.name} features page on ${plan.type} plan and sends analytics event`, function () {
             window.metaAttributesCache.set('ol-usersBestSubscription', {
               ...plan,
             })
@@ -300,6 +311,14 @@ describe('<CurrentPlanWidget />', function () {
             const links = screen.getAllByRole('link')
             expect(links[0].getAttribute('href')).to.equal(variant.link)
 
+            fireEvent.click(links[0])
+            expect(sendMBSpy).to.be.calledOnce
+            expect(sendMBSpy).calledWith('features-page-link', {
+              splitTest: 'features-page',
+              splitTestVariant: variant.name,
+              page: '/',
+            })
+
             window.metaAttributesCache.delete('ol-usersBestSubscription')
           })
         }

+ 3 - 3
services/web/test/frontend/features/settings/components/leavers-survey-alert.test.tsx

@@ -75,7 +75,7 @@ describe('<LeaversSurveyAlert/>', function () {
       expect(sendMBSpy).to.be.calledOnce
       expect(sendMBSpy).calledWith(
         'institutional-leavers-survey-notification',
-        { type: 'view' }
+        { type: 'view', page: '/' }
       )
     })
 
@@ -84,7 +84,7 @@ describe('<LeaversSurveyAlert/>', function () {
       expect(sendMBSpy).to.be.calledTwice
       expect(sendMBSpy).calledWith(
         'institutional-leavers-survey-notification',
-        { type: 'click' }
+        { type: 'click', page: '/' }
       )
     })
 
@@ -93,7 +93,7 @@ describe('<LeaversSurveyAlert/>', function () {
       expect(sendMBSpy).to.be.calledTwice
       expect(sendMBSpy).calledWith(
         'institutional-leavers-survey-notification',
-        { type: 'close' }
+        { type: 'close', page: '/' }
       )
     })
   })