import {Fragment, ReactNode} from 'react'; import styled from '@emotion/styled'; import {Location} from 'history'; import {Alert} from 'sentry/components/alert'; import LoadingIndicator from 'sentry/components/loadingIndicator'; import PanelTable from 'sentry/components/panels/panelTable'; import {t} from 'sentry/locale'; import EventView from 'sentry/utils/discover/eventView'; import type {Sort} from 'sentry/utils/discover/fields'; import getRouteStringFromRoutes from 'sentry/utils/getRouteStringFromRoutes'; import {useLocation} from 'sentry/utils/useLocation'; import useOrganization from 'sentry/utils/useOrganization'; import {useRoutes} from 'sentry/utils/useRoutes'; import type {ReplayListRecordWithTx} from 'sentry/views/performance/transactionSummary/transactionReplays/useReplaysWithTxData'; import HeaderCell from 'sentry/views/replays/replayTable/headerCell'; import { ActivityCell, BrowserCell, DeadClickCountCell, DurationCell, ErrorCountCell, OSCell, RageClickCountCell, ReplayCell, TransactionCell, } from 'sentry/views/replays/replayTable/tableCell'; import {ReplayColumn} from 'sentry/views/replays/replayTable/types'; import type {ReplayListRecord} from 'sentry/views/replays/types'; type Props = { fetchError: undefined | Error; isFetching: boolean; replays: undefined | ReplayListRecord[] | ReplayListRecordWithTx[]; sort: Sort | undefined; visibleColumns: ReplayColumn[]; emptyMessage?: ReactNode; gridRows?: string; saveLocation?: boolean; showDropdownFilters?: boolean; }; function ReplayTable({ fetchError, isFetching, replays, sort, visibleColumns, emptyMessage, saveLocation, gridRows, showDropdownFilters, }: Props) { const routes = useRoutes(); const newLocation = useLocation(); const organization = useOrganization(); const location: Location = saveLocation ? { pathname: '', search: '', query: {}, hash: '', state: '', action: 'PUSH', key: '', } : newLocation; const tableHeaders = visibleColumns .filter(Boolean) .map(column => ); if (fetchError && !isFetching) { return ( {typeof fetchError === 'string' ? fetchError : t( 'Sorry, the list of replays could not be loaded. This could be due to invalid search parameters or an internal systems error.' )} ); } const referrer = getRouteStringFromRoutes(routes); const eventView = EventView.fromLocation(location); return ( } > {replays?.map(replay => { return ( {visibleColumns.map(column => { switch (column) { case ReplayColumn.ACTIVITY: return ( ); case ReplayColumn.BROWSER: return ( ); case ReplayColumn.COUNT_DEAD_CLICKS: return ( ); case ReplayColumn.COUNT_DEAD_CLICKS_NO_HEADER: return ( ); case ReplayColumn.COUNT_ERRORS: return ( ); case ReplayColumn.COUNT_RAGE_CLICKS: return ( ); case ReplayColumn.COUNT_RAGE_CLICKS_NO_HEADER: return ( ); case ReplayColumn.DURATION: return ( ); case ReplayColumn.OS: return ( ); case ReplayColumn.REPLAY: return ( ); case ReplayColumn.SLOWEST_TRANSACTION: return ( ); case ReplayColumn.MOST_RAGE_CLICKS: return ( ); case ReplayColumn.MOST_DEAD_CLICKS: return ( ); case ReplayColumn.MOST_ERRONEOUS_REPLAYS: return ( ); default: return null; } })} ); })} ); } const flexibleColumns = [ ReplayColumn.REPLAY, ReplayColumn.MOST_RAGE_CLICKS, ReplayColumn.MOST_DEAD_CLICKS, ReplayColumn.MOST_ERRONEOUS_REPLAYS, ]; const StyledPanelTable = styled(PanelTable)<{ visibleColumns: ReplayColumn[]; gridRows?: string; }>` ${props => props.visibleColumns.includes(ReplayColumn.MOST_RAGE_CLICKS) || props.visibleColumns.includes(ReplayColumn.MOST_DEAD_CLICKS) || props.visibleColumns.includes(ReplayColumn.MOST_ERRONEOUS_REPLAYS) ? `border-bottom-left-radius: 0; border-bottom-right-radius: 0;` : ``} margin-bottom: 0; grid-template-columns: ${p => p.visibleColumns .filter(Boolean) .map(column => flexibleColumns.includes(column) ? 'minmax(100px, 1fr)' : 'max-content' ) .join(' ')}; ${props => props.gridRows ? `grid-template-rows: ${props.gridRows};` : `grid-template-rows: 44px max-content;`} `; const StyledAlert = styled(Alert)` border-radius: 0; border-width: 1px 0 0 0; grid-column: 1/-1; margin-bottom: 0; `; export default ReplayTable;