index.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import {memo, useRef} from 'react';
  2. import {
  3. AutoSizer,
  4. CellMeasurer,
  5. List as ReactVirtualizedList,
  6. ListRowProps,
  7. } from 'react-virtualized';
  8. import styled from '@emotion/styled';
  9. import Placeholder from 'sentry/components/placeholder';
  10. import {t} from 'sentry/locale';
  11. import type {BreadcrumbTypeDefault, Crumb} from 'sentry/types/breadcrumbs';
  12. import ConsoleFilters from 'sentry/views/replays/detail/console/consoleFilters';
  13. import ConsoleLogRow from 'sentry/views/replays/detail/console/consoleLogRow';
  14. import useConsoleFilters from 'sentry/views/replays/detail/console/useConsoleFilters';
  15. import FluidHeight from 'sentry/views/replays/detail/layout/fluidHeight';
  16. import NoRowRenderer from 'sentry/views/replays/detail/noRowRenderer';
  17. import useVirtualizedList from 'sentry/views/replays/detail/useVirtualizedList';
  18. interface Props {
  19. breadcrumbs: undefined | Extract<Crumb, BreadcrumbTypeDefault>[];
  20. startTimestampMs: number;
  21. }
  22. function Console({breadcrumbs, startTimestampMs}: Props) {
  23. const filterProps = useConsoleFilters({breadcrumbs: breadcrumbs || []});
  24. const {items, setSearchTerm} = filterProps;
  25. const clearSearchTerm = () => setSearchTerm('');
  26. const listRef = useRef<ReactVirtualizedList>(null);
  27. const {cache} = useVirtualizedList({
  28. cellMeasurer: {
  29. fixedWidth: true,
  30. minHeight: 24,
  31. },
  32. ref: listRef,
  33. deps: [items],
  34. });
  35. const renderRow = ({index, key, style, parent}: ListRowProps) => {
  36. const item = items[index];
  37. return (
  38. <CellMeasurer
  39. cache={cache}
  40. columnIndex={0}
  41. key={key}
  42. parent={parent}
  43. rowIndex={index}
  44. >
  45. <ConsoleLogRow
  46. breadcrumb={item}
  47. breadcrumbs={items}
  48. startTimestampMs={startTimestampMs}
  49. style={style}
  50. />
  51. </CellMeasurer>
  52. );
  53. };
  54. return (
  55. <ConsoleContainer>
  56. <ConsoleFilters breadcrumbs={breadcrumbs} {...filterProps} />
  57. <ConsoleLogContainer>
  58. {breadcrumbs ? (
  59. <AutoSizer>
  60. {({width, height}) => (
  61. <ReactVirtualizedList
  62. deferredMeasurementCache={cache}
  63. height={height}
  64. noRowsRenderer={() => (
  65. <NoRowRenderer
  66. unfilteredItems={breadcrumbs}
  67. clearSearchTerm={clearSearchTerm}
  68. >
  69. {t('No console logs recorded')}
  70. </NoRowRenderer>
  71. )}
  72. overscanRowCount={5}
  73. ref={listRef}
  74. rowCount={items.length}
  75. rowHeight={cache.rowHeight}
  76. rowRenderer={renderRow}
  77. width={width}
  78. />
  79. )}
  80. </AutoSizer>
  81. ) : (
  82. <Placeholder height="100%" />
  83. )}
  84. </ConsoleLogContainer>
  85. </ConsoleContainer>
  86. );
  87. }
  88. const ConsoleContainer = styled(FluidHeight)`
  89. height: 100%;
  90. `;
  91. const ConsoleLogContainer = styled('div')`
  92. position: relative;
  93. height: 100%;
  94. overflow: hidden;
  95. border: 1px solid ${p => p.theme.border};
  96. border-radius: ${p => p.theme.borderRadius};
  97. `;
  98. export default memo(Console);