import {memo, useMemo, useRef, useState} from 'react'; import type {ListRowProps} from 'react-virtualized'; import {AutoSizer, CellMeasurer, List as ReactVirtualizedList} from 'react-virtualized'; import Placeholder from 'sentry/components/placeholder'; import JumpButtons from 'sentry/components/replays/jumpButtons'; import {useReplayContext} from 'sentry/components/replays/replayContext'; import useJumpButtons from 'sentry/components/replays/useJumpButtons'; import {t} from 'sentry/locale'; import useCrumbHandlers from 'sentry/utils/replays/hooks/useCrumbHandlers'; import ConsoleFilters from 'sentry/views/replays/detail/console/consoleFilters'; import ConsoleLogRow from 'sentry/views/replays/detail/console/consoleLogRow'; import useConsoleFilters from 'sentry/views/replays/detail/console/useConsoleFilters'; import FluidHeight from 'sentry/views/replays/detail/layout/fluidHeight'; import NoRowRenderer from 'sentry/views/replays/detail/noRowRenderer'; import TabItemContainer from 'sentry/views/replays/detail/tabItemContainer'; import useVirtualizedList from 'sentry/views/replays/detail/useVirtualizedList'; import useVirtualizedInspector from '../useVirtualizedInspector'; // Ensure this object is created once as it is an input to // `useVirtualizedList`'s memoization const cellMeasurer = { fixedWidth: true, minHeight: 24, }; function Console() { const {currentTime, currentHoverTime, replay} = useReplayContext(); const {onMouseEnter, onMouseLeave, onClickTimestamp} = useCrumbHandlers(); const startTimestampMs = replay?.getReplay()?.started_at?.getTime() ?? 0; const frames = replay?.getConsoleFrames(); const [scrollToRow, setScrollToRow] = useState(undefined); const filterProps = useConsoleFilters({frames: frames || []}); const {expandPathsRef, searchTerm, logLevel, items, setSearchTerm} = filterProps; const clearSearchTerm = () => setSearchTerm(''); const listRef = useRef(null); const deps = useMemo(() => [items], [items]); const {cache, updateList} = useVirtualizedList({ cellMeasurer, ref: listRef, deps, }); const {handleDimensionChange} = useVirtualizedInspector({ cache, listRef, expandPathsRef, }); const { handleClick: onClickToJump, onRowsRendered, showJumpDownButton, showJumpUpButton, } = useJumpButtons({ currentTime, frames: items, isTable: false, setScrollToRow, }); const renderRow = ({index, key, style, parent}: ListRowProps) => { const item = items[index]; return ( when filtering key={`${searchTerm}-${logLevel.join(',')}-${key}`} parent={parent} rowIndex={index} > ); }; return ( {frames ? ( {({width, height}) => ( ( {t('No console logs recorded')} )} onRowsRendered={onRowsRendered} onScroll={() => { if (scrollToRow !== undefined) { setScrollToRow(undefined); } }} overscanRowCount={5} ref={listRef} rowCount={items.length} rowHeight={cache.rowHeight} rowRenderer={renderRow} scrollToIndex={scrollToRow} width={width} /> )} ) : ( )} {items?.length ? ( ) : null} ); } export default memo(Console);