pdf-error-state.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import OLButton from '@/features/ui/components/ol/ol-button'
  2. import MaterialIcon from '@/shared/components/material-icon'
  3. import { useTranslation } from 'react-i18next'
  4. import { useRailContext } from '../../contexts/rail-context'
  5. import { usePdfPreviewContext } from '@/features/pdf-preview/components/pdf-preview-provider'
  6. import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
  7. import { useIsNewEditorEnabled } from '../../utils/new-editor-utils'
  8. import { upgradePlan } from '@/main/account-upgrade'
  9. import classNames from 'classnames'
  10. function PdfErrorState() {
  11. const { loadingError } = usePdfPreviewContext()
  12. // TODO ide-redesign-cleanup: rename showLogs to something else and check usages
  13. const { hasShortCompileTimeout, error, showLogs } = useCompileContext()
  14. const newEditor = useIsNewEditorEnabled()
  15. if (!newEditor || (!loadingError && !showLogs)) {
  16. return null
  17. }
  18. if (hasShortCompileTimeout && error === 'timedout') {
  19. return <CompileTimeoutErrorState />
  20. }
  21. return <GeneralErrorState />
  22. }
  23. const GeneralErrorState = () => {
  24. const { t } = useTranslation()
  25. const { openTab: openRailTab } = useRailContext()
  26. return (
  27. <ErrorState
  28. title={t('pdf_couldnt_compile')}
  29. description={t('we_are_unable_to_generate_the_pdf_at_this_time')}
  30. iconType="warning"
  31. iconClassName="pdf-error-state-warning-icon"
  32. actions={
  33. <OLButton
  34. variant="secondary"
  35. size="sm"
  36. onClick={() => {
  37. openRailTab('errors')
  38. }}
  39. >
  40. {t('check_logs')}
  41. </OLButton>
  42. }
  43. extraContent={
  44. <div className="pdf-error-state-info-box">
  45. <div className="pdf-error-state-info-box-title">
  46. <MaterialIcon type="info" unfilled />
  47. {t('why_might_this_happen')}
  48. </div>
  49. <ul className="pdf-error-state-info-box-text">
  50. <li>{t('there_is_an_unrecoverable_latex_error')}</li>
  51. <li>{t('the_document_environment_contains_no_content')}</li>
  52. <li>{t('this_project_contains_a_file_called_output')}</li>
  53. </ul>
  54. </div>
  55. }
  56. />
  57. )
  58. }
  59. const CompileTimeoutErrorState = () => {
  60. const { t } = useTranslation()
  61. return (
  62. <ErrorState
  63. title={t('compile_limit_reached')}
  64. description={t('compile_limit_upgrade_prompt')}
  65. iconType="running_with_errors"
  66. actions={
  67. <OLButton
  68. variant="premium"
  69. size="sm"
  70. onClick={() => upgradePlan('compile-timeout')}
  71. >
  72. {t('upgrade')}
  73. </OLButton>
  74. }
  75. />
  76. )
  77. }
  78. const ErrorState = ({
  79. title,
  80. description,
  81. iconType,
  82. actions,
  83. iconClassName,
  84. extraContent,
  85. }: {
  86. title: string
  87. description: string
  88. iconType: string
  89. actions: React.ReactNode
  90. iconClassName?: string
  91. extraContent?: React.ReactNode
  92. }) => {
  93. return (
  94. <div className="pdf-error-state">
  95. <div className="pdf-error-state-top-section">
  96. <div className={classNames('pdf-error-state-icon', iconClassName)}>
  97. <MaterialIcon type={iconType} />
  98. </div>
  99. <div className="pdf-error-state-text">
  100. <p className="pdf-error-state-label">{title}</p>
  101. <p className="pdf-error-state-description">{description}</p>
  102. </div>
  103. {actions}
  104. </div>
  105. {extraContent}
  106. </div>
  107. )
  108. }
  109. export default PdfErrorState