Merge pull request #29495 from overleaf/dp-remove-new-logs-position

Remove error logs from new editor rail

GitOrigin-RevId: 9d0b134345b63618334c5507089debf2df104274
This commit is contained in:
David
2025-11-04 12:55:17 +00:00
committed by Copybot
parent 5140fff347
commit d48518e01d
26 changed files with 44 additions and 1065 deletions

View File

@@ -124,7 +124,6 @@
"ai_feedback_the_suggestion_wasnt_the_best_fix_available": "",
"ai_feedback_there_was_no_code_fix_suggested": "",
"alignment": "",
"all": "",
"all_borders": "",
"all_events": "",
"all_features_in_group_standard_plus": "",
@@ -257,7 +256,6 @@
"characters": "",
"chat": "",
"chat_error": "",
"check_error_logs": "",
"checking_dropbox_status": "",
"checking_project_github_status": "",
"choose_a_custom_color": "",
@@ -573,7 +571,6 @@
"equation_preview": "",
"error": "",
"error_assist": "",
"error_log": "",
"error_opening_document": "",
"error_opening_document_detail": "",
"error_performing_request": "",
@@ -620,7 +617,7 @@
"file_size": "",
"file_tree": "",
"files_cannot_include_invalid_characters": "",
"files_collaboration_integrations_logs": "",
"files_collaboration_integrations": "",
"files_selected": "",
"filter_projects": "",
"find": "",
@@ -1011,7 +1008,6 @@
"log_entry_maximum_entries": "",
"log_entry_maximum_entries_enable_stop_on_first_error": "",
"log_entry_maximum_entries_see_full_logs": "",
"log_entry_maximum_entries_see_full_logs_new": "",
"log_entry_maximum_entries_title": "",
"log_hint_extra_info": "",
"log_in": "",
@@ -1023,7 +1019,6 @@
"login_count": "",
"login_to_accept_invitation": "",
"login_with_service": "",
"logs": "",
"logs_and_output_files": "",
"looking_multiple_licenses": "",
"looks_like_youre_at": "",
@@ -1097,7 +1092,6 @@
"more_compile_time": "",
"more_editor_toolbar_item": "",
"more_info": "",
"more_logs_and_files": "",
"more_options": "",
"my_library": "",
"n_items": "",
@@ -1268,7 +1262,6 @@
"pdf_compile_in_progress_error": "",
"pdf_compile_rate_limit_hit": "",
"pdf_compile_try_again": "",
"pdf_couldnt_compile": "",
"pdf_in_separate_tab": "",
"pdf_only": "",
"pdf_only_hide_editor": "",
@@ -1376,7 +1369,6 @@
"project_timed_out_enable_stop_on_first_error": "",
"project_timed_out_fatal_error": "",
"project_timed_out_intro": "",
"project_timed_out_intro_short": "",
"project_timed_out_learn_more": "",
"project_timed_out_optimize_images": "",
"project_title_options": "",
@@ -1667,7 +1659,6 @@
"something_went_wrong_processing_the_request": "",
"something_went_wrong_rendering_pdf": "",
"something_went_wrong_rendering_pdf_expected": "",
"something_went_wrong_rendering_pdf_expected_new": "",
"something_went_wrong_server": "",
"somthing_went_wrong_compiling": "",
"sorry_it_looks_like_that_didnt_work_this_time": "",
@@ -1842,7 +1833,6 @@
"thanks_settings_updated": "",
"the_add_on_will_remain_active_until": "",
"the_code_editor_color_scheme": "",
"the_document_environment_contains_no_content_learn_about_environments": "",
"the_following_files_already_exist_in_this_project": "",
"the_following_files_and_folders_already_exist_in_this_project": "",
"the_following_folder_already_exists_in_this_project": "",
@@ -1862,7 +1852,6 @@
"then_x_price_per_month": "",
"then_x_price_per_year": "",
"there_are_lots_of_options_to_edit_and_customize_your_figures": "",
"there_is_a_latex_error_check_logs": "",
"there_was_a_problem_restoring_the_project_please_try_again_in_a_few_moments_or_contact_us": "",
"they_lose_access_to_account": "",
"they_will_be_removed_from_the_group": "",
@@ -1884,7 +1873,6 @@
"this_is_the_file_that_references_pulled_from_your_reference_manager_will_be_added_to": "",
"this_organization_is_tax_exempt": "",
"this_project_already_has_maximum_collaborators": "",
"this_project_contains_a_file_called_output_pdf": "",
"this_project_exceeded_collaborator_limit": "",
"this_project_exceeded_compile_timeout_limit_on_free_plan": "",
"this_project_has_more_than_max_collabs": "",
@@ -2175,7 +2163,6 @@
"what_should_we_call_you": "",
"whats_different": "",
"when_you_tick_the_include_caption_box": "",
"why_might_this_happen": "",
"why_not_pause_instead": "",
"wide": "",
"will_lose_edit_access_on_date": "",
@@ -2235,7 +2222,6 @@
"you_have_been_invited_to_transfer_management_of_your_account": "",
"you_have_been_invited_to_transfer_management_of_your_account_to": "",
"you_have_been_removed_from_this_project_and_will_be_redirected_to_project_dashboard": "",
"you_have_errors_the_pdf_couldnt_compile": "",
"you_have_x_licenses_and_your_plan_supports_up_to_y": "",
"you_have_x_licenses_on_your_subscription": "",
"you_need_to_configure_your_sso_settings": "",

View File

@@ -1,25 +0,0 @@
import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
import { RailIndicator } from '../rail/rail-indicator'
export default function ErrorIndicator() {
const { logEntries } = useCompileContext()
if (!logEntries) {
return null
}
const errorCount = Number(logEntries.errors?.length)
const warningCount = Number(logEntries.warnings?.length)
const totalCount = errorCount + warningCount
if (totalCount === 0) {
return null
}
return (
<RailIndicator
count={totalCount}
type={errorCount > 0 ? 'danger' : 'warning'}
/>
)
}

View File

