perfTable.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import {useMemo, useRef} from 'react';
  2. import type {ListRowProps} from 'react-virtualized';
  3. import {AutoSizer, CellMeasurer, List as ReactVirtualizedList} from 'react-virtualized';
  4. import Placeholder from 'sentry/components/placeholder';
  5. import {useReplayContext} from 'sentry/components/replays/replayContext';
  6. import {t} from 'sentry/locale';
  7. import FilterLoadingIndicator from 'sentry/views/replays/detail/filterLoadingIndicator';
  8. import FluidHeight from 'sentry/views/replays/detail/layout/fluidHeight';
  9. import NoRowRenderer from 'sentry/views/replays/detail/noRowRenderer';
  10. import PerfFilters from 'sentry/views/replays/detail/perfTable/perfFilters';
  11. import PerfRow from 'sentry/views/replays/detail/perfTable/perfRow';
  12. import usePerfFilters from 'sentry/views/replays/detail/perfTable/usePerfFilters';
  13. import type useReplayPerfData from 'sentry/views/replays/detail/perfTable/useReplayPerfData';
  14. import TabItemContainer from 'sentry/views/replays/detail/tabItemContainer';
  15. import useVirtualizedList from 'sentry/views/replays/detail/useVirtualizedList';
  16. import useVirtualListDimentionChange from 'sentry/views/replays/detail/useVirtualListDimentionChange';
  17. interface Props {
  18. perfData: ReturnType<typeof useReplayPerfData>;
  19. }
  20. const cellMeasurer = {
  21. fixedWidth: true,
  22. minHeight: 24,
  23. };
  24. export default function PerfTable({perfData}: Props) {
  25. const {currentTime, currentHoverTime, replay} = useReplayContext();
  26. const startTimestampMs = replay?.getReplay().started_at.getTime() ?? 0;
  27. const traceRows = Array.from(perfData.data.values());
  28. const filterProps = usePerfFilters({traceRows: traceRows || []});
  29. const {items} = filterProps; // setSearchTerm
  30. const clearSearchTerm = () => {}; // setSearchTerm('');
  31. const listRef = useRef<ReactVirtualizedList>(null);
  32. const deps = useMemo(() => [items], [items]);
  33. const {cache, updateList} = useVirtualizedList({
  34. cellMeasurer,
  35. ref: listRef,
  36. deps,
  37. });
  38. const {handleDimensionChange} = useVirtualListDimentionChange({cache, listRef});
  39. const renderRow = ({index, key, style, parent}: ListRowProps) => {
  40. const traceRow = items[index];
  41. return (
  42. <CellMeasurer
  43. cache={cache}
  44. columnIndex={0}
  45. key={key}
  46. parent={parent}
  47. rowIndex={index}
  48. >
  49. <PerfRow
  50. currentHoverTime={currentHoverTime}
  51. currentTime={currentTime}
  52. index={index}
  53. onDimensionChange={handleDimensionChange}
  54. startTimestampMs={startTimestampMs}
  55. style={style}
  56. traceRow={traceRow}
  57. />
  58. </CellMeasurer>
  59. );
  60. };
  61. return (
  62. <FluidHeight>
  63. <FilterLoadingIndicator isLoading={perfData.isFetching}>
  64. <PerfFilters traceRows={traceRows} {...filterProps} />
  65. </FilterLoadingIndicator>
  66. <TabItemContainer>
  67. {traceRows ? (
  68. <AutoSizer onResize={updateList}>
  69. {({width, height}) => (
  70. <ReactVirtualizedList
  71. deferredMeasurementCache={cache}
  72. height={height}
  73. noRowsRenderer={() => (
  74. <NoRowRenderer
  75. unfilteredItems={traceRows}
  76. clearSearchTerm={clearSearchTerm}
  77. >
  78. {t('No events recorded')}
  79. </NoRowRenderer>
  80. )}
  81. overscanRowCount={5}
  82. ref={listRef}
  83. rowCount={items.length}
  84. rowHeight={cache.rowHeight}
  85. rowRenderer={renderRow}
  86. width={width}
  87. />
  88. )}
  89. </AutoSizer>
  90. ) : (
  91. <Placeholder height="100%" />
  92. )}
  93. </TabItemContainer>
  94. </FluidHeight>
  95. );
  96. }