import {memo, useRef} from 'react'; import { AutoSizer, CellMeasurer, List as ReactVirtualizedList, ListRowProps, } from 'react-virtualized'; import styled from '@emotion/styled'; import Placeholder from 'sentry/components/placeholder'; import {t} from 'sentry/locale'; import useExtractedCrumbHtml from 'sentry/utils/replays/hooks/useExtractedCrumbHtml'; import type ReplayReader from 'sentry/utils/replays/replayReader'; import DomFilters from 'sentry/views/replays/detail/domMutations/domFilters'; import DomMutationRow from 'sentry/views/replays/detail/domMutations/domMutationRow'; import useDomFilters from 'sentry/views/replays/detail/domMutations/useDomFilters'; import FluidHeight from 'sentry/views/replays/detail/layout/fluidHeight'; import NoRowRenderer from 'sentry/views/replays/detail/noRowRenderer'; import useVirtualizedList from 'sentry/views/replays/detail/useVirtualizedList'; type Props = { replay: null | ReplayReader; startTimestampMs: number; }; function DomMutations({replay, startTimestampMs}: Props) { const {isLoading, actions} = useExtractedCrumbHtml({replay}); const filterProps = useDomFilters({actions: actions || []}); const {items, setSearchTerm} = filterProps; const clearSearchTerm = () => setSearchTerm(''); const listRef = useRef(null); const {cache} = useVirtualizedList({ cellMeasurer: { fixedWidth: true, minHeight: 82, }, ref: listRef, deps: [items], }); const renderRow = ({index, key, style, parent}: ListRowProps) => { const mutation = items[index]; return ( ); }; return ( {isLoading || !actions ? ( ) : ( {({width, height}) => ( ( {t('No DOM events recorded')} )} overscanRowCount={5} ref={listRef} rowCount={items.length} rowHeight={cache.rowHeight} rowRenderer={renderRow} width={width} /> )} )} ); } const MutationContainer = styled(FluidHeight)` height: 100%; `; const MutationItemContainer = styled('div')` position: relative; height: 100%; overflow: hidden; border: 1px solid ${p => p.theme.border}; border-radius: ${p => p.theme.borderRadius}; `; export default memo(DomMutations);