mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-15 06:33:55 +01:00
Implement test to reduce compile timeout to 20 seconds (#14705)
Compile timeout reduction to 20s for treatment users Co-authored-by: Rebeka <rebeka.dekany@overleaf.com> GitOrigin-RevId: 54f70fe4b1fc631cef966deb0c1d28c904dd3a44
This commit is contained in:
committed by
Copybot
co-authored by
Rebeka
parent
d04a1d3767
commit
31cb9e336b
@@ -3,6 +3,7 @@
|
||||
"1_4_width": "",
|
||||
"3_4_width": "",
|
||||
"a_custom_size_has_been_used_in_the_latex_code": "",
|
||||
"a_fatal_compile_error_that_completely_blocks_compilation": "",
|
||||
"a_file_with_that_name_already_exists_and_will_be_overriden": "",
|
||||
"a_more_comprehensive_list_of_keyboard_shortcuts": "",
|
||||
"about_to_archive_projects": "",
|
||||
@@ -63,6 +64,7 @@
|
||||
"also": "",
|
||||
"an_email_has_already_been_sent_to": "",
|
||||
"an_error_occurred_when_verifying_the_coupon_code": "",
|
||||
"and_you_can_upgrade_for_plenty_more_compile_time": "",
|
||||
"anonymous": "",
|
||||
"anyone_with_link_can_edit": "",
|
||||
"anyone_with_link_can_view": "",
|
||||
@@ -102,6 +104,7 @@
|
||||
"browser": "",
|
||||
"bulk_accept_confirm": "",
|
||||
"bulk_reject_confirm": "",
|
||||
"but_note_that_free_compile_timeout_limit_will_be_reduced_on_x_date": "",
|
||||
"by_subscribing_you_agree_to_our_terms_of_service": "",
|
||||
"can_edit": "",
|
||||
"can_link_institution_email_acct_to_institution_acct": "",
|
||||
@@ -167,6 +170,7 @@
|
||||
"comment": "",
|
||||
"commit": "",
|
||||
"common": "",
|
||||
"common_causes_of_compile_timeouts_are": "",
|
||||
"commons_plan_tooltip": "",
|
||||
"compact": "",
|
||||
"company_name": "",
|
||||
@@ -177,6 +181,7 @@
|
||||
"compile_larger_projects": "",
|
||||
"compile_mode": "",
|
||||
"compile_terminated_by_user": "",
|
||||
"compile_timeout_will_be_reduced_project_exceeds_limit_speed_up_compile": "",
|
||||
"compiler": "",
|
||||
"compiling": "",
|
||||
"configure_sso": "",
|
||||
@@ -311,6 +316,7 @@
|
||||
"emails_and_affiliations_explanation": "",
|
||||
"emails_and_affiliations_title": "",
|
||||
"enable_managed_users": "",
|
||||
"enable_stop_on_first_error_under_recompile_dropdown_menu": "",
|
||||
"enabled_managed_users_set_up_sso": "",
|
||||
"enabling": "",
|
||||
"end_of_document": "",
|
||||
@@ -549,6 +555,7 @@
|
||||
"labs_program_already_participating": "",
|
||||
"labs_program_benefits": "<0></0>",
|
||||
"labs_program_not_participating": "",
|
||||
"large_or_high-resolution_images_taking_too_long": "",
|
||||
"last_active": "",
|
||||
"last_active_description": "",
|
||||
"last_modified": "",
|
||||
@@ -565,6 +572,7 @@
|
||||
"learn_more": "",
|
||||
"learn_more_about_link_sharing": "",
|
||||
"learn_more_about_managed_users": "",
|
||||
"learn_more_about_other_causes_of_compile_timeouts": "",
|
||||
"leave": "",
|
||||
"leave_any_group_subscriptions": "",
|
||||
"leave_group": "",
|
||||
@@ -737,6 +745,7 @@
|
||||
"organize_projects": "",
|
||||
"other_logs_and_files": "",
|
||||
"other_output_files": "",
|
||||
"other_ways_to_prevent_compile_timeouts": "",
|
||||
"output_file": "",
|
||||
"overall_theme": "",
|
||||
"overleaf": "",
|
||||
@@ -789,6 +798,7 @@
|
||||
"please_select_a_project": "",
|
||||
"please_select_an_output_file": "",
|
||||
"please_set_main_file": "",
|
||||
"plus_additional_collaborators_document_history_track_changes_and_more": "",
|
||||
"plus_more": "",
|
||||
"plus_upgraded_accounts_receive": "",
|
||||
"postal_code": "",
|
||||
@@ -841,6 +851,8 @@
|
||||
"react_history_tutorial_content": "",
|
||||
"react_history_tutorial_title": "",
|
||||
"reactivate_subscription": "",
|
||||
"read_more_about_fix_prevent_timeout": "",
|
||||
"read_more_about_free_compile_timeouts_servers": "",
|
||||
"read_only": "",
|
||||
"read_only_token": "",
|
||||
"read_write_token": "",
|
||||
@@ -1022,8 +1034,10 @@
|
||||
"sso_config_prop_help_user_id": "",
|
||||
"sso_explanation": "",
|
||||
"sso_link_error": "",
|
||||
"start_a_free_trial": "",
|
||||
"start_by_adding_your_email": "",
|
||||
"start_free_trial": "",
|
||||
"start_free_trial_without_exclamation": "",
|
||||
"stop_compile": "",
|
||||
"stop_on_first_error": "",
|
||||
"stop_on_first_error_enabled_description": "",
|
||||
@@ -1065,6 +1079,8 @@
|
||||
"tc_switch_everyone_tip": "",
|
||||
"tc_switch_guests_tip": "",
|
||||
"tc_switch_user_tip": "",
|
||||
"tell_the_project_owner_and_ask_them_to_upgrade": "",
|
||||
"tell_the_project_owner_to_upgrade_plan_for_more_compile_time": "",
|
||||
"template_approved_by_publisher": "",
|
||||
"template_description": "",
|
||||
"template_title_taken_from_project_title": "",
|
||||
@@ -1088,6 +1104,8 @@
|
||||
"this_could_be_because_we_cant_support_some_elements_of_the_table": "",
|
||||
"this_field_is_required": "",
|
||||
"this_grants_access_to_features_2": "",
|
||||
"this_project_compiled_but_soon_might_not": "",
|
||||
"this_project_exceeded_compile_timeout_limit_on_free_plan": "",
|
||||
"this_project_is_public": "",
|
||||
"this_project_is_public_read_only": "",
|
||||
"this_project_will_appear_in_your_dropbox_folder_at": "",
|
||||
@@ -1112,6 +1130,7 @@
|
||||
"too_many_requests": "",
|
||||
"too_many_search_results": "",
|
||||
"too_recently_compiled": "",
|
||||
"took_a_while": "",
|
||||
"toolbar_add_comment": "",
|
||||
"toolbar_bullet_list": "",
|
||||
"toolbar_choose_section_heading_level": "",
|
||||
@@ -1203,7 +1222,9 @@
|
||||
"updating": "",
|
||||
"upgrade": "",
|
||||
"upgrade_cc_btn": "",
|
||||
"upgrade_for_12x_more_compile_time": "",
|
||||
"upgrade_for_longer_compiles": "",
|
||||
"upgrade_for_plenty_more_compile_time": "",
|
||||
"upgrade_now": "",
|
||||
"upgrade_to_get_feature": "",
|
||||
"upgrade_to_track_changes": "",
|
||||
@@ -1275,10 +1296,12 @@
|
||||
"you_have_added_x_of_group_size_y": "",
|
||||
"you_have_been_invited_to_transfer_management_of_your_account": "",
|
||||
"you_have_been_invited_to_transfer_management_of_your_account_to": "",
|
||||
"you_may_be_able_to_prevent_a_compile_timeout": "",
|
||||
"you_will_be_able_to_reassign_subscription": "",
|
||||
"youll_get_best_results_in_visual_but_can_be_used_in_source": "",
|
||||
"your_affiliation_is_confirmed": "",
|
||||
"your_browser_does_not_support_this_feature": "",
|
||||
"your_compile_timed_out": "",
|
||||
"your_git_access_info": "",
|
||||
"your_git_access_info_bullet_1": "",
|
||||
"your_git_access_info_bullet_2": "",
|
||||
@@ -1290,6 +1313,9 @@
|
||||
"your_new_plan": "",
|
||||
"your_plan": "",
|
||||
"your_plan_is_changing_at_term_end": "",
|
||||
"your_project_compiled_but_soon_might_not": "",
|
||||
"your_project_exceeded_compile_timeout_limit_on_free_plan": "",
|
||||
"your_project_near_compile_timeout_limit": "",
|
||||
"your_projects": "",
|
||||
"your_subscription": "",
|
||||
"your_subscription_has_expired": "",
|
||||
|
||||
@@ -29,7 +29,7 @@ function CompileTimeWarning() {
|
||||
return
|
||||
}
|
||||
setDisplayStatus({ lastDisplayTime: Date.now(), dismissed: false })
|
||||
eventTracking.sendMB('compile-time-warning-displayed', {})
|
||||
eventTracking.sendMB('compile-time-warning-displayed', { time: 30 })
|
||||
}
|
||||
}, [showCompileTimeWarning, displayStatus, setDisplayStatus])
|
||||
|
||||
@@ -40,6 +40,7 @@ function CompileTimeWarning() {
|
||||
const closeWarning = useCallback(() => {
|
||||
eventTracking.sendMB('compile-time-warning-dismissed', {
|
||||
'time-since-displayed': getTimeSinceDisplayed(),
|
||||
time: 30,
|
||||
})
|
||||
setShowCompileTimeWarning(false)
|
||||
setDisplayStatus(displayStatus => ({ ...displayStatus, dismissed: true }))
|
||||
@@ -48,6 +49,7 @@ function CompileTimeWarning() {
|
||||
const handleUpgradeClick = useCallback(() => {
|
||||
eventTracking.sendMB('compile-time-warning-upgrade-click', {
|
||||
'time-since-displayed': getTimeSinceDisplayed(),
|
||||
time: 30,
|
||||
})
|
||||
setShowCompileTimeWarning(false)
|
||||
setDisplayStatus(displayStatus => ({ ...displayStatus, dismissed: true }))
|
||||
|
||||
+250
@@ -0,0 +1,250 @@
|
||||
import { memo, useCallback, useEffect, useState, useMemo } from 'react'
|
||||
import * as eventTracking from '../../../infrastructure/event-tracking'
|
||||
import { useDetachCompileContext } from '../../../shared/context/detach-compile-context'
|
||||
import usePersistedState from '../../../shared/hooks/use-persisted-state'
|
||||
import Notification from '../../../shared/components/notification'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import StartFreeTrialButton from '@/shared/components/start-free-trial-button'
|
||||
|
||||
function CompileTimeoutMessages() {
|
||||
const {
|
||||
showNewCompileTimeoutUI,
|
||||
isProjectOwner,
|
||||
deliveryLatencies,
|
||||
compiling,
|
||||
showLogs,
|
||||
error,
|
||||
} = useDetachCompileContext()
|
||||
|
||||
const { t } = useTranslation()
|
||||
|
||||
const [showWarning, setShowWarning] = useState(false)
|
||||
const [showChangingSoon, setShowChangingSoon] = useState(false)
|
||||
const [dismissedUntilWarning, setDismissedUntilWarning] = usePersistedState<
|
||||
Date | undefined
|
||||
>(`has-dismissed-10s-compile-time-warning-until`)
|
||||
|
||||
const segmentation = useMemo(() => {
|
||||
return {
|
||||
newCompileTimeout: showNewCompileTimeoutUI || 'control',
|
||||
isProjectOwner,
|
||||
}
|
||||
}, [showNewCompileTimeoutUI, isProjectOwner])
|
||||
|
||||
const handleNewCompile = useCallback(
|
||||
compileTime => {
|
||||
setShowWarning(false)
|
||||
setShowChangingSoon(false)
|
||||
if (compileTime > 20000) {
|
||||
if (showNewCompileTimeoutUI === 'changing') {
|
||||
setShowChangingSoon(true)
|
||||
eventTracking.sendMB('compile-time-warning-displayed', {
|
||||
time: 20,
|
||||
...segmentation,
|
||||
})
|
||||
}
|
||||
} else if (compileTime > 10000) {
|
||||
setShowChangingSoon(false)
|
||||
if (
|
||||
(isProjectOwner && showNewCompileTimeoutUI === 'active') ||
|
||||
showNewCompileTimeoutUI === 'changing'
|
||||
) {
|
||||
if (
|
||||
!dismissedUntilWarning ||
|
||||
new Date(dismissedUntilWarning) < new Date()
|
||||
) {
|
||||
setShowWarning(true)
|
||||
eventTracking.sendMB('compile-time-warning-displayed', {
|
||||
time: 10,
|
||||
...segmentation,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
eventTracking.sendMB('compile-time-warning-would-display', {
|
||||
time: 10,
|
||||
...segmentation,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
[
|
||||
isProjectOwner,
|
||||
showNewCompileTimeoutUI,
|
||||
dismissedUntilWarning,
|
||||
segmentation,
|
||||
]
|
||||
)
|
||||
|
||||
const handleDismissWarning = useCallback(() => {
|
||||
eventTracking.sendMB('compile-time-warning-dismissed', {
|
||||
time: 10,
|
||||
...segmentation,
|
||||
})
|
||||
setShowWarning(false)
|
||||
const until = new Date()
|
||||
until.setDate(until.getDate() + 1) // 1 day
|
||||
setDismissedUntilWarning(until)
|
||||
}, [setDismissedUntilWarning, segmentation])
|
||||
|
||||
const handleDismissChangingSoon = useCallback(() => {
|
||||
eventTracking.sendMB('compile-time-warning-dismissed', {
|
||||
time: 20,
|
||||
...segmentation,
|
||||
})
|
||||
}, [segmentation])
|
||||
|
||||
useEffect(() => {
|
||||
if (compiling || error || showLogs) return
|
||||
window.sl_console.log(
|
||||
`[compileTimeout] compiledTimeServerE2E ${
|
||||
deliveryLatencies.compileTimeServerE2E / 1000
|
||||
}s`
|
||||
)
|
||||
handleNewCompile(deliveryLatencies.compileTimeServerE2E)
|
||||
}, [compiling, error, showLogs, deliveryLatencies, handleNewCompile])
|
||||
|
||||
if (!window.ExposedSettings.enableSubscriptions) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (compiling || error || showLogs) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (!showWarning && !showChangingSoon) {
|
||||
return null
|
||||
}
|
||||
|
||||
function sendInfoClickEvent() {
|
||||
eventTracking.sendMB('paywall-info-click', {
|
||||
'paywall-type': 'compile-time-warning',
|
||||
content: 'blog',
|
||||
})
|
||||
}
|
||||
|
||||
const compileTimeoutBlogLinks = [
|
||||
/* eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key */
|
||||
<a
|
||||
aria-label={t('read_more_about_free_compile_timeouts_servers')}
|
||||
href="/blog/changes-to-free-compile-timeouts-and-servers"
|
||||
key="compileTimeoutBlogLink1"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
onClick={sendInfoClickEvent}
|
||||
/>,
|
||||
/* eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key */
|
||||
<a
|
||||
aria-label={t('read_more_about_fix_prevent_timeout')}
|
||||
href="/learn/how-to/Fixing_and_preventing_compile_timeouts"
|
||||
key="compileTimeoutBlogLink2"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>,
|
||||
]
|
||||
|
||||
// if showWarning is true then the 10s warning is shown
|
||||
// and if showChangingSoon is true then the 20s-60s should show
|
||||
|
||||
return (
|
||||
<div>
|
||||
{showWarning && isProjectOwner && (
|
||||
<Notification
|
||||
action={
|
||||
<StartFreeTrialButton
|
||||
source="compile-time-warning-new-10s"
|
||||
buttonProps={{
|
||||
className: 'btn-secondary-compile-timeout-override',
|
||||
}}
|
||||
>
|
||||
{t('start_free_trial_without_exclamation')}
|
||||
</StartFreeTrialButton>
|
||||
}
|
||||
ariaLive="polite"
|
||||
content={
|
||||
<div>
|
||||
<div>
|
||||
<span>
|
||||
<Trans i18nKey="your_project_near_compile_timeout_limit" />
|
||||
</span>
|
||||
</div>
|
||||
{showNewCompileTimeoutUI === 'active' ? (
|
||||
<>
|
||||
<strong>
|
||||
<Trans i18nKey="upgrade_for_12x_more_compile_time" />
|
||||
</strong>
|
||||
{'. '}
|
||||
</>
|
||||
) : (
|
||||
<strong>
|
||||
<Trans i18nKey="upgrade_for_plenty_more_compile_time" />
|
||||
</strong>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
type="warning"
|
||||
title={t('took_a_while')}
|
||||
isActionBelowContent
|
||||
isDismissible
|
||||
onDismiss={handleDismissWarning}
|
||||
/>
|
||||
)}
|
||||
{showChangingSoon &&
|
||||
(isProjectOwner ? (
|
||||
<Notification
|
||||
action={
|
||||
<StartFreeTrialButton
|
||||
source="compile-time-warning-new-changing-soon"
|
||||
buttonProps={{
|
||||
className: 'btn-secondary-compile-timeout-override',
|
||||
}}
|
||||
>
|
||||
{t('start_free_trial_without_exclamation')}
|
||||
</StartFreeTrialButton>
|
||||
}
|
||||
ariaLive="polite"
|
||||
content={
|
||||
<div>
|
||||
<p>
|
||||
<Trans
|
||||
i18nKey="compile_timeout_will_be_reduced_project_exceeds_limit_speed_up_compile"
|
||||
components={compileTimeoutBlogLinks}
|
||||
values={{ date: 'October 6 2023' }}
|
||||
/>{' '}
|
||||
<Trans i18nKey="and_you_can_upgrade_for_plenty_more_compile_time" />
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
title={t('your_project_compiled_but_soon_might_not')}
|
||||
type="warning"
|
||||
isActionBelowContent
|
||||
isDismissible
|
||||
onDismiss={handleDismissChangingSoon}
|
||||
/>
|
||||
) : (
|
||||
<Notification
|
||||
ariaLive="polite"
|
||||
content={
|
||||
<div>
|
||||
<p>
|
||||
<Trans
|
||||
i18nKey="compile_timeout_will_be_reduced_project_exceeds_limit_speed_up_compile"
|
||||
components={compileTimeoutBlogLinks}
|
||||
values={{ date: 'October 6 2023' }}
|
||||
/>
|
||||
</p>
|
||||
<p className="row-spaced">
|
||||
<Trans i18nKey="tell_the_project_owner_to_upgrade_plan_for_more_compile_time" />
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
title={t('this_project_compiled_but_soon_might_not')}
|
||||
type="warning"
|
||||
isDismissible
|
||||
onDismiss={handleDismissChangingSoon}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(CompileTimeoutMessages)
|
||||
@@ -4,6 +4,7 @@ import classnames from 'classnames'
|
||||
import PdfValidationIssue from './pdf-validation-issue'
|
||||
import StopOnFirstErrorPrompt from './stop-on-first-error-prompt'
|
||||
import TimeoutUpgradePrompt from './timeout-upgrade-prompt'
|
||||
import TimeoutUpgradePromptNew from './timeout-upgrade-prompt-new'
|
||||
import PdfPreviewError from './pdf-preview-error'
|
||||
import PdfClearCacheButton from './pdf-clear-cache-button'
|
||||
import PdfDownloadFilesButton from './pdf-download-files-button'
|
||||
@@ -23,6 +24,7 @@ function PdfLogsViewer() {
|
||||
validationIssues,
|
||||
showLogs,
|
||||
stoppedOnFirstError,
|
||||
showNewCompileTimeoutUI,
|
||||
} = useCompileContext()
|
||||
|
||||
const { t } = useTranslation()
|
||||
@@ -34,9 +36,14 @@ function PdfLogsViewer() {
|
||||
|
||||
{stoppedOnFirstError && <StopOnFirstErrorPrompt />}
|
||||
|
||||
{error && <PdfPreviewError error={error} />}
|
||||
|
||||
{error === 'timedout' && <TimeoutUpgradePrompt />}
|
||||
{showNewCompileTimeoutUI && error === 'timedout' ? (
|
||||
<TimeoutUpgradePromptNew />
|
||||
) : (
|
||||
<>
|
||||
{error && <PdfPreviewError error={error} />}
|
||||
{error === 'timedout' && <TimeoutUpgradePrompt />}
|
||||
</>
|
||||
)}
|
||||
|
||||
{validationIssues &&
|
||||
Object.entries(validationIssues).map(([name, issue]) => (
|
||||
|
||||
@@ -8,9 +8,10 @@ import { useDetachCompileContext as useCompileContext } from '../../../shared/co
|
||||
import FasterCompilesFeedback from './faster-compiles-feedback'
|
||||
import { PdfPreviewMessages } from './pdf-preview-messages'
|
||||
import CompileTimeWarning from './compile-time-warning'
|
||||
import CompileTimeoutMessages from './compile-timeout-messages'
|
||||
|
||||
function PdfPreviewPane() {
|
||||
const { pdfUrl } = useCompileContext()
|
||||
const { pdfUrl, showNewCompileTimeoutUI } = useCompileContext()
|
||||
const classes = classNames('pdf', 'full-size', {
|
||||
'pdf-empty': !pdfUrl,
|
||||
})
|
||||
@@ -18,7 +19,11 @@ function PdfPreviewPane() {
|
||||
<div className={classes}>
|
||||
<PdfHybridPreviewToolbar />
|
||||
<PdfPreviewMessages>
|
||||
<CompileTimeWarning />
|
||||
{showNewCompileTimeoutUI ? (
|
||||
<CompileTimeoutMessages />
|
||||
) : (
|
||||
<CompileTimeWarning />
|
||||
)}
|
||||
</PdfPreviewMessages>
|
||||
<Suspense fallback={<LoadingPreview />}>
|
||||
<div className="pdf-viewer">
|
||||
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useDetachCompileContext } from '../../../shared/context/detach-compile-context'
|
||||
import StartFreeTrialButton from '../../../shared/components/start-free-trial-button'
|
||||
import { memo, useCallback } from 'react'
|
||||
import PdfLogEntry from './pdf-log-entry'
|
||||
import { useStopOnFirstError } from '../../../shared/hooks/use-stop-on-first-error'
|
||||
import { Button } from 'react-bootstrap'
|
||||
import * as eventTracking from '../../../infrastructure/event-tracking'
|
||||
|
||||
function TimeoutUpgradePromptNew() {
|
||||
const {
|
||||
startCompile,
|
||||
lastCompileOptions,
|
||||
setAnimateCompileDropdownArrow,
|
||||
showNewCompileTimeoutUI,
|
||||
isProjectOwner,
|
||||
} = useDetachCompileContext()
|
||||
|
||||
const { enableStopOnFirstError } = useStopOnFirstError({
|
||||
eventSource: 'timeout-new',
|
||||
})
|
||||
|
||||
const handleEnableStopOnFirstErrorClick = useCallback(() => {
|
||||
enableStopOnFirstError()
|
||||
startCompile({ stopOnFirstError: true })
|
||||
setAnimateCompileDropdownArrow(true)
|
||||
}, [enableStopOnFirstError, startCompile, setAnimateCompileDropdownArrow])
|
||||
|
||||
if (!window.ExposedSettings.enableSubscriptions) {
|
||||
return null
|
||||
}
|
||||
|
||||
const compileTimeChanging = showNewCompileTimeoutUI === 'changing'
|
||||
|
||||
return (
|
||||
<>
|
||||
<CompileTimeout
|
||||
compileTimeChanging={compileTimeChanging}
|
||||
isProjectOwner={isProjectOwner}
|
||||
/>
|
||||
<PreventTimeoutHelpMessage
|
||||
compileTimeChanging={compileTimeChanging}
|
||||
handleEnableStopOnFirstErrorClick={handleEnableStopOnFirstErrorClick}
|
||||
lastCompileOptions={lastCompileOptions}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
type CompileTimeoutProps = {
|
||||
compileTimeChanging?: boolean
|
||||
isProjectOwner: boolean
|
||||
}
|
||||
|
||||
function CompileTimeout({
|
||||
compileTimeChanging,
|
||||
isProjectOwner,
|
||||
}: CompileTimeoutProps) {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<PdfLogEntry
|
||||
headerTitle={t('your_compile_timed_out')}
|
||||
formattedContent={
|
||||
<>
|
||||
<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>
|
||||
{compileTimeChanging ? (
|
||||
<>
|
||||
<strong>{t('upgrade_for_plenty_more_compile_time')}</strong>{' '}
|
||||
{t(
|
||||
'plus_additional_collaborators_document_history_track_changes_and_more'
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<strong>
|
||||
<Trans i18nKey="upgrade_for_12x_more_compile_time" />
|
||||
</strong>{' '}
|
||||
<Trans i18nKey="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 />,
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
|
||||
{isProjectOwner && (
|
||||
<p className="text-center">
|
||||
<StartFreeTrialButton
|
||||
source={
|
||||
compileTimeChanging
|
||||
? 'compile-timeout-new-changing'
|
||||
: 'compile-timeout-new-active'
|
||||
}
|
||||
buttonProps={{
|
||||
bsStyle: 'success',
|
||||
className: 'row-spaced-small',
|
||||
block: true,
|
||||
}}
|
||||
>
|
||||
{t('start_a_free_trial')}
|
||||
</StartFreeTrialButton>
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
entryAriaLabel={t('your_compile_timed_out')}
|
||||
level="error"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
type PreventTimeoutHelpMessageProps = {
|
||||
compileTimeChanging?: boolean
|
||||
lastCompileOptions: any
|
||||
handleEnableStopOnFirstErrorClick: () => void
|
||||
}
|
||||
|
||||
function PreventTimeoutHelpMessage({
|
||||
compileTimeChanging,
|
||||
lastCompileOptions,
|
||||
handleEnableStopOnFirstErrorClick,
|
||||
}: PreventTimeoutHelpMessageProps) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
function sendInfoClickEvent() {
|
||||
eventTracking.sendMB('paywall-info-click', {
|
||||
'paywall-type': 'compile-timeout',
|
||||
content: 'blog',
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<PdfLogEntry
|
||||
headerTitle={t('other_ways_to_prevent_compile_timeouts')}
|
||||
formattedContent={
|
||||
<>
|
||||
<p>
|
||||
{t('you_may_be_able_to_prevent_a_compile_timeout')}
|
||||
{compileTimeChanging && (
|
||||
<>
|
||||
{' '}
|
||||
<Trans
|
||||
i18nKey="but_note_that_free_compile_timeout_limit_will_be_reduced_on_x_date"
|
||||
components={[
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
|
||||
<a
|
||||
aria-label={t(
|
||||
'read_more_about_free_compile_timeouts_servers'
|
||||
)}
|
||||
href="/blog/changes-to-free-compile-timeouts-and-servers"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
onClick={sendInfoClickEvent}
|
||||
/>,
|
||||
]}
|
||||
values={{ date: 'October 6 2023' }}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
<p>{t('common_causes_of_compile_timeouts_are')}:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<Trans
|
||||
i18nKey="large_or_high-resolution_images_taking_too_long"
|
||||
components={[
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
|
||||
<a
|
||||
href="/learn/how-to/Optimising_very_large_image_files"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
</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="/learn/how-to/Fixing_and_preventing_compile_timeouts#Step_3:_Assess_your_project_for_time-consuming_tasks_and_fatal_errors"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
{!lastCompileOptions.stopOnFirstError && (
|
||||
<>
|
||||
{' '}
|
||||
<Trans
|
||||
i18nKey="enable_stop_on_first_error_under_recompile_dropdown_menu"
|
||||
components={[
|
||||
// eslint-disable-next-line react/jsx-key
|
||||
<Button
|
||||
bsSize="xs"
|
||||
bsStyle="info-ghost-inline"
|
||||
onClick={handleEnableStopOnFirstErrorClick}
|
||||
/>,
|
||||
// eslint-disable-next-line react/jsx-key
|
||||
<strong />,
|
||||
]}
|
||||
/>{' '}
|
||||
</>
|
||||
)}
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<Trans
|
||||
i18nKey="learn_more_about_other_causes_of_compile_timeouts"
|
||||
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"
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
entryAriaLabel={t('other_ways_to_prevent_compile_timeouts')}
|
||||
level="raw"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(TimeoutUpgradePromptNew)
|
||||
@@ -184,6 +184,14 @@ export default class DocumentCompiler {
|
||||
params.file_line_errors = 'true'
|
||||
}
|
||||
|
||||
// temporary override to force the new compile timeout
|
||||
const newCompileTimeoutOverride = new URLSearchParams(
|
||||
window.location.search
|
||||
).get('force_new_compile_timeout')
|
||||
if (newCompileTimeoutOverride) {
|
||||
params.set('force_new_compile_timeout', newCompileTimeoutOverride)
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ export function DetachCompileProvider({ children }) {
|
||||
fileList: _fileList,
|
||||
hasChanges: _hasChanges,
|
||||
highlights: _highlights,
|
||||
isProjectOwner: _isProjectOwner,
|
||||
lastCompileOptions: _lastCompileOptions,
|
||||
logEntries: _logEntries,
|
||||
logEntryAnnotations: _logEntryAnnotations,
|
||||
@@ -55,6 +56,7 @@ export function DetachCompileProvider({ children }) {
|
||||
setStopOnValidationError: _setStopOnValidationError,
|
||||
showLogs: _showLogs,
|
||||
showCompileTimeWarning: _showCompileTimeWarning,
|
||||
showNewCompileTimeoutUI: _showNewCompileTimeoutUI,
|
||||
showFasterCompilesFeedbackUI: _showFasterCompilesFeedbackUI,
|
||||
stopOnFirstError: _stopOnFirstError,
|
||||
stopOnValidationError: _stopOnValidationError,
|
||||
@@ -135,6 +137,12 @@ export function DetachCompileProvider({ children }) {
|
||||
'detacher',
|
||||
'detached'
|
||||
)
|
||||
const [isProjectOwner] = useDetachStateWatcher(
|
||||
'isProjectOwner',
|
||||
_isProjectOwner,
|
||||
'detacher',
|
||||
'detached'
|
||||
)
|
||||
const [lastCompileOptions] = useDetachStateWatcher(
|
||||
'lastCompileOptions',
|
||||
_lastCompileOptions,
|
||||
@@ -189,6 +197,12 @@ export function DetachCompileProvider({ children }) {
|
||||
'detacher',
|
||||
'detached'
|
||||
)
|
||||
const [showNewCompileTimeoutUI] = useDetachStateWatcher(
|
||||
'showNewCompileTimeoutUI',
|
||||
_showNewCompileTimeoutUI,
|
||||
'detacher',
|
||||
'detached'
|
||||
)
|
||||
const [showFasterCompilesFeedbackUI] = useDetachStateWatcher(
|
||||
'showFasterCompilesFeedbackUI',
|
||||
_showFasterCompilesFeedbackUI,
|
||||
@@ -384,6 +398,7 @@ export function DetachCompileProvider({ children }) {
|
||||
fileList,
|
||||
hasChanges,
|
||||
highlights,
|
||||
isProjectOwner,
|
||||
lastCompileOptions,
|
||||
logEntryAnnotations,
|
||||
logEntries,
|
||||
@@ -409,6 +424,7 @@ export function DetachCompileProvider({ children }) {
|
||||
setStopOnValidationError,
|
||||
showLogs,
|
||||
showCompileTimeWarning,
|
||||
showNewCompileTimeoutUI,
|
||||
showFasterCompilesFeedbackUI,
|
||||
startCompile,
|
||||
stopCompile,
|
||||
@@ -437,6 +453,7 @@ export function DetachCompileProvider({ children }) {
|
||||
fileList,
|
||||
hasChanges,
|
||||
highlights,
|
||||
isProjectOwner,
|
||||
lastCompileOptions,
|
||||
logEntryAnnotations,
|
||||
logEntries,
|
||||
@@ -460,6 +477,7 @@ export function DetachCompileProvider({ children }) {
|
||||
setStopOnValidationError,
|
||||
showCompileTimeWarning,
|
||||
showLogs,
|
||||
showNewCompileTimeoutUI,
|
||||
showFasterCompilesFeedbackUI,
|
||||
startCompile,
|
||||
stopCompile,
|
||||
|
||||
@@ -66,6 +66,7 @@ export const CompileContextPropTypes = {
|
||||
setStopOnValidationError: PropTypes.func.isRequired,
|
||||
showCompileTimeWarning: PropTypes.bool.isRequired,
|
||||
showLogs: PropTypes.bool.isRequired,
|
||||
showNewCompileTimeoutUI: PropTypes.string,
|
||||
showFasterCompilesFeedbackUI: PropTypes.bool.isRequired,
|
||||
stopOnFirstError: PropTypes.bool.isRequired,
|
||||
stopOnValidationError: PropTypes.bool.isRequired,
|
||||
@@ -84,7 +85,11 @@ export function LocalCompileProvider({ children }) {
|
||||
|
||||
const { hasPremiumCompile, isProjectOwner } = useEditorContext()
|
||||
|
||||
const { _id: projectId, rootDocId } = useProjectContext()
|
||||
const {
|
||||
_id: projectId,
|
||||
rootDocId,
|
||||
showNewCompileTimeoutUI,
|
||||
} = useProjectContext()
|
||||
|
||||
const { pdfPreviewOpen } = useLayoutContext()
|
||||
|
||||
@@ -555,6 +560,7 @@ export function LocalCompileProvider({ children }) {
|
||||
fileList,
|
||||
hasChanges,
|
||||
highlights,
|
||||
isProjectOwner,
|
||||
lastCompileOptions,
|
||||
logEntryAnnotations,
|
||||
logEntries,
|
||||
@@ -580,6 +586,7 @@ export function LocalCompileProvider({ children }) {
|
||||
setStopOnFirstError,
|
||||
setStopOnValidationError,
|
||||
showLogs,
|
||||
showNewCompileTimeoutUI,
|
||||
showFasterCompilesFeedbackUI,
|
||||
startCompile,
|
||||
stopCompile,
|
||||
@@ -609,6 +616,7 @@ export function LocalCompileProvider({ children }) {
|
||||
fileList,
|
||||
hasChanges,
|
||||
highlights,
|
||||
isProjectOwner,
|
||||
lastCompileOptions,
|
||||
logEntries,
|
||||
logEntryAnnotations,
|
||||
@@ -629,6 +637,7 @@ export function LocalCompileProvider({ children }) {
|
||||
setStopOnValidationError,
|
||||
showCompileTimeWarning,
|
||||
showLogs,
|
||||
showNewCompileTimeoutUI,
|
||||
showFasterCompilesFeedbackUI,
|
||||
startCompile,
|
||||
stopCompile,
|
||||
|
||||
@@ -33,6 +33,7 @@ export const projectShape = {
|
||||
_id: PropTypes.string.isRequired,
|
||||
email: PropTypes.string.isRequired,
|
||||
}),
|
||||
useNewCompileTimeoutUI: PropTypes.string,
|
||||
}
|
||||
|
||||
ProjectContext.Provider.propTypes = {
|
||||
@@ -79,8 +80,20 @@ export function ProjectProvider({ children }) {
|
||||
features,
|
||||
publicAccesLevel: publicAccessLevel,
|
||||
owner,
|
||||
showNewCompileTimeoutUI,
|
||||
} = project || projectFallback
|
||||
|
||||
// temporary override for new compile timeout
|
||||
const forceNewCompileTimeout = new URLSearchParams(
|
||||
window.location.search
|
||||
).get('force_new_compile_timeout')
|
||||
const newCompileTimeoutOverride =
|
||||
forceNewCompileTimeout === 'active'
|
||||
? 'active'
|
||||
: forceNewCompileTimeout === 'changing'
|
||||
? 'changing'
|
||||
: undefined
|
||||
|
||||
const value = useMemo(() => {
|
||||
return {
|
||||
_id,
|
||||
@@ -91,6 +104,8 @@ export function ProjectProvider({ children }) {
|
||||
features,
|
||||
publicAccessLevel,
|
||||
owner,
|
||||
showNewCompileTimeoutUI:
|
||||
newCompileTimeoutOverride || showNewCompileTimeoutUI,
|
||||
}
|
||||
}, [
|
||||
_id,
|
||||
@@ -101,6 +116,8 @@ export function ProjectProvider({ children }) {
|
||||
features,
|
||||
publicAccessLevel,
|
||||
owner,
|
||||
showNewCompileTimeoutUI,
|
||||
newCompileTimeoutOverride,
|
||||
])
|
||||
|
||||
return (
|
||||
|
||||
@@ -756,6 +756,7 @@ CodeMirror
|
||||
.pdf-preview-messages {
|
||||
position: absolute;
|
||||
right: @margin-sm;
|
||||
left: @margin-sm;
|
||||
top: @margin-xl;
|
||||
z-index: @zindex-popover;
|
||||
}
|
||||
|
||||
@@ -589,3 +589,10 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-secondary-compile-timeout-override {
|
||||
color: #1b222c;
|
||||
background-color: #ffffff;
|
||||
border-color: #677283;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
@@ -156,6 +156,35 @@
|
||||
background-color: @red-10;
|
||||
}
|
||||
}
|
||||
.btn-info-ghost when (@is-new-css = true) {
|
||||
.btn-borderless(@blue-50, @btn-info-ghost-bg, @blue-10);
|
||||
}
|
||||
// Info Ghost appear as info blue with no border
|
||||
.btn-info-ghost when (@is-new-css = false) {
|
||||
.button-variant(@btn-info-ghost-color; @btn-info-ghost-bg; @btn-info-ghost-border);
|
||||
// hover for ghost acts different from typical variants, as it's default state has no bg
|
||||
&:hover {
|
||||
background-color: @blue-10;
|
||||
}
|
||||
}
|
||||
// Inline button to fit text, without link styling.
|
||||
// TODO: generic class for other styles
|
||||
.btn-info-ghost-inline when (@is-new-css = true) {
|
||||
.btn-borderless(@blue-50, @btn-info-ghost-bg, @blue-10);
|
||||
padding: 0 !important;
|
||||
font-size: inherit !important;
|
||||
vertical-align: inherit;
|
||||
}
|
||||
.btn-info-ghost-inline when (@is-new-css = false) {
|
||||
.button-variant(@btn-info-ghost-color; @btn-info-ghost-bg; @btn-info-ghost-border);
|
||||
// hover for ghost acts different from typical variants, as it's default state has no bg
|
||||
&:hover {
|
||||
background-color: @blue-10;
|
||||
}
|
||||
padding: 0 !important;
|
||||
font-size: inherit !important;
|
||||
vertical-align: inherit;
|
||||
}
|
||||
.btn-danger-ghost when (@is-new-css = true) {
|
||||
.btn-borderless(@red-50, @btn-danger-ghost-bg, @red-10);
|
||||
}
|
||||
|
||||
@@ -241,6 +241,10 @@
|
||||
@btn-info-bg: @ol-blue;
|
||||
@btn-info-border: transparent;
|
||||
|
||||
@btn-info-ghost-color: @blue-50;
|
||||
@btn-info-ghost-bg: transparent;
|
||||
@btn-info-ghost-border: transparent;
|
||||
|
||||
@btn-warning-color: #fff;
|
||||
@btn-warning-bg: @orange;
|
||||
@btn-warning-border: transparent;
|
||||
|
||||
@@ -171,6 +171,10 @@
|
||||
@btn-info-bg: @blue;
|
||||
@btn-info-border: transparent;
|
||||
|
||||
@btn-info-ghost-color: @blue-50;
|
||||
@btn-info-ghost-bg: transparent;
|
||||
@btn-info-ghost-border: transparent;
|
||||
|
||||
@btn-warning-color: #fff;
|
||||
@btn-warning-bg: @orange;
|
||||
@btn-warning-border: transparent;
|
||||
|
||||
Reference in New Issue
Block a user