@@ -1,98 +0,0 @@
import { useTranslation } from 'react-i18next'
import RailPanelHeader from '../rail/rail-panel-header'
import OLIconButton from '@/shared/components/ol/ol-icon-button'
import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
import {
Dropdown,
DropdownMenu,
DropdownToggle,
} from '@/shared/components/dropdown/dropdown-menu'
import PdfFileList from '@/features/pdf-preview/components/pdf-file-list'
import { forwardRef } from 'react'
import OLTooltip from '@/shared/components/ol/ol-tooltip'
export default function ErrorLogsHeader() {
const { t } = useTranslation()
return (
<RailPanelHeader
title={t('logs')}
actions={[
<DownloadFileDropdown key="download-files" />,
<ClearCacheButton key="clear-cache" />,
]}
/>
)
}
const ClearCacheButton = () => {
const { compiling, clearCache, clearingCache } = useCompileContext()
const { t } = useTranslation()
return (
<OLTooltip
id="clear-cache"
description={t('clear_cached_files')}
overlayProps={{ placement: 'bottom' }}
>
<OLIconButton
unfilled
onClick={() => clearCache()}
className="rail-panel-header-button-subdued"
icon="auto_delete"
isLoading={clearingCache}
disabled={clearingCache || compiling}
accessibilityLabel={t('clear_cached_files')}
size="sm"
/>
</OLTooltip>
)
}
const DownloadFileDropdown = () => {
const { fileList } = useCompileContext()
const { t } = useTranslation()
return (
<Dropdown align="end">
<DropdownToggle
as={DownloadFileDropdownToggleButton}
id="dropdown-files-dropdown-toggle"
>
{t('other_logs_and_files')}
</DropdownToggle>
{fileList && (
<DropdownMenu id="dropdown-files-logs-pane-list">
<PdfFileList fileList={fileList} />
</DropdownMenu>
)}
</Dropdown>
)
}
const DownloadFileDropdownToggleButton = forwardRef<
HTMLButtonElement,
{ onClick: React.MouseEventHandler }
>(function DownloadFileDropdownToggleButton({ onClick }, ref) {
const { compiling, fileList } = useCompileContext()
const { t } = useTranslation()
return (
<OLTooltip
id="more-logs-and-files"
description={t('more_logs_and_files')}
overlayProps={{ placement: 'bottom' }}
>
<OLIconButton
ref={ref}
onClick={onClick}
className="rail-panel-header-button-subdued"
icon="download"
disabled={compiling || !fileList}
accessibilityLabel={t('other_logs_and_files')}
size="sm"
/>
</OLTooltip>
)
})

View File

@@ -1,14 +0,0 @@
import { PdfPreviewProvider } from '@/features/pdf-preview/components/pdf-preview-provider'
import ErrorLogs from './error-logs'
import ErrorLogsHeader from './error-logs-header'
export default function ErrorLogsPanel() {
return (
<PdfPreviewProvider>
<div className="error-logs-panel">
<ErrorLogsHeader />
<ErrorLogs />
</div>
</PdfPreviewProvider>
)
}

View File

