Răsfoiți Sursa

Merge pull request #28392 from overleaf/dp-segment-editor-analytics

Add editor-redesign segmentation to a bunch of analytics events

GitOrigin-RevId: e8d2091028dab09de06362c38c5a17f32253e7cc
David 11 luni în urmă
părinte
comite
ae9d84c279

+ 3 - 2
services/web/frontend/js/features/editor-left-menu/components/download-pdf.tsx

@@ -1,18 +1,19 @@
 import { useTranslation } from 'react-i18next'
 import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
 import { useProjectContext } from '../../../shared/context/project-context'
-import * as eventTracking from '../../../infrastructure/event-tracking'
 import { isSmallDevice } from '../../../infrastructure/event-tracking'
 import MaterialIcon from '@/shared/components/material-icon'
 import OLTooltip from '@/shared/components/ol/ol-tooltip'
+import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
 
 export default function DownloadPDF() {
   const { t } = useTranslation()
   const { pdfDownloadUrl, pdfUrl } = useCompileContext()
   const { projectId } = useProjectContext()
+  const { sendEvent } = useEditorAnalytics()
 
   function sendDownloadEvent() {
-    eventTracking.sendMB('download-pdf-button-click', {
+    sendEvent('download-pdf-button-click', {
       projectId,
       location: 'left-menu',
       isSmallDevice,

+ 1 - 0
services/web/frontend/js/features/event-tracking/search-events.ts

@@ -17,6 +17,7 @@ type SearchEventSegmentation = {
     searchType: 'full-project'
     totalDocs: number
     totalResults: number
+    'editor-redesign'?: 'enabled'
   }
   'search-result-click': {
     searchType: 'full-project'

+ 8 - 7
services/web/frontend/js/features/ide-react/context/outline-context.tsx

@@ -10,12 +10,12 @@ import {
 } from 'react'
 import useScopeEventEmitter from '@/shared/hooks/use-scope-event-emitter'
 import useEventListener from '@/shared/hooks/use-event-listener'
-import * as eventTracking from '@/infrastructure/event-tracking'
 import { isValidTeXFile } from '@/main/is-valid-tex-file'
 import localStorage from '@/infrastructure/local-storage'
 import { useProjectContext } from '@/shared/context/project-context'
 import { useEditorOpenDocContext } from '@/features/ide-react/context/editor-open-doc-context'
 import { useFileTreeOpenContext } from './file-tree-open-context'
+import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
 
 export type PartialFlatOutline = {
   level: number
@@ -53,6 +53,7 @@ export const OutlineProvider: FC<React.PropsWithChildren> = ({ children }) => {
   const [ignoreNextCursorUpdate, setIgnoreNextCursorUpdate] =
     useState<boolean>(false)
   const [ignoreNextScroll, setIgnoreNextScroll] = useState<boolean>(false)
+  const { sendEvent } = useEditorAnalytics()
 
   const goToLineEmitter = useScopeEventEmitter('editor:gotoLine', true)
 
@@ -110,9 +111,9 @@ export const OutlineProvider: FC<React.PropsWithChildren> = ({ children }) => {
         gotoColumn: 0,
         syncToPdf,
       })
-      eventTracking.sendMB('outline-jump-to-line')
+      sendEvent('outline-jump-to-line')
     },
-    [goToLineEmitter]
+    [goToLineEmitter, sendEvent]
   )
 
   const highlightedLine = useMemo(
@@ -142,18 +143,18 @@ export const OutlineProvider: FC<React.PropsWithChildren> = ({ children }) => {
   const expandOutline = useCallback(() => {
     if (canShowOutline) {
       localStorage.setItem(storageKey, true)
-      eventTracking.sendMB('outline-expand')
+      sendEvent('outline-expand')
       setOutlineExpanded(true)
     }
-  }, [canShowOutline, storageKey])
+  }, [canShowOutline, storageKey, sendEvent])
 
   const collapseOutline = useCallback(() => {
     if (canShowOutline) {
       localStorage.setItem(storageKey, false)
-      eventTracking.sendMB('outline-collapse')
+      sendEvent('outline-collapse')
       setOutlineExpanded(false)
     }
-  }, [canShowOutline, storageKey])
+  }, [canShowOutline, storageKey, sendEvent])
 
   const toggleOutlineExpanded = useCallback(() => {
     if (outlineExpanded) {

+ 6 - 4
services/web/frontend/js/features/ide-redesign/components/toolbar/download-project.tsx

@@ -6,6 +6,7 @@ import { useDetachCompileContext as useCompileContext } from '@/shared/context/d
 import { useProjectContext } from '@/shared/context/project-context'
 import { useCallback } from 'react'
 import { useTranslation } from 'react-i18next'
+import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
 
 export const DownloadProjectZip = () => {
   const { t } = useTranslation()
@@ -45,13 +46,14 @@ export const DownloadProjectPDF = () => {
   const { t } = useTranslation()
   const { pdfDownloadUrl, pdfUrl } = useCompileContext()
   const { projectId } = useProjectContext()
+  const { sendEvent } = useEditorAnalytics()
   const sendDownloadEvent = useCallback(() => {
-    sendMB('download-pdf-button-click', {
+    sendEvent('download-pdf-button-click', {
       projectId,
       location: 'project-name-dropdown',
       isSmallDevice,
     })
-  }, [projectId])
+  }, [projectId, sendEvent])
 
   useCommandProvider(
     () => [
@@ -60,7 +62,7 @@ export const DownloadProjectPDF = () => {
         disabled: !pdfUrl,
         href: pdfDownloadUrl || pdfUrl,
         handler: ({ location }) => {
-          sendMB('download-pdf-button-click', {
+          sendEvent('download-pdf-button-click', {
             projectId,
             location,
             isSmallDevice,
@@ -69,7 +71,7 @@ export const DownloadProjectPDF = () => {
         label: t('download_as_pdf'),
       },
     ],
-    [t, pdfUrl, projectId, pdfDownloadUrl]
+    [t, pdfUrl, projectId, pdfDownloadUrl, sendEvent]
   )
 
   const button = (

+ 4 - 2
services/web/frontend/js/features/pdf-preview/components/pdf-hybrid-download-button.tsx

@@ -1,13 +1,15 @@
 import { useTranslation } from 'react-i18next'
 import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
 import { useProjectContext } from '@/shared/context/project-context'
-import { sendMB, isSmallDevice } from '@/infrastructure/event-tracking'
+import { isSmallDevice } from '@/infrastructure/event-tracking'
 import OLTooltip from '@/shared/components/ol/ol-tooltip'
 import OLButton from '@/shared/components/ol/ol-button'
 import MaterialIcon from '@/shared/components/material-icon'
+import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
 
 function PdfHybridDownloadButton() {
   const { pdfDownloadUrl } = useCompileContext()
+  const { sendEvent } = useEditorAnalytics()
 
   const { projectId } = useProjectContext()
 
@@ -23,7 +25,7 @@ function PdfHybridDownloadButton() {
       return
     }
 
-    sendMB('download-pdf-button-click', {
+    sendEvent('download-pdf-button-click', {
       projectId,
       location: 'pdf-preview',
       isSmallDevice,

+ 4 - 3
services/web/frontend/js/features/pdf-preview/hooks/use-presentation-mode.ts

@@ -1,7 +1,7 @@
 import { useCallback, useEffect, useRef, useState } from 'react'
 import PDFJSWrapper from '../util/pdf-js-wrapper'
-import { sendMB } from '@/infrastructure/event-tracking'
 import { debugConsole } from '@/utils/debugging'
+import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
 
 type StoredPDFState = {
   scrollMode?: number
@@ -17,6 +17,7 @@ export default function usePresentationMode(
   setScale: (scale: string) => void
 ): () => void {
   const storedState = useRef<StoredPDFState>({})
+  const { sendEvent } = useEditorAnalytics()
 
   const [presentationMode, setPresentationMode] = useState(false)
 
@@ -114,14 +115,14 @@ export default function usePresentationMode(
   }, [presentationMode, arrowKeyListener, clickListener, mouseWheelListener])
 
   const requestPresentationMode = useCallback(() => {
-    sendMB('pdf-viewer-enter-presentation-mode')
+    sendEvent('pdf-viewer-enter-presentation-mode')
 
     if (pdfJsWrapper) {
       pdfJsWrapper.container.parentElement
         ?.requestFullscreen()
         .catch(debugConsole.error)
     }
-  }, [pdfJsWrapper])
+  }, [pdfJsWrapper, sendEvent])
 
   const handleEnterFullscreen = useCallback(() => {
     if (pdfJsWrapper) {

+ 12 - 3
services/web/frontend/js/shared/hooks/use-editor-analytics.ts

@@ -7,14 +7,23 @@ import {
 } from '@/infrastructure/event-tracking'
 import { useCallback } from 'react'
 
+export function populateEditorRedesignSegmentation<
+  SegmentationType extends Segmentation,
+>(
+  segmentation: SegmentationType | undefined = {} as SegmentationType,
+  editorRedesign: boolean
+): SegmentationType & { 'editor-redesign'?: 'enabled' } {
+  return editorRedesign
+    ? { ...segmentation, 'editor-redesign': 'enabled' }
+    : segmentation
+}
+
 export const useEditorAnalytics = () => {
   const editorRedesign = useIsNewEditorEnabled()
 
   const populateSegmentation = useCallback(
     (segmentation: Segmentation | undefined = {}): Segmentation => {
-      return editorRedesign
-        ? { ...segmentation, 'editor-redesign': 'enabled' }
-        : segmentation
+      return populateEditorRedesignSegmentation(segmentation, editorRedesign)
     },
     [editorRedesign]
   )

+ 6 - 2
services/web/modules/full-project-search/frontend/js/components/full-project-search-ui.tsx

@@ -111,7 +111,11 @@ const FullProjectSearchUI: FC = () => {
 
         await projectSnapshot.refresh()
         if (!abortControllerRef.current.signal.aborted) {
-          const results = await searchSnapshot(projectSnapshot, searchQuery)
+          const results = await searchSnapshot(
+            projectSnapshot,
+            searchQuery,
+            newEditor
+          )
           setMatchedFiles(results)
         }
       } catch (error) {
@@ -121,7 +125,7 @@ const FullProjectSearchUI: FC = () => {
         setLoading(false)
       }
     },
-    [openDocs, projectSnapshot, t]
+    [openDocs, projectSnapshot, t, newEditor]
   )
 
   const searchInputRef = useRef<HTMLInputElement>(null)

+ 14 - 6
services/web/modules/full-project-search/frontend/js/util/search-snapshot.ts

@@ -3,6 +3,7 @@ import { RegExpCursor, SearchCursor, SearchQuery } from '@codemirror/search'
 import { ProjectSnapshot } from '@/infrastructure/project-snapshot'
 import { categorizer, regexpWordTest, stringWordTest } from './search'
 import { sendSearchEvent } from '@/features/event-tracking/search-events'
+import { populateEditorRedesignSegmentation } from '@/shared/hooks/use-editor-analytics'
 
 export type Hit = {
   lineIndex: number
@@ -20,7 +21,8 @@ const toLowerCase = (string: string) => string.toLowerCase()
 
 export const searchSnapshot = async (
   projectSnapshot: ProjectSnapshot,
-  searchQuery: SearchQuery
+  searchQuery: SearchQuery,
+  newEditor: boolean
 ) => {
   if (!searchQuery.search.trim().length) {
     return
@@ -82,11 +84,17 @@ export const searchSnapshot = async (
     a.path.localeCompare(b.path)
   )
 
-  sendSearchEvent('search-execute', {
-    searchType: 'full-project',
-    totalDocs: docPaths.length,
-    totalResults: results.flatMap(file => file.hits).length,
-  })
+  sendSearchEvent(
+    'search-execute',
+    populateEditorRedesignSegmentation(
+      {
+        searchType: 'full-project',
+        totalDocs: docPaths.length,
+        totalResults: results.flatMap(file => file.hits).length,
+      },
+      newEditor
+    )
+  )
 
   return results
 }