Просмотр исходного кода

Merge pull request #8237 from overleaf/em-halt-on-error

Stop on first error dropdown UI

GitOrigin-RevId: 5191a37f6c227ff5a91c10ce965832e1702c3931
Eric Mc Sween 4 лет назад
Родитель
Сommit
2ab5189771

+ 20 - 0
services/web/app/src/Features/Project/ProjectController.js

@@ -884,6 +884,21 @@ const ProjectController = {
             }
           )
         },
+        stopOnFirstErrorAssignment(cb) {
+          SplitTestHandler.getAssignment(
+            req,
+            res,
+            'stop-on-first-error',
+            (error, assignment) => {
+              // do not fail editor load if assignment fails
+              if (error) {
+                cb(null, { variant: 'default' })
+              } else {
+                cb(null, assignment)
+              }
+            }
+          )
+        },
       },
       (
         err,
@@ -900,6 +915,7 @@ const ProjectController = {
           pdfDetachAssignment,
           pdfjsAssignment,
           dictionaryEditorAssignment,
+          stopOnFirstErrorAssignment,
         }
       ) => {
         if (err != null) {
@@ -1017,6 +1033,9 @@ const ProjectController = {
               !userIsMemberOfGroupSubscription &&
               !userHasInstitutionLicence
 
+            const showStopOnFirstError =
+              stopOnFirstErrorAssignment.variant === 'enabled'
+
             const template =
               detachRole === 'detached'
                 ? 'project/editor_detached'
@@ -1082,6 +1101,7 @@ const ProjectController = {
               debugPdfDetach,
               showNewSourceEditorOption,
               showSymbolPalette,
+              showStopOnFirstError,
               trackPdfDownload: partOfPdfCachingRollout('collect-metrics'),
               enablePdfCaching: partOfPdfCachingRollout('enable-caching'),
               resetServiceWorker:

+ 1 - 0
services/web/app/views/project/editor/meta.pug

@@ -31,6 +31,7 @@ meta(name="ol-trackPdfDownload" data-type="boolean" content=trackPdfDownload)
 meta(name="ol-resetServiceWorker" data-type="boolean" content=resetServiceWorker)
 meta(name="ol-detachRole" data-type="string" content=detachRole)
 meta(name="ol-showHeaderUpgradePrompt" data-type="boolean" content=showHeaderUpgradePrompt)
+meta(name="ol-showStopOnFirstError" data-type="boolean" content=showStopOnFirstError)
 
 - var fileActionI18n = ['edited', 'renamed', 'created', 'deleted'].reduce((acc, i) => {acc[i] = translate('file_action_' + i); return acc}, {})
 meta(name="ol-fileActionI18n" data-type="json" content=fileActionI18n)

+ 3 - 0
services/web/frontend/extracted-translations.json

@@ -59,6 +59,7 @@
   "commit": "",
   "common": "",
   "compile_error_entry_description": "",
+  "compile_error_handling": "",
   "compile_larger_projects": "",
   "compile_mode": "",
   "compile_terminated_by_user": "",
@@ -433,6 +434,7 @@
   "start_by_adding_your_email": "",
   "start_free_trial": "",
   "stop_compile": "",
+  "stop_on_first_error": "",
   "stop_on_validation_error": "",
   "store_your_work": "",
   "subject": "",
@@ -470,6 +472,7 @@
   "try_premium_for_free": "",
   "try_recompile_project": "",
   "try_refresh_page": "",
+  "try_to_compile_despite_errors": "",
   "turn_off_link_sharing": "",
   "turn_on_link_sharing": "",
   "unconfirmed": "",

+ 22 - 0
services/web/frontend/js/features/pdf-preview/components/pdf-compile-button.js

@@ -6,6 +6,7 @@ import { memo } from 'react'
 import classnames from 'classnames'
 import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
 import PdfCompileButtonInner from './pdf-compile-button-inner'
+import getMeta from '../../../utils/meta'
 
 function PdfCompileButton() {
   const {
@@ -15,7 +16,9 @@ function PdfCompileButton() {
     hasChanges,
     setAutoCompile,
     setDraft,
+    setStopOnFirstError,
     setStopOnValidationError,
+    stopOnFirstError,
     stopOnValidationError,
     startCompile,
     stopCompile,
@@ -23,6 +26,7 @@ function PdfCompileButton() {
   } = useCompileContext()
 
   const { t } = useTranslation()
+  const showStopOnFirstError = getMeta('ol-showStopOnFirstError')
 
   return (
     <ControlledDropdown
@@ -81,6 +85,24 @@ function PdfCompileButton() {
           {t('ignore_validation_errors')}
         </MenuItem>
 
+        {showStopOnFirstError && (
+          <MenuItem header>{t('compile_error_handling')}</MenuItem>
+        )}
+
+        {showStopOnFirstError && (
+          <MenuItem onSelect={() => setStopOnFirstError(true)}>
+            <Icon type={stopOnFirstError ? 'check' : ''} fw />
+            {t('stop_on_first_error')}
+          </MenuItem>
+        )}
+
+        {showStopOnFirstError && (
+          <MenuItem onSelect={() => setStopOnFirstError(false)}>
+            <Icon type={!stopOnFirstError ? 'check' : ''} fw />
+            {t('try_to_compile_despite_errors')}
+          </MenuItem>
+        )}
+
         <MenuItem divider />
 
         <MenuItem

+ 20 - 0
services/web/frontend/js/shared/context/detach-compile-context.js

@@ -45,8 +45,10 @@ export function DetachCompileProvider({ children }) {
     setPosition: _setPosition,
     setShowLogs: _setShowLogs,
     toggleLogs: _toggleLogs,
+    setStopOnFirstError: _setStopOnFirstError,
     setStopOnValidationError: _setStopOnValidationError,
     showLogs: _showLogs,
+    stopOnFirstError: _stopOnFirstError,
     stopOnValidationError: _stopOnValidationError,
     uncompiled: _uncompiled,
     validationIssues: _validationIssues,
@@ -158,6 +160,12 @@ export function DetachCompileProvider({ children }) {
     'detacher',
     'detached'
   )
+  const [stopOnFirstError] = useDetachStateWatcher(
+    'stopOnFirstError',
+    _stopOnFirstError,
+    'detacher',
+    'detached'
+  )
   const [stopOnValidationError] = useDetachStateWatcher(
     'stopOnValidationError',
     _stopOnValidationError,
@@ -231,6 +239,14 @@ export function DetachCompileProvider({ children }) {
     'detached',
     'detacher'
   )
+
+  const setStopOnFirstError = useDetachAction(
+    'setStopOnFirstError',
+    _setStopOnFirstError,
+    'detached',
+    'detacher'
+  )
+
   const setStopOnValidationError = useDetachAction(
     'setStopOnValidationError',
     _setStopOnValidationError,
@@ -310,10 +326,12 @@ export function DetachCompileProvider({ children }) {
       setPosition,
       setShowLogs,
       toggleLogs,
+      setStopOnFirstError,
       setStopOnValidationError,
       showLogs,
       startCompile,
       stopCompile,
+      stopOnFirstError,
       stopOnValidationError,
       uncompiled,
       validationIssues,
@@ -350,10 +368,12 @@ export function DetachCompileProvider({ children }) {
       setPosition,
       setShowLogs,
       toggleLogs,
+      setStopOnFirstError,
       setStopOnValidationError,
       showLogs,
       startCompile,
       stopCompile,
+      stopOnFirstError,
       stopOnValidationError,
       uncompiled,
       validationIssues,

+ 13 - 0
services/web/frontend/js/shared/context/local-compile-context.js

@@ -57,8 +57,10 @@ export const CompileContextPropTypes = {
     setPosition: PropTypes.func.isRequired,
     setShowLogs: PropTypes.func.isRequired,
     toggleLogs: PropTypes.func.isRequired,
+    setStopOnFirstError: PropTypes.func.isRequired,
     setStopOnValidationError: PropTypes.func.isRequired,
     showLogs: PropTypes.bool.isRequired,
+    stopOnFirstError: PropTypes.bool.isRequired,
     stopOnValidationError: PropTypes.bool.isRequired,
     uncompiled: PropTypes.bool,
     validationIssues: PropTypes.object,
@@ -155,6 +157,13 @@ export function LocalCompileProvider({ children }) {
   // whether the compile should run in draft mode
   const [draft, setDraft] = usePersistedState(`draft:${projectId}`, false, true)
 
+  // whether compiling should stop on first error
+  const [stopOnFirstError, setStopOnFirstError] = usePersistedState(
+    `stop_on_first_error:${projectId}`,
+    false,
+    true
+  )
+
   // whether compiling should be prevented if there are linting errors
   const [stopOnValidationError, setStopOnValidationError] = usePersistedState(
     `stop_on_validation_error:${projectId}`,
@@ -463,10 +472,12 @@ export function LocalCompileProvider({ children }) {
       setPosition,
       setShowLogs,
       toggleLogs,
+      setStopOnFirstError,
       setStopOnValidationError,
       showLogs,
       startCompile,
       stopCompile,
+      stopOnFirstError,
       stopOnValidationError,
       uncompiled,
       validationIssues,
@@ -500,10 +511,12 @@ export function LocalCompileProvider({ children }) {
       setHasLintingError, // only for stories
       setHighlights,
       setPosition,
+      setStopOnFirstError,
       setStopOnValidationError,
       showLogs,
       startCompile,
       stopCompile,
+      stopOnFirstError,
       stopOnValidationError,
       uncompiled,
       validationIssues,

+ 4 - 1
services/web/locales/en.json

@@ -1749,5 +1749,8 @@
   "unlink_dropbox_folder": "Unlink Dropbox Account",
   "unlink_dropbox_warning": "Any projects that you have synced with Dropbox will be disconnected and no longer kept in sync with Dropbox. Are you sure you want to unlink your Dropbox account?",
   "group_plans_are_only_available_on_an_annual_billing_cycle": "Group plans are only available on an annual billing cycle",
-  "email_or_password_wrong_try_again_or_reset": "Your email or password is incorrect. Please try again, or <0>set or reset your password</0>."
+  "email_or_password_wrong_try_again_or_reset": "Your email or password is incorrect. Please try again, or <0>set or reset your password</0>.",
+  "compile_error_handling": "Compile Error Handling",
+  "stop_on_first_error": "Stop on first error",
+  "try_to_compile_despite_errors": "Try to compile despite errors"
 }