logFileViewer.tsx 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import styled from '@emotion/styled';
  2. import Ansi from 'ansi-to-react';
  3. import AsyncComponent from 'sentry/components/asyncComponent';
  4. import PreviewPanelItem from 'sentry/components/events/attachmentViewers/previewPanelItem';
  5. import {
  6. getAttachmentUrl,
  7. ViewerProps,
  8. } from 'sentry/components/events/attachmentViewers/utils';
  9. import space from 'sentry/styles/space';
  10. type Props = ViewerProps & AsyncComponent['props'];
  11. type State = AsyncComponent['state'];
  12. class LogFileViewer extends AsyncComponent<Props, State> {
  13. getEndpoints(): [string, string][] {
  14. return [['attachmentText', getAttachmentUrl(this.props)]];
  15. }
  16. renderBody() {
  17. const {attachmentText} = this.state;
  18. return !attachmentText ? null : (
  19. <PreviewPanelItem>
  20. <CodeWrapper>
  21. <SentryStyleAnsi useClasses>{attachmentText}</SentryStyleAnsi>
  22. </CodeWrapper>
  23. </PreviewPanelItem>
  24. );
  25. }
  26. }
  27. export default LogFileViewer;
  28. /**
  29. * Maps ANSI color names -> theme.tsx color names
  30. */
  31. const COLOR_MAP = {
  32. red: 'red',
  33. green: 'green',
  34. blue: 'blue',
  35. yellow: 'yellow',
  36. magenta: 'pink',
  37. cyan: 'purple',
  38. };
  39. const SentryStyleAnsi = styled(Ansi)`
  40. ${p =>
  41. Object.entries(COLOR_MAP).map(
  42. ([ansiColor, themeColor]) => `
  43. .ansi-${ansiColor}-bg {
  44. background-color: ${p.theme[`${themeColor}400`]};
  45. }
  46. .ansi-${ansiColor}-fg {
  47. color: ${p.theme[`${themeColor}400`]};
  48. }
  49. .ansi-bright-${ansiColor}-fg {
  50. color: ${p.theme[`${themeColor}200`]};
  51. }`
  52. )}
  53. .ansi-black-fg,
  54. .ansi-bright-black-fg {
  55. color: ${p => p.theme.black};
  56. }
  57. .ansi-white-fg,
  58. .ansi-bright-white-fg {
  59. color: ${p => p.theme.white};
  60. }
  61. `;
  62. const CodeWrapper = styled('pre')`
  63. padding: ${space(1)} ${space(2)};
  64. width: 100%;
  65. margin-bottom: 0;
  66. &:after {
  67. content: '';
  68. }
  69. `;