preview-logs-pane-entry.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import PropTypes from 'prop-types'
  2. import classNames from 'classnames'
  3. import { useTranslation } from 'react-i18next'
  4. import useExpandCollapse from '../../../shared/hooks/use-expand-collapse'
  5. import Icon from '../../../shared/components/icon'
  6. import PreviewLogEntryHeader from './preview-log-entry-header'
  7. function PreviewLogsPaneEntry({
  8. headerTitle,
  9. headerIcon,
  10. rawContent,
  11. logType,
  12. formattedContent,
  13. extraInfoURL,
  14. level,
  15. sourceLocation,
  16. showSourceLocationLink = true,
  17. showCloseButton = false,
  18. entryAriaLabel = null,
  19. customClass,
  20. onSourceLocationClick,
  21. onClose,
  22. }) {
  23. const logEntryClasses = classNames('log-entry', customClass)
  24. function handleLogEntryLinkClick(e) {
  25. e.preventDefault()
  26. onSourceLocationClick(sourceLocation)
  27. }
  28. return (
  29. <div className={logEntryClasses} aria-label={entryAriaLabel}>
  30. <PreviewLogEntryHeader
  31. level={level}
  32. sourceLocation={sourceLocation}
  33. headerTitle={headerTitle}
  34. headerIcon={headerIcon}
  35. logType={logType}
  36. showSourceLocationLink={showSourceLocationLink}
  37. onSourceLocationClick={handleLogEntryLinkClick}
  38. showCloseButton={showCloseButton}
  39. onClose={onClose}
  40. />
  41. {rawContent || formattedContent ? (
  42. <PreviewLogEntryContent
  43. rawContent={rawContent}
  44. formattedContent={formattedContent}
  45. extraInfoURL={extraInfoURL}
  46. />
  47. ) : null}
  48. </div>
  49. )
  50. }
  51. function PreviewLogEntryContent({
  52. rawContent,
  53. formattedContent,
  54. extraInfoURL,
  55. }) {
  56. const { isExpanded, needsExpandCollapse, expandableProps, toggleProps } =
  57. useExpandCollapse({
  58. collapsedSize: 150,
  59. })
  60. const buttonContainerClasses = classNames(
  61. 'log-entry-content-button-container',
  62. {
  63. 'log-entry-content-button-container-collapsed': !isExpanded,
  64. }
  65. )
  66. const { t } = useTranslation()
  67. return (
  68. <div className="log-entry-content">
  69. {formattedContent ? (
  70. <div className="log-entry-formatted-content">{formattedContent}</div>
  71. ) : null}
  72. {extraInfoURL ? (
  73. <div className="log-entry-content-link">
  74. <a href={extraInfoURL} target="_blank" rel="noopener">
  75. {t('log_hint_extra_info')}
  76. </a>
  77. </div>
  78. ) : null}
  79. {rawContent ? (
  80. <div className="log-entry-content-raw-container">
  81. <div {...expandableProps}>
  82. <pre className="log-entry-content-raw">{rawContent.trim()}</pre>
  83. </div>
  84. {needsExpandCollapse ? (
  85. <div className={buttonContainerClasses}>
  86. <button
  87. type="button"
  88. className="btn btn-xs btn-default log-entry-btn-expand-collapse"
  89. {...toggleProps}
  90. >
  91. {isExpanded ? (
  92. <>
  93. <Icon type="angle-up" /> {t('collapse')}
  94. </>
  95. ) : (
  96. <>
  97. <Icon type="angle-down" /> {t('expand')}
  98. </>
  99. )}
  100. </button>
  101. </div>
  102. ) : null}
  103. </div>
  104. ) : null}
  105. </div>
  106. )
  107. }
  108. PreviewLogEntryContent.propTypes = {
  109. rawContent: PropTypes.string,
  110. formattedContent: PropTypes.node,
  111. extraInfoURL: PropTypes.string,
  112. }
  113. PreviewLogsPaneEntry.propTypes = {
  114. sourceLocation: PreviewLogEntryHeader.propTypes.sourceLocation,
  115. headerTitle: PropTypes.string,
  116. headerIcon: PropTypes.element,
  117. rawContent: PropTypes.string,
  118. logType: PropTypes.string,
  119. formattedContent: PropTypes.node,
  120. extraInfoURL: PropTypes.string,
  121. level: PropTypes.oneOf(['error', 'warning', 'typesetting', 'raw', 'success'])
  122. .isRequired,
  123. customClass: PropTypes.string,
  124. showSourceLocationLink: PropTypes.bool,
  125. showCloseButton: PropTypes.bool,
  126. entryAriaLabel: PropTypes.string,
  127. onSourceLocationClick: PropTypes.func,
  128. onClose: PropTypes.func,
  129. }
  130. export default PreviewLogsPaneEntry