mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 22:23:42 +01:00
[web] Move pdf.* scopes to react states (#26599)
* Move `pdf.logEntryAnnotations` to react state * Remove unused scope `pdf.downloadUrl` * Remove unused scope `pdf.url` * Move `pdf.uncompiled` to react state * Move `pdf.logEntries` to react state * Remove `pdf` from `mockScope` * Fix test: "renders annotations in the gutter" GitOrigin-RevId: bf1d0ec30cc0ffcc1177871651483c296ed08baf
This commit is contained in:
@@ -143,6 +143,10 @@ export const handleLogFiles = async (outputFiles, data, signal) => {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import('../../../../../types/annotation').Annotation} Annotation
|
||||||
|
* @returns {Record<string, Annotation[]>}
|
||||||
|
*/
|
||||||
export function buildLogEntryAnnotations(entries, fileTreeData, rootDocId) {
|
export function buildLogEntryAnnotations(entries, fileTreeData, rootDocId) {
|
||||||
const rootDocDirname = dirname(fileTreeData, rootDocId)
|
const rootDocDirname = dirname(fileTreeData, rootDocId)
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
SetStateAction,
|
SetStateAction,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import useScopeValue from '../hooks/use-scope-value'
|
import useScopeValue from '../hooks/use-scope-value'
|
||||||
import useScopeValueSetterOnly from '../hooks/use-scope-value-setter-only'
|
|
||||||
import usePersistedState from '../hooks/use-persisted-state'
|
import usePersistedState from '../hooks/use-persisted-state'
|
||||||
import useAbortController from '../hooks/use-abort-controller'
|
import useAbortController from '../hooks/use-abort-controller'
|
||||||
import DocumentCompiler from '../../features/pdf-preview/util/compiler'
|
import DocumentCompiler from '../../features/pdf-preview/util/compiler'
|
||||||
@@ -51,6 +50,7 @@ import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
|||||||
import { captureException } from '@/infrastructure/error-reporter'
|
import { captureException } from '@/infrastructure/error-reporter'
|
||||||
import OError from '@overleaf/o-error'
|
import OError from '@overleaf/o-error'
|
||||||
import getMeta from '@/utils/meta'
|
import getMeta from '@/utils/meta'
|
||||||
|
import type { Annotation } from '../../../../types/annotation'
|
||||||
|
|
||||||
type PdfFile = Record<string, any>
|
type PdfFile = Record<string, any>
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ export type CompileContext = {
|
|||||||
warnings: LogEntry[]
|
warnings: LogEntry[]
|
||||||
typesetting: LogEntry[]
|
typesetting: LogEntry[]
|
||||||
}
|
}
|
||||||
logEntryAnnotations?: Record<string, any>
|
logEntryAnnotations?: Record<string, Annotation[]>
|
||||||
outputFilesArchive?: string
|
outputFilesArchive?: string
|
||||||
pdfDownloadUrl?: string
|
pdfDownloadUrl?: string
|
||||||
pdfFile?: PdfFile
|
pdfFile?: PdfFile
|
||||||
@@ -98,7 +98,7 @@ export type CompileContext = {
|
|||||||
stopOnFirstError: boolean
|
stopOnFirstError: boolean
|
||||||
stopOnValidationError: boolean
|
stopOnValidationError: boolean
|
||||||
stoppedOnFirstError: boolean
|
stoppedOnFirstError: boolean
|
||||||
uncompiled?: boolean
|
uncompiled: boolean
|
||||||
validationIssues?: Record<string, any>
|
validationIssues?: Record<string, any>
|
||||||
firstRenderDone: (metrics: {
|
firstRenderDone: (metrics: {
|
||||||
latencyFetch: number
|
latencyFetch: number
|
||||||
@@ -156,34 +156,22 @@ export const LocalCompileProvider: FC<React.PropsWithChildren> = ({
|
|||||||
const [hasShortCompileTimeout, setHasShortCompileTimeout] = useState(false)
|
const [hasShortCompileTimeout, setHasShortCompileTimeout] = useState(false)
|
||||||
|
|
||||||
// the log entries parsed from the compile output log
|
// the log entries parsed from the compile output log
|
||||||
const [logEntries, setLogEntries] = useScopeValueSetterOnly('pdf.logEntries')
|
const [logEntries, setLogEntries] = useState<CompileContext['logEntries']>()
|
||||||
|
|
||||||
// annotations for display in the editor, built from the log entries
|
// annotations for display in the editor, built from the log entries
|
||||||
const [logEntryAnnotations, setLogEntryAnnotations] = useScopeValue(
|
const [logEntryAnnotations, setLogEntryAnnotations] = useState<
|
||||||
'pdf.logEntryAnnotations'
|
undefined | Record<string, Annotation[]>
|
||||||
)
|
>()
|
||||||
|
|
||||||
// the PDF viewer and whether syntax validation is enabled globally
|
// the PDF viewer and whether syntax validation is enabled globally
|
||||||
const { userSettings } = useUserSettingsContext()
|
const { userSettings } = useUserSettingsContext()
|
||||||
const { pdfViewer, syntaxValidation } = userSettings
|
const { pdfViewer, syntaxValidation } = userSettings
|
||||||
|
|
||||||
// the URL for downloading the PDF
|
|
||||||
const [, setPdfDownloadUrl] =
|
|
||||||
useScopeValueSetterOnly<string>('pdf.downloadUrl')
|
|
||||||
|
|
||||||
// the URL for loading the PDF in the preview pane
|
|
||||||
const [, setPdfUrl] = useScopeValueSetterOnly<string>('pdf.url')
|
|
||||||
|
|
||||||
// low level details for metrics
|
// low level details for metrics
|
||||||
const [pdfFile, setPdfFile] = useState<PdfFile | undefined>()
|
const [pdfFile, setPdfFile] = useState<PdfFile | undefined>()
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setPdfDownloadUrl(pdfFile?.pdfDownloadUrl)
|
|
||||||
setPdfUrl(pdfFile?.pdfUrl)
|
|
||||||
}, [pdfFile, setPdfDownloadUrl, setPdfUrl])
|
|
||||||
|
|
||||||
// the project is considered to be "uncompiled" if a doc has changed, or finished saving, since the last compile started.
|
// the project is considered to be "uncompiled" if a doc has changed, or finished saving, since the last compile started.
|
||||||
const [uncompiled, setUncompiled] = useScopeValue('pdf.uncompiled')
|
const [uncompiled, setUncompiled] = useState(false)
|
||||||
|
|
||||||
// whether a doc has been edited since the last compile started
|
// whether a doc has been edited since the last compile started
|
||||||
const [editedSinceCompileStarted, setEditedSinceCompileStarted] =
|
const [editedSinceCompileStarted, setEditedSinceCompileStarted] =
|
||||||
@@ -294,7 +282,7 @@ export const LocalCompileProvider: FC<React.PropsWithChildren> = ({
|
|||||||
|
|
||||||
const cleanupCompileResult = useCallback(() => {
|
const cleanupCompileResult = useCallback(() => {
|
||||||
setPdfFile(undefined)
|
setPdfFile(undefined)
|
||||||
setLogEntries(null)
|
setLogEntries(undefined)
|
||||||
setLogEntryAnnotations({})
|
setLogEntryAnnotations({})
|
||||||
}, [setPdfFile, setLogEntries, setLogEntryAnnotations])
|
}, [setPdfFile, setLogEntries, setLogEntryAnnotations])
|
||||||
|
|
||||||
@@ -513,8 +501,8 @@ export const LocalCompileProvider: FC<React.PropsWithChildren> = ({
|
|||||||
|
|
||||||
// handle log files
|
// handle log files
|
||||||
// asynchronous (TODO: cancel on new compile?)
|
// asynchronous (TODO: cancel on new compile?)
|
||||||
setLogEntryAnnotations(null)
|
setLogEntryAnnotations(undefined)
|
||||||
setLogEntries(null)
|
setLogEntries(undefined)
|
||||||
setRawLog(undefined)
|
setRawLog(undefined)
|
||||||
|
|
||||||
handleLogFiles(outputFiles, data, abortController.signal).then(
|
handleLogFiles(outputFiles, data, abortController.signal).then(
|
||||||
|
|||||||
+27
-3
@@ -7,7 +7,9 @@ import { activeEditorLine } from '../helpers/active-editor-line'
|
|||||||
import { TestContainer } from '../helpers/test-container'
|
import { TestContainer } from '../helpers/test-container'
|
||||||
import customLocalStorage from '@/infrastructure/local-storage'
|
import customLocalStorage from '@/infrastructure/local-storage'
|
||||||
import { OnlineUsersContext } from '@/features/ide-react/context/online-users-context'
|
import { OnlineUsersContext } from '@/features/ide-react/context/online-users-context'
|
||||||
import { FC } from 'react'
|
import { LocalCompileContext } from '@/shared/context/local-compile-context'
|
||||||
|
import type { FC, PropsWithChildren } from 'react'
|
||||||
|
import type { Annotation } from '../../../../../types/annotation'
|
||||||
|
|
||||||
describe('<CodeMirrorEditor/>', { scrollBehavior: false }, function () {
|
describe('<CodeMirrorEditor/>', { scrollBehavior: false }, function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
@@ -64,27 +66,39 @@ describe('<CodeMirrorEditor/>', { scrollBehavior: false }, function () {
|
|||||||
it('renders annotations in the gutter', function () {
|
it('renders annotations in the gutter', function () {
|
||||||
const scope = mockScope()
|
const scope = mockScope()
|
||||||
|
|
||||||
scope.pdf.logEntryAnnotations = {
|
const logEntryAnnotations: Record<string, Annotation[]> = {
|
||||||
[docId]: [
|
[docId]: [
|
||||||
{
|
{
|
||||||
|
id: '1',
|
||||||
|
entryIndex: 1,
|
||||||
row: 20,
|
row: 20,
|
||||||
type: 'error',
|
type: 'error',
|
||||||
text: 'Another error',
|
text: 'Another error',
|
||||||
|
firstOnLine: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: '2',
|
||||||
|
entryIndex: 2,
|
||||||
row: 19,
|
row: 19,
|
||||||
type: 'error',
|
type: 'error',
|
||||||
text: 'An error',
|
text: 'An error',
|
||||||
|
firstOnLine: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: '3',
|
||||||
|
entryIndex: 3,
|
||||||
row: 20,
|
row: 20,
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
text: 'A warning on the same line',
|
text: 'A warning on the same line',
|
||||||
|
firstOnLine: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: '4',
|
||||||
|
entryIndex: 4,
|
||||||
row: 25,
|
row: 25,
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
text: 'Another warning',
|
text: 'Another warning',
|
||||||
|
firstOnLine: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@@ -93,9 +107,19 @@ describe('<CodeMirrorEditor/>', { scrollBehavior: false }, function () {
|
|||||||
|
|
||||||
cy.clock()
|
cy.clock()
|
||||||
|
|
||||||
|
const LocalCompileProvider: FC<PropsWithChildren> = ({ children }) => (
|
||||||
|
// @ts-expect-error: not entering all the values for LocalCompileContext
|
||||||
|
<LocalCompileContext.Provider value={{ logEntryAnnotations }}>
|
||||||
|
{children}
|
||||||
|
</LocalCompileContext.Provider>
|
||||||
|
)
|
||||||
cy.mount(
|
cy.mount(
|
||||||
<TestContainer>
|
<TestContainer>
|
||||||
<EditorProviders scope={scope} userSettings={userSettings}>
|
<EditorProviders
|
||||||
|
scope={scope}
|
||||||
|
userSettings={userSettings}
|
||||||
|
providers={{ LocalCompileProvider }}
|
||||||
|
>
|
||||||
<CodeMirrorEditor />
|
<CodeMirrorEditor />
|
||||||
</EditorProviders>
|
</EditorProviders>
|
||||||
</TestContainer>
|
</TestContainer>
|
||||||
|
|||||||
@@ -22,9 +22,6 @@ export const mockScope = (
|
|||||||
showVisual: false,
|
showVisual: false,
|
||||||
wantTrackChanges: false,
|
wantTrackChanges: false,
|
||||||
},
|
},
|
||||||
pdf: {
|
|
||||||
logEntryAnnotations: {},
|
|
||||||
},
|
|
||||||
project: {
|
project: {
|
||||||
_id: 'test-project',
|
_id: 'test-project',
|
||||||
name: 'Test Project',
|
name: 'Test Project',
|
||||||
|
|||||||
Reference in New Issue
Block a user