diff --git a/services/web/frontend/js/features/pdf-preview/components/error-boundary-fallback.js b/services/web/frontend/js/features/pdf-preview/components/error-boundary-fallback.js deleted file mode 100644 index 91d93c4142..0000000000 --- a/services/web/frontend/js/features/pdf-preview/components/error-boundary-fallback.js +++ /dev/null @@ -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 `` individually so `i18next-scanner` can detect hardcoded `i18nKey` values - let content - if (type === 'pdf') { - content = ( - <> -

{t('pdf_viewer_error')}

-

- , - ]} - /> -

- - ) - } else if (type === 'logs') { - content = ( - <> -

{t('log_viewer_error')}

-

- , - ]} - /> -

- - ) - } else { - content = ( - <> -

{t('pdf_preview_error')}

-

- , - ]} - /> -

- - ) - } - - return ( -
- {content} -
- ) -} - -ErrorBoundaryFallback.propTypes = { - type: PropTypes.oneOf(['preview', 'pdf', 'logs']).isRequired, -} - -export default ErrorBoundaryFallback diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-js-viewer.js b/services/web/frontend/js/features/pdf-preview/components/pdf-js-viewer.js index 936bcbb07b..ea1bb5c66b 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-js-viewer.js +++ b/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), () => ( - + )) diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-logs-viewer.js b/services/web/frontend/js/features/pdf-preview/components/pdf-logs-viewer.js index 3354439787..f41a2abd59 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-logs-viewer.js +++ b/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), () => ( - + )) diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-preview-error-boundary-fallback.js b/services/web/frontend/js/features/pdf-preview/components/pdf-preview-error-boundary-fallback.js new file mode 100644 index 0000000000..bfd3772ce9 --- /dev/null +++ b/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 = ( + , + ]} + /> + ) + + switch (type) { + case 'pdf': + return ( + +

{t('pdf_viewer_error')}

+

{showInfoLink}

+
+ ) + + case 'logs': + return ( + +

{t('log_viewer_error')}

+

{showInfoLink}

+
+ ) + + case 'preview': + default: + return ( + +

{t('pdf_preview_error')}

+

{showInfoLink}

+
+ ) + } +} + +PdfPreviewErrorBoundaryFallback.propTypes = { + type: PropTypes.oneOf(['preview', 'pdf', 'logs']).isRequired, +} + +export default PdfPreviewErrorBoundaryFallback diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-preview.js b/services/web/frontend/js/features/pdf-preview/components/pdf-preview.js index 33d820df0b..ae6c905415 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-preview.js +++ b/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), () => ( - + )) diff --git a/services/web/frontend/js/shared/components/error-boundary-fallback.tsx b/services/web/frontend/js/shared/components/error-boundary-fallback.tsx new file mode 100644 index 0000000000..14b9dc183b --- /dev/null +++ b/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 ( +
+ {children || } + {modal} +
+ ) +} + +const DefaultContent = () => { + const { t } = useTranslation() + + return

{`${t('generic_something_went_wrong')}. ${t('please_refresh')}`}

+} diff --git a/services/web/frontend/js/shared/hooks/use-contact-us-modal.tsx b/services/web/frontend/js/shared/hooks/use-contact-us-modal.tsx new file mode 100644 index 0000000000..c4bc80b83a --- /dev/null +++ b/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 && ( + + ) + + return { modal, hideModal, showModal } +} diff --git a/services/web/frontend/stories/pdf-preview-error-boundary.stories.js b/services/web/frontend/stories/pdf-preview-error-boundary.stories.js index 353234d372..6ea6b4b3ab 100644 --- a/services/web/frontend/stories/pdf-preview-error-boundary.stories.js +++ b/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 + return } export const PdfErrorBoundary = () => { - return + return } export const LogsErrorBoundary = () => { - return + return } diff --git a/services/web/frontend/stylesheets/app/editor.less b/services/web/frontend/stylesheets/app/editor.less index c80b719499..b93fe5757e 100644 --- a/services/web/frontend/stylesheets/app/editor.less +++ b/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'; diff --git a/services/web/frontend/stylesheets/app/editor/error-boundary.less b/services/web/frontend/stylesheets/app/editor/error-boundary.less new file mode 100644 index 0000000000..dcbcf8ee92 --- /dev/null +++ b/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; +} diff --git a/services/web/frontend/stylesheets/app/editor/pdf.less b/services/web/frontend/stylesheets/app/editor/pdf.less index bd9aada6c7..f2e31afc82 100644 --- a/services/web/frontend/stylesheets/app/editor/pdf.less +++ b/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%;