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:
Thomas
2023-09-19 08:03:52 +00:00
committed by Copybot
co-authored by Rebeka
parent d04a1d3767
commit 31cb9e336b
22 changed files with 838 additions and 8 deletions
@@ -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 }))
@@ -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">
@@ -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;