index.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import {memo, useMemo, useRef} from 'react';
  2. import {
  3. AutoSizer,
  4. CellMeasurer,
  5. List as ReactVirtualizedList,
  6. ListRowProps,
  7. } from 'react-virtualized';
  8. import Placeholder from 'sentry/components/placeholder';
  9. import {useReplayContext} from 'sentry/components/replays/replayContext';
  10. import {t} from 'sentry/locale';
  11. import useCrumbHandlers from 'sentry/utils/replays/hooks/useCrumbHandlers';
  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 TabItemContainer from 'sentry/views/replays/detail/tabItemContainer';
  18. import useVirtualizedList from 'sentry/views/replays/detail/useVirtualizedList';
  19. import useVirtualizedInspector from '../useVirtualizedInspector';
  20. // Ensure this object is created once as it is an input to
  21. // `useVirtualizedList`'s memoization
  22. const cellMeasurer = {
  23. fixedWidth: true,
  24. minHeight: 24,
  25. };
  26. function Console() {
  27. const {currentTime, currentHoverTime, replay} = useReplayContext();
  28. const {onMouseEnter, onMouseLeave, onClickTimestamp} = useCrumbHandlers();
  29. const startTimestampMs = replay?.getReplay()?.started_at?.getTime() ?? 0;
  30. const frames = replay?.getConsoleFrames();
  31. const filterProps = useConsoleFilters({frames: frames || []});
  32. const {expandPathsRef, searchTerm, logLevel, items, setSearchTerm} = filterProps;
  33. const clearSearchTerm = () => setSearchTerm('');
  34. const listRef = useRef<ReactVirtualizedList>(null);
  35. const deps = useMemo(() => [items], [items]);
  36. const {cache, updateList} = useVirtualizedList({
  37. cellMeasurer,
  38. ref: listRef,
  39. deps,
  40. });
  41. const {handleDimensionChange} = useVirtualizedInspector({
  42. cache,
  43. listRef,
  44. expandPathsRef,
  45. });
  46. const renderRow = ({index, key, style, parent}: ListRowProps) => {
  47. const item = items[index];
  48. return (
  49. <CellMeasurer
  50. cache={cache}
  51. columnIndex={0}
  52. // Set key based on filters, otherwise we can have odd expand/collapse state
  53. // with <ObjectInspector> when filtering
  54. key={`${searchTerm}-${logLevel.join(',')}-${key}`}
  55. parent={parent}
  56. rowIndex={index}
  57. >
  58. <ConsoleLogRow
  59. currentHoverTime={currentHoverTime}
  60. currentTime={currentTime}
  61. expandPaths={Array.from(expandPathsRef.current?.get(index) || [])}
  62. frame={item}
  63. onMouseEnter={onMouseEnter}
  64. onMouseLeave={onMouseLeave}
  65. index={index}
  66. onClickTimestamp={onClickTimestamp}
  67. onDimensionChange={handleDimensionChange}
  68. startTimestampMs={startTimestampMs}
  69. style={style}
  70. />
  71. </CellMeasurer>
  72. );
  73. };
  74. return (
  75. <FluidHeight>
  76. <ConsoleFilters frames={frames} {...filterProps} />
  77. <TabItemContainer data-test-id="replay-details-console-tab">
  78. {frames ? (
  79. <AutoSizer onResize={updateList}>
  80. {({width, height}) => (
  81. <ReactVirtualizedList
  82. deferredMeasurementCache={cache}
  83. height={height}
  84. noRowsRenderer={() => (
  85. <NoRowRenderer
  86. unfilteredItems={frames}
  87. clearSearchTerm={clearSearchTerm}
  88. >
  89. {t('No console logs recorded')}
  90. </NoRowRenderer>
  91. )}
  92. overscanRowCount={5}
  93. ref={listRef}
  94. rowCount={items.length}
  95. rowHeight={cache.rowHeight}
  96. rowRenderer={renderRow}
  97. width={width}
  98. />
  99. )}
  100. </AutoSizer>
  101. ) : (
  102. <Placeholder height="100%" />
  103. )}
  104. </TabItemContainer>
  105. </FluidHeight>
  106. );
  107. }
  108. export default memo(Console);