mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
Merge pull request #28037 from overleaf/dp-additional-error-states
Add additional pdf error states in new editor GitOrigin-RevId: a7e08652cb5ff23d2139106629f13aad20bd32a0
This commit is contained in:
+3
-132
@@ -1,103 +1,13 @@
|
||||
import OLButton from '@/shared/components/ol/ol-button'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useRailContext } from '../../contexts/rail-context'
|
||||
import { usePdfPreviewContext } from '@/features/pdf-preview/components/pdf-preview-provider'
|
||||
import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
|
||||
import { useIsNewEditorEnabled } from '../../utils/new-editor-utils'
|
||||
import { upgradePlan } from '@/main/account-upgrade'
|
||||
import classNames from 'classnames'
|
||||
import { useStopOnFirstError } from '@/shared/hooks/use-stop-on-first-error'
|
||||
import { useCallback } from 'react'
|
||||
import ErrorState from './error-state'
|
||||
|
||||
// AvailableStates
|
||||
// - rendering-error-expected
|
||||
// - rendering-error
|
||||
// - clsi-maintenance
|
||||
// - clsi-unavailable
|
||||
// - too-recently-compiled
|
||||
// - terminated
|
||||
// - rate-limited
|
||||
// - compile-in-progress
|
||||
// - autocompile-disabled
|
||||
// - project-too-large
|
||||
// - timedout
|
||||
// - failure
|
||||
// - clear-cache
|
||||
// - pdf-viewer-loading-error
|
||||
// - validation-problems
|
||||
function PdfErrorState() {
|
||||
const { loadingError } = usePdfPreviewContext()
|
||||
// TODO ide-redesign-cleanup: rename showLogs to something else and check usages
|
||||
const { hasShortCompileTimeout, error, showLogs } = useCompileContext()
|
||||
const newEditor = useIsNewEditorEnabled()
|
||||
const { t } = useTranslation()
|
||||
|
||||
if (!newEditor || (!loadingError && !showLogs)) {
|
||||
return null
|
||||
}
|
||||
|
||||
switch (error) {
|
||||
case 'timedout': {
|
||||
if (hasShortCompileTimeout) {
|
||||
return <CompileTimeoutErrorState />
|
||||
} else {
|
||||
return <LongCompileTimeoutErrorState />
|
||||
}
|
||||
}
|
||||
case 'compile-in-progress':
|
||||
return (
|
||||
<ErrorState
|
||||
title={t('pdf_compile_in_progress_error')}
|
||||
description={t('pdf_compile_try_again')}
|
||||
iconType="warning"
|
||||
/>
|
||||
)
|
||||
default:
|
||||
return <GeneralErrorState />
|
||||
}
|
||||
}
|
||||
|
||||
const GeneralErrorState = () => {
|
||||
const { t } = useTranslation()
|
||||
const { openTab: openRailTab } = useRailContext()
|
||||
|
||||
return (
|
||||
<ErrorState
|
||||
title={t('pdf_couldnt_compile')}
|
||||
description={t('we_are_unable_to_generate_the_pdf_at_this_time')}
|
||||
iconType="warning"
|
||||
actions={
|
||||
<OLButton
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
openRailTab('errors')
|
||||
}}
|
||||
>
|
||||
{t('check_logs')}
|
||||
</OLButton>
|
||||
}
|
||||
extraContent={
|
||||
<div className="pdf-error-state-info-box">
|
||||
<div className="pdf-error-state-info-box-title">
|
||||
<MaterialIcon type="info" unfilled />
|
||||
{t('why_might_this_happen')}
|
||||
</div>
|
||||
<div className="pdf-error-state-info-box-text">
|
||||
<ul className="pdf-error-state-info-box-list">
|
||||
<li>{t('there_is_an_unrecoverable_latex_error_check_logs')}</li>
|
||||
<li>{t('the_document_environment_contains_no_content')}</li>
|
||||
<li>{t('this_project_contains_a_file_called_output')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const CompileTimeoutErrorState = () => {
|
||||
export const ShortCompileTimeoutErrorState = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
@@ -118,7 +28,7 @@ const CompileTimeoutErrorState = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const LongCompileTimeoutErrorState = () => {
|
||||
export const LongCompileTimeoutErrorState = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const { enableStopOnFirstError } = useStopOnFirstError({
|
||||
@@ -196,42 +106,3 @@ const LongCompileTimeoutErrorState = () => {
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const ErrorState = ({
|
||||
title,
|
||||
description,
|
||||
iconType,
|
||||
actions,
|
||||
iconClassName,
|
||||
extraContent,
|
||||
}: {
|
||||
title: string
|
||||
description: string
|
||||
iconType: string
|
||||
actions?: React.ReactNode
|
||||
iconClassName?: string
|
||||
extraContent?: React.ReactNode
|
||||
}) => {
|
||||
return (
|
||||
<div className="pdf-error-state">
|
||||
<div className="pdf-error-state-top-section">
|
||||
<div
|
||||
className={classNames(
|
||||
'pdf-error-state-icon',
|
||||
'pdf-error-state-warning-icon',
|
||||
iconClassName
|
||||
)}
|
||||
>
|
||||
<MaterialIcon type={iconType} />
|
||||
</div>
|
||||
<div className="pdf-error-state-text">
|
||||
<p className="pdf-error-state-label">{title}</p>
|
||||
<p className="pdf-error-state-description">{description}</p>
|
||||
</div>
|
||||
{actions}
|
||||
</div>
|
||||
{extraContent}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default PdfErrorState
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
import { useRailContext } from '@/features/ide-redesign/contexts/rail-context'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import OLButton from '@/shared/components/ol/ol-button'
|
||||
import classNames from 'classnames'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function ErrorState({
|
||||
title,
|
||||
description,
|
||||
iconType = 'warning',
|
||||
actions,
|
||||
iconClassName,
|
||||
extraContent,
|
||||
}: {
|
||||
title: string
|
||||
description: React.ReactNode
|
||||
iconType?: string
|
||||
actions?: React.ReactNode
|
||||
iconClassName?: string
|
||||
extraContent?: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<div className="pdf-error-state">
|
||||
<div className="pdf-error-state-top-section">
|
||||
<div
|
||||
className={classNames(
|
||||
'pdf-error-state-icon',
|
||||
'pdf-error-state-warning-icon',
|
||||
iconClassName
|
||||
)}
|
||||
>
|
||||
<MaterialIcon type={iconType} />
|
||||
</div>
|
||||
<div className="pdf-error-state-text">
|
||||
<p className="pdf-error-state-label">{title}</p>
|
||||
<p className="pdf-error-state-description">{description}</p>
|
||||
</div>
|
||||
{actions}
|
||||
</div>
|
||||
{extraContent}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const CheckLogsButton = () => {
|
||||
const { t } = useTranslation()
|
||||
const { openTab: openRailTab } = useRailContext()
|
||||
|
||||
return (
|
||||
<OLButton
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
openRailTab('errors')
|
||||
}}
|
||||
>
|
||||
{t('check_logs')}
|
||||
</OLButton>
|
||||
)
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import ErrorState, { CheckLogsButton } from './error-state'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
|
||||
export default function GeneralErrorState() {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<ErrorState
|
||||
title={t('pdf_couldnt_compile')}
|
||||
description={t('we_are_unable_to_generate_the_pdf_at_this_time')}
|
||||
actions={<CheckLogsButton />}
|
||||
extraContent={
|
||||
<div className="pdf-error-state-info-box">
|
||||
<div className="pdf-error-state-info-box-title">
|
||||
<MaterialIcon type="info" unfilled />
|
||||
{t('why_might_this_happen')}
|
||||
</div>
|
||||
<div className="pdf-error-state-info-box-text">
|
||||
<ul className="pdf-error-state-info-box-list">
|
||||
<li>{t('there_is_an_unrecoverable_latex_error_check_logs')}</li>
|
||||
<li>{t('the_document_environment_contains_no_content')}</li>
|
||||
<li>{t('this_project_contains_a_file_called_output')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { usePdfPreviewContext } from '@/features/pdf-preview/components/pdf-preview-provider'
|
||||
import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
|
||||
import { useIsNewEditorEnabled } from '../../../utils/new-editor-utils'
|
||||
import ErrorState, { CheckLogsButton } from './error-state'
|
||||
import {
|
||||
LongCompileTimeoutErrorState,
|
||||
ShortCompileTimeoutErrorState,
|
||||
} from './compile-timeout-error-state'
|
||||
import GeneralErrorState from './general-error-state'
|
||||
|
||||
// AvailableStates
|
||||
// - rendering-error-expected
|
||||
// - rendering-error
|
||||
// - clsi-maintenance
|
||||
// - clsi-unavailable
|
||||
// - too-recently-compiled
|
||||
// - terminated
|
||||
// - rate-limited
|
||||
// - compile-in-progress
|
||||
// - autocompile-disabled
|
||||
// - project-too-large
|
||||
// - timedout
|
||||
// - failure
|
||||
// - clear-cache
|
||||
// - pdf-viewer-loading-error
|
||||
// - validation-problems
|
||||
function PdfErrorState() {
|
||||
const { loadingError } = usePdfPreviewContext()
|
||||
// TODO ide-redesign-cleanup: rename showLogs to something else and check usages
|
||||
const { hasShortCompileTimeout, error, showLogs } = useCompileContext()
|
||||
const newEditor = useIsNewEditorEnabled()
|
||||
const { t } = useTranslation()
|
||||
|
||||
if (!newEditor || (!loadingError && !showLogs)) {
|
||||
return null
|
||||
}
|
||||
|
||||
switch (error) {
|
||||
case 'timedout': {
|
||||
if (hasShortCompileTimeout) {
|
||||
return <ShortCompileTimeoutErrorState />
|
||||
} else {
|
||||
return <LongCompileTimeoutErrorState />
|
||||
}
|
||||
}
|
||||
case 'compile-in-progress':
|
||||
return (
|
||||
<ErrorState
|
||||
title={t('pdf_compile_in_progress_error')}
|
||||
description={t('pdf_compile_try_again')}
|
||||
/>
|
||||
)
|
||||
case 'clsi-maintenance':
|
||||
return (
|
||||
<ErrorState
|
||||
title={t('server_error')}
|
||||
description={t('clsi_maintenance')}
|
||||
iconType="build"
|
||||
/>
|
||||
)
|
||||
case 'clsi-unavailable':
|
||||
return (
|
||||
<ErrorState
|
||||
title={t('server_error')}
|
||||
description={t('clsi_unavailable')}
|
||||
/>
|
||||
)
|
||||
case 'too-recently-compiled':
|
||||
return (
|
||||
<ErrorState
|
||||
title={t('server_error')}
|
||||
description={t('too_recently_compiled')}
|
||||
/>
|
||||
)
|
||||
case 'terminated':
|
||||
return (
|
||||
<ErrorState
|
||||
title={t('terminated')}
|
||||
description={t('compile_terminated_by_user')}
|
||||
actions={<CheckLogsButton />}
|
||||
/>
|
||||
)
|
||||
case 'rate-limited':
|
||||
return (
|
||||
<ErrorState
|
||||
title={t('pdf_compile_rate_limit_hit')}
|
||||
description={t('project_flagged_too_many_compiles')}
|
||||
/>
|
||||
)
|
||||
case 'autocompile-disabled':
|
||||
return (
|
||||
<ErrorState
|
||||
title={t('autocompile_disabled')}
|
||||
description={t('autocompile_disabled_reason')}
|
||||
/>
|
||||
)
|
||||
case 'project-too-large':
|
||||
return (
|
||||
<ErrorState
|
||||
title={t('project_too_large')}
|
||||
description={t('project_too_much_editable_text')}
|
||||
/>
|
||||
)
|
||||
case 'clear-cache':
|
||||
return (
|
||||
<ErrorState
|
||||
title={t('server_error')}
|
||||
description={t('somthing_went_wrong_compiling')}
|
||||
/>
|
||||
)
|
||||
case 'pdf-viewer-loading-error':
|
||||
return (
|
||||
<ErrorState
|
||||
title={t('pdf_rendering_error')}
|
||||
description={
|
||||
<Trans
|
||||
i18nKey="something_went_wrong_loading_pdf_viewer"
|
||||
components={[
|
||||
<strong key="strong-" />,
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
||||
<a
|
||||
href="/learn/how-to/Resolving_access%2C_loading%2C_and_display_problems"
|
||||
target="_blank"
|
||||
key="troubleshooting-link"
|
||||
/>,
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
||||
<a key="contact-link" target="_blank" href="/contact" />,
|
||||
]}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)
|
||||
default:
|
||||
return <GeneralErrorState />
|
||||
}
|
||||
}
|
||||
|
||||
export default PdfErrorState
|
||||
@@ -9,7 +9,7 @@ import { PdfPreviewMessages } from './pdf-preview-messages'
|
||||
import CompileTimeWarningUpgradePrompt from './compile-time-warning-upgrade-prompt'
|
||||
import { PdfPreviewProvider } from './pdf-preview-provider'
|
||||
import PdfPreviewHybridToolbarNew from '@/features/ide-redesign/components/pdf-preview/pdf-preview-hybrid-toolbar'
|
||||
import PdfErrorState from '@/features/ide-redesign/components/pdf-preview/pdf-error-state'
|
||||
import PdfErrorState from '@/features/ide-redesign/components/pdf-preview/pdf-error-state/pdf-error-state'
|
||||
import { useIsNewEditorEnabled } from '@/features/ide-redesign/utils/new-editor-utils'
|
||||
import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
|
||||
import PdfCodeCheckFailedBanner from '@/features/ide-redesign/components/pdf-preview/pdf-code-check-failed-banner'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import useFetchMock from './hooks/use-fetch-mock'
|
||||
import { mockCompile } from './fixtures/compile'
|
||||
import { ScopeDecorator, user } from './decorators/scope'
|
||||
import PdfErrorState from '@/features/ide-redesign/components/pdf-preview/pdf-error-state'
|
||||
import PdfErrorState from '@/features/ide-redesign/components/pdf-preview/pdf-error-state/pdf-error-state'
|
||||
import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
|
||||
import { useEffect } from 'react'
|
||||
import PdfPreview from '@/features/pdf-preview/components/pdf-preview'
|
||||
@@ -12,13 +12,16 @@ export default {
|
||||
}
|
||||
|
||||
const compileErrors = [
|
||||
'autocompile-disabled',
|
||||
'autocompile-backoff',
|
||||
'clear-cache',
|
||||
'clsi-maintenance',
|
||||
'clsi-unavailable',
|
||||
'compile-in-progress',
|
||||
'exited',
|
||||
'failure',
|
||||
'generic',
|
||||
'pdf-viewer-loading-error',
|
||||
'project-too-large',
|
||||
'rate-limited',
|
||||
'success',
|
||||
|
||||
Reference in New Issue
Block a user