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

Merge pull request #8747 from overleaf/ae-error-boundary-fallback

Create a generic ErrorBoundaryFallback component

GitOrigin-RevId: 0c9200ddef2be3b90030a32eb8c36a59047cf2b4
Alf Eaton 4 лет назад
Родитель
Сommit
d905863002

+ 0 - 68
services/web/frontend/js/features/pdf-preview/components/error-boundary-fallback.js

@@ -1,68 +0,0 @@
-import PropTypes from 'prop-types'
-import { Alert } from 'react-bootstrap'
-import { Trans, useTranslation } from 'react-i18next'
-
-function ErrorBoundaryFallback({ type }) {
-  const { t } = useTranslation()
-
-  // we create each instance of `<Trans/>` individually so `i18next-scanner` can detect hardcoded `i18nKey` values
-  let content
-  if (type === 'pdf') {
-    content = (
-      <>
-        <p>{t('pdf_viewer_error')}</p>
-        <p>
-          <Trans
-            i18nKey="try_recompile_project_or_troubleshoot"
-            components={[
-              // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
-              <a href="/learn/how-to/Resolving_access%2C_loading%2C_and_display_problems" />,
-            ]}
-          />
-        </p>
-      </>
-    )
-  } else if (type === 'logs') {
-    content = (
-      <>
-        <p>{t('log_viewer_error')}</p>
-        <p>
-          <Trans
-            i18nKey="try_recompile_project_or_troubleshoot"
-            components={[
-              // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
-              <a href="/learn/how-to/Resolving_access%2C_loading%2C_and_display_problems" />,
-            ]}
-          />
-        </p>
-      </>
-    )
-  } else {
-    content = (
-      <>
-        <p>{t('pdf_preview_error')}</p>
-        <p>
-          <Trans
-            i18nKey="try_recompile_project_or_troubleshoot"
-            components={[
-              // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
-              <a href="/learn/how-to/Resolving_access%2C_loading%2C_and_display_problems" />,
-            ]}
-          />
-        </p>
-      </>
-    )
-  }
-
-  return (
-    <div className="pdf-error-alert">
-      <Alert bsStyle="danger">{content}</Alert>
-    </div>
-  )
-}
-
-ErrorBoundaryFallback.propTypes = {
-  type: PropTypes.oneOf(['preview', 'pdf', 'logs']).isRequired,
-}
-
-export default ErrorBoundaryFallback

+ 2 - 2
services/web/frontend/js/features/pdf-preview/components/pdf-js-viewer.js

@@ -7,7 +7,7 @@ import usePersistedState from '../../../shared/hooks/use-persisted-state'
 import { buildHighlightElement } from '../util/highlights'
 import PDFJSWrapper from '../util/pdf-js-wrapper'
 import withErrorBoundary from '../../../infrastructure/error-boundary'
-import ErrorBoundaryFallback from './error-boundary-fallback'
+import PdfPreviewErrorBoundaryFallback from './pdf-preview-error-boundary-fallback'
 import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
 import { captureException } from '../../../infrastructure/error-reporter'
 import { getPdfCachingMetrics } from '../util/metrics'
@@ -409,5 +409,5 @@ PdfJsViewer.propTypes = {
 }
 
 export default withErrorBoundary(memo(PdfJsViewer), () => (
-  <ErrorBoundaryFallback type="pdf" />
+  <PdfPreviewErrorBoundaryFallback type="pdf" />
 ))

+ 2 - 2
services/web/frontend/js/features/pdf-preview/components/pdf-logs-viewer.js

@@ -9,7 +9,7 @@ import PdfClearCacheButton from './pdf-clear-cache-button'
 import PdfDownloadFilesButton from './pdf-download-files-button'
 import PdfLogsEntries from './pdf-logs-entries'
 import withErrorBoundary from '../../../infrastructure/error-boundary'
-import ErrorBoundaryFallback from './error-boundary-fallback'
+import PdfPreviewErrorBoundaryFallback from './pdf-preview-error-boundary-fallback'
 import PdfCodeCheckFailedNotice from './pdf-code-check-failed-notice'
 import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
 import PdfLogEntry from './pdf-log-entry'
@@ -69,5 +69,5 @@ function PdfLogsViewer() {
 }
 
 export default withErrorBoundary(memo(PdfLogsViewer), () => (
-  <ErrorBoundaryFallback type="logs" />
+  <PdfPreviewErrorBoundaryFallback type="logs" />
 ))

+ 50 - 0
services/web/frontend/js/features/pdf-preview/components/pdf-preview-error-boundary-fallback.js

@@ -0,0 +1,50 @@
+import PropTypes from 'prop-types'
+import { Trans, useTranslation } from 'react-i18next'
+import { ErrorBoundaryFallback } from '../../../shared/components/error-boundary-fallback'
+
+function PdfPreviewErrorBoundaryFallback({ type }) {
+  const { t } = useTranslation()
+
+  const showInfoLink = (
+    <Trans
+      i18nKey="try_recompile_project_or_troubleshoot"
+      components={[
+        // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content, jsx-a11y/anchor-is-valid
+        <a href="/learn/how-to/Resolving_access%2C_loading%2C_and_display_problems" />,
+      ]}
+    />
+  )
+
+  switch (type) {
+    case 'pdf':
+      return (
+        <ErrorBoundaryFallback>
+          <p>{t('pdf_viewer_error')}</p>
+          <p>{showInfoLink}</p>
+        </ErrorBoundaryFallback>
+      )
+
+    case 'logs':
+      return (
+        <ErrorBoundaryFallback>
+          <p>{t('log_viewer_error')}</p>
+          <p>{showInfoLink}</p>
+        </ErrorBoundaryFallback>
+      )
+
+    case 'preview':
+    default:
+      return (
+        <ErrorBoundaryFallback>
+          <p>{t('pdf_preview_error')}</p>
+          <p>{showInfoLink}</p>
+        </ErrorBoundaryFallback>
+      )
+  }
+}
+
+PdfPreviewErrorBoundaryFallback.propTypes = {
+  type: PropTypes.oneOf(['preview', 'pdf', 'logs']).isRequired,
+}
+
+export default PdfPreviewErrorBoundaryFallback

