mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #17909 from overleaf/ac-tear-down-compile-timeout-tests-2
[web] Remove split-tests `compile-backend-class*` and `compile-timeout-20s*` (attempt 2) GitOrigin-RevId: 5658f2977d3e7089eec5bbe7a33eee81c153e41d
This commit is contained in:
parent
bd570cc473
commit
d35204033f
27 changed files with 393 additions and 1051 deletions
|
@ -105,15 +105,6 @@ module.exports = CompileController = {
|
||||||
stopOnFirstError,
|
stopOnFirstError,
|
||||||
}
|
}
|
||||||
|
|
||||||
// temporary override to force the new compile timeout
|
|
||||||
const forceNewCompileTimeout = req.query.force_new_compile_timeout
|
|
||||||
if (
|
|
||||||
forceNewCompileTimeout === 'active' ||
|
|
||||||
forceNewCompileTimeout === 'changing'
|
|
||||||
) {
|
|
||||||
options.forceNewCompileTimeout = forceNewCompileTimeout
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.body.rootDoc_id) {
|
if (req.body.rootDoc_id) {
|
||||||
options.rootDoc_id = req.body.rootDoc_id
|
options.rootDoc_id = req.body.rootDoc_id
|
||||||
} else if (
|
} else if (
|
||||||
|
|
|
@ -8,18 +8,9 @@ const UserGetter = require('../User/UserGetter')
|
||||||
const ClsiManager = require('./ClsiManager')
|
const ClsiManager = require('./ClsiManager')
|
||||||
const Metrics = require('@overleaf/metrics')
|
const Metrics = require('@overleaf/metrics')
|
||||||
const { RateLimiter } = require('../../infrastructure/RateLimiter')
|
const { RateLimiter } = require('../../infrastructure/RateLimiter')
|
||||||
const SplitTestHandler = require('../SplitTests/SplitTestHandler')
|
|
||||||
const UserAnalyticsIdCache = require('../Analytics/UserAnalyticsIdCache')
|
const UserAnalyticsIdCache = require('../Analytics/UserAnalyticsIdCache')
|
||||||
|
|
||||||
const NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF = new Date('2023-09-18T11:00:00.000Z')
|
|
||||||
const NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF_DEFAULT_BASELINE = new Date(
|
|
||||||
'2023-10-10T11:00:00.000Z'
|
|
||||||
)
|
|
||||||
|
|
||||||
module.exports = CompileManager = {
|
module.exports = CompileManager = {
|
||||||
NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF,
|
|
||||||
NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF_DEFAULT_BASELINE,
|
|
||||||
|
|
||||||
compile(projectId, userId, options = {}, _callback) {
|
compile(projectId, userId, options = {}, _callback) {
|
||||||
const timer = new Metrics.Timer('editor.compile')
|
const timer = new Metrics.Timer('editor.compile')
|
||||||
const callback = function (...args) {
|
const callback = function (...args) {
|
||||||
|
@ -62,16 +53,6 @@ module.exports = CompileManager = {
|
||||||
const value = limits[key]
|
const value = limits[key]
|
||||||
options[key] = value
|
options[key] = value
|
||||||
}
|
}
|
||||||
if (options.timeout !== 20) {
|
|
||||||
// temporary override to force the new compile timeout
|
|
||||||
if (options.forceNewCompileTimeout === 'active') {
|
|
||||||
options.timeout = 20
|
|
||||||
} else if (
|
|
||||||
options.forceNewCompileTimeout === 'changing'
|
|
||||||
) {
|
|
||||||
options.timeout = 60
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Put a lower limit on autocompiles for free users, based on compileGroup
|
// Put a lower limit on autocompiles for free users, based on compileGroup
|
||||||
CompileManager._checkCompileGroupAutoCompileLimit(
|
CompileManager._checkCompileGroupAutoCompileLimit(
|
||||||
options.isAutoCompile,
|
options.isAutoCompile,
|
||||||
|
@ -184,78 +165,25 @@ module.exports = CompileManager = {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
|
const compileGroup =
|
||||||
|
ownerFeatures.compileGroup ||
|
||||||
|
Settings.defaultFeatures.compileGroup
|
||||||
|
const compileTimeout =
|
||||||
|
ownerFeatures.compileTimeout ||
|
||||||
|
Settings.defaultFeatures.compileTimeout
|
||||||
|
|
||||||
const limits = {
|
const limits = {
|
||||||
timeout:
|
timeout:
|
||||||
ownerFeatures.compileTimeout ||
|
// temporary override until users' compileTimeout is migrated
|
||||||
Settings.defaultFeatures.compileTimeout,
|
compileGroup === 'standard' && compileTimeout <= 60
|
||||||
compileGroup:
|
? 20
|
||||||
ownerFeatures.compileGroup ||
|
: compileTimeout,
|
||||||
Settings.defaultFeatures.compileGroup,
|
compileGroup,
|
||||||
|
compileBackendClass:
|
||||||
|
compileGroup === 'standard' ? 'n2d' : 'c2d',
|
||||||
ownerAnalyticsId: analyticsId,
|
ownerAnalyticsId: analyticsId,
|
||||||
}
|
}
|
||||||
CompileManager._getCompileBackendClassDetails(
|
callback(null, limits)
|
||||||
owner,
|
|
||||||
limits.compileGroup,
|
|
||||||
(
|
|
||||||
err,
|
|
||||||
{ compileBackendClass, showFasterCompilesFeedbackUI }
|
|
||||||
) => {
|
|
||||||
if (err) return callback(err)
|
|
||||||
limits.compileBackendClass = compileBackendClass
|
|
||||||
limits.showFasterCompilesFeedbackUI =
|
|
||||||
showFasterCompilesFeedbackUI
|
|
||||||
if (compileBackendClass === 'n2d' && limits.timeout <= 60) {
|
|
||||||
// project owners with faster compiles but with <= 60 compile timeout (default)
|
|
||||||
// will have a 20s compile timeout
|
|
||||||
// The compile-timeout-20s split test exists to enable a gradual rollout
|
|
||||||
SplitTestHandler.getAssignmentForMongoUser(
|
|
||||||
owner,
|
|
||||||
'compile-timeout-20s',
|
|
||||||
(err, assignment) => {
|
|
||||||
if (err) return callback(err)
|
|
||||||
// users who were on the 'default' servers at time of original rollout
|
|
||||||
// will have a later cutoff date for the 20s timeout in the next phase
|
|
||||||
// we check the backend class at version 8 (baseline)
|
|
||||||
const backendClassHistory =
|
|
||||||
owner.splitTests?.['compile-backend-class-n2d'] ||
|
|
||||||
[]
|
|
||||||
const backendClassBaselineVariant =
|
|
||||||
backendClassHistory.find(version => {
|
|
||||||
return version.versionNumber === 8
|
|
||||||
})?.variantName
|
|
||||||
const timeoutEnforcedCutoff =
|
|
||||||
backendClassBaselineVariant === 'default'
|
|
||||||
? NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF_DEFAULT_BASELINE
|
|
||||||
: NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF
|
|
||||||
if (assignment?.variant === '20s') {
|
|
||||||
if (owner.signUpDate > timeoutEnforcedCutoff) {
|
|
||||||
limits.timeout = 20
|
|
||||||
callback(null, limits)
|
|
||||||
} else {
|
|
||||||
SplitTestHandler.getAssignmentForMongoUser(
|
|
||||||
owner,
|
|
||||||
'compile-timeout-20s-existing-users',
|
|
||||||
(err, assignmentExistingUsers) => {
|
|
||||||
if (err) return callback(err)
|
|
||||||
if (
|
|
||||||
assignmentExistingUsers?.variant === '20s'
|
|
||||||
) {
|
|
||||||
limits.timeout = 20
|
|
||||||
}
|
|
||||||
callback(null, limits)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback(null, limits)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
callback(null, limits)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -322,39 +250,6 @@ module.exports = CompileManager = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
_getCompileBackendClassDetails(owner, compileGroup, callback) {
|
|
||||||
const { defaultBackendClass } = Settings.apis.clsi
|
|
||||||
if (compileGroup === 'standard') {
|
|
||||||
return SplitTestHandler.getAssignmentForMongoUser(
|
|
||||||
owner,
|
|
||||||
'compile-backend-class-n2d',
|
|
||||||
(err, assignment) => {
|
|
||||||
if (err) return callback(err, {})
|
|
||||||
const { variant } = assignment
|
|
||||||
callback(null, {
|
|
||||||
compileBackendClass:
|
|
||||||
variant === 'default' ? defaultBackendClass : variant,
|
|
||||||
showFasterCompilesFeedbackUI: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
SplitTestHandler.getAssignmentForMongoUser(
|
|
||||||
owner,
|
|
||||||
'compile-backend-class',
|
|
||||||
(err, assignment) => {
|
|
||||||
if (err) return callback(err, {})
|
|
||||||
const { analytics, variant } = assignment
|
|
||||||
const activeForUser = analytics?.segmentation?.splitTest != null
|
|
||||||
callback(null, {
|
|
||||||
compileBackendClass:
|
|
||||||
variant === 'default' ? defaultBackendClass : variant,
|
|
||||||
showFasterCompilesFeedbackUI: activeForUser,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
wordCount(projectId, userId, file, clsiserverid, callback) {
|
wordCount(projectId, userId, file, clsiserverid, callback) {
|
||||||
CompileManager.getProjectCompileLimits(projectId, function (error, limits) {
|
CompileManager.getProjectCompileLimits(projectId, function (error, limits) {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|
|
@ -13,12 +13,6 @@ const Errors = require('../Errors/Errors')
|
||||||
const DocstoreManager = require('../Docstore/DocstoreManager')
|
const DocstoreManager = require('../Docstore/DocstoreManager')
|
||||||
const logger = require('@overleaf/logger')
|
const logger = require('@overleaf/logger')
|
||||||
const { expressify } = require('@overleaf/promise-utils')
|
const { expressify } = require('@overleaf/promise-utils')
|
||||||
const SplitTestHandler = require('../SplitTests/SplitTestHandler')
|
|
||||||
const {
|
|
||||||
NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF,
|
|
||||||
NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF_DEFAULT_BASELINE,
|
|
||||||
} = require('../Compile/CompileManager')
|
|
||||||
const UserGetter = require('../User/UserGetter')
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
joinProject: expressify(joinProject),
|
joinProject: expressify(joinProject),
|
||||||
|
@ -72,58 +66,6 @@ async function joinProject(req, res, next) {
|
||||||
if (!project) {
|
if (!project) {
|
||||||
return res.sendStatus(403)
|
return res.sendStatus(403)
|
||||||
}
|
}
|
||||||
// Compile timeout 20s test
|
|
||||||
if (project.features?.compileTimeout <= 60) {
|
|
||||||
const compileAssignment =
|
|
||||||
await SplitTestHandler.promises.getAssignmentForUser(
|
|
||||||
project.owner._id,
|
|
||||||
'compile-backend-class-n2d'
|
|
||||||
)
|
|
||||||
if (compileAssignment?.variant === 'n2d') {
|
|
||||||
const timeoutAssignment =
|
|
||||||
await SplitTestHandler.promises.getAssignmentForUser(
|
|
||||||
project.owner._id,
|
|
||||||
'compile-timeout-20s'
|
|
||||||
)
|
|
||||||
if (timeoutAssignment?.variant === '20s') {
|
|
||||||
// users who were on the 'default' servers at time of original rollout
|
|
||||||
// will have a later cutoff date for the 20s timeout in the next phase
|
|
||||||
// we check the backend class at version 8 (baseline)
|
|
||||||
const owner = await UserGetter.promises.getUser(project.owner._id, {
|
|
||||||
_id: 1,
|
|
||||||
'splitTests.compile-backend-class-n2d': 1,
|
|
||||||
})
|
|
||||||
const backendClassHistory =
|
|
||||||
owner.splitTests?.['compile-backend-class-n2d'] || []
|
|
||||||
const backendClassBaselineVariant = backendClassHistory.find(
|
|
||||||
version => {
|
|
||||||
return version.versionNumber === 8
|
|
||||||
}
|
|
||||||
)?.variantName
|
|
||||||
const timeoutEnforcedCutoff =
|
|
||||||
backendClassBaselineVariant === 'default'
|
|
||||||
? NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF_DEFAULT_BASELINE
|
|
||||||
: NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF
|
|
||||||
if (project.owner.signUpDate > timeoutEnforcedCutoff) {
|
|
||||||
// New users will see a 10s warning and compile fail at 20s
|
|
||||||
project.showNewCompileTimeoutUI = 'active'
|
|
||||||
} else {
|
|
||||||
const existingUserTimeoutAssignment =
|
|
||||||
await SplitTestHandler.promises.getAssignmentForUser(
|
|
||||||
project.owner._id,
|
|
||||||
'compile-timeout-20s-existing-users'
|
|
||||||
)
|
|
||||||
if (existingUserTimeoutAssignment?.variant === '20s') {
|
|
||||||
// Older users in treatment see 10s warning and compile fail at 20s
|
|
||||||
project.showNewCompileTimeoutUI = 'active'
|
|
||||||
} else {
|
|
||||||
// Older users in control aren't limited to 20s, but will see a notice of upcoming changes if compile >20s
|
|
||||||
project.showNewCompileTimeoutUI = 'changing'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Hide sensitive data if the user is restricted
|
// Hide sensitive data if the user is restricted
|
||||||
if (isRestrictedUser) {
|
if (isRestrictedUser) {
|
||||||
project.owner = { _id: project.owner._id }
|
project.owner = { _id: project.owner._id }
|
||||||
|
|
|
@ -272,7 +272,6 @@ module.exports = {
|
||||||
url: `http://${process.env.CLSI_HOST || 'localhost'}:3013`,
|
url: `http://${process.env.CLSI_HOST || 'localhost'}:3013`,
|
||||||
// url: "http://#{process.env['CLSI_LB_HOST']}:3014"
|
// url: "http://#{process.env['CLSI_LB_HOST']}:3014"
|
||||||
backendGroupName: undefined,
|
backendGroupName: undefined,
|
||||||
defaultBackendClass: process.env.CLSI_DEFAULT_BACKEND_CLASS || 'e2',
|
|
||||||
submissionBackendClass:
|
submissionBackendClass:
|
||||||
process.env.CLSI_SUBMISSION_BACKEND_CLASS || 'n2d',
|
process.env.CLSI_SUBMISSION_BACKEND_CLASS || 'n2d',
|
||||||
},
|
},
|
||||||
|
|
|
@ -70,11 +70,9 @@
|
||||||
"also": "",
|
"also": "",
|
||||||
"an_email_has_already_been_sent_to": "",
|
"an_email_has_already_been_sent_to": "",
|
||||||
"an_error_occurred_when_verifying_the_coupon_code": "",
|
"an_error_occurred_when_verifying_the_coupon_code": "",
|
||||||
"and_you_can_upgrade_for_plenty_more_compile_time": "",
|
|
||||||
"anonymous": "",
|
"anonymous": "",
|
||||||
"anyone_with_link_can_edit": "",
|
"anyone_with_link_can_edit": "",
|
||||||
"anyone_with_link_can_view": "",
|
"anyone_with_link_can_view": "",
|
||||||
"approaching_compile_timeout_limit_upgrade_for_more_compile_time": "",
|
|
||||||
"archive": "",
|
"archive": "",
|
||||||
"archive_projects": "",
|
"archive_projects": "",
|
||||||
"archived": "",
|
"archived": "",
|
||||||
|
@ -86,7 +84,6 @@
|
||||||
"are_you_sure": "",
|
"are_you_sure": "",
|
||||||
"ask_proj_owner_to_unlink_from_current_github": "",
|
"ask_proj_owner_to_unlink_from_current_github": "",
|
||||||
"ask_proj_owner_to_upgrade_for_full_history": "",
|
"ask_proj_owner_to_upgrade_for_full_history": "",
|
||||||
"ask_proj_owner_to_upgrade_for_longer_compiles": "",
|
|
||||||
"ask_proj_owner_to_upgrade_for_references_search": "",
|
"ask_proj_owner_to_upgrade_for_references_search": "",
|
||||||
"ask_repo_owner_to_reconnect": "",
|
"ask_repo_owner_to_reconnect": "",
|
||||||
"ask_repo_owner_to_renew_overleaf_subscription": "",
|
"ask_repo_owner_to_renew_overleaf_subscription": "",
|
||||||
|
@ -192,7 +189,6 @@
|
||||||
"compile_mode": "",
|
"compile_mode": "",
|
||||||
"compile_terminated_by_user": "",
|
"compile_terminated_by_user": "",
|
||||||
"compiler": "",
|
"compiler": "",
|
||||||
"compiles_on_our_free_plan_are_now_on_faster_servers": "",
|
|
||||||
"compiling": "",
|
"compiling": "",
|
||||||
"configure_sso": "",
|
"configure_sso": "",
|
||||||
"confirm": "",
|
"confirm": "",
|
||||||
|
@ -285,7 +281,6 @@
|
||||||
"disabling": "",
|
"disabling": "",
|
||||||
"disconnected": "",
|
"disconnected": "",
|
||||||
"discount_of": "",
|
"discount_of": "",
|
||||||
"dismiss": "",
|
|
||||||
"dismiss_error_popup": "",
|
"dismiss_error_popup": "",
|
||||||
"display_deleted_user": "",
|
"display_deleted_user": "",
|
||||||
"do_you_want_to_change_your_primary_email_address_to": "",
|
"do_you_want_to_change_your_primary_email_address_to": "",
|
||||||
|
@ -386,11 +381,6 @@
|
||||||
"failed_to_send_managed_user_invite_to_email": "",
|
"failed_to_send_managed_user_invite_to_email": "",
|
||||||
"failed_to_send_sso_link_invite_to_email": "",
|
"failed_to_send_sso_link_invite_to_email": "",
|
||||||
"fast": "",
|
"fast": "",
|
||||||
"faster_compiles_feedback_question": "",
|
|
||||||
"faster_compiles_feedback_seems_faster": "",
|
|
||||||
"faster_compiles_feedback_seems_same": "",
|
|
||||||
"faster_compiles_feedback_seems_slower": "",
|
|
||||||
"faster_compiles_feedback_thanks": "",
|
|
||||||
"file_action_created": "",
|
"file_action_created": "",
|
||||||
"file_action_deleted": "",
|
"file_action_deleted": "",
|
||||||
"file_action_edited": "",
|
"file_action_edited": "",
|
||||||
|
@ -426,7 +416,6 @@
|
||||||
"found_matching_deleted_users": "",
|
"found_matching_deleted_users": "",
|
||||||
"free_7_day_trial_billed_annually": "",
|
"free_7_day_trial_billed_annually": "",
|
||||||
"free_7_day_trial_billed_monthly": "",
|
"free_7_day_trial_billed_monthly": "",
|
||||||
"free_accounts_have_timeout_upgrade_to_increase": "",
|
|
||||||
"free_plan_label": "",
|
"free_plan_label": "",
|
||||||
"free_plan_tooltip": "",
|
"free_plan_tooltip": "",
|
||||||
"from_another_project": "",
|
"from_another_project": "",
|
||||||
|
@ -918,7 +907,6 @@
|
||||||
"please_wait": "",
|
"please_wait": "",
|
||||||
"plus_additional_collaborators_document_history_track_changes_and_more": "",
|
"plus_additional_collaborators_document_history_track_changes_and_more": "",
|
||||||
"plus_more": "",
|
"plus_more": "",
|
||||||
"plus_upgraded_accounts_receive": "",
|
|
||||||
"postal_code": "",
|
"postal_code": "",
|
||||||
"premium_feature": "",
|
"premium_feature": "",
|
||||||
"premium_plan_label": "",
|
"premium_plan_label": "",
|
||||||
|
@ -980,7 +968,6 @@
|
||||||
"react_history_tutorial_content": "",
|
"react_history_tutorial_content": "",
|
||||||
"react_history_tutorial_title": "",
|
"react_history_tutorial_title": "",
|
||||||
"reactivate_subscription": "",
|
"reactivate_subscription": "",
|
||||||
"read_more_about_fix_prevent_timeout": "",
|
|
||||||
"read_more_about_free_compile_timeouts_servers": "",
|
"read_more_about_free_compile_timeouts_servers": "",
|
||||||
"read_only": "",
|
"read_only": "",
|
||||||
"read_only_token": "",
|
"read_only_token": "",
|
||||||
|
@ -1292,7 +1279,6 @@
|
||||||
"tc_switch_guests_tip": "",
|
"tc_switch_guests_tip": "",
|
||||||
"tc_switch_user_tip": "",
|
"tc_switch_user_tip": "",
|
||||||
"tell_the_project_owner_and_ask_them_to_upgrade": "",
|
"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_approved_by_publisher": "",
|
||||||
"template_description": "",
|
"template_description": "",
|
||||||
"template_title_taken_from_project_title": "",
|
"template_title_taken_from_project_title": "",
|
||||||
|
@ -1322,7 +1308,6 @@
|
||||||
"this_could_be_because_we_cant_support_some_elements_of_the_table": "",
|
"this_could_be_because_we_cant_support_some_elements_of_the_table": "",
|
||||||
"this_field_is_required": "",
|
"this_field_is_required": "",
|
||||||
"this_grants_access_to_features_2": "",
|
"this_grants_access_to_features_2": "",
|
||||||
"this_project_compiled_but_soon_might_not": "",
|
|
||||||
"this_project_exceeded_compile_timeout_limit_on_free_plan": "",
|
"this_project_exceeded_compile_timeout_limit_on_free_plan": "",
|
||||||
"this_project_is_public": "",
|
"this_project_is_public": "",
|
||||||
"this_project_is_public_read_only": "",
|
"this_project_is_public_read_only": "",
|
||||||
|
@ -1464,8 +1449,6 @@
|
||||||
"upgrade": "",
|
"upgrade": "",
|
||||||
"upgrade_cc_btn": "",
|
"upgrade_cc_btn": "",
|
||||||
"upgrade_for_12x_more_compile_time": "",
|
"upgrade_for_12x_more_compile_time": "",
|
||||||
"upgrade_for_longer_compiles": "",
|
|
||||||
"upgrade_for_plenty_more_compile_time": "",
|
|
||||||
"upgrade_now": "",
|
"upgrade_now": "",
|
||||||
"upgrade_to_get_feature": "",
|
"upgrade_to_get_feature": "",
|
||||||
"upgrade_to_track_changes": "",
|
"upgrade_to_track_changes": "",
|
||||||
|
@ -1519,8 +1502,6 @@
|
||||||
"we_sent_new_code": "",
|
"we_sent_new_code": "",
|
||||||
"wed_love_you_to_stay": "",
|
"wed_love_you_to_stay": "",
|
||||||
"welcome_to_sl": "",
|
"welcome_to_sl": "",
|
||||||
"were_in_the_process_of_reducing_compile_timeout_which_may_affect_this_project": "",
|
|
||||||
"were_in_the_process_of_reducing_compile_timeout_which_may_affect_your_project": "",
|
|
||||||
"were_performing_maintenance": "",
|
"were_performing_maintenance": "",
|
||||||
"weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_this_project": "",
|
"weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_this_project": "",
|
||||||
"weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_your_project": "",
|
"weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_your_project": "",
|
||||||
|
@ -1571,7 +1552,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": "",
|
||||||
"you_have_been_removed_from_this_project_and_will_be_redirected_to_project_dashboard": "",
|
"you_have_been_removed_from_this_project_and_will_be_redirected_to_project_dashboard": "",
|
||||||
"you_may_be_able_to_fix_issues_to_speed_up_the_compile": "",
|
|
||||||
"you_need_to_configure_your_sso_settings": "",
|
"you_need_to_configure_your_sso_settings": "",
|
||||||
"you_will_be_able_to_reassign_subscription": "",
|
"you_will_be_able_to_reassign_subscription": "",
|
||||||
"youll_get_best_results_in_visual_but_can_be_used_in_source": "",
|
"youll_get_best_results_in_visual_but_can_be_used_in_source": "",
|
||||||
|
@ -1591,7 +1571,6 @@
|
||||||
"your_new_plan": "",
|
"your_new_plan": "",
|
||||||
"your_plan": "",
|
"your_plan": "",
|
||||||
"your_plan_is_changing_at_term_end": "",
|
"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_exceeded_compile_timeout_limit_on_free_plan": "",
|
||||||
"your_project_near_compile_timeout_limit": "",
|
"your_project_near_compile_timeout_limit": "",
|
||||||
"your_projects": "",
|
"your_projects": "",
|
||||||
|
|
|
@ -4,10 +4,9 @@ import { useTranslation } from 'react-i18next'
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import { useSplitTestContext } from '@/shared/context/split-test-context'
|
import { useSplitTestContext } from '@/shared/context/split-test-context'
|
||||||
|
|
||||||
export const CompileTimeoutWarning: FC<{
|
export const CompileTimeWarningUpgradePromptInner: FC<{
|
||||||
handleDismissWarning: () => void
|
handleDismissWarning: () => void
|
||||||
showNewCompileTimeoutUI?: string
|
}> = ({ handleDismissWarning }) => {
|
||||||
}> = ({ handleDismissWarning, showNewCompileTimeoutUI }) => {
|
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const { splitTestVariants } = useSplitTestContext()
|
const { splitTestVariants } = useSplitTestContext()
|
||||||
|
@ -34,14 +33,8 @@ export const CompileTimeoutWarning: FC<{
|
||||||
<div>
|
<div>
|
||||||
<span>{t('your_project_near_compile_timeout_limit')}</span>
|
<span>{t('your_project_near_compile_timeout_limit')}</span>
|
||||||
</div>
|
</div>
|
||||||
{showNewCompileTimeoutUI === 'active' ? (
|
<strong>{t('upgrade_for_12x_more_compile_time')}</strong>
|
||||||
<>
|
{'. '}
|
||||||
<strong>{t('upgrade_for_12x_more_compile_time')}</strong>
|
|
||||||
{'. '}
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<strong>{t('upgrade_for_plenty_more_compile_time')}</strong>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
type="warning"
|
type="warning"
|
|
@ -0,0 +1,78 @@
|
||||||
|
import { memo, useCallback, useEffect, useState } 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 { CompileTimeWarningUpgradePromptInner } from '@/features/pdf-preview/components/compile-time-warning-upgrade-prompt-inner'
|
||||||
|
|
||||||
|
function CompileTimeWarningUpgradePrompt() {
|
||||||
|
const { isProjectOwner, deliveryLatencies, compiling, showLogs, error } =
|
||||||
|
useDetachCompileContext()
|
||||||
|
|
||||||
|
const [showWarning, setShowWarning] = useState(false)
|
||||||
|
const [dismissedUntilWarning, setDismissedUntilWarning] = usePersistedState<
|
||||||
|
Date | undefined
|
||||||
|
>(`has-dismissed-10s-compile-time-warning-until`)
|
||||||
|
|
||||||
|
const handleNewCompile = useCallback(
|
||||||
|
compileTime => {
|
||||||
|
setShowWarning(false)
|
||||||
|
if (compileTime > 10000) {
|
||||||
|
if (isProjectOwner) {
|
||||||
|
if (
|
||||||
|
!dismissedUntilWarning ||
|
||||||
|
new Date(dismissedUntilWarning) < new Date()
|
||||||
|
) {
|
||||||
|
setShowWarning(true)
|
||||||
|
eventTracking.sendMB('compile-time-warning-displayed', {
|
||||||
|
time: 10,
|
||||||
|
isProjectOwner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[isProjectOwner, dismissedUntilWarning]
|
||||||
|
)
|
||||||
|
|
||||||
|
const handleDismissWarning = useCallback(() => {
|
||||||
|
eventTracking.sendMB('compile-time-warning-dismissed', {
|
||||||
|
time: 10,
|
||||||
|
isProjectOwner,
|
||||||
|
})
|
||||||
|
setShowWarning(false)
|
||||||
|
const until = new Date()
|
||||||
|
until.setDate(until.getDate() + 1) // 1 day
|
||||||
|
setDismissedUntilWarning(until)
|
||||||
|
}, [isProjectOwner, setDismissedUntilWarning])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (compiling || error || showLogs) return
|
||||||
|
handleNewCompile(deliveryLatencies.compileTimeServerE2E)
|
||||||
|
}, [compiling, error, showLogs, deliveryLatencies, handleNewCompile])
|
||||||
|
|
||||||
|
if (!window.ExposedSettings.enableSubscriptions) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compiling || error || showLogs) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!showWarning) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// if showWarning is true then the 10s warning is shown
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{showWarning && isProjectOwner && (
|
||||||
|
<CompileTimeWarningUpgradePromptInner
|
||||||
|
handleDismissWarning={handleDismissWarning}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(CompileTimeWarningUpgradePrompt)
|
|
@ -1,116 +0,0 @@
|
||||||
import { memo, useCallback, useEffect } from 'react'
|
|
||||||
import { Button } from 'react-bootstrap'
|
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
|
||||||
import * as eventTracking from '../../../infrastructure/event-tracking'
|
|
||||||
import StartFreeTrialButton from '../../../shared/components/start-free-trial-button'
|
|
||||||
import { useDetachCompileContext } from '../../../shared/context/detach-compile-context'
|
|
||||||
import usePersistedState from '../../../shared/hooks/use-persisted-state'
|
|
||||||
import { useSplitTestContext } from '@/shared/context/split-test-context'
|
|
||||||
|
|
||||||
const TWENTY_FOUR_DAYS = 24 * 60 * 60 * 24 * 1000
|
|
||||||
|
|
||||||
function CompileTimeWarning() {
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
const [displayStatus, setDisplayStatus] = usePersistedState(
|
|
||||||
'compile-time-warning-display-status',
|
|
||||||
{ lastDisplayTime: 0, dismissed: false },
|
|
||||||
true
|
|
||||||
)
|
|
||||||
|
|
||||||
const {
|
|
||||||
showCompileTimeWarning,
|
|
||||||
setShowCompileTimeWarning,
|
|
||||||
deliveryLatencies,
|
|
||||||
isProjectOwner,
|
|
||||||
} = useDetachCompileContext()
|
|
||||||
|
|
||||||
const { splitTestVariants } = useSplitTestContext()
|
|
||||||
const hasNewPaywallCta = splitTestVariants['paywall-cta'] === 'enabled'
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (deliveryLatencies && deliveryLatencies.compileTimeServerE2E) {
|
|
||||||
// compile-timeout-20s test
|
|
||||||
if (deliveryLatencies.compileTimeServerE2E > 10000) {
|
|
||||||
eventTracking.sendMB('compile-time-warning-would-display', {
|
|
||||||
time: 10,
|
|
||||||
newCompileTimeout: 'control',
|
|
||||||
isProjectOwner,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [deliveryLatencies, isProjectOwner])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (showCompileTimeWarning) {
|
|
||||||
if (
|
|
||||||
displayStatus &&
|
|
||||||
Date.now() - displayStatus.lastDisplayTime < TWENTY_FOUR_DAYS
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
setDisplayStatus({ lastDisplayTime: Date.now(), dismissed: false })
|
|
||||||
eventTracking.sendMB('compile-time-warning-displayed', { time: 30 })
|
|
||||||
}
|
|
||||||
}, [showCompileTimeWarning, displayStatus, setDisplayStatus])
|
|
||||||
|
|
||||||
const getTimeSinceDisplayed = useCallback(() => {
|
|
||||||
return (Date.now() - displayStatus.lastDisplayTime) / 1000
|
|
||||||
}, [displayStatus])
|
|
||||||
|
|
||||||
const closeWarning = useCallback(() => {
|
|
||||||
eventTracking.sendMB('compile-time-warning-dismissed', {
|
|
||||||
'time-since-displayed': getTimeSinceDisplayed(),
|
|
||||||
time: 30,
|
|
||||||
})
|
|
||||||
setShowCompileTimeWarning(false)
|
|
||||||
setDisplayStatus(displayStatus => ({ ...displayStatus, dismissed: true }))
|
|
||||||
}, [getTimeSinceDisplayed, setShowCompileTimeWarning, setDisplayStatus])
|
|
||||||
|
|
||||||
const handleUpgradeClick = useCallback(() => {
|
|
||||||
eventTracking.sendMB('compile-time-warning-upgrade-click', {
|
|
||||||
'time-since-displayed': getTimeSinceDisplayed(),
|
|
||||||
time: 30,
|
|
||||||
})
|
|
||||||
setShowCompileTimeWarning(false)
|
|
||||||
setDisplayStatus(displayStatus => ({ ...displayStatus, dismissed: true }))
|
|
||||||
}, [getTimeSinceDisplayed, setShowCompileTimeWarning, setDisplayStatus])
|
|
||||||
|
|
||||||
if (!showCompileTimeWarning || displayStatus.dismissed) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="alert alert-success compile-time-warning" role="alert">
|
|
||||||
<Button
|
|
||||||
className="close"
|
|
||||||
data-dismiss="alert"
|
|
||||||
aria-label="Close"
|
|
||||||
onClick={closeWarning}
|
|
||||||
>
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</Button>
|
|
||||||
<div className="warning-content">
|
|
||||||
<div className="warning-text">
|
|
||||||
<Trans
|
|
||||||
i18nKey="approaching_compile_timeout_limit_upgrade_for_more_compile_time"
|
|
||||||
components={{
|
|
||||||
strong: <strong style={{ display: 'inline-block' }} />,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="upgrade-prompt">
|
|
||||||
<StartFreeTrialButton
|
|
||||||
buttonProps={{ bsStyle: 'primary', bsSize: 'sm' }}
|
|
||||||
handleClick={handleUpgradeClick}
|
|
||||||
source="compile-time-warning"
|
|
||||||
>
|
|
||||||
{hasNewPaywallCta ? t('get_more_compile_time') : t('upgrade')}
|
|
||||||
</StartFreeTrialButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(CompileTimeWarning)
|
|
|
@ -1,122 +0,0 @@
|
||||||
import Notification from '@/shared/components/notification'
|
|
||||||
import StartFreeTrialButton from '@/shared/components/start-free-trial-button'
|
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
|
||||||
import * as eventTracking from '@/infrastructure/event-tracking'
|
|
||||||
import { FC } from 'react'
|
|
||||||
import { useSplitTestContext } from '@/shared/context/split-test-context'
|
|
||||||
|
|
||||||
const sendInfoClickEvent = () => {
|
|
||||||
eventTracking.sendMB('paywall-info-click', {
|
|
||||||
'paywall-type': 'compile-time-warning',
|
|
||||||
content: 'blog',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CompileTimeoutChangingSoon: FC<{
|
|
||||||
isProjectOwner?: boolean
|
|
||||||
handleDismissChangingSoon: () => void
|
|
||||||
}> = ({ isProjectOwner = false, handleDismissChangingSoon }) => {
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
const { splitTestVariants } = useSplitTestContext()
|
|
||||||
const hasNewPaywallCta = splitTestVariants['paywall-cta'] === 'enabled'
|
|
||||||
|
|
||||||
const compileTimeoutChangesBlogLink = (
|
|
||||||
/* eslint-disable-next-line jsx-a11y/anchor-has-content */
|
|
||||||
<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}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
|
|
||||||
const fixingCompileTimeoutsLearnLink = (
|
|
||||||
/* eslint-disable-next-line jsx-a11y/anchor-has-content */
|
|
||||||
<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 (isProjectOwner) {
|
|
||||||
return (
|
|
||||||
<Notification
|
|
||||||
action={
|
|
||||||
<StartFreeTrialButton
|
|
||||||
variant="new-changing"
|
|
||||||
source="compile-time-warning"
|
|
||||||
buttonProps={{
|
|
||||||
className: 'btn-secondary-compile-timeout-override',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{hasNewPaywallCta
|
|
||||||
? t('get_more_compile_time')
|
|
||||||
: t('start_free_trial_without_exclamation')}
|
|
||||||
</StartFreeTrialButton>
|
|
||||||
}
|
|
||||||
ariaLive="polite"
|
|
||||||
content={
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
<Trans
|
|
||||||
i18nKey="compiles_on_our_free_plan_are_now_on_faster_servers"
|
|
||||||
components={[compileTimeoutChangesBlogLink]}
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
<p className="row-spaced">
|
|
||||||
<Trans
|
|
||||||
i18nKey="you_may_be_able_to_fix_issues_to_speed_up_the_compile"
|
|
||||||
components={[fixingCompileTimeoutsLearnLink]}
|
|
||||||
/>{' '}
|
|
||||||
<Trans
|
|
||||||
i18nKey="and_you_can_upgrade_for_plenty_more_compile_time"
|
|
||||||
components={{ strong: <strong /> }}
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
title={t('your_project_compiled_but_soon_might_not')}
|
|
||||||
type="warning"
|
|
||||||
isActionBelowContent
|
|
||||||
isDismissible
|
|
||||||
onDismiss={handleDismissChangingSoon}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Notification
|
|
||||||
ariaLive="polite"
|
|
||||||
content={
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
<Trans
|
|
||||||
i18nKey="compiles_on_our_free_plan_are_now_on_faster_servers"
|
|
||||||
components={[compileTimeoutChangesBlogLink]}
|
|
||||||
/>{' '}
|
|
||||||
<Trans
|
|
||||||
i18nKey="you_may_be_able_to_fix_issues_to_speed_up_the_compile"
|
|
||||||
components={[fixingCompileTimeoutsLearnLink]}
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
<p className="row-spaced">
|
|
||||||
<Trans
|
|
||||||
i18nKey="tell_the_project_owner_to_upgrade_plan_for_more_compile_time"
|
|
||||||
components={{ strong: <strong /> }}
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
title={t('this_project_compiled_but_soon_might_not')}
|
|
||||||
type="warning"
|
|
||||||
isDismissible
|
|
||||||
onDismiss={handleDismissChangingSoon}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,126 +0,0 @@
|
||||||
import { memo, useCallback, useEffect, useMemo, useState } 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 { CompileTimeoutWarning } from '@/features/pdf-preview/components/compile-timeout-warning'
|
|
||||||
import { CompileTimeoutChangingSoon } from '@/features/pdf-preview/components/compile-timeout-changing-soon'
|
|
||||||
|
|
||||||
function CompileTimeoutMessages() {
|
|
||||||
const {
|
|
||||||
showNewCompileTimeoutUI,
|
|
||||||
isProjectOwner,
|
|
||||||
deliveryLatencies,
|
|
||||||
compiling,
|
|
||||||
showLogs,
|
|
||||||
error,
|
|
||||||
} = useDetachCompileContext()
|
|
||||||
|
|
||||||
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,
|
|
||||||
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,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[
|
|
||||||
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
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 && (
|
|
||||||
<CompileTimeoutWarning
|
|
||||||
showNewCompileTimeoutUI={showNewCompileTimeoutUI}
|
|
||||||
handleDismissWarning={handleDismissWarning}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{showChangingSoon && (
|
|
||||||
<CompileTimeoutChangingSoon
|
|
||||||
isProjectOwner={isProjectOwner}
|
|
||||||
handleDismissChangingSoon={handleDismissChangingSoon}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(CompileTimeoutMessages)
|
|
|
@ -1,135 +0,0 @@
|
||||||
import { memo, useEffect, useRef, useState } from 'react'
|
|
||||||
import { Button, Alert } from 'react-bootstrap'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
|
||||||
import Icon from '../../../shared/components/icon'
|
|
||||||
import { sendMB } from '../../../infrastructure/event-tracking'
|
|
||||||
import usePersistedState from '../../../shared/hooks/use-persisted-state'
|
|
||||||
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
|
|
||||||
import { useProjectContext } from '../../../shared/context/project-context'
|
|
||||||
|
|
||||||
const SAY_THANKS_TIMEOUT = 10 * 1000
|
|
||||||
|
|
||||||
function FasterCompilesFeedbackContent() {
|
|
||||||
const { clsiServerId, deliveryLatencies, pdfFile, pdfUrl } =
|
|
||||||
useCompileContext()
|
|
||||||
const { _id: projectId } = useProjectContext()
|
|
||||||
|
|
||||||
const [incrementalCompiles, setIncrementalCompiles] = useState(0)
|
|
||||||
const [hasRatedProject, setHasRatedProject] = usePersistedState(
|
|
||||||
`faster-compiles-feedback:${projectId}`,
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
const [dismiss, setDismiss] = usePersistedState(
|
|
||||||
'faster-compiles-feedback:dismiss',
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
const [sayThanks, setSayThanks] = useState(false)
|
|
||||||
const lastClsiServerId = useRef<string | undefined>(undefined)
|
|
||||||
const lastPdfUrl = useRef<string | undefined>(undefined)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (
|
|
||||||
!pdfUrl ||
|
|
||||||
!lastPdfUrl.current ||
|
|
||||||
clsiServerId !== lastClsiServerId.current
|
|
||||||
) {
|
|
||||||
// Reset history after
|
|
||||||
// - clearing cache / server error (both reset pdfUrl)
|
|
||||||
// - initial compile after reset of pdfUrl
|
|
||||||
// - switching the clsi server, aka we get a _slow_ full compile.
|
|
||||||
setIncrementalCompiles(0)
|
|
||||||
lastClsiServerId.current = clsiServerId
|
|
||||||
} else {
|
|
||||||
setIncrementalCompiles(n => n + 1)
|
|
||||||
}
|
|
||||||
lastPdfUrl.current = pdfUrl
|
|
||||||
}, [clsiServerId, lastPdfUrl, pdfUrl, setIncrementalCompiles])
|
|
||||||
|
|
||||||
function submitFeedback(feedback = '') {
|
|
||||||
sendMB('faster-compiles-feedback', {
|
|
||||||
projectId,
|
|
||||||
server: clsiServerId?.includes('-c2d-') ? 'faster' : 'normal',
|
|
||||||
feedback,
|
|
||||||
pdfSize: pdfFile?.size,
|
|
||||||
...deliveryLatencies,
|
|
||||||
})
|
|
||||||
setHasRatedProject(true)
|
|
||||||
setSayThanks(true)
|
|
||||||
window.setTimeout(() => {
|
|
||||||
setSayThanks(false)
|
|
||||||
}, SAY_THANKS_TIMEOUT)
|
|
||||||
}
|
|
||||||
|
|
||||||
function dismissFeedback() {
|
|
||||||
sendMB('faster-compiles-feedback-dismiss')
|
|
||||||
setDismiss(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
// Hide the feedback prompt in all these cases:
|
|
||||||
// - the initial compile (0), its always perceived as _slow_.
|
|
||||||
// - the first incremental compile (1), its always _faster_ than ^.
|
|
||||||
// - the user has dismissed the prompt
|
|
||||||
// - the user has rated compile speed already (say thanks if needed)
|
|
||||||
switch (true) {
|
|
||||||
case sayThanks:
|
|
||||||
return (
|
|
||||||
<Alert
|
|
||||||
bsStyle="info"
|
|
||||||
className="faster-compiles-feedback"
|
|
||||||
onClick={() => setSayThanks(false)}
|
|
||||||
>
|
|
||||||
{t('faster_compiles_feedback_thanks')}
|
|
||||||
</Alert>
|
|
||||||
)
|
|
||||||
case dismiss || hasRatedProject:
|
|
||||||
return null
|
|
||||||
case incrementalCompiles > 1:
|
|
||||||
return (
|
|
||||||
<Alert bsStyle="info" className="faster-compiles-feedback">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
aria-label={t('dismiss')}
|
|
||||||
className="btn-inline-link faster-compiles-feedback-dismiss"
|
|
||||||
onClick={dismissFeedback}
|
|
||||||
>
|
|
||||||
<Icon type="close" fw />
|
|
||||||
</button>
|
|
||||||
{t('faster_compiles_feedback_question')}
|
|
||||||
<div className="faster-compiles-feedback-options">
|
|
||||||
{['slower', 'same', 'faster'].map(feedback => (
|
|
||||||
<Button
|
|
||||||
bsStyle="default"
|
|
||||||
bsSize="xs"
|
|
||||||
className="faster-compiles-feedback-option"
|
|
||||||
onClick={() => submitFeedback(feedback)}
|
|
||||||
key={feedback}
|
|
||||||
>
|
|
||||||
{feedback === 'faster'
|
|
||||||
? t('faster_compiles_feedback_seems_faster')
|
|
||||||
: feedback === 'same'
|
|
||||||
? t('faster_compiles_feedback_seems_same')
|
|
||||||
: t('faster_compiles_feedback_seems_slower')}
|
|
||||||
</Button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</Alert>
|
|
||||||
)
|
|
||||||
default:
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function FasterCompilesFeedback() {
|
|
||||||
const { showFasterCompilesFeedbackUI } = useCompileContext()
|
|
||||||
|
|
||||||
if (!showFasterCompilesFeedbackUI) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return <FasterCompilesFeedbackContent />
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(FasterCompilesFeedback)
|
|
|
@ -3,7 +3,6 @@ import { memo } from 'react'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import PdfValidationIssue from './pdf-validation-issue'
|
import PdfValidationIssue from './pdf-validation-issue'
|
||||||
import StopOnFirstErrorPrompt from './stop-on-first-error-prompt'
|
import StopOnFirstErrorPrompt from './stop-on-first-error-prompt'
|
||||||
import TimeoutUpgradePrompt from './timeout-upgrade-prompt'
|
|
||||||
import TimeoutUpgradePromptNew from './timeout-upgrade-prompt-new'
|
import TimeoutUpgradePromptNew from './timeout-upgrade-prompt-new'
|
||||||
import PdfPreviewError from './pdf-preview-error'
|
import PdfPreviewError from './pdf-preview-error'
|
||||||
import PdfClearCacheButton from './pdf-clear-cache-button'
|
import PdfClearCacheButton from './pdf-clear-cache-button'
|
||||||
|
@ -20,12 +19,12 @@ function PdfLogsViewer() {
|
||||||
const {
|
const {
|
||||||
codeCheckFailed,
|
codeCheckFailed,
|
||||||
error,
|
error,
|
||||||
|
hasShortCompileTimeout,
|
||||||
logEntries,
|
logEntries,
|
||||||
rawLog,
|
rawLog,
|
||||||
validationIssues,
|
validationIssues,
|
||||||
showLogs,
|
showLogs,
|
||||||
stoppedOnFirstError,
|
stoppedOnFirstError,
|
||||||
showNewCompileTimeoutUI,
|
|
||||||
} = useCompileContext()
|
} = useCompileContext()
|
||||||
|
|
||||||
const { loadingError } = usePdfPreviewContext()
|
const { loadingError } = usePdfPreviewContext()
|
||||||
|
@ -45,13 +44,10 @@ function PdfLogsViewer() {
|
||||||
|
|
||||||
{loadingError && <PdfPreviewError error="pdf-viewer-loading-error" />}
|
{loadingError && <PdfPreviewError error="pdf-viewer-loading-error" />}
|
||||||
|
|
||||||
{showNewCompileTimeoutUI && error === 'timedout' ? (
|
{hasShortCompileTimeout && error === 'timedout' ? (
|
||||||
<TimeoutUpgradePromptNew />
|
<TimeoutUpgradePromptNew />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>{error && <PdfPreviewError error={error} />}</>
|
||||||
{error && <PdfPreviewError error={error} />}
|
|
||||||
{error === 'timedout' && <TimeoutUpgradePrompt />}
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{validationIssues &&
|
{validationIssues &&
|
||||||
|
|
|
@ -5,14 +5,12 @@ import PdfViewer from './pdf-viewer'
|
||||||
import { FullSizeLoadingSpinner } from '../../../shared/components/loading-spinner'
|
import { FullSizeLoadingSpinner } from '../../../shared/components/loading-spinner'
|
||||||
import PdfHybridPreviewToolbar from './pdf-preview-hybrid-toolbar'
|
import PdfHybridPreviewToolbar from './pdf-preview-hybrid-toolbar'
|
||||||
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
|
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
|
||||||
import FasterCompilesFeedback from './faster-compiles-feedback'
|
|
||||||
import { PdfPreviewMessages } from './pdf-preview-messages'
|
import { PdfPreviewMessages } from './pdf-preview-messages'
|
||||||
import CompileTimeWarning from './compile-time-warning'
|
import CompileTimeWarningUpgradePrompt from './compile-time-warning-upgrade-prompt'
|
||||||
import CompileTimeoutMessages from './compile-timeout-messages'
|
|
||||||
import { PdfPreviewProvider } from './pdf-preview-provider'
|
import { PdfPreviewProvider } from './pdf-preview-provider'
|
||||||
|
|
||||||
function PdfPreviewPane() {
|
function PdfPreviewPane() {
|
||||||
const { pdfUrl, showNewCompileTimeoutUI } = useCompileContext()
|
const { pdfUrl, hasShortCompileTimeout } = useCompileContext()
|
||||||
const classes = classNames('pdf', 'full-size', {
|
const classes = classNames('pdf', 'full-size', {
|
||||||
'pdf-empty': !pdfUrl,
|
'pdf-empty': !pdfUrl,
|
||||||
})
|
})
|
||||||
|
@ -21,16 +19,11 @@ function PdfPreviewPane() {
|
||||||
<PdfPreviewProvider>
|
<PdfPreviewProvider>
|
||||||
<PdfHybridPreviewToolbar />
|
<PdfHybridPreviewToolbar />
|
||||||
<PdfPreviewMessages>
|
<PdfPreviewMessages>
|
||||||
{showNewCompileTimeoutUI ? (
|
{hasShortCompileTimeout && <CompileTimeWarningUpgradePrompt />}
|
||||||
<CompileTimeoutMessages />
|
|
||||||
) : (
|
|
||||||
<CompileTimeWarning />
|
|
||||||
)}
|
|
||||||
</PdfPreviewMessages>
|
</PdfPreviewMessages>
|
||||||
<Suspense fallback={<FullSizeLoadingSpinner delay={500} />}>
|
<Suspense fallback={<FullSizeLoadingSpinner delay={500} />}>
|
||||||
<div className="pdf-viewer">
|
<div className="pdf-viewer">
|
||||||
<PdfViewer />
|
<PdfViewer />
|
||||||
<FasterCompilesFeedback />
|
|
||||||
</div>
|
</div>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
<PdfLogsViewer />
|
<PdfLogsViewer />
|
||||||
|
|
|
@ -13,7 +13,6 @@ function TimeoutUpgradePromptNew() {
|
||||||
startCompile,
|
startCompile,
|
||||||
lastCompileOptions,
|
lastCompileOptions,
|
||||||
setAnimateCompileDropdownArrow,
|
setAnimateCompileDropdownArrow,
|
||||||
showNewCompileTimeoutUI,
|
|
||||||
isProjectOwner,
|
isProjectOwner,
|
||||||
} = useDetachCompileContext()
|
} = useDetachCompileContext()
|
||||||
|
|
||||||
|
@ -27,35 +26,25 @@ function TimeoutUpgradePromptNew() {
|
||||||
setAnimateCompileDropdownArrow(true)
|
setAnimateCompileDropdownArrow(true)
|
||||||
}, [enableStopOnFirstError, startCompile, setAnimateCompileDropdownArrow])
|
}, [enableStopOnFirstError, startCompile, setAnimateCompileDropdownArrow])
|
||||||
|
|
||||||
if (!window.ExposedSettings.enableSubscriptions) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
const compileTimeChanging = showNewCompileTimeoutUI === 'changing'
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<CompileTimeout
|
<CompileTimeout isProjectOwner={isProjectOwner} />
|
||||||
compileTimeChanging={compileTimeChanging}
|
{window.ExposedSettings.enableSubscriptions && (
|
||||||
isProjectOwner={isProjectOwner}
|
<PreventTimeoutHelpMessage
|
||||||
/>
|
handleEnableStopOnFirstErrorClick={handleEnableStopOnFirstErrorClick}
|
||||||
<PreventTimeoutHelpMessage
|
lastCompileOptions={lastCompileOptions}
|
||||||
compileTimeChanging={compileTimeChanging}
|
isProjectOwner={isProjectOwner}
|
||||||
handleEnableStopOnFirstErrorClick={handleEnableStopOnFirstErrorClick}
|
/>
|
||||||
lastCompileOptions={lastCompileOptions}
|
)}
|
||||||
isProjectOwner={isProjectOwner}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CompileTimeoutProps = {
|
type CompileTimeoutProps = {
|
||||||
compileTimeChanging?: boolean
|
|
||||||
isProjectOwner: boolean
|
isProjectOwner: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const CompileTimeout = memo(function CompileTimeout({
|
const CompileTimeout = memo(function CompileTimeout({
|
||||||
compileTimeChanging,
|
|
||||||
isProjectOwner,
|
isProjectOwner,
|
||||||
}: CompileTimeoutProps) {
|
}: CompileTimeoutProps) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
@ -67,58 +56,48 @@ const CompileTimeout = memo(function CompileTimeout({
|
||||||
<PdfLogEntry
|
<PdfLogEntry
|
||||||
headerTitle={t('your_compile_timed_out')}
|
headerTitle={t('your_compile_timed_out')}
|
||||||
formattedContent={
|
formattedContent={
|
||||||
<>
|
window.ExposedSettings.enableSubscriptions && (
|
||||||
<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>
|
<p>
|
||||||
{compileTimeChanging ? (
|
{isProjectOwner
|
||||||
<>
|
? t('your_project_exceeded_compile_timeout_limit_on_free_plan')
|
||||||
<strong>{t('upgrade_for_plenty_more_compile_time')}</strong>{' '}
|
: t('this_project_exceeded_compile_timeout_limit_on_free_plan')}
|
||||||
{t(
|
|
||||||
'plus_additional_collaborators_document_history_track_changes_and_more'
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<strong>{t('upgrade_for_12x_more_compile_time')}</strong>{' '}
|
|
||||||
{t(
|
|
||||||
'plus_additional_collaborators_document_history_track_changes_and_more'
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</p>
|
</p>
|
||||||
) : (
|
{isProjectOwner ? (
|
||||||
<Trans
|
<p>
|
||||||
i18nKey="tell_the_project_owner_and_ask_them_to_upgrade"
|
<strong>{t('upgrade_for_12x_more_compile_time')}</strong>{' '}
|
||||||
components={[
|
{t(
|
||||||
// eslint-disable-next-line react/jsx-key
|
'plus_additional_collaborators_document_history_track_changes_and_more'
|
||||||
<strong />,
|
)}
|
||||||
]}
|
</p>
|
||||||
/>
|
) : (
|
||||||
)}
|
<Trans
|
||||||
|
i18nKey="tell_the_project_owner_and_ask_them_to_upgrade"
|
||||||
|
components={[
|
||||||
|
// eslint-disable-next-line react/jsx-key
|
||||||
|
<strong />,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{isProjectOwner && (
|
{isProjectOwner && (
|
||||||
<p className="text-center">
|
<p className="text-center">
|
||||||
<StartFreeTrialButton
|
<StartFreeTrialButton
|
||||||
variant={compileTimeChanging ? 'new-changing' : 'new-20s'}
|
source="compile-timeout"
|
||||||
source="compile-timeout"
|
buttonProps={{
|
||||||
buttonProps={{
|
bsStyle: 'success',
|
||||||
bsStyle: 'success',
|
className: 'row-spaced-small',
|
||||||
className: 'row-spaced-small',
|
block: true,
|
||||||
block: true,
|
}}
|
||||||
}}
|
>
|
||||||
>
|
{hasNewPaywallCta
|
||||||
{hasNewPaywallCta
|
? t('get_more_compile_time')
|
||||||
? t('get_more_compile_time')
|
: t('start_a_free_trial')}
|
||||||
: t('start_a_free_trial')}
|
</StartFreeTrialButton>
|
||||||
</StartFreeTrialButton>
|
</p>
|
||||||
</p>
|
)}
|
||||||
)}
|
</>
|
||||||
</>
|
)
|
||||||
}
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
entryAriaLabel={t('your_compile_timed_out')}
|
entryAriaLabel={t('your_compile_timed_out')}
|
||||||
|
@ -128,14 +107,12 @@ const CompileTimeout = memo(function CompileTimeout({
|
||||||
})
|
})
|
||||||
|
|
||||||
type PreventTimeoutHelpMessageProps = {
|
type PreventTimeoutHelpMessageProps = {
|
||||||
compileTimeChanging?: boolean
|
|
||||||
lastCompileOptions: any
|
lastCompileOptions: any
|
||||||
handleEnableStopOnFirstErrorClick: () => void
|
handleEnableStopOnFirstErrorClick: () => void
|
||||||
isProjectOwner: boolean
|
isProjectOwner: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const PreventTimeoutHelpMessage = memo(function PreventTimeoutHelpMessage({
|
const PreventTimeoutHelpMessage = memo(function PreventTimeoutHelpMessage({
|
||||||
compileTimeChanging,
|
|
||||||
lastCompileOptions,
|
lastCompileOptions,
|
||||||
handleEnableStopOnFirstErrorClick,
|
handleEnableStopOnFirstErrorClick,
|
||||||
isProjectOwner,
|
isProjectOwner,
|
||||||
|
@ -227,35 +204,19 @@ const PreventTimeoutHelpMessage = memo(function PreventTimeoutHelpMessage({
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<em>
|
<em>
|
||||||
{compileTimeChanging ? (
|
<>
|
||||||
<>
|
{isProjectOwner ? (
|
||||||
{isProjectOwner ? (
|
<Trans
|
||||||
<Trans
|
i18nKey="weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_your_project"
|
||||||
i18nKey="were_in_the_process_of_reducing_compile_timeout_which_may_affect_your_project"
|
components={[compileTimeoutChangesBlogLink]}
|
||||||
components={[compileTimeoutChangesBlogLink]}
|
/>
|
||||||
/>
|
) : (
|
||||||
) : (
|
<Trans
|
||||||
<Trans
|
i18nKey="weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_this_project"
|
||||||
i18nKey="were_in_the_process_of_reducing_compile_timeout_which_may_affect_this_project"
|
components={[compileTimeoutChangesBlogLink]}
|
||||||
components={[compileTimeoutChangesBlogLink]}
|
/>
|
||||||
/>
|
)}
|
||||||
)}
|
</>
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
{isProjectOwner ? (
|
|
||||||
<Trans
|
|
||||||
i18nKey="weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_your_project"
|
|
||||||
components={[compileTimeoutChangesBlogLink]}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Trans
|
|
||||||
i18nKey="weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_this_project"
|
|
||||||
components={[compileTimeoutChangesBlogLink]}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</em>
|
</em>
|
||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
import { useTranslation } from 'react-i18next'
|
|
||||||
import { useEditorContext } from '../../../shared/context/editor-context'
|
|
||||||
import StartFreeTrialButton from '../../../shared/components/start-free-trial-button'
|
|
||||||
import { memo } from 'react'
|
|
||||||
import PdfLogEntry from './pdf-log-entry'
|
|
||||||
import UpgradeBenefits from '../../../shared/components/upgrade-benefits'
|
|
||||||
import { useSplitTestContext } from '@/shared/context/split-test-context'
|
|
||||||
|
|
||||||
function TimeoutUpgradePrompt() {
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
const { hasPremiumCompile, isProjectOwner } = useEditorContext()
|
|
||||||
|
|
||||||
const { splitTestVariants } = useSplitTestContext()
|
|
||||||
const hasNewPaywallCta = splitTestVariants['paywall-cta'] === 'enabled'
|
|
||||||
|
|
||||||
if (!window.ExposedSettings.enableSubscriptions || hasPremiumCompile) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PdfLogEntry
|
|
||||||
headerTitle={
|
|
||||||
isProjectOwner
|
|
||||||
? t('upgrade_for_longer_compiles')
|
|
||||||
: t('ask_proj_owner_to_upgrade_for_longer_compiles')
|
|
||||||
}
|
|
||||||
formattedContent={
|
|
||||||
<>
|
|
||||||
<p>{t('free_accounts_have_timeout_upgrade_to_increase')}</p>
|
|
||||||
<p>{t('plus_upgraded_accounts_receive')}:</p>
|
|
||||||
<div>
|
|
||||||
<UpgradeBenefits />
|
|
||||||
</div>
|
|
||||||
{isProjectOwner && (
|
|
||||||
<p className="text-center">
|
|
||||||
<StartFreeTrialButton
|
|
||||||
source="compile-timeout"
|
|
||||||
buttonProps={{
|
|
||||||
bsStyle: 'success',
|
|
||||||
className: 'row-spaced-small',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{hasNewPaywallCta
|
|
||||||
? t('get_more_compile_time')
|
|
||||||
: t('start_free_trial')}
|
|
||||||
</StartFreeTrialButton>
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
entryAriaLabel={
|
|
||||||
isProjectOwner
|
|
||||||
? t('upgrade_for_longer_compiles')
|
|
||||||
: t('ask_proj_owner_to_upgrade_for_longer_compiles')
|
|
||||||
}
|
|
||||||
level="success"
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(TimeoutUpgradePrompt)
|
|
|
@ -221,14 +221,6 @@ export default class DocumentCompiler {
|
||||||
params.file_line_errors = 'true'
|
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
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ export const DetachCompileProvider: FC = ({ children }) => {
|
||||||
error: _error,
|
error: _error,
|
||||||
fileList: _fileList,
|
fileList: _fileList,
|
||||||
hasChanges: _hasChanges,
|
hasChanges: _hasChanges,
|
||||||
|
hasShortCompileTimeout: _hasShortCompileTimeout,
|
||||||
highlights: _highlights,
|
highlights: _highlights,
|
||||||
isProjectOwner: _isProjectOwner,
|
isProjectOwner: _isProjectOwner,
|
||||||
lastCompileOptions: _lastCompileOptions,
|
lastCompileOptions: _lastCompileOptions,
|
||||||
|
@ -52,8 +53,6 @@ export const DetachCompileProvider: FC = ({ children }) => {
|
||||||
setStopOnValidationError: _setStopOnValidationError,
|
setStopOnValidationError: _setStopOnValidationError,
|
||||||
showLogs: _showLogs,
|
showLogs: _showLogs,
|
||||||
showCompileTimeWarning: _showCompileTimeWarning,
|
showCompileTimeWarning: _showCompileTimeWarning,
|
||||||
showNewCompileTimeoutUI: _showNewCompileTimeoutUI,
|
|
||||||
showFasterCompilesFeedbackUI: _showFasterCompilesFeedbackUI,
|
|
||||||
stopOnFirstError: _stopOnFirstError,
|
stopOnFirstError: _stopOnFirstError,
|
||||||
stopOnValidationError: _stopOnValidationError,
|
stopOnValidationError: _stopOnValidationError,
|
||||||
stoppedOnFirstError: _stoppedOnFirstError,
|
stoppedOnFirstError: _stoppedOnFirstError,
|
||||||
|
@ -126,6 +125,12 @@ export const DetachCompileProvider: FC = ({ children }) => {
|
||||||
'detacher',
|
'detacher',
|
||||||
'detached'
|
'detached'
|
||||||
)
|
)
|
||||||
|
const [hasShortCompileTimeout] = useDetachStateWatcher(
|
||||||
|
'hasShortCompileTimeout',
|
||||||
|
_hasShortCompileTimeout,
|
||||||
|
'detacher',
|
||||||
|
'detached'
|
||||||
|
)
|
||||||
const [highlights] = useDetachStateWatcher(
|
const [highlights] = useDetachStateWatcher(
|
||||||
'highlights',
|
'highlights',
|
||||||
_highlights,
|
_highlights,
|
||||||
|
@ -192,18 +197,6 @@ export const DetachCompileProvider: FC = ({ children }) => {
|
||||||
'detacher',
|
'detacher',
|
||||||
'detached'
|
'detached'
|
||||||
)
|
)
|
||||||
const [showNewCompileTimeoutUI] = useDetachStateWatcher(
|
|
||||||
'showNewCompileTimeoutUI',
|
|
||||||
_showNewCompileTimeoutUI,
|
|
||||||
'detacher',
|
|
||||||
'detached'
|
|
||||||
)
|
|
||||||
const [showFasterCompilesFeedbackUI] = useDetachStateWatcher(
|
|
||||||
'showFasterCompilesFeedbackUI',
|
|
||||||
_showFasterCompilesFeedbackUI,
|
|
||||||
'detacher',
|
|
||||||
'detached'
|
|
||||||
)
|
|
||||||
const [stopOnFirstError] = useDetachStateWatcher(
|
const [stopOnFirstError] = useDetachStateWatcher(
|
||||||
'stopOnFirstError',
|
'stopOnFirstError',
|
||||||
_stopOnFirstError,
|
_stopOnFirstError,
|
||||||
|
@ -386,6 +379,7 @@ export const DetachCompileProvider: FC = ({ children }) => {
|
||||||
error,
|
error,
|
||||||
fileList,
|
fileList,
|
||||||
hasChanges,
|
hasChanges,
|
||||||
|
hasShortCompileTimeout,
|
||||||
highlights,
|
highlights,
|
||||||
isProjectOwner,
|
isProjectOwner,
|
||||||
lastCompileOptions,
|
lastCompileOptions,
|
||||||
|
@ -413,8 +407,6 @@ export const DetachCompileProvider: FC = ({ children }) => {
|
||||||
setStopOnValidationError,
|
setStopOnValidationError,
|
||||||
showLogs,
|
showLogs,
|
||||||
showCompileTimeWarning,
|
showCompileTimeWarning,
|
||||||
showNewCompileTimeoutUI,
|
|
||||||
showFasterCompilesFeedbackUI,
|
|
||||||
startCompile,
|
startCompile,
|
||||||
stopCompile,
|
stopCompile,
|
||||||
stopOnFirstError,
|
stopOnFirstError,
|
||||||
|
@ -437,10 +429,11 @@ export const DetachCompileProvider: FC = ({ children }) => {
|
||||||
compiling,
|
compiling,
|
||||||
deliveryLatencies,
|
deliveryLatencies,
|
||||||
draft,
|
draft,
|
||||||
error,
|
|
||||||
editedSinceCompileStarted,
|
editedSinceCompileStarted,
|
||||||
|
error,
|
||||||
fileList,
|
fileList,
|
||||||
hasChanges,
|
hasChanges,
|
||||||
|
hasShortCompileTimeout,
|
||||||
highlights,
|
highlights,
|
||||||
isProjectOwner,
|
isProjectOwner,
|
||||||
lastCompileOptions,
|
lastCompileOptions,
|
||||||
|
@ -466,8 +459,6 @@ export const DetachCompileProvider: FC = ({ children }) => {
|
||||||
setStopOnValidationError,
|
setStopOnValidationError,
|
||||||
showCompileTimeWarning,
|
showCompileTimeWarning,
|
||||||
showLogs,
|
showLogs,
|
||||||
showNewCompileTimeoutUI,
|
|
||||||
showFasterCompilesFeedbackUI,
|
|
||||||
startCompile,
|
startCompile,
|
||||||
stopCompile,
|
stopCompile,
|
||||||
stopOnFirstError,
|
stopOnFirstError,
|
||||||
|
|
|
@ -49,6 +49,7 @@ export type CompileContext = {
|
||||||
error?: string
|
error?: string
|
||||||
fileList?: Record<string, any>
|
fileList?: Record<string, any>
|
||||||
hasChanges: boolean
|
hasChanges: boolean
|
||||||
|
hasShortCompileTimeout: boolean
|
||||||
highlights?: Record<string, any>[]
|
highlights?: Record<string, any>[]
|
||||||
isProjectOwner: boolean
|
isProjectOwner: boolean
|
||||||
logEntries?: Record<string, any>
|
logEntries?: Record<string, any>
|
||||||
|
@ -72,8 +73,6 @@ export type CompileContext = {
|
||||||
setStopOnValidationError: (value: boolean) => void
|
setStopOnValidationError: (value: boolean) => void
|
||||||
showCompileTimeWarning: boolean
|
showCompileTimeWarning: boolean
|
||||||
showLogs: boolean
|
showLogs: boolean
|
||||||
showNewCompileTimeoutUI?: string
|
|
||||||
showFasterCompilesFeedbackUI: boolean
|
|
||||||
stopOnFirstError: boolean
|
stopOnFirstError: boolean
|
||||||
stopOnValidationError: boolean
|
stopOnValidationError: boolean
|
||||||
stoppedOnFirstError: boolean
|
stoppedOnFirstError: boolean
|
||||||
|
@ -103,11 +102,7 @@ export const LocalCompileProvider: FC = ({ children }) => {
|
||||||
|
|
||||||
const { hasPremiumCompile, isProjectOwner } = useEditorContext()
|
const { hasPremiumCompile, isProjectOwner } = useEditorContext()
|
||||||
|
|
||||||
const {
|
const { _id: projectId, rootDocId } = useProjectContext()
|
||||||
_id: projectId,
|
|
||||||
rootDocId,
|
|
||||||
showNewCompileTimeoutUI,
|
|
||||||
} = useProjectContext()
|
|
||||||
|
|
||||||
const { pdfPreviewOpen } = useLayoutContext()
|
const { pdfPreviewOpen } = useLayoutContext()
|
||||||
|
|
||||||
|
@ -122,6 +117,8 @@ export const LocalCompileProvider: FC = ({ children }) => {
|
||||||
// whether to show the compile time warning
|
// whether to show the compile time warning
|
||||||
const [showCompileTimeWarning, setShowCompileTimeWarning] = useState(false)
|
const [showCompileTimeWarning, setShowCompileTimeWarning] = useState(false)
|
||||||
|
|
||||||
|
const [hasShortCompileTimeout, setHasShortCompileTimeout] = useState(false)
|
||||||
|
|
||||||
// the log entries parsed from the compile output log
|
// the log entries parsed from the compile output log
|
||||||
const [logEntries, setLogEntries] = useScopeValueSetterOnly('pdf.logEntries')
|
const [logEntries, setLogEntries] = useScopeValueSetterOnly('pdf.logEntries')
|
||||||
|
|
||||||
|
@ -182,10 +179,6 @@ export const LocalCompileProvider: FC = ({ children }) => {
|
||||||
// whether the logs should be visible
|
// whether the logs should be visible
|
||||||
const [showLogs, setShowLogs] = useState(false)
|
const [showLogs, setShowLogs] = useState(false)
|
||||||
|
|
||||||
// whether the faster compiles feedback UI should be displayed
|
|
||||||
const [showFasterCompilesFeedbackUI, setShowFasterCompilesFeedbackUI] =
|
|
||||||
useState(false)
|
|
||||||
|
|
||||||
// whether the compile dropdown arrow should be animated
|
// whether the compile dropdown arrow should be animated
|
||||||
const [animateCompileDropdownArrow, setAnimateCompileDropdownArrow] =
|
const [animateCompileDropdownArrow, setAnimateCompileDropdownArrow] =
|
||||||
useState(false)
|
useState(false)
|
||||||
|
@ -332,10 +325,13 @@ export const LocalCompileProvider: FC = ({ children }) => {
|
||||||
}, [compiledOnce, currentDoc, compiler])
|
}, [compiledOnce, currentDoc, compiler])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const compileTimeWarningEnabled =
|
setHasShortCompileTimeout(
|
||||||
features?.compileTimeout !== undefined && features.compileTimeout <= 60
|
features?.compileTimeout !== undefined && features.compileTimeout <= 60
|
||||||
|
)
|
||||||
|
}, [features])
|
||||||
|
|
||||||
if (compileTimeWarningEnabled && compiling && isProjectOwner) {
|
useEffect(() => {
|
||||||
|
if (hasShortCompileTimeout && compiling && isProjectOwner) {
|
||||||
const timeout = window.setTimeout(() => {
|
const timeout = window.setTimeout(() => {
|
||||||
setShowCompileTimeWarning(true)
|
setShowCompileTimeWarning(true)
|
||||||
}, 30000)
|
}, 30000)
|
||||||
|
@ -344,7 +340,7 @@ export const LocalCompileProvider: FC = ({ children }) => {
|
||||||
window.clearTimeout(timeout)
|
window.clearTimeout(timeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [compiling, isProjectOwner, features])
|
}, [compiling, isProjectOwner, hasShortCompileTimeout])
|
||||||
|
|
||||||
const { splitTestVariants } = useSplitTestContext()
|
const { splitTestVariants } = useSplitTestContext()
|
||||||
|
|
||||||
|
@ -358,9 +354,6 @@ export const LocalCompileProvider: FC = ({ children }) => {
|
||||||
if (data.clsiServerId) {
|
if (data.clsiServerId) {
|
||||||
setClsiServerId(data.clsiServerId) // set in scope, for PdfSynctexController
|
setClsiServerId(data.clsiServerId) // set in scope, for PdfSynctexController
|
||||||
}
|
}
|
||||||
setShowFasterCompilesFeedbackUI(
|
|
||||||
Boolean(data.showFasterCompilesFeedbackUI)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (data.outputFiles) {
|
if (data.outputFiles) {
|
||||||
const outputFiles = new Map()
|
const outputFiles = new Map()
|
||||||
|
@ -606,6 +599,7 @@ export const LocalCompileProvider: FC = ({ children }) => {
|
||||||
error,
|
error,
|
||||||
fileList,
|
fileList,
|
||||||
hasChanges,
|
hasChanges,
|
||||||
|
hasShortCompileTimeout,
|
||||||
highlights,
|
highlights,
|
||||||
isProjectOwner,
|
isProjectOwner,
|
||||||
lastCompileOptions,
|
lastCompileOptions,
|
||||||
|
@ -633,8 +627,6 @@ export const LocalCompileProvider: FC = ({ children }) => {
|
||||||
setStopOnFirstError,
|
setStopOnFirstError,
|
||||||
setStopOnValidationError,
|
setStopOnValidationError,
|
||||||
showLogs,
|
showLogs,
|
||||||
showNewCompileTimeoutUI,
|
|
||||||
showFasterCompilesFeedbackUI,
|
|
||||||
startCompile,
|
startCompile,
|
||||||
stopCompile,
|
stopCompile,
|
||||||
stopOnFirstError,
|
stopOnFirstError,
|
||||||
|
@ -661,6 +653,7 @@ export const LocalCompileProvider: FC = ({ children }) => {
|
||||||
error,
|
error,
|
||||||
fileList,
|
fileList,
|
||||||
hasChanges,
|
hasChanges,
|
||||||
|
hasShortCompileTimeout,
|
||||||
highlights,
|
highlights,
|
||||||
isProjectOwner,
|
isProjectOwner,
|
||||||
lastCompileOptions,
|
lastCompileOptions,
|
||||||
|
@ -683,8 +676,6 @@ export const LocalCompileProvider: FC = ({ children }) => {
|
||||||
setStopOnValidationError,
|
setStopOnValidationError,
|
||||||
showCompileTimeWarning,
|
showCompileTimeWarning,
|
||||||
showLogs,
|
showLogs,
|
||||||
showNewCompileTimeoutUI,
|
|
||||||
showFasterCompilesFeedbackUI,
|
|
||||||
startCompile,
|
startCompile,
|
||||||
stopCompile,
|
stopCompile,
|
||||||
stopOnFirstError,
|
stopOnFirstError,
|
||||||
|
|
|
@ -30,7 +30,6 @@ const ProjectContext = createContext<
|
||||||
_id: UserId
|
_id: UserId
|
||||||
email: string
|
email: string
|
||||||
}
|
}
|
||||||
showNewCompileTimeoutUI?: string
|
|
||||||
tags: {
|
tags: {
|
||||||
_id: string
|
_id: string
|
||||||
name: string
|
name: string
|
||||||
|
@ -74,7 +73,6 @@ export const ProjectProvider: FC = ({ children }) => {
|
||||||
features,
|
features,
|
||||||
publicAccesLevel: publicAccessLevel,
|
publicAccesLevel: publicAccessLevel,
|
||||||
owner,
|
owner,
|
||||||
showNewCompileTimeoutUI,
|
|
||||||
trackChangesState,
|
trackChangesState,
|
||||||
} = project || projectFallback
|
} = project || projectFallback
|
||||||
|
|
||||||
|
@ -86,17 +84,6 @@ export const ProjectProvider: FC = ({ children }) => {
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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(() => {
|
const value = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
_id,
|
_id,
|
||||||
|
@ -107,8 +94,6 @@ export const ProjectProvider: FC = ({ children }) => {
|
||||||
features,
|
features,
|
||||||
publicAccessLevel,
|
publicAccessLevel,
|
||||||
owner,
|
owner,
|
||||||
showNewCompileTimeoutUI:
|
|
||||||
newCompileTimeoutOverride || showNewCompileTimeoutUI,
|
|
||||||
tags,
|
tags,
|
||||||
trackChangesState,
|
trackChangesState,
|
||||||
}
|
}
|
||||||
|
@ -121,8 +106,6 @@ export const ProjectProvider: FC = ({ children }) => {
|
||||||
features,
|
features,
|
||||||
publicAccessLevel,
|
publicAccessLevel,
|
||||||
owner,
|
owner,
|
||||||
showNewCompileTimeoutUI,
|
|
||||||
newCompileTimeoutOverride,
|
|
||||||
tags,
|
tags,
|
||||||
trackChangesState,
|
trackChangesState,
|
||||||
])
|
])
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { ScopeDecorator } from './decorators/scope'
|
||||||
import { useLocalCompileContext } from '../js/shared/context/local-compile-context'
|
import { useLocalCompileContext } from '../js/shared/context/local-compile-context'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { PdfPreviewMessages } from '../js/features/pdf-preview/components/pdf-preview-messages'
|
import { PdfPreviewMessages } from '../js/features/pdf-preview/components/pdf-preview-messages'
|
||||||
import CompileTimeWarning from '../js/features/pdf-preview/components/compile-time-warning'
|
import CompileTimeWarningUpgradePrompt from '@/features/pdf-preview/components/compile-time-warning-upgrade-prompt'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Editor / PDF Preview / Messages',
|
title: 'Editor / PDF Preview / Messages',
|
||||||
|
@ -20,7 +20,7 @@ export const Dismissible = () => {
|
||||||
return (
|
return (
|
||||||
<div style={{ width: 800, position: 'relative' }}>
|
<div style={{ width: 800, position: 'relative' }}>
|
||||||
<PdfPreviewMessages>
|
<PdfPreviewMessages>
|
||||||
<CompileTimeWarning />
|
<CompileTimeWarningUpgradePrompt />
|
||||||
</PdfPreviewMessages>
|
</PdfPreviewMessages>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
import { useEffect } from 'react'
|
|
||||||
import { ScopeDecorator } from './decorators/scope'
|
import { ScopeDecorator } from './decorators/scope'
|
||||||
import { useLocalCompileContext } from '@/shared/context/local-compile-context'
|
|
||||||
import { PdfPreviewMessages } from '@/features/pdf-preview/components/pdf-preview-messages'
|
import { PdfPreviewMessages } from '@/features/pdf-preview/components/pdf-preview-messages'
|
||||||
import CompileTimeWarning from '@/features/pdf-preview/components/compile-time-warning'
|
import { CompileTimeWarningUpgradePromptInner } from '@/features/pdf-preview/components/compile-time-warning-upgrade-prompt-inner'
|
||||||
import { CompileTimeoutChangingSoon } from '@/features/pdf-preview/components/compile-timeout-changing-soon'
|
|
||||||
import { CompileTimeoutWarning } from '@/features/pdf-preview/components/compile-timeout-warning'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Editor / PDF Preview / Messages',
|
title: 'Editor / PDF Preview / Messages',
|
||||||
|
@ -21,40 +17,9 @@ export default {
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CompileTime = () => {
|
|
||||||
const { setShowCompileTimeWarning } = useLocalCompileContext()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setShowCompileTimeWarning(true)
|
|
||||||
}, [setShowCompileTimeWarning])
|
|
||||||
|
|
||||||
return <CompileTimeWarning />
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CompileTimeoutChangingSoonNotProjectOwner = (args: any) => {
|
|
||||||
return <CompileTimeoutChangingSoon {...args} />
|
|
||||||
}
|
|
||||||
CompileTimeoutChangingSoonNotProjectOwner.argTypes = {
|
|
||||||
handleDismissChangingSoon: { action: 'dismiss changing soon' },
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CompileTimeoutChangingSoonProjectOwner = (args: any) => {
|
|
||||||
return <CompileTimeoutChangingSoon {...args} isProjectOwner />
|
|
||||||
}
|
|
||||||
CompileTimeoutChangingSoonProjectOwner.argTypes = {
|
|
||||||
handleDismissChangingSoon: { action: 'dismiss changing soon' },
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CompileTimeoutWarningActive = (args: any) => {
|
export const CompileTimeoutWarningActive = (args: any) => {
|
||||||
return <CompileTimeoutWarning {...args} showNewCompileTimeoutUI="active" />
|
return <CompileTimeWarningUpgradePromptInner {...args} />
|
||||||
}
|
}
|
||||||
CompileTimeoutWarningActive.argTypes = {
|
CompileTimeoutWarningActive.argTypes = {
|
||||||
handleDismissWarning: { action: 'dismiss warning' },
|
handleDismissWarning: { action: 'dismiss warning' },
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CompileTimeoutWarningChanging = (args: any) => {
|
|
||||||
return <CompileTimeoutWarning {...args} showNewCompileTimeoutUI="changing" />
|
|
||||||
}
|
|
||||||
CompileTimeoutWarningChanging.argTypes = {
|
|
||||||
handleDismissWarning: { action: 'dismiss warning' },
|
|
||||||
}
|
|
||||||
|
|
|
@ -106,7 +106,6 @@
|
||||||
"an_email_has_already_been_sent_to": "An email has already been sent to <0>__email__</0>. Please wait and try again later.",
|
"an_email_has_already_been_sent_to": "An email has already been sent to <0>__email__</0>. Please wait and try again later.",
|
||||||
"an_error_occurred_when_verifying_the_coupon_code": "An error occurred when verifying the coupon code",
|
"an_error_occurred_when_verifying_the_coupon_code": "An error occurred when verifying the coupon code",
|
||||||
"and": "and",
|
"and": "and",
|
||||||
"and_you_can_upgrade_for_plenty_more_compile_time": "And you can <strong>upgrade to get plenty more compile time.</strong>",
|
|
||||||
"annual": "Annual",
|
"annual": "Annual",
|
||||||
"annual_billing_enabled": "Annual billing enabled",
|
"annual_billing_enabled": "Annual billing enabled",
|
||||||
"anonymous": "Anonymous",
|
"anonymous": "Anonymous",
|
||||||
|
@ -115,7 +114,6 @@
|
||||||
"app_on_x": "__appName__ on __social__",
|
"app_on_x": "__appName__ on __social__",
|
||||||
"apply_educational_discount": "Apply educational discount",
|
"apply_educational_discount": "Apply educational discount",
|
||||||
"apply_educational_discount_info": "Overleaf offers a 40% educational discount for groups of 10 or more. Applies to students or faculty using Overleaf for teaching.",
|
"apply_educational_discount_info": "Overleaf offers a 40% educational discount for groups of 10 or more. Applies to students or faculty using Overleaf for teaching.",
|
||||||
"approaching_compile_timeout_limit_upgrade_for_more_compile_time": "You are approaching your compile timeout limit. Upgrade to <strong>Overleaf Premium</strong> for <0>4x more</0> compile time.",
|
|
||||||
"april": "April",
|
"april": "April",
|
||||||
"archive": "Archive",
|
"archive": "Archive",
|
||||||
"archive_projects": "Archive Projects",
|
"archive_projects": "Archive Projects",
|
||||||
|
@ -132,7 +130,6 @@
|
||||||
"ascending": "Ascending",
|
"ascending": "Ascending",
|
||||||
"ask_proj_owner_to_unlink_from_current_github": "Ask the owner of the project (<0>__projectOwnerEmail__</0>) to unlink the project from the current GitHub repository and create a connection to a different repository.",
|
"ask_proj_owner_to_unlink_from_current_github": "Ask the owner of the project (<0>__projectOwnerEmail__</0>) to unlink the project from the current GitHub repository and create a connection to a different repository.",
|
||||||
"ask_proj_owner_to_upgrade_for_full_history": "Please ask the project owner to upgrade to access this project’s full history.",
|
"ask_proj_owner_to_upgrade_for_full_history": "Please ask the project owner to upgrade to access this project’s full history.",
|
||||||
"ask_proj_owner_to_upgrade_for_longer_compiles": "Please ask the project owner to upgrade to increase the timeout limit.",
|
|
||||||
"ask_proj_owner_to_upgrade_for_references_search": "Please ask the project owner to upgrade to use the References Search feature.",
|
"ask_proj_owner_to_upgrade_for_references_search": "Please ask the project owner to upgrade to use the References Search feature.",
|
||||||
"ask_repo_owner_to_reconnect": "Ask the GitHub repository owner (<0>__repoOwnerEmail__</0>) to reconnect the project.",
|
"ask_repo_owner_to_reconnect": "Ask the GitHub repository owner (<0>__repoOwnerEmail__</0>) to reconnect the project.",
|
||||||
"ask_repo_owner_to_renew_overleaf_subscription": "Ask the GitHub repository owner (<0>__repoOwnerEmail__</0>) to renew their __appName__ subscription and reconnect the project.",
|
"ask_repo_owner_to_renew_overleaf_subscription": "Ask the GitHub repository owner (<0>__repoOwnerEmail__</0>) to renew their __appName__ subscription and reconnect the project.",
|
||||||
|
@ -293,7 +290,6 @@
|
||||||
"compile_timeout_short": "Compile timeout",
|
"compile_timeout_short": "Compile timeout",
|
||||||
"compile_timeout_short_info_basic": "This is how much time you get to compile your project on the Overleaf servers. You may need additional time for longer or more complex projects.",
|
"compile_timeout_short_info_basic": "This is how much time you get to compile your project on the Overleaf servers. You may need additional time for longer or more complex projects.",
|
||||||
"compiler": "Compiler",
|
"compiler": "Compiler",
|
||||||
"compiles_on_our_free_plan_are_now_on_faster_servers": "Compiles on our free plan are now on faster servers, and we’re gradually <0>introducing a shorter compile timeout limit</0>. This project currently exceeds the new limit, so it might not compile in future.",
|
|
||||||
"compiling": "Compiling",
|
"compiling": "Compiling",
|
||||||
"complete": "Complete",
|
"complete": "Complete",
|
||||||
"compliance": "Compliance",
|
"compliance": "Compliance",
|
||||||
|
@ -420,7 +416,6 @@
|
||||||
"disabling": "Disabling",
|
"disabling": "Disabling",
|
||||||
"disconnected": "Disconnected",
|
"disconnected": "Disconnected",
|
||||||
"discount_of": "Discount of __amount__",
|
"discount_of": "Discount of __amount__",
|
||||||
"dismiss": "Dismiss",
|
|
||||||
"dismiss_error_popup": "Dismiss first error alert",
|
"dismiss_error_popup": "Dismiss first error alert",
|
||||||
"display_deleted_user": "Display deleted users",
|
"display_deleted_user": "Display deleted users",
|
||||||
"do_not_have_acct_or_do_not_want_to_link": "If you don’t have an <b>__appName__</b> account, or if you don’t want to link to your <b>__institutionName__</b> account, please click <b>__clickText__</b>.",
|
"do_not_have_acct_or_do_not_want_to_link": "If you don’t have an <b>__appName__</b> account, or if you don’t want to link to your <b>__institutionName__</b> account, please click <b>__clickText__</b>.",
|
||||||
|
@ -579,11 +574,6 @@
|
||||||
"faq_what_is_the_difference_between_users_and_collaborators_answer_second_paragraph": "In other words, collaborators are just other Overleaf users that you are working with on one of your projects.",
|
"faq_what_is_the_difference_between_users_and_collaborators_answer_second_paragraph": "In other words, collaborators are just other Overleaf users that you are working with on one of your projects.",
|
||||||
"faq_what_is_the_difference_between_users_and_collaborators_question": "What’s the difference between users and collaborators?",
|
"faq_what_is_the_difference_between_users_and_collaborators_question": "What’s the difference between users and collaborators?",
|
||||||
"fast": "Fast",
|
"fast": "Fast",
|
||||||
"faster_compiles_feedback_question": "Was this compile different than usual?",
|
|
||||||
"faster_compiles_feedback_seems_faster": "Faster",
|
|
||||||
"faster_compiles_feedback_seems_same": "Same",
|
|
||||||
"faster_compiles_feedback_seems_slower": "Slower",
|
|
||||||
"faster_compiles_feedback_thanks": "Thanks for the feedback!",
|
|
||||||
"fastest": "Fastest",
|
"fastest": "Fastest",
|
||||||
"feature_included": "Feature included",
|
"feature_included": "Feature included",
|
||||||
"feature_not_included": "Feature not included",
|
"feature_not_included": "Feature not included",
|
||||||
|
@ -650,7 +640,6 @@
|
||||||
"free": "Free",
|
"free": "Free",
|
||||||
"free_7_day_trial_billed_annually": "Free 7-day trial, then billed annually",
|
"free_7_day_trial_billed_annually": "Free 7-day trial, then billed annually",
|
||||||
"free_7_day_trial_billed_monthly": "Free 7-day trial, then billed monthly",
|
"free_7_day_trial_billed_monthly": "Free 7-day trial, then billed monthly",
|
||||||
"free_accounts_have_timeout_upgrade_to_increase": "Free accounts have a one minute timeout, whereas upgraded accounts have a timeout of four minutes.",
|
|
||||||
"free_dropbox_and_history": "Free Dropbox and History",
|
"free_dropbox_and_history": "Free Dropbox and History",
|
||||||
"free_plan_label": "You’re on the <b>free plan</b>",
|
"free_plan_label": "You’re on the <b>free plan</b>",
|
||||||
"free_plan_tooltip": "Click to find out how you could benefit from Overleaf premium features.",
|
"free_plan_tooltip": "Click to find out how you could benefit from Overleaf premium features.",
|
||||||
|
@ -1371,7 +1360,6 @@
|
||||||
"please_wait": "Please wait",
|
"please_wait": "Please wait",
|
||||||
"plus_additional_collaborators_document_history_track_changes_and_more": "(plus additional collaborators, document history, track changes, and more).",
|
"plus_additional_collaborators_document_history_track_changes_and_more": "(plus additional collaborators, document history, track changes, and more).",
|
||||||
"plus_more": "plus more",
|
"plus_more": "plus more",
|
||||||
"plus_upgraded_accounts_receive": "Plus with an upgraded account you get",
|
|
||||||
"popular_tags": "Popular Tags",
|
"popular_tags": "Popular Tags",
|
||||||
"portal_add_affiliation_to_join": "It looks like you are already logged in to __appName__. If you have a __portalTitle__ email you can add it now.",
|
"portal_add_affiliation_to_join": "It looks like you are already logged in to __appName__. If you have a __portalTitle__ email you can add it now.",
|
||||||
"position": "Position",
|
"position": "Position",
|
||||||
|
@ -1454,7 +1442,6 @@
|
||||||
"react_history_tutorial_content": "To compare a range of versions, use the <0></0> on the versions you want at the start and end of the range. To add a label or to download a version use the options in the three-dot menu. <1>Learn more about using Overleaf History.</1>",
|
"react_history_tutorial_content": "To compare a range of versions, use the <0></0> on the versions you want at the start and end of the range. To add a label or to download a version use the options in the three-dot menu. <1>Learn more about using Overleaf History.</1>",
|
||||||
"react_history_tutorial_title": "History actions have a new home",
|
"react_history_tutorial_title": "History actions have a new home",
|
||||||
"reactivate_subscription": "Reactivate your subscription",
|
"reactivate_subscription": "Reactivate your subscription",
|
||||||
"read_more_about_fix_prevent_timeout": "Read more about how to fix and prevent timeouts",
|
|
||||||
"read_more_about_free_compile_timeouts_servers": "Read more about changes to free compile timeouts and servers",
|
"read_more_about_free_compile_timeouts_servers": "Read more about changes to free compile timeouts and servers",
|
||||||
"read_only": "Read Only",
|
"read_only": "Read Only",
|
||||||
"read_only_token": "Read-Only Token",
|
"read_only_token": "Read-Only Token",
|
||||||
|
@ -1864,7 +1851,6 @@
|
||||||
"tc_switch_guests_tip": "Toggle track-changes for all link-sharing guests",
|
"tc_switch_guests_tip": "Toggle track-changes for all link-sharing guests",
|
||||||
"tc_switch_user_tip": "Toggle track-changes for this user",
|
"tc_switch_user_tip": "Toggle track-changes for this user",
|
||||||
"tell_the_project_owner_and_ask_them_to_upgrade": "<0>Tell the project owner</0> and ask them to upgrade their Overleaf plan if you need more compile time.",
|
"tell_the_project_owner_and_ask_them_to_upgrade": "<0>Tell the project owner</0> and ask them to upgrade their Overleaf plan if you need more compile time.",
|
||||||
"tell_the_project_owner_to_upgrade_plan_for_more_compile_time": "<strong>Tell the project owner</strong> and ask them to upgrade their Overleaf plan if you need more compile time.",
|
|
||||||
"template": "Template",
|
"template": "Template",
|
||||||
"template_approved_by_publisher": "This template has been approved by the publisher",
|
"template_approved_by_publisher": "This template has been approved by the publisher",
|
||||||
"template_description": "Template Description",
|
"template_description": "Template Description",
|
||||||
|
@ -1918,7 +1904,6 @@
|
||||||
"this_field_is_required": "This field is required",
|
"this_field_is_required": "This field is required",
|
||||||
"this_grants_access_to_features_2": "This grants you access to <0>__appName__</0> <0>__featureType__</0> features.",
|
"this_grants_access_to_features_2": "This grants you access to <0>__appName__</0> <0>__featureType__</0> features.",
|
||||||
"this_is_your_template": "This is your template from your project",
|
"this_is_your_template": "This is your template from your project",
|
||||||
"this_project_compiled_but_soon_might_not": "This project compiled, but soon it might not",
|
|
||||||
"this_project_exceeded_compile_timeout_limit_on_free_plan": "This project exceeded the compile timeout limit on our free plan.",
|
"this_project_exceeded_compile_timeout_limit_on_free_plan": "This project exceeded the compile timeout limit on our free plan.",
|
||||||
"this_project_is_public": "This project is public and can be edited by anyone with the URL.",
|
"this_project_is_public": "This project is public and can be edited by anyone with the URL.",
|
||||||
"this_project_is_public_read_only": "This project is public and can be viewed but not edited by anyone with the URL",
|
"this_project_is_public_read_only": "This project is public and can be viewed but not edited by anyone with the URL",
|
||||||
|
@ -2086,8 +2071,6 @@
|
||||||
"upgrade": "Upgrade",
|
"upgrade": "Upgrade",
|
||||||
"upgrade_cc_btn": "Upgrade now, pay after 7 days",
|
"upgrade_cc_btn": "Upgrade now, pay after 7 days",
|
||||||
"upgrade_for_12x_more_compile_time": "Upgrade to get 12x more compile time",
|
"upgrade_for_12x_more_compile_time": "Upgrade to get 12x more compile time",
|
||||||
"upgrade_for_longer_compiles": "Upgrade to increase your timeout limit.",
|
|
||||||
"upgrade_for_plenty_more_compile_time": "Upgrade to get plenty more compile time.",
|
|
||||||
"upgrade_now": "Upgrade Now",
|
"upgrade_now": "Upgrade Now",
|
||||||
"upgrade_to_get_feature": "Upgrade to get __feature__, plus:",
|
"upgrade_to_get_feature": "Upgrade to get __feature__, plus:",
|
||||||
"upgrade_to_track_changes": "Upgrade to track changes",
|
"upgrade_to_track_changes": "Upgrade to track changes",
|
||||||
|
@ -2155,8 +2138,6 @@
|
||||||
"website_status": "Website status",
|
"website_status": "Website status",
|
||||||
"wed_love_you_to_stay": "We’d love you to stay",
|
"wed_love_you_to_stay": "We’d love you to stay",
|
||||||
"welcome_to_sl": "Welcome to __appName__",
|
"welcome_to_sl": "Welcome to __appName__",
|
||||||
"were_in_the_process_of_reducing_compile_timeout_which_may_affect_this_project": "We’re in the process of <0>reducing the compile timeout limit</0> on our free plan, which may affect this project in future.",
|
|
||||||
"were_in_the_process_of_reducing_compile_timeout_which_may_affect_your_project": "We’re in the process of <0>reducing the compile timeout limit</0> on our free plan, which may affect your project in future.",
|
|
||||||
"were_performing_maintenance": "We’re performing maintenance on Overleaf and you need to wait a moment. Sorry for any inconvenience. The editor will refresh automatically in __seconds__ seconds.",
|
"were_performing_maintenance": "We’re performing maintenance on Overleaf and you need to wait a moment. Sorry for any inconvenience. The editor will refresh automatically in __seconds__ seconds.",
|
||||||
"weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_this_project": "We’ve recently <0>reduced the compile timeout limit</0> on our free plan, which may have affected this project.",
|
"weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_this_project": "We’ve recently <0>reduced the compile timeout limit</0> on our free plan, which may have affected this project.",
|
||||||
"weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_your_project": "We’ve recently <0>reduced the compile timeout limit</0> on our free plan, which may have affected your project.",
|
"weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_your_project": "We’ve recently <0>reduced the compile timeout limit</0> on our free plan, which may have affected your project.",
|
||||||
|
@ -2227,7 +2208,6 @@
|
||||||
"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_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_introed_high_number": " You’ve introduced <0>__numberOfPeople__</0> people to __appName__. Good job!",
|
"you_introed_high_number": " You’ve introduced <0>__numberOfPeople__</0> people to __appName__. Good job!",
|
||||||
"you_introed_small_number": " You’ve introduced <0>__numberOfPeople__</0> person to __appName__. Good job, but can you get some more?",
|
"you_introed_small_number": " You’ve introduced <0>__numberOfPeople__</0> person to __appName__. Good job, but can you get some more?",
|
||||||
"you_may_be_able_to_fix_issues_to_speed_up_the_compile": "You may be able to fix issues to <0>speed up the compile</0>.",
|
|
||||||
"you_need_to_configure_your_sso_settings": "You need to configure and test your SSO settings before enabling SSO",
|
"you_need_to_configure_your_sso_settings": "You need to configure and test your SSO settings before enabling SSO",
|
||||||
"you_not_introed_anyone_to_sl": "You’ve not introduced anyone to __appName__ yet. Get sharing!",
|
"you_not_introed_anyone_to_sl": "You’ve not introduced anyone to __appName__ yet. Get sharing!",
|
||||||
"you_plus_1": "You + 1",
|
"you_plus_1": "You + 1",
|
||||||
|
@ -2255,7 +2235,6 @@
|
||||||
"your_password_has_been_successfully_changed": "Your password has been successfully changed",
|
"your_password_has_been_successfully_changed": "Your password has been successfully changed",
|
||||||
"your_plan": "Your plan",
|
"your_plan": "Your plan",
|
||||||
"your_plan_is_changing_at_term_end": "Your plan is changing to <0>__pendingPlanName__</0> at the end of the current billing period.",
|
"your_plan_is_changing_at_term_end": "Your plan is changing to <0>__pendingPlanName__</0> at the end of the current billing period.",
|
||||||
"your_project_compiled_but_soon_might_not": "Your project compiled, but soon it might not",
|
|
||||||
"your_project_exceeded_compile_timeout_limit_on_free_plan": "Your project exceeded the compile timeout limit on our free plan.",
|
"your_project_exceeded_compile_timeout_limit_on_free_plan": "Your project exceeded the compile timeout limit on our free plan.",
|
||||||
"your_project_near_compile_timeout_limit": "Your project is near the compile timeout limit for our free plan.",
|
"your_project_near_compile_timeout_limit": "Your project is near the compile timeout limit for our free plan.",
|
||||||
"your_projects": "Your Projects",
|
"your_projects": "Your Projects",
|
||||||
|
|
57
services/web/scripts/migration_compile_timeout_60s_to_20s.js
Normal file
57
services/web/scripts/migration_compile_timeout_60s_to_20s.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const minimist = require('minimist')
|
||||||
|
const {
|
||||||
|
db,
|
||||||
|
READ_PREFERENCE_SECONDARY,
|
||||||
|
waitForDb,
|
||||||
|
} = require('../app/src/infrastructure/mongodb')
|
||||||
|
const { batchedUpdate } = require('./helpers/batchedUpdate')
|
||||||
|
|
||||||
|
async function logCount() {
|
||||||
|
const count60s = await db.users.countDocuments(
|
||||||
|
{ 'features.compileTimeout': { $lte: 60, $ne: 20 } },
|
||||||
|
{ readPreference: READ_PREFERENCE_SECONDARY }
|
||||||
|
)
|
||||||
|
const count20s = await db.users.countDocuments(
|
||||||
|
{ 'features.compileTimeout': 20 },
|
||||||
|
{ readPreference: READ_PREFERENCE_SECONDARY }
|
||||||
|
)
|
||||||
|
console.log(`Found ${count60s} users with compileTimeout <= 60s && != 20s`)
|
||||||
|
console.log(`Found ${count20s} users with compileTimeout == 20s`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const main = async ({ COMMIT }) => {
|
||||||
|
console.time('Script Duration')
|
||||||
|
|
||||||
|
await waitForDb()
|
||||||
|
|
||||||
|
await logCount()
|
||||||
|
|
||||||
|
if (COMMIT) {
|
||||||
|
const nModified = await batchedUpdate(
|
||||||
|
'users',
|
||||||
|
{ 'features.compileTimeout': { $lte: 60, $ne: 20 } },
|
||||||
|
{ $set: { 'features.compileTimeout': 20 } }
|
||||||
|
)
|
||||||
|
console.log(`Updated ${nModified} records`)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.timeEnd('Script Duration')
|
||||||
|
}
|
||||||
|
|
||||||
|
const setup = () => {
|
||||||
|
const argv = minimist(process.argv.slice(2))
|
||||||
|
const COMMIT = argv.commit !== undefined
|
||||||
|
if (!COMMIT) {
|
||||||
|
console.warn('Doing dry run. Add --commit to commit changes')
|
||||||
|
}
|
||||||
|
return { COMMIT }
|
||||||
|
}
|
||||||
|
|
||||||
|
main(setup())
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
.then(() => process.exit(0))
|
|
@ -0,0 +1,134 @@
|
||||||
|
const { expect } = require('chai')
|
||||||
|
const { promisify } = require('node:util')
|
||||||
|
const { exec } = require('node:child_process')
|
||||||
|
const logger = require('@overleaf/logger')
|
||||||
|
const { db } = require('../../../app/src/infrastructure/mongodb')
|
||||||
|
|
||||||
|
async function runScript(args = []) {
|
||||||
|
try {
|
||||||
|
return await promisify(exec)(
|
||||||
|
['node', 'scripts/migration_compile_timeout_60s_to_20s.js', ...args].join(
|
||||||
|
' '
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
logger.error({ error }, 'script failed')
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('MigrateUserFeatureTimeoutTests', function () {
|
||||||
|
const usersInput = {
|
||||||
|
noFeatures: {},
|
||||||
|
noFeatureTimeout: { features: {} },
|
||||||
|
timeout10s: { features: { compileTimeout: 10, other: 'val1' }, bar: '1' },
|
||||||
|
timeout20s: { features: { compileTimeout: 20, other: 'val2' }, bar: '2' },
|
||||||
|
timeout30s: { features: { compileTimeout: 30, other: 'val3' }, bar: '3' },
|
||||||
|
timeout60s: { features: { compileTimeout: 60, other: 'val4' }, bar: '4' },
|
||||||
|
timeout120s: { features: { compileTimeout: 120, other: 'val5' }, bar: '5' },
|
||||||
|
timeout180s: { features: { compileTimeout: 180, other: 'val6' }, bar: '6' },
|
||||||
|
}
|
||||||
|
|
||||||
|
const usersKeys = Object.keys(usersInput)
|
||||||
|
const userIds = {}
|
||||||
|
|
||||||
|
beforeEach('insert users', async function () {
|
||||||
|
const usersInsertedValues = await db.users.insertMany(
|
||||||
|
usersKeys.map(key => ({
|
||||||
|
...usersInput[key],
|
||||||
|
email: `${key}@example.com`,
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
usersKeys.forEach(
|
||||||
|
(key, index) => (userIds[key] = usersInsertedValues.insertedIds[index])
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('gives correct counts in dry mode', async function () {
|
||||||
|
const users = await db.users.find().toArray()
|
||||||
|
expect(users).to.have.lengthOf(usersKeys.length)
|
||||||
|
|
||||||
|
const result = await runScript([])
|
||||||
|
|
||||||
|
expect(result.stderr).to.contain(
|
||||||
|
'Doing dry run. Add --commit to commit changes'
|
||||||
|
)
|
||||||
|
expect(result.stdout).to.contain(
|
||||||
|
'Found 3 users with compileTimeout <= 60s && != 20s'
|
||||||
|
)
|
||||||
|
expect(result.stdout).to.contain('Found 1 users with compileTimeout == 20s')
|
||||||
|
expect(result.stdout).not.to.contain('Updated')
|
||||||
|
|
||||||
|
const usersAfter = await db.users.find().toArray()
|
||||||
|
|
||||||
|
expect(usersAfter).to.deep.equal(users)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("updates users compileTimeout when '--commit' is set", async function () {
|
||||||
|
const users = await db.users.find().toArray()
|
||||||
|
expect(users).to.have.lengthOf(usersKeys.length)
|
||||||
|
const result = await runScript(['--commit'])
|
||||||
|
|
||||||
|
expect(result.stdout).to.contain(
|
||||||
|
'Found 3 users with compileTimeout <= 60s && != 20s'
|
||||||
|
)
|
||||||
|
expect(result.stdout).to.contain('Found 1 users with compileTimeout == 20s')
|
||||||
|
expect(result.stdout).to.contain('Updated 3 records')
|
||||||
|
|
||||||
|
const usersAfter = await db.users.find().toArray()
|
||||||
|
|
||||||
|
expect(usersAfter).to.deep.equal([
|
||||||
|
{ _id: userIds.noFeatures, email: 'noFeatures@example.com' },
|
||||||
|
{
|
||||||
|
_id: userIds.noFeatureTimeout,
|
||||||
|
email: 'noFeatureTimeout@example.com',
|
||||||
|
features: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_id: userIds.timeout10s,
|
||||||
|
email: 'timeout10s@example.com',
|
||||||
|
features: { compileTimeout: 20, other: 'val1' },
|
||||||
|
bar: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_id: userIds.timeout20s,
|
||||||
|
email: 'timeout20s@example.com',
|
||||||
|
features: { compileTimeout: 20, other: 'val2' },
|
||||||
|
bar: '2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_id: userIds.timeout30s,
|
||||||
|
email: 'timeout30s@example.com',
|
||||||
|
features: { compileTimeout: 20, other: 'val3' },
|
||||||
|
bar: '3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_id: userIds.timeout60s,
|
||||||
|
email: 'timeout60s@example.com',
|
||||||
|
features: { compileTimeout: 20, other: 'val4' },
|
||||||
|
bar: '4',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_id: userIds.timeout120s,
|
||||||
|
email: 'timeout120s@example.com',
|
||||||
|
features: { compileTimeout: 120, other: 'val5' },
|
||||||
|
bar: '5',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_id: userIds.timeout180s,
|
||||||
|
email: 'timeout180s@example.com',
|
||||||
|
features: { compileTimeout: 180, other: 'val6' },
|
||||||
|
bar: '6',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const result2 = await runScript([])
|
||||||
|
|
||||||
|
expect(result2.stdout).to.contain(
|
||||||
|
'Found 0 users with compileTimeout <= 60s && != 20s'
|
||||||
|
)
|
||||||
|
expect(result2.stdout).to.contain(
|
||||||
|
'Found 4 users with compileTimeout == 20s'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
|
@ -120,7 +120,6 @@ describe('ClsiManager', function () {
|
||||||
},
|
},
|
||||||
clsi: {
|
clsi: {
|
||||||
url: `http://${CLSI_HOST}`,
|
url: `http://${CLSI_HOST}`,
|
||||||
defaultBackendClass: 'e2',
|
|
||||||
submissionBackendClass: 'n2d',
|
submissionBackendClass: 'n2d',
|
||||||
},
|
},
|
||||||
clsi_priority: {
|
clsi_priority: {
|
||||||
|
|
|
@ -32,7 +32,6 @@ describe('CompileController', function () {
|
||||||
apis: {
|
apis: {
|
||||||
clsi: {
|
clsi: {
|
||||||
url: 'http://clsi.example.com',
|
url: 'http://clsi.example.com',
|
||||||
defaultBackendClass: 'e2',
|
|
||||||
submissionBackendClass: 'n2d',
|
submissionBackendClass: 'n2d',
|
||||||
},
|
},
|
||||||
clsi_priority: {
|
clsi_priority: {
|
||||||
|
|
|
@ -23,7 +23,7 @@ describe('CompileManager', function () {
|
||||||
requires: {
|
requires: {
|
||||||
'@overleaf/settings': (this.settings = {
|
'@overleaf/settings': (this.settings = {
|
||||||
apis: {
|
apis: {
|
||||||
clsi: { defaultBackendClass: 'e2', submissionBackendClass: 'n2d' },
|
clsi: { submissionBackendClass: 'n2d' },
|
||||||
},
|
},
|
||||||
redis: { web: { host: 'localhost', port: 42 } },
|
redis: { web: { host: 'localhost', port: 42 } },
|
||||||
rateLimit: { autoCompile: {} },
|
rateLimit: { autoCompile: {} },
|
||||||
|
@ -235,9 +235,8 @@ describe('CompileManager', function () {
|
||||||
.calledWith(null, {
|
.calledWith(null, {
|
||||||
timeout: this.timeout,
|
timeout: this.timeout,
|
||||||
compileGroup: this.group,
|
compileGroup: this.group,
|
||||||
compileBackendClass: 'e2',
|
compileBackendClass: 'c2d',
|
||||||
ownerAnalyticsId: 'abc',
|
ownerAnalyticsId: 'abc',
|
||||||
showFasterCompilesFeedbackUI: false,
|
|
||||||
})
|
})
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
|
@ -303,7 +302,7 @@ describe('CompileManager', function () {
|
||||||
this.callback
|
this.callback
|
||||||
)
|
)
|
||||||
this.callback
|
this.callback
|
||||||
.calledWith(null, sinon.match({ timeout: 60 }))
|
.calledWith(null, sinon.match({ timeout: 20 }))
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
describe('user is in the compile-timeout-20s-existing-users treatment', function () {
|
describe('user is in the compile-timeout-20s-existing-users treatment', function () {
|
||||||
|
@ -388,20 +387,12 @@ describe('CompileManager', function () {
|
||||||
this.callback
|
this.callback
|
||||||
)
|
)
|
||||||
this.callback
|
this.callback
|
||||||
.calledWith(null, sinon.match({ timeout: 60 }))
|
.calledWith(null, sinon.match({ timeout: 20 }))
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('user signed up after the second phase rollout', function () {
|
describe('user signed up after the second phase rollout', function () {
|
||||||
beforeEach(function () {
|
|
||||||
const signUpDate = new Date(
|
|
||||||
this.CompileManager.NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF_DEFAULT_BASELINE
|
|
||||||
)
|
|
||||||
signUpDate.setDate(signUpDate.getDate() + 1)
|
|
||||||
this.user.signUpDate = signUpDate
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should reduce compile timeout to 20s', function () {
|
it('should reduce compile timeout to 20s', function () {
|
||||||
this.CompileManager.getProjectCompileLimits(
|
this.CompileManager.getProjectCompileLimits(
|
||||||
this.project_id,
|
this.project_id,
|
||||||
|
@ -441,13 +432,12 @@ describe('CompileManager', function () {
|
||||||
variant: 'default',
|
variant: 'default',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should return the e2 class and disable the ui', function (done) {
|
it('should return the n2d class and disable the ui', function (done) {
|
||||||
this.CompileManager.getProjectCompileLimits(
|
this.CompileManager.getProjectCompileLimits(
|
||||||
this.project_id,
|
this.project_id,
|
||||||
(err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
|
(err, { compileBackendClass }) => {
|
||||||
if (err) return done(err)
|
if (err) return done(err)
|
||||||
expect(compileBackendClass).to.equal('e2')
|
expect(compileBackendClass).to.equal('n2d')
|
||||||
expect(showFasterCompilesFeedbackUI).to.equal(false)
|
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -463,10 +453,9 @@ describe('CompileManager', function () {
|
||||||
it('should return the n2d class and disable the ui', function (done) {
|
it('should return the n2d class and disable the ui', function (done) {
|
||||||
this.CompileManager.getProjectCompileLimits(
|
this.CompileManager.getProjectCompileLimits(
|
||||||
this.project_id,
|
this.project_id,
|
||||||
(err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
|
(err, { compileBackendClass }) => {
|
||||||
if (err) return done(err)
|
if (err) return done(err)
|
||||||
expect(compileBackendClass).to.equal('n2d')
|
expect(compileBackendClass).to.equal('n2d')
|
||||||
expect(showFasterCompilesFeedbackUI).to.equal(false)
|
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -489,10 +478,9 @@ describe('CompileManager', function () {
|
||||||
it('should return the default class and disable ui', function (done) {
|
it('should return the default class and disable ui', function (done) {
|
||||||
this.CompileManager.getProjectCompileLimits(
|
this.CompileManager.getProjectCompileLimits(
|
||||||
this.project_id,
|
this.project_id,
|
||||||
(err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
|
(err, { compileBackendClass }) => {
|
||||||
if (err) return done(err)
|
if (err) return done(err)
|
||||||
expect(compileBackendClass).to.equal('e2')
|
expect(compileBackendClass).to.equal('c2d')
|
||||||
expect(showFasterCompilesFeedbackUI).to.equal(false)
|
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -510,10 +498,9 @@ describe('CompileManager', function () {
|
||||||
it('should return the default class and enable ui', function (done) {
|
it('should return the default class and enable ui', function (done) {
|
||||||
this.CompileManager.getProjectCompileLimits(
|
this.CompileManager.getProjectCompileLimits(
|
||||||
this.project_id,
|
this.project_id,
|
||||||
(err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
|
(err, { compileBackendClass }) => {
|
||||||
if (err) return done(err)
|
if (err) return done(err)
|
||||||
expect(compileBackendClass).to.equal('e2')
|
expect(compileBackendClass).to.equal('c2d')
|
||||||
expect(showFasterCompilesFeedbackUI).to.equal(true)
|
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -530,10 +517,9 @@ describe('CompileManager', function () {
|
||||||
it('should return the c2d class and enable ui', function (done) {
|
it('should return the c2d class and enable ui', function (done) {
|
||||||
this.CompileManager.getProjectCompileLimits(
|
this.CompileManager.getProjectCompileLimits(
|
||||||
this.project_id,
|
this.project_id,
|
||||||
(err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
|
(err, { compileBackendClass }) => {
|
||||||
if (err) return done(err)
|
if (err) return done(err)
|
||||||
expect(compileBackendClass).to.equal('c2d')
|
expect(compileBackendClass).to.equal('c2d')
|
||||||
expect(showFasterCompilesFeedbackUI).to.equal(true)
|
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue