mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-25 02:00:10 +02: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
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {import('../../../../../types/annotation').Annotation} Annotation
|
||||
* @returns {Record<string, Annotation[]>}
|
||||
*/
|
||||
export function buildLogEntryAnnotations(entries, fileTreeData, rootDocId) {
|
||||
const rootDocDirname = dirname(fileTreeData, rootDocId)
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
SetStateAction,
|
||||
} from 'react'
|
||||
import useScopeValue from '../hooks/use-scope-value'
|
||||
import useScopeValueSetterOnly from '../hooks/use-scope-value-setter-only'
|
||||
import usePersistedState from '../hooks/use-persisted-state'
|
||||
import useAbortController from '../hooks/use-abort-controller'
|
||||
import DocumentCompiler from '../../features/pdf-preview/util/compiler'
|
||||
@@ -51,6 +50,7 @@ import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
||||
import { captureException } from '@/infrastructure/error-reporter'
|
||||
import OError from '@overleaf/o-error'
|
||||
import getMeta from '@/utils/meta'
|
||||
import type { Annotation } from '../../../../types/annotation'
|
||||
|
||||
type PdfFile = Record<string, any>
|
||||
|
||||
@@ -74,7 +74,7 @@ export type CompileContext = {
|
||||
warnings: LogEntry[]
|
||||
typesetting: LogEntry[]
|
||||
}
|
||||
logEntryAnnotations?: Record<string, any>
|
||||
logEntryAnnotations?: Record<string, Annotation[]>
|
||||
outputFilesArchive?: string
|
||||
pdfDownloadUrl?: string
|
||||
pdfFile?: PdfFile
|
||||
@@ -98,7 +98,7 @@ export type CompileContext = {
|
||||
stopOnFirstError: boolean
|
||||
stopOnValidationError: boolean
|
||||
stoppedOnFirstError: boolean
|
||||
uncompiled?: boolean
|
||||
uncompiled: boolean
|
||||
validationIssues?: Record<string, any>
|
||||
firstRenderDone: (metrics: {
|
||||
latencyFetch: number
|
||||
@@ -156,34 +156,22 @@ export const LocalCompileProvider: FC<React.PropsWithChildren> = ({
|
||||
const [hasShortCompileTimeout, setHasShortCompileTimeout] = useState(false)
|
||||
|
||||
// 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
|
||||
const [logEntryAnnotations, setLogEntryAnnotations] = useScopeValue(
|
||||
'pdf.logEntryAnnotations'
|
||||
)
|
||||
const [logEntryAnnotations, setLogEntryAnnotations] = useState<
|
||||
undefined | Record<string, Annotation[]>
|
||||
>()
|
||||
|
||||
// the PDF viewer and whether syntax validation is enabled globally
|
||||
const { userSettings } = useUserSettingsContext()
|
||||
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
|
||||
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.
|
||||
const [uncompiled, setUncompiled] = useScopeValue('pdf.uncompiled')
|
||||
const [uncompiled, setUncompiled] = useState(false)
|
||||
|
||||
// whether a doc has been edited since the last compile started
|
||||
const [editedSinceCompileStarted, setEditedSinceCompileStarted] =
|
||||
@@ -294,7 +282,7 @@ export const LocalCompileProvider: FC<React.PropsWithChildren> = ({
|
||||
|
||||
const cleanupCompileResult = useCallback(() => {
|
||||
setPdfFile(undefined)
|
||||
setLogEntries(null)
|
||||
setLogEntries(undefined)
|
||||
setLogEntryAnnotations({})
|
||||
}, [setPdfFile, setLogEntries, setLogEntryAnnotations])
|
||||
|
||||
@@ -513,8 +501,8 @@ export const LocalCompileProvider: FC<React.PropsWithChildren> = ({
|
||||
|
||||
// handle log files
|
||||
// asynchronous (TODO: cancel on new compile?)
|
||||
setLogEntryAnnotations(null)
|
||||
setLogEntries(null)
|
||||
setLogEntryAnnotations(undefined)
|
||||
setLogEntries(undefined)
|
||||
setRawLog(undefined)
|
||||
|
||||
handleLogFiles(outputFiles, data, abortController.signal).then(
|
||||
|
||||
@@ -7,7 +7,9 @@ import { activeEditorLine } from '../helpers/active-editor-line'
|
||||
import { TestContainer } from '../helpers/test-container'
|
||||
import customLocalStorage from '@/infrastructure/local-storage'
|
||||
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 () {
|
||||
beforeEach(function () {
|
||||
@@ -64,27 +66,39 @@ describe('<CodeMirrorEditor/>', { scrollBehavior: false }, function () {
|
||||
it('renders annotations in the gutter', function () {
|
||||
const scope = mockScope()
|
||||
|
||||
scope.pdf.logEntryAnnotations = {
|
||||
const logEntryAnnotations: Record<string, Annotation[]> = {
|
||||
[docId]: [
|
||||
{
|
||||
id: '1',
|
||||
entryIndex: 1,
|
||||
row: 20,
|
||||
type: 'error',
|
||||
text: 'Another error',
|
||||
firstOnLine: true,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
entryIndex: 2,
|
||||
row: 19,
|
||||
type: 'error',
|
||||
text: 'An error',
|
||||
firstOnLine: true,
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
entryIndex: 3,
|
||||
row: 20,
|
||||
type: 'warning',
|
||||
text: 'A warning on the same line',
|
||||
firstOnLine: false,
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
entryIndex: 4,
|
||||
row: 25,
|
||||
type: 'warning',
|
||||
text: 'Another warning',
|
||||
firstOnLine: true,
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -93,9 +107,19 @@ describe('<CodeMirrorEditor/>', { scrollBehavior: false }, function () {
|
||||
|
||||
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(
|
||||
<TestContainer>
|
||||
<EditorProviders scope={scope} userSettings={userSettings}>
|
||||
<EditorProviders
|
||||
scope={scope}
|
||||
userSettings={userSettings}
|
||||
providers={{ LocalCompileProvider }}
|
||||
>
|
||||
<CodeMirrorEditor />
|
||||
</EditorProviders>
|
||||
</TestContainer>
|
||||
|
||||
@@ -22,9 +22,6 @@ export const mockScope = (
|
||||
showVisual: false,
|
||||
wantTrackChanges: false,
|
||||
},
|
||||
pdf: {
|
||||
logEntryAnnotations: {},
|
||||
},
|
||||
project: {
|
||||
_id: 'test-project',
|
||||
name: 'Test Project',
|
||||
|
||||
Reference in New Issue
Block a user