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;