123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- import {Fragment, ReactNode, useCallback, useMemo} from 'react';
- import styled from '@emotion/styled';
- import type {Location} from 'history';
- import renderSortableHeaderCell from 'sentry/components/feedback/table/renderSortableHeaderCell';
- import useQueryBasedColumnResize from 'sentry/components/feedback/table/useQueryBasedColumnResize';
- import useQueryBasedSorting from 'sentry/components/feedback/table/useQueryBasedSorting';
- import GridEditable, {GridColumnOrder} from 'sentry/components/gridEditable';
- import Link from 'sentry/components/links/link';
- import TextOverflow from 'sentry/components/textOverflow';
- import {Organization} from 'sentry/types';
- import useOrganization from 'sentry/utils/useOrganization';
- import {normalizeUrl} from 'sentry/utils/withDomainRequired';
- import {DeadRageSelectorItem} from 'sentry/views/replays/types';
- export interface UrlState {
- widths: string[];
- }
- interface Props {
- clickCountColumn: {key: string; name: string};
- clickCountSortable: boolean;
- data: DeadRageSelectorItem[];
- isError: boolean;
- isLoading: boolean;
- location: Location<any>;
- customHandleResize?: () => void;
- headerButtons?: ReactNode;
- title?: ReactNode;
- }
- const BASE_COLUMNS: GridColumnOrder<string>[] = [
- {key: 'element', name: 'element'},
- {key: 'dom_element', name: 'selector'},
- {key: 'aria_label', name: 'aria label'},
- ];
- export default function SelectorTable({
- clickCountColumn,
- clickCountSortable,
- data,
- isError,
- isLoading,
- location,
- title,
- headerButtons,
- customHandleResize,
- }: Props) {
- const organization = useOrganization();
- const {currentSort, makeSortLinkGenerator} = useQueryBasedSorting({
- defaultSort: {field: clickCountColumn.key, kind: 'desc'},
- location,
- });
- const {columns, handleResizeColumn} = useQueryBasedColumnResize({
- columns: BASE_COLUMNS.concat(clickCountColumn),
- location,
- });
- const renderHeadCell = useMemo(
- () =>
- renderSortableHeaderCell({
- currentSort,
- makeSortLinkGenerator,
- onClick: () => {},
- rightAlignedColumns: [],
- sortableColumns: clickCountSortable ? [clickCountColumn] : [],
- }),
- [clickCountColumn, currentSort, makeSortLinkGenerator, clickCountSortable]
- );
- const renderBodyCell = useCallback(
- (column, dataRow) => {
- const value = dataRow[column.key];
- switch (column.key) {
- case 'dom_element':
- return <SelectorLink organization={organization} value={value} />;
- case 'element':
- case 'aria_label':
- return (
- <code>
- <TextOverflow>{value}</TextOverflow>
- </code>
- );
- default:
- return renderSimpleBodyCell<DeadRageSelectorItem>(column, dataRow);
- }
- },
- [organization]
- );
- return (
- <Fragment>
- <GridEditable
- error={isError}
- isLoading={isLoading}
- data={data ?? []}
- columnOrder={columns}
- columnSortBy={[]}
- stickyHeader
- grid={{
- onResizeColumn: customHandleResize ?? handleResizeColumn,
- renderHeadCell,
- renderBodyCell,
- }}
- location={location as Location<any>}
- title={title}
- headerButtons={() => headerButtons}
- />
- </Fragment>
- );
- }
- function SelectorLink({
- organization,
- value,
- }: {
- organization: Organization;
- value: string;
- }) {
- return (
- <Link
- to={{
- pathname: normalizeUrl(`/organizations/${organization.slug}/replays/`),
- }}
- >
- <TextOverflow>{value}</TextOverflow>
- </Link>
- );
- }
- function renderSimpleBodyCell<T>(column: GridColumnOrder<string>, dataRow: T) {
- if (column.key === 'count_dead_clicks') {
- return <DeadClickCount>{dataRow[column.key]}</DeadClickCount>;
- }
- if (column.key === 'count_rage_clicks') {
- return <RageClickCount>{dataRow[column.key]}</RageClickCount>;
- }
- return <TextOverflow>{dataRow[column.key]}</TextOverflow>;
- }
- const DeadClickCount = styled(TextOverflow)`
- color: ${p => p.theme.yellow300};
- `;
- const RageClickCount = styled(TextOverflow)`
- color: ${p => p.theme.red300};
- `;
|