preview-logs-toggle-button.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. import { OverlayTrigger, Tooltip } from 'react-bootstrap'
  2. import PropTypes from 'prop-types'
  3. import classNames from 'classnames'
  4. import { useTranslation } from 'react-i18next'
  5. import Icon from '../../../shared/components/icon'
  6. const MAX_ERRORS_COUNT = 99
  7. function PreviewLogsToggleButton({
  8. onToggle,
  9. showLogs,
  10. autoCompileLintingError = false,
  11. compileFailed = false,
  12. logsState: { nErrors, nWarnings },
  13. showText,
  14. }) {
  15. const { t } = useTranslation()
  16. let textStyle = {}
  17. let btnColorCssClass = 'btn-default'
  18. let buttonContents
  19. if (!showText) {
  20. textStyle = {
  21. position: 'absolute',
  22. right: '-100vw',
  23. }
  24. }
  25. function handleOnClick(e) {
  26. e.currentTarget.blur()
  27. onToggle()
  28. }
  29. if (showLogs) {
  30. buttonContents = <ViewPdf textStyle={textStyle} />
  31. } else {
  32. buttonContents = (
  33. <CompilationResult
  34. textStyle={textStyle}
  35. autoCompileLintingError={autoCompileLintingError}
  36. nErrors={nErrors}
  37. nWarnings={nWarnings}
  38. />
  39. )
  40. if (autoCompileLintingError || nErrors > 0) {
  41. btnColorCssClass = 'btn-danger'
  42. } else if (nWarnings > 0) {
  43. btnColorCssClass = 'btn-warning'
  44. }
  45. }
  46. const buttonClasses = classNames(
  47. 'btn',
  48. 'btn-xs',
  49. 'btn-toggle-logs',
  50. 'toolbar-item',
  51. btnColorCssClass
  52. )
  53. const buttonElement = (
  54. <button
  55. id="logs-toggle"
  56. type="button"
  57. disabled={compileFailed}
  58. className={buttonClasses}
  59. onClick={handleOnClick}
  60. >
  61. {buttonContents}
  62. </button>
  63. )
  64. return showText ? (
  65. buttonElement
  66. ) : (
  67. <OverlayTrigger
  68. placement="bottom"
  69. overlay={
  70. <Tooltip id="tooltip-logs-toggle">
  71. {showLogs ? t('view_pdf') : t('view_logs')}
  72. </Tooltip>
  73. }
  74. >
  75. {buttonElement}
  76. </OverlayTrigger>
  77. )
  78. }
  79. function CompilationResult({
  80. textStyle,
  81. autoCompileLintingError,
  82. nErrors,
  83. nWarnings,
  84. }) {
  85. if (autoCompileLintingError) {
  86. return <AutoCompileLintingError textStyle={textStyle} />
  87. } else if (nErrors || nWarnings) {
  88. return (
  89. <LogsCompilationResult
  90. logType={nErrors ? 'errors' : 'warnings'}
  91. nLogs={nErrors || nWarnings}
  92. textStyle={textStyle}
  93. />
  94. )
  95. } else {
  96. return <ViewLogs textStyle={textStyle} />
  97. }
  98. }
  99. function ViewPdf({ textStyle }) {
  100. const { t } = useTranslation()
  101. return (
  102. <>
  103. <Icon type="file-pdf-o" />
  104. <span className="toolbar-text" style={textStyle}>
  105. {t('view_pdf')}
  106. </span>
  107. </>
  108. )
  109. }
  110. function LogsCompilationResult({ textStyle, logType, nLogs }) {
  111. const { t } = useTranslation()
  112. const label =
  113. logType === 'errors' ? t('your_project_has_errors') : t('view_warnings')
  114. return (
  115. <>
  116. <Icon type="file-text-o" />
  117. <span
  118. className="btn-toggle-logs-label toolbar-text"
  119. aria-label={label}
  120. style={textStyle}
  121. >
  122. {`${label} (${
  123. nLogs > MAX_ERRORS_COUNT ? `${MAX_ERRORS_COUNT}+` : nLogs
  124. })`}
  125. </span>
  126. </>
  127. )
  128. }
  129. function AutoCompileLintingError({ textStyle }) {
  130. const { t } = useTranslation()
  131. return (
  132. <>
  133. <Icon type="exclamation-triangle" />
  134. <span className="toolbar-text" style={textStyle}>
  135. {t('code_check_failed')}
  136. </span>
  137. </>
  138. )
  139. }
  140. function ViewLogs({ textStyle }) {
  141. const { t } = useTranslation()
  142. return (
  143. <>
  144. <Icon type="file-text-o" />
  145. <span className="toolbar-text" style={textStyle}>
  146. {t('view_logs')}
  147. </span>
  148. </>
  149. )
  150. }
  151. PreviewLogsToggleButton.propTypes = {
  152. onToggle: PropTypes.func.isRequired,
  153. logsState: PropTypes.shape({
  154. nErrors: PropTypes.number.isRequired,
  155. nWarnings: PropTypes.number.isRequired,
  156. }),
  157. showLogs: PropTypes.bool.isRequired,
  158. showText: PropTypes.bool.isRequired,
  159. compileFailed: PropTypes.bool,
  160. autoCompileLintingError: PropTypes.bool,
  161. }
  162. CompilationResult.propTypes = {
  163. textStyle: PropTypes.object.isRequired,
  164. autoCompileLintingError: PropTypes.bool,
  165. nErrors: PropTypes.number.isRequired,
  166. nWarnings: PropTypes.number.isRequired,
  167. }
  168. LogsCompilationResult.propTypes = {
  169. logType: PropTypes.string.isRequired,
  170. nLogs: PropTypes.number.isRequired,
  171. textStyle: PropTypes.object.isRequired,
  172. }
  173. AutoCompileLintingError.propTypes = {
  174. textStyle: PropTypes.object.isRequired,
  175. }
  176. ViewLogs.propTypes = {
  177. textStyle: PropTypes.object.isRequired,
  178. }
  179. ViewPdf.propTypes = {
  180. textStyle: PropTypes.object.isRequired,
  181. }
  182. export default PreviewLogsToggleButton