preview-logs-toggle-button.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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 logTypeLabel =
  113. logType === 'errors'
  114. ? t('your_project_has_an_error', { count: nLogs })
  115. : t('view_warning', { count: nLogs })
  116. const errorCountLabel = ` (${
  117. nLogs > MAX_ERRORS_COUNT ? `${MAX_ERRORS_COUNT}+` : nLogs
  118. })`
  119. return (
  120. <>
  121. <Icon type="file-text-o" />
  122. <span
  123. className="btn-toggle-logs-label toolbar-text"
  124. aria-label={logTypeLabel}
  125. style={textStyle}
  126. >
  127. {`${logTypeLabel}${nLogs > 1 ? errorCountLabel : ''}`}
  128. </span>
  129. </>
  130. )
  131. }
  132. function AutoCompileLintingError({ textStyle }) {
  133. const { t } = useTranslation()
  134. return (
  135. <>
  136. <Icon type="exclamation-triangle" />
  137. <span className="toolbar-text" style={textStyle}>
  138. {t('code_check_failed')}
  139. </span>
  140. </>
  141. )
  142. }
  143. function ViewLogs({ textStyle }) {
  144. const { t } = useTranslation()
  145. return (
  146. <>
  147. <Icon type="file-text-o" />
  148. <span className="toolbar-text" style={textStyle}>
  149. {t('view_logs')}
  150. </span>
  151. </>
  152. )
  153. }
  154. PreviewLogsToggleButton.propTypes = {
  155. onToggle: PropTypes.func.isRequired,
  156. logsState: PropTypes.shape({
  157. nErrors: PropTypes.number.isRequired,
  158. nWarnings: PropTypes.number.isRequired,
  159. }),
  160. showLogs: PropTypes.bool.isRequired,
  161. showText: PropTypes.bool.isRequired,
  162. compileFailed: PropTypes.bool,
  163. autoCompileLintingError: PropTypes.bool,
  164. }
  165. CompilationResult.propTypes = {
  166. textStyle: PropTypes.object.isRequired,
  167. autoCompileLintingError: PropTypes.bool,
  168. nErrors: PropTypes.number.isRequired,
  169. nWarnings: PropTypes.number.isRequired,
  170. }
  171. LogsCompilationResult.propTypes = {
  172. logType: PropTypes.string.isRequired,
  173. nLogs: PropTypes.number.isRequired,
  174. textStyle: PropTypes.object.isRequired,
  175. }
  176. AutoCompileLintingError.propTypes = {
  177. textStyle: PropTypes.object.isRequired,
  178. }
  179. ViewLogs.propTypes = {
  180. textStyle: PropTypes.object.isRequired,
  181. }
  182. ViewPdf.propTypes = {
  183. textStyle: PropTypes.object.isRequired,
  184. }
  185. export default PreviewLogsToggleButton