Просмотр исходного кода

Merge pull request #6199 from overleaf/ta-pdf-detach-sync-to-entry

Make syncToEntry a Detach Action

GitOrigin-RevId: 92e92b770c4e2be5b001c083d2d490231a7fddfb
Timothée Alby 4 лет назад
Родитель
Сommit
55829a3382

+ 9 - 1
services/web/frontend/js/features/pdf-preview/components/pdf-logs-entries.js

@@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next'
 import PreviewLogsPaneMaxEntries from '../../preview/components/preview-logs-pane-max-entries'
 import PdfLogEntry from './pdf-log-entry'
 import { useIdeContext } from '../../../shared/context/ide-context'
+import useDetachAction from '../../../shared/hooks/use-detach-action'
 
 const LOG_PREVIEW_LIMIT = 100
 
@@ -12,7 +13,7 @@ function PdfLogsEntries({ entries, hasErrors }) {
 
   const ide = useIdeContext()
 
-  const syncToEntry = useCallback(
+  const _syncToEntry = useCallback(
     entry => {
       const entity = ide.fileTreeManager.findEntityByPath(entry.file)
 
@@ -26,6 +27,13 @@ function PdfLogsEntries({ entries, hasErrors }) {
     [ide]
   )
 
+  const syncToEntry = useDetachAction(
+    'sync-to-entry',
+    _syncToEntry,
+    'detached',
+    'detacher'
+  )
+
   const logEntries = entries.slice(0, LOG_PREVIEW_LIMIT)
 
   return (

+ 114 - 0
services/web/test/frontend/features/pdf-preview/components/pdf-logs-entries.test.js

@@ -0,0 +1,114 @@
+import PdfLogsEntries from '../../../../../frontend/js/features/pdf-preview/components/pdf-logs-entries'
+import { renderWithEditorContext } from '../../../helpers/render-with-context'
+import { screen, fireEvent } from '@testing-library/react'
+import sysendTestHelper from '../../../helpers/sysend'
+import { expect } from 'chai'
+import sinon from 'sinon'
+
+describe('<PdfLogsEntries/>', function () {
+  const fileTreeManager = {}
+  const editorManager = {}
+  const logEntries = [
+    {
+      file: 'main.tex',
+      line: 9,
+      column: 8,
+      level: 'error',
+      message: 'LaTeX Error',
+      content: 'See the LaTeX manual',
+      raw: '',
+      ruleId: 'latex_error',
+      humanReadableHint: '',
+      humanReadableHintComponent: <></>,
+      key: '',
+    },
+  ]
+  const fakeEntity = { type: 'doc' }
+
+  beforeEach(function () {
+    fileTreeManager.findEntityByPath = sinon.stub().returns(fakeEntity)
+    editorManager.openDoc = sinon.stub()
+  })
+
+  afterEach(function () {
+    window.metaAttributesCache = new Map()
+    sysendTestHelper.resetHistory()
+    fileTreeManager.findEntityByPath.resetHistory()
+  })
+
+  it('opens doc on click', async function () {
+    renderWithEditorContext(<PdfLogsEntries entries={logEntries} />, {
+      fileTreeManager,
+      editorManager,
+    })
+
+    const button = await screen.getByRole('button', {
+      name: 'Navigate to log position in source code: main.tex, 9',
+    })
+    fireEvent.click(button)
+    sinon.assert.calledOnce(fileTreeManager.findEntityByPath)
+    sinon.assert.calledOnce(editorManager.openDoc)
+    sinon.assert.calledWith(editorManager.openDoc, fakeEntity, {
+      gotoLine: 9,
+      gotoColumn: 8,
+    })
+  })
+
+  it('opens doc via detached action', async function () {
+    window.metaAttributesCache.set('ol-detachRole', 'detacher')
+
+    renderWithEditorContext(<PdfLogsEntries entries={logEntries} />, {
+      fileTreeManager,
+      editorManager,
+    })
+
+    sysendTestHelper.receiveMessage({
+      role: 'detached',
+      event: 'action-sync-to-entry',
+      data: {
+        args: [
+          {
+            file: 'main.tex',
+            line: 7,
+            column: 6,
+          },
+        ],
+      },
+    })
+
+    sinon.assert.calledOnce(fileTreeManager.findEntityByPath)
+    sinon.assert.calledOnce(editorManager.openDoc)
+    sinon.assert.calledWith(editorManager.openDoc, fakeEntity, {
+      gotoLine: 7,
+      gotoColumn: 6,
+    })
+  })
+
+  it('sends open doc clicks via detached action', async function () {
+    window.metaAttributesCache.set('ol-detachRole', 'detached')
+    renderWithEditorContext(<PdfLogsEntries entries={logEntries} />, {
+      fileTreeManager,
+      editorManager,
+    })
+
+    const button = await screen.getByRole('button', {
+      name: 'Navigate to log position in source code: main.tex, 9',
+    })
+    fireEvent.click(button)
+    sinon.assert.notCalled(fileTreeManager.findEntityByPath)
+    sinon.assert.notCalled(editorManager.openDoc)
+    expect(sysendTestHelper.getLastBroacastMessage()).to.deep.equal({
+      role: 'detached',
+      event: 'action-sync-to-entry',
+      data: {
+        args: [
+          {
+            file: 'main.tex',
+            line: 9,
+            column: 8,
+          },
+        ],
+      },
+    })
+  })
+})

+ 11 - 13
services/web/test/frontend/helpers/render-with-context.js

@@ -33,6 +33,17 @@ export function EditorProviders({
   children,
   rootFolder,
   ui = { view: null, pdfLayout: 'flat', chatOpen: true },
+  fileTreeManager = {
+    findEntityById: () => null,
+    findEntityByPath: () => null,
+    getEntityPath: () => '',
+    getRootDocDirname: () => '',
+  },
+  editorManager = {
+    getCurrentDocId: () => 'foo',
+    getCurrentDocValue: () => {},
+    openDoc: sinon.stub(),
+  },
 }) {
   window.user = user || window.user
   window.gitBridgePublicBaseUrl = 'git.overleaf.test'
@@ -66,19 +77,6 @@ export function EditorProviders({
     ...scope,
   }
 
-  const fileTreeManager = {
-    findEntityById: () => null,
-    findEntityByPath: () => null,
-    getEntityPath: () => '',
-    getRootDocDirname: () => '',
-  }
-
-  const editorManager = {
-    getCurrentDocId: () => 'foo',
-    getCurrentDocValue: () => {},
-    openDoc: sinon.stub(),
-  }
-
   const metadataManager = {
     metadata: {
       state: {