preview-pane.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import { useState } from 'react'
  2. import PropTypes from 'prop-types'
  3. import PreviewToolbar from './preview-toolbar'
  4. import PreviewLogsPane from './preview-logs-pane'
  5. import PreviewFirstErrorPopUp from './preview-first-error-pop-up'
  6. import { useTranslation } from 'react-i18next'
  7. function PreviewPane({
  8. compilerState,
  9. onClearCache,
  10. onRecompile,
  11. onRecompileFromScratch,
  12. onRunSyntaxCheckNow,
  13. onSetAutoCompile,
  14. onSetDraftMode,
  15. onSetSyntaxCheck,
  16. onToggleLogs,
  17. onSetFullLayout,
  18. onSetSplitLayout,
  19. onStopCompilation,
  20. outputFiles,
  21. pdfDownloadUrl,
  22. onLogEntryLocationClick,
  23. showLogs,
  24. variantWithFirstErrorPopup = true,
  25. splitLayout,
  26. }) {
  27. const { t } = useTranslation()
  28. const [lastCompileTimestamp, setLastCompileTimestamp] = useState(
  29. compilerState.lastCompileTimestamp
  30. )
  31. const [seenLogsForCurrentCompile, setSeenLogsForCurrentCompile] =
  32. useState(false)
  33. const [dismissedFirstErrorPopUp, setDismissedFirstErrorPopUp] =
  34. useState(false)
  35. if (lastCompileTimestamp < compilerState.lastCompileTimestamp) {
  36. setLastCompileTimestamp(compilerState.lastCompileTimestamp)
  37. setSeenLogsForCurrentCompile(false)
  38. }
  39. if (showLogs && !seenLogsForCurrentCompile) {
  40. setSeenLogsForCurrentCompile(true)
  41. }
  42. const nErrors =
  43. compilerState.logEntries && compilerState.logEntries.errors
  44. ? compilerState.logEntries.errors.length
  45. : 0
  46. const nWarnings =
  47. compilerState.logEntries && compilerState.logEntries.warnings
  48. ? compilerState.logEntries.warnings.length
  49. : 0
  50. const hasCLSIErrors =
  51. compilerState.errors &&
  52. Object.keys(compilerState.errors).length > 0 &&
  53. compilerState.compileFailed &&
  54. !compilerState.isCompiling
  55. const hasValidationIssues =
  56. compilerState.validationIssues &&
  57. Object.keys(compilerState.validationIssues).length > 0 &&
  58. compilerState.compileFailed &&
  59. !compilerState.isCompiling
  60. const showFirstErrorPopUp =
  61. variantWithFirstErrorPopup &&
  62. nErrors > 0 &&
  63. !seenLogsForCurrentCompile &&
  64. !dismissedFirstErrorPopUp &&
  65. !compilerState.isCompiling
  66. function handleFirstErrorPopUpClose() {
  67. setDismissedFirstErrorPopUp(true)
  68. }
  69. return (
  70. <>
  71. <PreviewToolbar
  72. compilerState={compilerState}
  73. logsState={{ nErrors, nWarnings }}
  74. showLogs={showLogs}
  75. onRecompile={onRecompile}
  76. onRecompileFromScratch={onRecompileFromScratch}
  77. onRunSyntaxCheckNow={onRunSyntaxCheckNow}
  78. onSetAutoCompile={onSetAutoCompile}
  79. onSetDraftMode={onSetDraftMode}
  80. onSetSyntaxCheck={onSetSyntaxCheck}
  81. onToggleLogs={onToggleLogs}
  82. onSetSplitLayout={onSetSplitLayout}
  83. onSetFullLayout={onSetFullLayout}
  84. onStopCompilation={onStopCompilation}
  85. outputFiles={outputFiles}
  86. pdfDownloadUrl={pdfDownloadUrl}
  87. splitLayout={splitLayout}
  88. />
  89. <span aria-live="polite" className="sr-only">
  90. {hasCLSIErrors ? t('compile_error_description') : ''}
  91. </span>
  92. <span aria-live="polite" className="sr-only">
  93. {hasValidationIssues ? t('validation_issue_description') : ''}
  94. </span>
  95. <span aria-live="polite" className="sr-only">
  96. {nErrors && !compilerState.isCompiling
  97. ? t('n_errors', { count: nErrors })
  98. : ''}
  99. </span>
  100. <span aria-live="polite" className="sr-only">
  101. {nWarnings && !compilerState.isCompiling
  102. ? t('n_warnings', { count: nWarnings })
  103. : ''}
  104. </span>
  105. {showFirstErrorPopUp ? (
  106. <PreviewFirstErrorPopUp
  107. logEntry={compilerState.logEntries.errors[0]}
  108. nErrors={nErrors}
  109. onGoToErrorLocation={onLogEntryLocationClick}
  110. onViewLogs={onToggleLogs}
  111. onClose={handleFirstErrorPopUpClose}
  112. />
  113. ) : null}
  114. {showLogs ? (
  115. <PreviewLogsPane
  116. logEntries={compilerState.logEntries}
  117. rawLog={compilerState.rawLog}
  118. validationIssues={compilerState.validationIssues}
  119. errors={compilerState.errors}
  120. autoCompileHasLintingError={compilerState.autoCompileHasLintingError}
  121. outputFiles={outputFiles}
  122. onLogEntryLocationClick={onLogEntryLocationClick}
  123. isClearingCache={compilerState.isClearingCache}
  124. isCompiling={compilerState.isCompiling}
  125. variantWithFirstErrorPopup={variantWithFirstErrorPopup}
  126. onClearCache={onClearCache}
  127. />
  128. ) : null}
  129. </>
  130. )
  131. }
  132. PreviewPane.propTypes = {
  133. compilerState: PropTypes.shape({
  134. autoCompileHasLintingError: PropTypes.bool,
  135. isAutoCompileOn: PropTypes.bool.isRequired,
  136. isCompiling: PropTypes.bool.isRequired,
  137. isDraftModeOn: PropTypes.bool.isRequired,
  138. isSyntaxCheckOn: PropTypes.bool.isRequired,
  139. isClearingCache: PropTypes.bool.isRequired,
  140. lastCompileTimestamp: PropTypes.number,
  141. logEntries: PropTypes.object,
  142. validationIssues: PropTypes.object,
  143. errors: PropTypes.object,
  144. rawLog: PropTypes.string,
  145. compileFailed: PropTypes.bool,
  146. }),
  147. onClearCache: PropTypes.func.isRequired,
  148. onLogEntryLocationClick: PropTypes.func.isRequired,
  149. onRecompile: PropTypes.func.isRequired,
  150. onRecompileFromScratch: PropTypes.func.isRequired,
  151. onRunSyntaxCheckNow: PropTypes.func.isRequired,
  152. onSetAutoCompile: PropTypes.func.isRequired,
  153. onSetDraftMode: PropTypes.func.isRequired,
  154. onSetSyntaxCheck: PropTypes.func.isRequired,
  155. onSetSplitLayout: PropTypes.func.isRequired,
  156. onSetFullLayout: PropTypes.func.isRequired,
  157. onStopCompilation: PropTypes.func.isRequired,
  158. onToggleLogs: PropTypes.func.isRequired,
  159. outputFiles: PropTypes.array,
  160. pdfDownloadUrl: PropTypes.string,
  161. showLogs: PropTypes.bool.isRequired,
  162. variantWithFirstErrorPopup: PropTypes.bool,
  163. splitLayout: PropTypes.bool.isRequired,
  164. }
  165. export default PreviewPane