preview-logs-toggle-button.js 4.4 KB

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