Rolling builds error logs notification (#28654)

* feat: allow for monthly tl builds experiment

* feat: add in-editor notification when rolling image has updated

* feat: add in-editor notification when rolling image has updated

* feat: allowing for different messages in experiment when user is optend in

* feat: add a banner notification in the error logs when the user is on the rolling build

* moving rolling check from context to util

* Update services/web/frontend/js/features/pdf-preview/components/rolling-build-selected-reminder.tsx

Co-authored-by: Alf Eaton <alf.eaton@overleaf.com>

---------

Co-authored-by: Alf Eaton <alf.eaton@overleaf.com>
GitOrigin-RevId: fb669db28a7194babb299413f20209e76dcbd351
This commit is contained in:
Jimmy Domagala-Tang
2025-10-10 08:06:20 +00:00
committed by Copybot
co-authored by Alf Eaton
parent 81ababb7aa
commit 0ecfc246a2
8 changed files with 93 additions and 11 deletions
@@ -17,6 +17,7 @@ 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 { useIsNewErrorLogsPositionEnabled } from '../../utils/new-editor-utils'
import RollingBuildSelectedReminder from './rolling-build-selected-reminder'
const logsComponents: Array<{
import: { default: ElementType }
@@ -85,6 +86,7 @@ function ErrorLogs({
))}
<TabContent className="error-logs new-error-logs">
<div className="logs-pane-content">
<RollingBuildSelectedReminder />
{stoppedOnFirstError && includeErrors && <StopOnFirstErrorPrompt />}
{loadingError && (
@@ -0,0 +1,33 @@
import OLNotification from '@/shared/components/ol/ol-notification'
import { useTranslation, Trans } from 'react-i18next'
import { useProjectContext } from '@/shared/context/project-context'
import { onRollingBuild } from '@/shared/utils/rolling-build'
const RollingBuildSelectedReminder = () => {
const { t } = useTranslation()
const { project } = useProjectContext()
if (!onRollingBuild(project?.imageName)) {
return null
}
const content = (
<Trans
i18nKey="please_keep_an_eye_out_for_issues"
components={[
<a href="https://forms.gle/yD8CVm4Kop9KwShx9" />, // eslint-disable-line react/jsx-key, jsx-a11y/anchor-has-content
<a href="https://docs.overleaf.com/getting-started/recompiling-your-project/selecting-a-tex-live-version-and-latex-compiler" />, // eslint-disable-line react/jsx-key, jsx-a11y/anchor-has-content
]}
/>
)
return (
<OLNotification
title={t('this_project_is_compiled_using_untested_version')}
content={content}
type="info"
className="mb-0"
/>
)
}
export default RollingBuildSelectedReminder
@@ -1,31 +1,28 @@
import { useTutorial } from '@/shared/hooks/promotions/use-tutorial'
import { useEditorContext } from '@/shared/context/editor-context'
import { useProjectSettingsContext } from '../editor-left-menu/context/project-settings-context'
import { useProjectContext } from '@/shared/context/project-context'
import OLNotification from '@/shared/components/ol/ol-notification'
import getMeta from '@/utils/meta'
import { useTranslation } from 'react-i18next'
import { useCallback } from 'react'
import { onRollingBuild } from '@/shared/utils/rolling-build'
export const TUTORIAL_KEY = 'rolling-compile-image-changed'
const rollingImages = getMeta('ol-imageNames')
.filter(img => img.rolling)
.map(img => img.imageName)
const RollingCompileImageChangedAlert = () => {
const { completeTutorial } = useTutorial(TUTORIAL_KEY)
const { project } = useProjectContext()
const { inactiveTutorials } = useEditorContext()
const { imageName } = useProjectSettingsContext()
const { t } = useTranslation()
const onClose = useCallback(() => {
completeTutorial({ event: 'promo-click', action: 'complete' })
}, [completeTutorial])
const onRollingBuild = imageName && rollingImages.includes(imageName)
if (inactiveTutorials.includes(TUTORIAL_KEY) || !onRollingBuild) {
if (
inactiveTutorials.includes(TUTORIAL_KEY) ||
!onRollingBuild(project?.imageName)
) {
return null
}
@@ -1,6 +1,7 @@
import { useTranslation } from 'react-i18next'
import { memo } from 'react'
import classnames from 'classnames'
import RollingBuildSelectedReminder from './rolling-build-selected-reminder'
import PdfValidationIssue from './pdf-validation-issue'
import StopOnFirstErrorPrompt from './stop-on-first-error-prompt'
import TimeoutUpgradePromptNew from './timeout-upgrade-prompt-new'
@@ -41,6 +42,8 @@ function PdfLogsViewer({ alwaysVisible = false }: { alwaysVisible?: boolean }) {
data-testid="logs-pane"
>
<div className="logs-pane-content">
<RollingBuildSelectedReminder />
{codeCheckFailed && <PdfCodeCheckFailedNotice />}
{stoppedOnFirstError && <StopOnFirstErrorPrompt />}
@@ -0,0 +1,33 @@
import OLNotification from '@/shared/components/ol/ol-notification'
import { useTranslation, Trans } from 'react-i18next'
import { useProjectContext } from '@/shared/context/project-context'
import { onRollingBuild } from '@/shared/utils/rolling-build'
const RollingBuildSelectedReminder = () => {
const { t } = useTranslation()
const { project } = useProjectContext()
if (!onRollingBuild(project?.imageName)) {
return null
}
const content = (
<Trans
i18nKey="please_keep_an_eye_out_for_issues"
components={[
<a href="https://forms.gle/yD8CVm4Kop9KwShx9" />, // eslint-disable-line react/jsx-key, jsx-a11y/anchor-has-content
<a href="https://docs.overleaf.com/getting-started/recompiling-your-project/selecting-a-tex-live-version-and-latex-compiler" />, // eslint-disable-line react/jsx-key, jsx-a11y/anchor-has-content
]}
/>
)
return (
<OLNotification
title={t('this_project_is_compiled_using_untested_version')}
content={content}
type="info"
/>
)
}
export default RollingBuildSelectedReminder
@@ -0,0 +1,10 @@
import getMeta from '@/utils/meta'
const images = getMeta('ol-imageNames') || []
const rollingImages = images
.filter(img => img.rolling)
.map(img => img.imageName)
export function onRollingBuild(imageName: string | undefined) {
return Boolean(imageName && rollingImages.includes(imageName))
}