@@ -16,7 +16,6 @@ import TimeoutUpgradePromptNew from '@/features/pdf-preview/components/timeout-u
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'
import ClsiCachePrompt from '@/features/pdf-preview/components/clsi-cache-prompt'
@@ -39,21 +38,20 @@ function ErrorLogs({
const { error, logEntries, rawLog, validationIssues, stoppedOnFirstError } =
useCompileContext()
const { compileTimeout } = getMeta('ol-compileSettings')
const newLogsPosition = useIsNewErrorLogsPositionEnabled()
const { t } = useTranslation()
const tabs = useMemo(() => {
return [
{
key: 'all',
label: newLogsPosition ? t('all') : t('all_logs'),
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, newLogsPosition, t])
}, [logEntries, t])
const { loadingError } = usePdfPreviewContext()

View File

@@ -1,227 +0,0 @@
import OLButton from '@/shared/components/ol/ol-button'
import MaterialIcon from '@/shared/components/material-icon'
import { Trans, useTranslation } from 'react-i18next'
import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
import { useStopOnFirstError } from '@/shared/hooks/use-stop-on-first-error'
import { sendMB } from '@/infrastructure/event-tracking'
import { useCallback, useMemo } from 'react'
import ErrorState from './error-state'
import StartFreeTrialButton from '@/shared/components/start-free-trial-button'
import getMeta from '@/utils/meta'
import { populateEditorRedesignSegmentation } from '@/shared/hooks/use-editor-analytics'
import {
isNewUser,
useIsNewEditorEnabled,
} from '@/features/ide-redesign/utils/new-editor-utils'
import { getSplitTestVariant, isSplitTestEnabled } from '@/utils/splitTestUtils'
export const ShortCompileTimeoutErrorState = () => {
const { t } = useTranslation()
const { isProjectOwner } = useCompileContext()
const newEditor = useIsNewEditorEnabled()
const shouldHideCompileTimeoutInfo = isSplitTestEnabled(
'compile-timeout-remove-info'
)
const { compileTimeout } = getMeta('ol-compileSettings')
const segmentation = useMemo(
() =>
populateEditorRedesignSegmentation(
{
'is-owner': isProjectOwner,
compileTime: compileTimeout,
location: 'error-state',
},
newEditor
),
[isProjectOwner, compileTimeout, newEditor]
)
const extraSearchParams = useMemo(() => {
if (!isNewUser()) {
return undefined
}
const variant = getSplitTestVariant('editor-redesign-new-users')
if (!variant) {
return undefined
}
return {
itm_content: variant,
}
}, [])
return (
<ErrorState
title={t('your_compile_timed_out')}
description={
<>
<p>
{isProjectOwner
? t('your_project_exceeded_compile_timeout_limit_on_free_plan')
: t('this_project_exceeded_compile_timeout_limit_on_free_plan')}
</p>
{isProjectOwner ? (
<p>
<strong>{t('upgrade_for_more_compile_time')}</strong>{' '}
{t(
'plus_additional_collaborators_document_history_track_changes_and_more'
)}
</p>
) : (
<Trans
i18nKey="tell_the_project_owner_and_ask_them_to_upgrade"
components={[
// eslint-disable-next-line react/jsx-key
<strong />,
]}
/>
)}
</>
}
iconType="running_with_errors"
extraContent={
!shouldHideCompileTimeoutInfo && (
<div className="pdf-error-state-info-box">
<ReasonsForTimeoutInfo />
</div>
)
}
actions={
isProjectOwner && (
<StartFreeTrialButton
source="compile-timeout"
buttonProps={{ variant: 'premium', size: 'sm' }}
segmentation={segmentation}
extraSearchParams={extraSearchParams}
>
{t('start_a_free_trial')}
</StartFreeTrialButton>
)
}
/>
)
}
export const LongCompileTimeoutErrorState = () => {
const { t } = useTranslation()
return (
<ErrorState
title={t('your_compile_timed_out')}
description={t('project_timed_out_intro_short')}
iconType="running_with_errors"
extraContent={
<div className="pdf-error-state-info-box">
<ReasonsForTimeoutInfo />
</div>
}
/>
)
}
const ReasonsForTimeoutInfo = () => {
const { t } = useTranslation()
const { enableStopOnFirstError } = useStopOnFirstError({
eventSource: 'timeout',
})
const { startCompile, lastCompileOptions, setAnimateCompileDropdownArrow } =
useCompileContext()
const handleEnableStopOnFirstErrorClick = useCallback(() => {
enableStopOnFirstError()
startCompile({ stopOnFirstError: true })
setAnimateCompileDropdownArrow(true)
}, [enableStopOnFirstError, startCompile, setAnimateCompileDropdownArrow])
return (
<>
<div className="pdf-error-state-info-box-title">
<MaterialIcon type="info" unfilled />
{t('common_causes_of_compile_timeouts_include')}:
</div>
<div className="pdf-error-state-info-box-text">
<ul className="pdf-error-state-info-box-list">
<li>
<Trans
i18nKey="project_timed_out_optimize_images"
components={[
// eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
<a
href="https://www.overleaf.com/learn/how-to/Optimising_very_large_image_files"
onClick={() => {
sendMB('paywall-info-click', {
'paywall-type': 'compile-timeout',
content: 'docs',
type: 'optimize',
})
}}
/>,
]}
/>
</li>
<li>
<Trans
i18nKey="a_fatal_compile_error_that_completely_blocks_compilation"
components={[
// eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
<a
href="https://www.overleaf.com/learn/how-to/Why_do_I_keep_getting_the_compile_timeout_error_message%3F#Fatal_compile_errors_blocking_the_compilation"
onClick={() => {
sendMB('paywall-info-click', {
'paywall-type': 'compile-timeout',
content: 'docs',
type: 'fatal-error',
})
}}
/>,
]}
/>
{!lastCompileOptions.stopOnFirstError && (
<>
{' '}
<Trans
i18nKey="enable_stop_on_first_error_under_recompile_dropdown_menu"
components={[
// eslint-disable-next-line react/jsx-key
<OLButton
variant="link"
className="btn-inline-link fw-bold"
size="sm"
onClick={handleEnableStopOnFirstErrorClick}
/>,
// eslint-disable-next-line react/jsx-key
<strong />,
]}
/>
</>
)}
</li>
</ul>
<p className="mb-0">
<Trans
i18nKey="project_timed_out_learn_more"
components={[
// eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
<a
href="/learn/how-to/Fixing_and_preventing_compile_timeouts"
rel="noopener noreferrer"
target="_blank"
onClick={() => {
sendMB('paywall-info-click', {
'paywall-type': 'compile-timeout',
content: 'docs',
type: 'learn-more',
})
}}
/>,
]}
/>
</p>
</div>
</>
)
}

View File

@@ -1,65 +0,0 @@
import { useRailContext } from '@/features/ide-redesign/contexts/rail-context'
import { sendMB } from '@/infrastructure/event-tracking'
import MaterialIcon from '@/shared/components/material-icon'
import OLButton from '@/shared/components/ol/ol-button'
import classNames from 'classnames'
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
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>
{description && (
<p className="pdf-error-state-description">{description}</p>
)}
</div>
{actions}
</div>
{extraContent}
</div>
)
}
export const CheckLogsButton = () => {
const { t } = useTranslation()
const { openTab: openRailTab } = useRailContext()
const { error } = useCompileContext()
const onClick = useCallback(() => {
openRailTab('errors')
sendMB('check-logs-click', { error })
}, [openRailTab, error])
return (
<OLButton variant="secondary" size="sm" onClick={onClick}>
{t('check_error_logs')}
</OLButton>
)
}

View File

@@ -1,64 +0,0 @@
import { Trans, useTranslation } from 'react-i18next'
import ErrorState, { CheckLogsButton } from './error-state'
import MaterialIcon from '@/shared/components/material-icon'
import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
export default function GeneralErrorState() {
const { logEntries } = useCompileContext()
const hasErrors = (logEntries?.errors?.length || 0) > 0
if (hasErrors) {
return <GeneralErrorStateWithErrors />
}
return <GeneralErrorStateWithoutErrors />
}
function GeneralErrorStateWithErrors() {
const { t } = useTranslation()
return (
<ErrorState
title={t('you_have_errors_the_pdf_couldnt_compile')}
actions={<CheckLogsButton />}
/>
)
}
function GeneralErrorStateWithoutErrors() {
const { t } = useTranslation()
return (
<ErrorState
title={t('pdf_couldnt_compile')}
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_a_latex_error_check_logs')}</li>
<li>
<Trans
i18nKey="the_document_environment_contains_no_content_learn_about_environments"
components={[
/* eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key */
<a
href="/learn/latex/Environments"
target="_blank"
rel="noopener noreferrer"
/>,
]}
/>
</li>
<li>{t('this_project_contains_a_file_called_output_pdf')}</li>
</ul>
</div>
</div>
}
/>
)
}

View File

@@ -1,148 +0,0 @@
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'
import RenderingErrorExpectedState from './rendering-error-expected-state'
import RenderingErrorState from './rendering-error-state'
import getMeta from '@/utils/meta'
// 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 { error, showLogs } = useCompileContext()
const { compileTimeout } = getMeta('ol-compileSettings')
const newEditor = useIsNewEditorEnabled()
const { t } = useTranslation()
if (!newEditor || (!loadingError && !showLogs)) {
return null
}
switch (error) {
case 'timedout': {
if (compileTimeout < 60) {
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" />,
]}
/>
}
/>
)
case 'rendering-error-expected':
return <RenderingErrorExpectedState />
case 'rendering-error':
return <RenderingErrorState />
default:
return <GeneralErrorState />
}
}
export default PdfErrorState

View File

@@ -1,36 +0,0 @@
import { Trans, useTranslation } from 'react-i18next'
import ErrorState from './error-state'
import OLButton from '@/shared/components/ol/ol-button'
import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
import ClsiCachePrompt from '@/features/pdf-preview/components/clsi-cache-prompt'
export default function RenderingErrorExpectedState() {
const { t } = useTranslation()
const { startCompile } = useCompileContext()
return (
<ErrorState
title={t('pdf_rendering_error')}
description={
<Trans
i18nKey="something_went_wrong_rendering_pdf_expected_new"
components={[
// 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"
/>,
]}
/>
}
actions={
<OLButton variant="primary" size="sm" onClick={() => startCompile()}>
{t('recompile')}
</OLButton>
}
extraContent={<ClsiCachePrompt />}
/>
)
}

View File

