mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
* feat: adding 2025 and 2026 incremental compiles options * feat: remove dmtcp from compiler list and autoselect checkpointing version with labs inclusion * feat: updating seccomp profile for checkpointing * feat: disable non-premium dmtcp compiles, and align checkpoint version detection between clsi and web * feat: adding in reminder of checkpoint experiment, and using session based split test retrieval * Increase Packer build.sh timeout from 1h15m to 1h30m as build takes approx 1h * fix: moving checkpointing check from tag name based to hasCheckpointing flag set as part of allowed_images, and removing uneeded seccomp rule * feat: move variant/ image selection to CLSI, and have web control only what options to set for a compile. removing uneeded extra variants from webs list of allowed images * feat: adding compile timer as a query string as well --------- Co-authored-by: Tim Gibbon <tim.gibbon@overleaf.com> GitOrigin-RevId: cdbdf76a62dcd5a585925f18d64b6cb9cd6ed373
171 lines
5.6 KiB
TypeScript
171 lines
5.6 KiB
TypeScript
import { useTranslation } from 'react-i18next'
|
|
import { memo, useCallback, useMemo, useState } from 'react'
|
|
import { usePdfPreviewContext } from '@/features/pdf-preview/components/pdf-preview-provider'
|
|
import StopOnFirstErrorPrompt from '@/features/pdf-preview/components/stop-on-first-error-prompt'
|
|
import PdfPreviewError from '@/features/pdf-preview/components/pdf-preview-error'
|
|
import PdfValidationIssue from '@/features/pdf-preview/components/pdf-validation-issue'
|
|
import PdfLogsEntries from '@/features/pdf-preview/components/pdf-logs-entries'
|
|
import PdfPreviewErrorBoundaryFallback from '@/features/pdf-preview/components/pdf-preview-error-boundary-fallback'
|
|
import withErrorBoundary from '@/infrastructure/error-boundary'
|
|
import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
|
|
import { Nav, NavLink, TabContainer, TabContent } from 'react-bootstrap'
|
|
import { LogEntry as LogEntryData } from '@/features/pdf-preview/util/types'
|
|
import LogEntry from './log-entry'
|
|
import TimeoutUpgradePromptNew from '@/features/pdf-preview/components/timeout-upgrade-prompt-new'
|
|
import getMeta from '@/utils/meta'
|
|
import PdfClearCacheButton from '@/features/pdf-preview/components/pdf-clear-cache-button'
|
|
import PdfDownloadFilesButton from '@/features/pdf-preview/components/pdf-download-files-button'
|
|
import RollingBuildSelectedReminder from './rolling-build-selected-reminder'
|
|
import CheckpointCompilesEnabledReminder from './checkpoint-compiles-enabled-reminder'
|
|
import ErrorAssistantAiPaywallNotification from './error-assistant-ai-paywall-notification'
|
|
|
|
type ErrorLogTab = {
|
|
key: string
|
|
label: string
|
|
entries: LogEntryData[] | undefined
|
|
}
|
|
|
|
function ErrorLogs({
|
|
includeActionButtons,
|
|
}: {
|
|
includeActionButtons?: boolean
|
|
}) {
|
|
const { error, logEntries, rawLog, validationIssues, stoppedOnFirstError } =
|
|
useCompileContext()
|
|
const { compileTimeout } = getMeta('ol-compileSettings')
|
|
const { t } = useTranslation()
|
|
|
|
const tabs = useMemo(() => {
|
|
return [
|
|
{
|
|
key: 'all',
|
|
label: t('all_logs'),
|
|
entries: logEntries?.all,
|
|
},
|
|
{ key: 'errors', label: t('errors'), entries: logEntries?.errors },
|
|
{ key: 'warnings', label: t('warnings'), entries: logEntries?.warnings },
|
|
{ key: 'info', label: t('info'), entries: logEntries?.typesetting },
|
|
]
|
|
}, [logEntries, t])
|
|
|
|
const { loadingError } = usePdfPreviewContext()
|
|
|
|
const [activeTab, setActiveTab] = useState<string | null>('all')
|
|
|
|
const changeTab = useCallback(
|
|
(key: string | null) => {
|
|
if (tabs.some(tab => tab.key === key)) {
|
|
setActiveTab(key)
|
|
}
|
|
},
|
|
[tabs]
|
|
)
|
|
|
|
const entries = useMemo(() => {
|
|
return tabs.find(tab => tab.key === activeTab)?.entries || []
|
|
}, [activeTab, tabs])
|
|
|
|
const includeErrors = activeTab === 'all' || activeTab === 'errors'
|
|
const includeWarnings = activeTab === 'all' || activeTab === 'warnings'
|
|
|
|
return (
|
|
<TabContainer onSelect={changeTab} defaultActiveKey={activeTab ?? 'all'}>
|
|
<Nav defaultActiveKey="all" className="error-logs-tabs">
|
|
{tabs.map(tab => (
|
|
<TabHeader key={tab.key} tab={tab} active={activeTab === tab.key} />
|
|
))}
|
|
</Nav>
|
|
<ErrorAssistantAiPaywallNotification />
|
|
<TabContent className="error-logs new-error-logs">
|
|
<div className="logs-pane-content">
|
|
<RollingBuildSelectedReminder />
|
|
<CheckpointCompilesEnabledReminder />
|
|
{stoppedOnFirstError && includeErrors && <StopOnFirstErrorPrompt />}
|
|
|
|
{loadingError && (
|
|
<PdfPreviewError
|
|
error="pdf-viewer-loading-error"
|
|
includeErrors={includeErrors}
|
|
includeWarnings={includeWarnings}
|
|
/>
|
|
)}
|
|
|
|
{compileTimeout < 60 && error === 'timedout' ? (
|
|
<TimeoutUpgradePromptNew />
|
|
) : (
|
|
<>{error && <PdfPreviewError error={error} />}</>
|
|
)}
|
|
|
|
{includeErrors &&
|
|
validationIssues &&
|
|
Object.entries(validationIssues).map(([name, issue]) => (
|
|
<PdfValidationIssue key={name} name={name} issue={issue} />
|
|
))}
|
|
|
|
{entries && (
|
|
<PdfLogsEntries
|
|
entries={entries}
|
|
hasErrors={
|
|
includeErrors &&
|
|
logEntries?.errors &&
|
|
logEntries?.errors.length > 0
|
|
}
|
|
/>
|
|
)}
|
|
|
|
{rawLog && activeTab === 'all' && (
|
|
<LogEntry
|
|
headerTitle={t('raw_logs')}
|
|
rawContent={rawLog}
|
|
entryAriaLabel={t('raw_logs_description')}
|
|
level="raw"
|
|
alwaysExpandRawContent
|
|
showSourceLocationLink={false}
|
|
/>
|
|
)}
|
|
|
|
{includeActionButtons && (
|
|
<div className="logs-pane-actions">
|
|
<PdfClearCacheButton />
|
|
<PdfDownloadFilesButton />
|
|
</div>
|
|
)}
|
|
</div>
|
|
</TabContent>
|
|
</TabContainer>
|
|
)
|
|
}
|
|
|
|
function formatErrorNumber(num: number | undefined) {
|
|
if (num === undefined) {
|
|
return undefined
|
|
}
|
|
|
|
if (num > 99) {
|
|
return '99+'
|
|
}
|
|
|
|
return Math.floor(num).toString()
|
|
}
|
|
|
|
const TabHeader = ({ tab, active }: { tab: ErrorLogTab; active: boolean }) => {
|
|
return (
|
|
<NavLink
|
|
eventKey={tab.key}
|
|
className="error-logs-tab-header"
|
|
active={active}
|
|
as="button"
|
|
>
|
|
{tab.label}
|
|
<div className="error-logs-tab-count">
|
|
{/* TODO: it would be nice if this number included custom errors */}
|
|
{formatErrorNumber(tab.entries?.length)}
|
|
</div>
|
|
</NavLink>
|
|
)
|
|
}
|
|
|
|
export default withErrorBoundary(memo(ErrorLogs), () => (
|
|
<PdfPreviewErrorBoundaryFallback type="logs" />
|
|
))
|