+ 2 - 2
services/web/frontend/js/features/pdf-preview/components/pdf-preview.js

@@ -2,7 +2,7 @@ import PdfPreviewPane from './pdf-preview-pane'
 import useCompileTriggers from '../hooks/use-compile-triggers'
 import { memo } from 'react'
 import withErrorBoundary from '../../../infrastructure/error-boundary'
-import ErrorBoundaryFallback from './error-boundary-fallback'
+import PdfPreviewErrorBoundaryFallback from './pdf-preview-error-boundary-fallback'
 import { useLayoutContext } from '../../../shared/context/layout-context'
 
 function PdfPreview() {
@@ -14,5 +14,5 @@ function PdfPreview() {
 }
 
 export default withErrorBoundary(memo(PdfPreview), () => (
-  <ErrorBoundaryFallback type="preview" />
+  <PdfPreviewErrorBoundaryFallback type="preview" />
 ))

+ 21 - 0
services/web/frontend/js/shared/components/error-boundary-fallback.tsx

@@ -0,0 +1,21 @@
+import { FC, ReactNode } from 'react'
+import { Alert } from 'react-bootstrap'
+import { useTranslation } from 'react-i18next'
+
+export const ErrorBoundaryFallback: FC<{ modal?: ReactNode }> = ({
+  children,
+  modal,
+}) => {
+  return (
+    <div className="error-boundary-alert">
+      <Alert bsStyle="danger">{children || <DefaultContent />}</Alert>
+      {modal}
+    </div>
+  )
+}
+
+const DefaultContent = () => {
+  const { t } = useTranslation()
+
+  return <p>{`${t('generic_something_went_wrong')}. ${t('please_refresh')}`}</p>
+}

+ 28 - 0
services/web/frontend/js/shared/hooks/use-contact-us-modal.tsx

@@ -0,0 +1,28 @@
+import importOverleafModules from '../../../macros/import-overleaf-module.macro'
+import { JSXElementConstructor, useCallback, useState } from 'react'
+
+const [contactUsModalModules] = importOverleafModules('contactUsModal')
+const ContactUsModal: JSXElementConstructor<{
+  show: boolean
+  handleHide: () => void
+}> = contactUsModalModules?.import.default
+
+export const useContactUsModal = () => {
+  const [show, setShow] = useState(false)
+
+  const hideModal = useCallback((event?: Event) => {
+    event?.preventDefault()
+    setShow(false)
+  }, [])
+
+  const showModal = useCallback((event?: Event) => {
+    event?.preventDefault()
+    setShow(true)
+  }, [])
+
+  const modal = ContactUsModal && (
+    <ContactUsModal show={show} handleHide={hideModal} />
+  )
+
+  return { modal, hideModal, showModal }
+}

+ 5 - 5
services/web/frontend/stories/pdf-preview-error-boundary.stories.js

@@ -1,20 +1,20 @@
-import ErrorBoundaryFallback from '../js/features/pdf-preview/components/error-boundary-fallback'
+import PdfPreviewErrorBoundaryFallback from '../js/features/pdf-preview/components/pdf-preview-error-boundary-fallback'
 import { ScopeDecorator } from './decorators/scope'
 
 export default {
   title: 'Editor / PDF Preview / Error Boundary',
-  component: ErrorBoundaryFallback,
+  component: PdfPreviewErrorBoundaryFallback,
   decorators: [ScopeDecorator],
 }
 
 export const PreviewErrorBoundary = () => {
-  return <ErrorBoundaryFallback type="preview" />
+  return <PdfPreviewErrorBoundaryFallback type="preview" />
 }
 
 export const PdfErrorBoundary = () => {
-  return <ErrorBoundaryFallback type="pdf" />
+  return <PdfPreviewErrorBoundaryFallback type="pdf" />
 }
 
 export const LogsErrorBoundary = () => {
-  return <ErrorBoundaryFallback type="logs" />
+  return <PdfPreviewErrorBoundaryFallback type="logs" />
 }

+ 1 - 0
services/web/frontend/stylesheets/app/editor.less

@@ -3,6 +3,7 @@
 @import './editor/toolbar.less';
 @import './editor/left-menu.less';
 @import './editor/pdf.less';
+@import './editor/error-boundary.less';
 @import './editor/share.less';
 @import './editor/chat.less';
 @import './editor/file-view.less';

+ 7 - 0
services/web/frontend/stylesheets/app/editor/error-boundary.less

@@ -0,0 +1,7 @@
+.error-boundary-alert {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  background-color: @ol-blue-gray-0;
+  padding: @line-height-computed / 2;
+}

+ 0 - 8
services/web/frontend/stylesheets/app/editor/pdf.less

@@ -649,14 +649,6 @@
   );
 }
 
-.pdf-error-alert {
-  position: absolute;
-  width: 100%;
-  height: 100%;
-  background-color: @pdf-bg;
-  padding: @line-height-computed / 2;
-}
-
 .pdf-loading-spinner-container {
   width: 100%;
   height: 100%;