@@ -1,55 +0,0 @@
import { Trans, useTranslation } from 'react-i18next'
import ErrorState from './error-state'
import getMeta from '@/utils/meta'
export default function RenderingErrorState() {
const { t } = useTranslation()
return (
<ErrorState
title={t('pdf_rendering_error')}
description={
<>
{t('something_went_wrong_rendering_pdf')}
&nbsp;
<Trans
i18nKey="try_recompile_project_or_troubleshoot"
components={[
// 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"
/>,
]}
/>
{getMeta('ol-compilesUserContentDomain') && (
<>
<br />
<br />
<Trans
i18nKey="new_compile_domain_notice"
values={{
compilesUserContentDomain: new URL(
getMeta('ol-compilesUserContentDomain')
).hostname,
}}
shouldUnescape
tOptions={{ interpolation: { escapeValue: true } }}
components={[
<code key="domain" />,
/* 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"
/>,
]}
/>
</>
)}
</>
}
/>
)
}

View File

@@ -6,11 +6,9 @@ import PdfHybridDownloadButton from '@/features/pdf-preview/components/pdf-hybri
import { DetachedSynctexControl } from '@/features/pdf-preview/components/detach-synctex-control'
import SwitchToEditorButton from '@/features/pdf-preview/components/switch-to-editor-button'
import PdfHybridLogsButton from '@/features/pdf-preview/components/pdf-hybrid-logs-button'
import { useIsNewErrorLogsPositionEnabled } from '../../utils/new-editor-utils'
function PdfPreviewHybridToolbar() {
const { t } = useTranslation()
const newErrorLogsPosition = useIsNewErrorLogsPositionEnabled()
// TODO: add detached pdf logic
return (
@@ -20,7 +18,7 @@ function PdfPreviewHybridToolbar() {
>
<div className="toolbar-pdf-left">
<PdfCompileButton />
{!newErrorLogsPosition && <PdfHybridLogsButton />}
<PdfHybridLogsButton />
<PdfHybridDownloadButton />
</div>
<div className="toolbar-pdf-right">

View File

@@ -36,7 +36,7 @@ export default function RailPanel({
id={`ide-redesign-sidebar-panel-${isHistoryView ? 'file-tree' : selectedTab}`}
className={classNames({ hidden: isReviewPanelOpen })}
order={1}
defaultSize={selectedTab === 'errors' ? 20 : 15}
defaultSize={15}
minSize={5}
maxSize={80}
ref={panelRef}

View File

@@ -1,8 +1,7 @@
import { useCallback, useMemo } from 'react'
import { useCallback, useEffect, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { Nav, TabContainer } from 'react-bootstrap'
import { useLayoutContext } from '@/shared/context/layout-context'
import ErrorIndicator from '../error-logs/error-indicator'
import { RailTabKey, useRailContext } from '../../contexts/rail-context'
import FileTreeOutlinePanel from '../file-tree/file-tree-outline-panel'
import { ChatIndicator, ChatPane } from '../chat/chat'
@@ -16,8 +15,6 @@ import {
hasFullProjectSearch,
} from '../full-project-search-panel'
import { sendSearchEvent } from '@/features/event-tracking/search-events'
import ErrorLogsPanel from '../error-logs/error-logs-panel'
import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
import { useProjectContext } from '@/shared/context/project-context'
import { useCommandProvider } from '@/features/ide-react/hooks/use-command-provider'
import RailHelpDropdown from './rail-help-dropdown'
@@ -29,15 +26,12 @@ import RailResizeHandle from './rail-resize-handle'
import RailModals from './rail-modals'
import RailOverflowDropdown from './rail-overflow-dropdown'
import useRailOverflow from '../../hooks/use-rail-overflow'
import { useIsNewErrorLogsPositionEnabled } from '../../utils/new-editor-utils'
export const RailLayout = () => {
const { sendEvent } = useEditorAnalytics()
const { t } = useTranslation()
const { selectedTab, openTab, isOpen, togglePane } = useRailContext()
const { logEntries } = useCompileContext()
const { features } = useProjectContext()
const errorLogsDisabled = !logEntries
const { view, setLeftMenuShown } = useLayoutContext()
@@ -45,8 +39,6 @@ export const RailLayout = () => {
const isHistoryView = view === 'history'
const newErrorlogsPosition = useIsNewErrorLogsPositionEnabled()
const railTabs: RailElement[] = useMemo(
() => [
{
@@ -87,23 +79,8 @@ export const RailLayout = () => {
title: t('chat'),
hide: !getMeta('ol-capabilities')?.includes('chat'),
},
{
key: 'errors',
icon: 'report',
title: t('error_log'),
component: <ErrorLogsPanel />,
indicator: <ErrorIndicator />,
disabled: errorLogsDisabled,
hide: !newErrorlogsPosition,
},
],
[
t,
features.trackChangesVisible,
newErrorlogsPosition,
errorLogsDisabled,
view,
]
[t, features.trackChangesVisible, view]
)
const railActions: RailAction[] = useMemo(
@@ -172,6 +149,15 @@ export const RailLayout = () => {
[openTab, togglePane, selectedTab, railTabs, sendEvent, markMessagesAsRead]
)
useEffect(() => {
const validTabKeys = railTabs.filter(tab => !tab.hide).map(tab => tab.key)
if (!validTabKeys.includes(selectedTab) && isOpen) {
// If the selected tab is no longer valid (e.g. due to permissions changes),
// switch back to the file tree
openTab('file-tree')
}
}, [railTabs, selectedTab, openTab, isOpen])
const isReviewPanelOpen =
selectedTab === 'review-panel' && isOpen && !isHistoryView
@@ -208,7 +194,7 @@ export const RailLayout = () => {
Therefore, we nest them: the parent <nav> is the landmark, and its child gets the "role="tablist"". */}
<nav
className={classNames('ide-rail', { hidden: isHistoryView })}
aria-label={t('files_collaboration_integrations_logs')}
aria-label={t('files_collaboration_integrations')}
>
<Nav activeKey={selectedTab} className="ide-rail-tabs-nav">
<div className="ide-rail-tabs-wrapper" ref={tabWrapperRef}>

View File

@@ -22,7 +22,6 @@ export type RailTabKey =
| 'integrations'
| 'review-panel'
| 'chat'
| 'errors'
| 'full-project-search'
export type RailModalKey = 'keyboard-shortcuts' | 'contact-us' | 'dictionary'

View File

@@ -41,16 +41,6 @@ export const canUseNewEditor = () => {
)
}
const canUseNewLogsPosition = () => {
const newUserTestVariant = getSplitTestVariant('editor-redesign-new-users')
const canUseNewLogsViaNewUserFeatureFlag =
isNewUser() && newUserTestVariant === 'new-editor'
return (
canUseNewEditorViaPrimaryFeatureFlag() || canUseNewLogsViaNewUserFeatureFlag
)
}
const canUseNewLogs = () => {
const newUserTestVariant = getSplitTestVariant('editor-redesign-new-users')
const canUseNewLogsViaNewUserFeatureFlag =
@@ -77,11 +67,6 @@ export const useIsNewEditorEnabled = () => {
return hasAccess && enabled
}
export const useIsNewErrorLogsPositionEnabled = () => {
const newEditorEnabled = useIsNewEditorEnabled()
return newEditorEnabled && canUseNewLogsPosition()
}
export const useAreNewErrorLogsEnabled = () => {
const newEditorEnabled = useIsNewEditorEnabled()
return newEditorEnabled && canUseNewLogs()
@@ -90,9 +75,7 @@ export const useAreNewErrorLogsEnabled = () => {
export function useNewEditorVariant() {
const newEditor = useIsNewEditorEnabled()
const newErrorLogs = useAreNewErrorLogsEnabled()
const newErrorLogsPosition = useIsNewErrorLogsPositionEnabled()
if (!newEditor) return 'default'
if (!newErrorLogs) return 'new-editor-old-logs'
if (!newErrorLogsPosition) return 'new-editor-new-logs-old-position'
return 'new-editor'
return 'new-editor-new-logs-old-position'
}

View File

@@ -9,11 +9,9 @@ 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/pdf-error-state'
import {
useAreNewErrorLogsEnabled,
useIsNewEditorEnabled,
useIsNewErrorLogsPositionEnabled,
} 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'
@@ -29,7 +27,6 @@ function PdfPreviewPane() {
})
const newEditor = useIsNewEditorEnabled()
const newErrorLogs = useAreNewErrorLogsEnabled()
const newErrorLogsPosition = useIsNewErrorLogsPositionEnabled()
const pdfPromotions = importOverleafModules('pdfPreviewPromotions') as {
import: { default: ElementType }
@@ -54,13 +51,7 @@ function PdfPreviewPane() {
<ClsiCachePrompt />
</div>
</Suspense>
{newErrorLogsPosition ? (
<PdfErrorState />
) : newErrorLogs ? (
<NewPdfLogsViewer />
) : (
<PdfLogsViewer />
)}
{newErrorLogs ? <NewPdfLogsViewer /> : <PdfLogsViewer />}
{pdfPromotions.map(({ import: { default: Component }, path }) => (
<Component key={path} />
))}

View File

@@ -11,7 +11,6 @@ import { populateEditorRedesignSegmentation } from '@/shared/hooks/use-editor-an
import {
isNewUser,
useIsNewEditorEnabled,
useIsNewErrorLogsPositionEnabled,
} from '@/features/ide-redesign/utils/new-editor-utils'
import { getSplitTestVariant, isSplitTestEnabled } from '@/utils/splitTestUtils'
@@ -81,8 +80,6 @@ const CompileTimeout = memo(function CompileTimeout({
segmentation,
}: CompileTimeoutProps) {
const { t } = useTranslation()
const newLogsPosition = useIsNewErrorLogsPositionEnabled()
const extraSearchParams = useMemo(() => {
if (!isNewUser()) {
return undefined
@@ -101,7 +98,7 @@ const CompileTimeout = memo(function CompileTimeout({
return (
<PdfLogEntry
autoExpand={!newLogsPosition}
autoExpand
headerTitle={t('your_compile_timed_out')}
formattedContent={
getMeta('ol-ExposedSettings').enableSubscriptions && (
@@ -160,11 +157,10 @@ const PreventTimeoutHelpMessage = memo(function PreventTimeoutHelpMessage({
handleEnableStopOnFirstErrorClick,
}: PreventTimeoutHelpMessageProps) {
const { t } = useTranslation()
const newLogsPosition = useIsNewErrorLogsPositionEnabled()
return (
<PdfLogEntry
autoExpand={!newLogsPosition}
autoExpand
headerTitle={t('reasons_for_compile_timeouts')}
formattedContent={
<>

View File

@@ -1,10 +1,6 @@
import { useCallback } from 'react'
import { useLayoutContext } from '@/shared/context/layout-context'
import {
useAreNewErrorLogsEnabled,
useIsNewErrorLogsPositionEnabled,
} from '@/features/ide-redesign/utils/new-editor-utils'
import { useRailContext } from '@/features/ide-redesign/contexts/rail-context'
import { useAreNewErrorLogsEnabled } from '@/features/ide-redesign/utils/new-editor-utils'
import { useEditorContext } from '@/shared/context/editor-context'
import useEventListener from '@/shared/hooks/use-event-listener'
@@ -23,8 +19,6 @@ function scrollIntoView(element: Element) {
export const useLogEvents = (setShowLogs: (show: boolean) => void) => {
const { pdfLayout, setView } = useLayoutContext()
const newLogs = useAreNewErrorLogsEnabled()
const newLogsPosition = useIsNewErrorLogsPositionEnabled()
const { openTab: openRailTab } = useRailContext()
const { hasPremiumSuggestion } = useEditorContext()
const selectLogOldLogs = useCallback((id: string, suggestFix: boolean) => {
@@ -103,11 +97,7 @@ export const useLogEvents = (setShowLogs: (show: boolean) => void) => {
[hasPremiumSuggestion]
)
const openNewLogsPosition = useCallback(() => {
openRailTab('errors')
}, [openRailTab])
const openOldLogsPosition = useCallback(() => {
const openLogs = useCallback(() => {
setShowLogs(true)
if (pdfLayout === 'flat') {
@@ -125,11 +115,7 @@ export const useLogEvents = (setShowLogs: (show: boolean) => void) => {
}>
).detail
if (newLogsPosition) {
openNewLogsPosition()
} else {
openOldLogsPosition()
}
openLogs()
if (newLogs) {
selectLogNewLogs(
@@ -141,14 +127,7 @@ export const useLogEvents = (setShowLogs: (show: boolean) => void) => {
selectLogOldLogs(id, Boolean(suggestFix))
}
},
[
openNewLogsPosition,
openOldLogsPosition,
selectLogNewLogs,
selectLogOldLogs,
newLogs,
newLogsPosition,
]
[openLogs, selectLogNewLogs, selectLogOldLogs, newLogs]
)
useEventListener(

View File

@@ -5,7 +5,6 @@ import { useDetachCompileContext as useCompileContext } from '../../../shared/co
import { useStopOnFirstError } from '../../../shared/hooks/use-stop-on-first-error'
import MaterialIcon from '@/shared/components/material-icon'
import PdfLogEntry from '@/features/pdf-preview/components/pdf-log-entry'
import { useIsNewErrorLogsPositionEnabled } from '@/features/ide-redesign/utils/new-editor-utils'
function PreviewLogsPaneMaxEntries({
totalEntries,
@@ -40,7 +39,6 @@ function PreviewLogsPaneMaxEntriesContent({
}: {
hasErrors?: boolean
}) {
const newLogsPosition = useIsNewErrorLogsPositionEnabled()
const { t } = useTranslation()
const { startCompile, stoppedOnFirstError, setAnimateCompileDropdownArrow } =
useCompileContext()
@@ -78,11 +76,7 @@ function PreviewLogsPaneMaxEntriesContent({
]}
/>{' '}
</p>
<p>
{newLogsPosition
? t('log_entry_maximum_entries_see_full_logs_new')
: t('log_entry_maximum_entries_see_full_logs')}
</p>
<p>{t('log_entry_maximum_entries_see_full_logs')}</p>
</>
)
}
@@ -92,9 +86,7 @@ function PreviewLogsPaneMaxEntriesContent({
<MaterialIcon type="lightbulb" className="align-middle" />
&nbsp;
<strong>{t('tip')}: </strong>
{newLogsPosition
? t('log_entry_maximum_entries_see_full_logs_new')
: t('log_entry_maximum_entries_see_full_logs')}
{t('log_entry_maximum_entries_see_full_logs')}
</p>
)
}

View File

@@ -1,95 +0,0 @@
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/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'
export default {
title: 'Editor / PDF Error States',
component: PdfErrorState,
}
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',
'rendering-error-expected',
'rendering-error',
'success',
'terminated',
'timedout',
'too-recently-compiled',
'unavailable',
'validation-problems',
'foo',
] as const
const ErrorPane = ({ error }: { error: (typeof compileErrors)[number] }) => {
window.metaAttributesCache.set('ol-splitTestVariants', {
'editor-redesign': 'enabled',
})
useFetchMock(fetchMock => {
mockCompile(fetchMock)
})
const { setError } = useCompileContext()
useEffect(() => {
setError(error)
}, [setError, error])
return (
<div className="ide-redesign-main">
<span style={{ fontFamily: 'monospace' }}>{error}</span>
<PdfPreview />
</div>
)
}
const story = {
render: (args: { error: (typeof compileErrors)[number] }) => {
return <ErrorPane error={args.error} />
},
argTypes: {
error: {
options: compileErrors,
control: {
type: 'select',
},
},
},
args: {
error: compileErrors[0],
},
}
export const PremiumUser = {
...story,
decorators: [ScopeDecorator],
}
export const FreeUser = {
...story,
decorators: [
(Story: any) =>
ScopeDecorator(
Story,
{ mockCompileOnLoad: false },
{
'ol-user': {
...user,
features: { ...user.features, compileTimeout: 20 },
},
}
),
],
}

View File

@@ -27,7 +27,6 @@
@import 'editor/write-and-cite';
@import 'subscription';
@import 'editor/pdf';
@import 'editor/pdf-error-state';
@import 'editor/compile-button';
@import 'editor/publish-modal';
@import 'editor/share';

View File

@@ -9,12 +9,6 @@
.ide-redesign-main {
--logs-pane-bg: var(--bg-primary-themed);
.error-logs-panel {
display: flex;
flex-direction: column;
height: 100%;
}
// TODO $ide-redesign-cleanup: Unnest everything from inside .error-logs
// when we remove the styles for the old pane
.error-logs {

View File

@@ -1,91 +0,0 @@
.pdf-error-state {
overflow-y: auto;
position: absolute;
inset: var(--toolbar-small-height) 0 0 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
justify-content: safe center;
padding: var(--spacing-06);
background-color: var(--pdf-bg);
}
.pdf-error-state-top-section {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--spacing-06);
padding: 0 var(--spacing-09) var(--spacing-09) var(--spacing-09);
}
.pdf-error-state-icon {
color: var(--content-primary-themed);
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 100%;
.material-symbols {
font-size: 80px;
}
&.pdf-error-state-warning-icon {
background-color: var(--bg-danger-03);
color: var(--content-danger);
.material-symbols {
font-size: 32px;
}
}
}
.pdf-error-state-text {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--spacing-02);
}
.pdf-error-state-label {
font-size: var(--font-size-02);
color: var(--content-primary-themed);
font-weight: 600;
margin-bottom: 0;
}
.pdf-error-state-description {
color: var(--content-secondary-themed);
font-size: var(--font-size-02);
margin-bottom: 0;
}
.pdf-error-state-info-box {
background-color: var(--bg-primary-themed);
color: var(--content-primary-themed);
padding: var(--spacing-06);
border: 1px solid var(--border-divider-themed);
border-radius: var(--border-radius-base);
font-size: var(--font-size-02);
line-height: var(--line-height-02);
@include themed-links;
}
.pdf-error-state-info-box-title {
font-weight: 600;
display: flex;
align-items: center;
gap: var(--spacing-02);
margin-bottom: var(--spacing-04);
}
.pdf-error-state-info-box-list {
margin-bottom: 0;
li + li {
margin-top: var(--spacing-02);
}
}

View File

@@ -325,7 +325,6 @@
"chat": "Chat",
"chat_error": "Could not load chat messages, please try again.",
"chat_with_sales_team_50_or_more": "Chat with our sales team about larger discounts for groups of 50 or more.",
"check_error_logs": "Check error logs",
"check_your_email": "Check your email",
"checking": "Checking",
"checking_dropbox_status": "Checking Dropbox status",
@@ -726,7 +725,6 @@
"equation_preview": "Equation preview",
"error": "Error",
"error_assist": "Error Assist",
"error_log": "Error log",
"error_opening_document": "Error opening document",
"error_opening_document_detail": "Sorry, something went wrong opening this document. Please try again.",
"error_performing_request": "An error has occurred while performing your request.",
@@ -796,7 +794,6 @@
"file_too_large": "File too large",
"file_tree": "File tree",
"files_cannot_include_invalid_characters": "File name is empty or contains invalid characters",
"files_collaboration_integrations_logs": "Files, collaboration, integrations, error logs",
"files_selected": "files selected.",
"filter_projects": "Filter projects",
"filters": "Filters",
@@ -1293,7 +1290,6 @@
"log_entry_maximum_entries": "Maximum log entries limit hit",
"log_entry_maximum_entries_enable_stop_on_first_error": "Try to fix the first error and recompile. Often one error causes many later error messages. You can <0>Enable “Stop on first error”</0> to focus on fixing errors. We recommend fixing errors as soon as possible; letting them accumulate may lead to hard-to-debug and fatal errors. <1>Learn more</1>",
"log_entry_maximum_entries_see_full_logs": "If you need to see the full logs, you can still download them or view the raw logs below.",
"log_entry_maximum_entries_see_full_logs_new": "If you need to see the full logs, you can still view the raw logs at the bottom of this pane or download them using the button at the top.",
"log_entry_maximum_entries_title": "__total__ log messages total. Showing the first __displayed__",
"log_hint_extra_info": "Learn more",
"log_in": "Log in",
@@ -1413,7 +1409,6 @@
"more_compile_time": "More compile time",
"more_editor_toolbar_item": "More editor toolbar items",
"more_info": "More Info",
"more_logs_and_files": "More logs and files",
"more_options": "More options",
"more_project_collaborators": "<0>More</0> project <0>collaborators</0>",
"more_than_one_kind_of_snippet_was_requested": "The link to open this content on Overleaf included some invalid parameters. If this keeps happening for links on a particular site, please report this to them.",
@@ -1652,7 +1647,6 @@
"pdf_compile_in_progress_error": "A previous compile is still running. Please wait a minute and try compiling again.",
"pdf_compile_rate_limit_hit": "Compile rate limit hit",
"pdf_compile_try_again": "Please wait for your other compile to finish before trying again.",
"pdf_couldnt_compile": "PDF couldnt compile",
"pdf_in_separate_tab": "PDF in separate tab",
"pdf_only": "PDF only",
"pdf_only_hide_editor": "PDF only <0>(hide editor)</0>",
@@ -1788,7 +1782,6 @@
"project_timed_out_enable_stop_on_first_error": "<0>Enable “Stop on first error”</0> to help you find and fix errors right away.",
"project_timed_out_fatal_error": "A <0>fatal compile error</0> may be completely blocking compilation.",
"project_timed_out_intro": "Sorry, your compile took too long to run and timed out. The most common causes of timeouts are:",
"project_timed_out_intro_short": "Sorry, your compile took too long to run and timed out",
"project_timed_out_learn_more": "<0>Learn more</0> about other causes of compile timeouts and how to fix them.",
"project_timed_out_optimize_images": "Large or high-resolution images are taking too long to process. You may be able to <0>optimize them</0>.",
"project_too_large": "Project too large",
@@ -2140,7 +2133,6 @@
"something_went_wrong_processing_the_request": "Something went wrong processing the request",
"something_went_wrong_rendering_pdf": "Something went wrong while rendering this PDF.",
"something_went_wrong_rendering_pdf_expected": "There was an issue displaying this PDF. <0>Please recompile</0>",
"something_went_wrong_rendering_pdf_expected_new": "There was an issue displaying this PDF. Please recompile. If that doesnt help, follow our <0>troubleshooting guide</0>.",
"something_went_wrong_server": "Something went wrong. Please try again.",
"somthing_went_wrong_compiling": "Sorry, something went wrong and your project could not be compiled. Please try again in a few moments.",
"sorry_detected_sales_restricted_region": "Sorry, weve detected that you are in a region from which we cannot presently accept payments. If you think youve received this message in error, please <a href=\"__link__\">contact us</a> with details of your location, and we will look into this for you. We apologize for the inconvenience.",
@@ -2351,7 +2343,6 @@
"thanks_settings_updated": "Thanks, your settings have been updated.",
"the_add_on_will_remain_active_until": "The add-on will remain active until the end of the current billing period.",
"the_code_editor_color_scheme": "The code editor color scheme",
"the_document_environment_contains_no_content_learn_about_environments": "The document environment contains no content. <0>Learn about environments</0>.",
"the_file_supplied_is_of_an_unsupported_type ": "The link to open this content on Overleaf pointed to the wrong kind of file. Valid file types are .tex documents and .zip files. If this keeps happening for links on a particular site, please report this to them.",
"the_following_files_already_exist_in_this_project": "The following files already exist in this project:",
"the_following_files_and_folders_already_exist_in_this_project": "The following files and folders already exist in this project:",
@@ -2378,7 +2369,6 @@
"then_x_price_per_month": "Then __price__ per month",
"then_x_price_per_year": "Then __price__ per year",
"there_are_lots_of_options_to_edit_and_customize_your_figures": "There are lots of options to edit and customize your figures, such as wrapping text around the figure, rotating the image, or including multiple images in a single figure. Youll need to edit the LaTeX code to do this. <0>Find out how</0>",
"there_is_a_latex_error_check_logs": "There is a LaTeX error. Check the error logs and fix any errors.",
"there_was_a_problem_restoring_the_project_please_try_again_in_a_few_moments_or_contact_us": "There was a problem restoring the project. Please try again in a few moments. Contact us if the problem persists.",
"there_was_an_error_opening_your_content": "There was an error creating your project",
"thesis": "Thesis",
@@ -2403,7 +2393,6 @@
"this_is_your_template": "This is your template from your project",
"this_organization_is_tax_exempt": "This organization is tax exempt",
"this_project_already_has_maximum_collaborators": "This project already has the maximum number of collaborators permitted on the owners plan. This means you can view but not edit or review the project.",
"this_project_contains_a_file_called_output_pdf": "The project contains a file called output.pdf. If that file exists, rename it.",
"this_project_exceeded_collaborator_limit": "This project exceeded the collaborator limit for your plan. All other users now have view-only access.",
"this_project_exceeded_compile_timeout_limit_on_free_plan": "This project exceeded the compile timeout limit on our free plan.",
"this_project_has_more_than_max_collabs": "This project has more than the maximum number of collaborators allowed on the project owners Overleaf plan. This means you could lose edit access from __linkSharingDate__.",
@@ -2720,7 +2709,6 @@
"when_you_join_labs": "When you join Labs, you can choose which experiments you want to be part of. Once youve done that, you can use Overleaf as normal, but youll see any labs features marked with this badge:",
"when_you_tick_the_include_caption_box": "When you tick the box “Include caption” the image will be inserted into your document with a placeholder caption. To edit it, you simply select the placeholder text and type to replace it with your own.",
"why_latex": "Why LaTeX?",
"why_might_this_happen": "Why might this happen?",
"why_not_pause_instead": "Pause instead, to pick up where you left off",
"wide": "Wide",
"will_lose_edit_access_on_date": "Will lose edit access on __date__",
@@ -2788,7 +2776,6 @@
"you_have_been_invited_to_transfer_management_of_your_account": "You have been invited to transfer management of your account.",
"you_have_been_invited_to_transfer_management_of_your_account_to": "You have been invited to transfer management of your account to __groupName__.",
"you_have_been_removed_from_this_project_and_will_be_redirected_to_project_dashboard": "You have been removed from this project, and will no longer have access to it. You will be redirected to your project dashboard momentarily.",
"you_have_errors_the_pdf_couldnt_compile": "You have errors. The PDF couldnt compile.",
"you_have_x_licenses_and_your_plan_supports_up_to_y": "You have allocated __addedUsersSize__ licenses and your plan supports up to __groupSize__.",
"you_have_x_licenses_on_your_subscription": "You have __groupSize__ licenses on your subscription.",
"you_need_to_configure_your_sso_settings": "You need to configure and test your SSO settings before enabling SSO",

View File

@@ -7,15 +7,24 @@ import { useNewEditorVariant } from '@/features/ide-redesign/utils/new-editor-ut
describe('new-editor-utils', function () {
describe('useNewEditorVariant', function () {
const newEditorVariants = [
'default',
'new-editor',
'new-editor-old-logs',
'new-editor-new-logs-old-position',
{ splitTestVariant: 'default', uiVariant: 'default' },
{
splitTestVariant: 'new-editor',
uiVariant: 'new-editor-new-logs-old-position',
},
{
splitTestVariant: 'new-editor-old-logs',
uiVariant: 'new-editor-old-logs',
},
{
splitTestVariant: 'new-editor-new-logs-old-position',
uiVariant: 'new-editor-new-logs-old-position',
},
]
for (const variant of newEditorVariants) {
it(`forwards ?editor-redesign-new-users=${variant}`, function () {
window.metaAttributesCache.set('ol-splitTestVariants', {
'editor-redesign-new-users': variant,
'editor-redesign-new-users': variant.splitTestVariant,
})
const scope = mockScope()
@@ -30,13 +39,13 @@ describe('new-editor-utils', function () {
</EditorProviders>
),
})
expect(result.current).to.equal(variant)
expect(result.current).to.equal(variant.uiVariant)
})
}
for (const variant of newEditorVariants) {
it(`ignores ?editor-redesign-new-users=${variant} when disabled by user`, function () {
window.metaAttributesCache.set('ol-splitTestVariants', {
'editor-redesign-new-users': variant,
'editor-redesign-new-users': variant.splitTestVariant,
})
const scope = mockScope()
@@ -71,7 +80,7 @@ describe('new-editor-utils', function () {
</EditorProviders>
),
})
expect(result.current).to.equal('new-editor')
expect(result.current).to.equal('new-editor-new-logs-old-position')
})
})
})