123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- import {Fragment, useMemo, useRef} from 'react';
- import EmptyStateWarning from 'sentry/components/emptyStateWarning';
- import {GridResizer} from 'sentry/components/gridEditable/styles';
- import LoadingIndicator from 'sentry/components/loadingIndicator';
- import Pagination from 'sentry/components/pagination';
- import {Tooltip} from 'sentry/components/tooltip';
- import {IconArrow} from 'sentry/icons/iconArrow';
- import {IconWarning} from 'sentry/icons/iconWarning';
- import {t} from 'sentry/locale';
- import {defined} from 'sentry/utils';
- import {fieldAlignment, prettifyTagKey} from 'sentry/utils/discover/fields';
- import {
- Table,
- TableBody,
- TableBodyCell,
- TableHead,
- TableHeadCell,
- TableHeadCellContent,
- TableRow,
- TableStatus,
- useTableStyles,
- } from 'sentry/views/explore/components/table';
- import {
- useExploreFields,
- useExploreSortBys,
- useSetExploreSortBys,
- } from 'sentry/views/explore/contexts/pageParamsContext';
- import {useSpanTags} from 'sentry/views/explore/contexts/spanTagsContext';
- import type {SpansTableResult} from 'sentry/views/explore/hooks/useExploreSpansTable';
- import {FieldRenderer} from './fieldRenderer';
- interface SpansTableProps {
- spansTableResult: SpansTableResult;
- }
- export function SpansTable({spansTableResult}: SpansTableProps) {
- const fields = useExploreFields();
- const sortBys = useExploreSortBys();
- const setSortBys = useSetExploreSortBys();
- const visibleFields = useMemo(
- () => (fields.includes('id') ? fields : ['id', ...fields]),
- [fields]
- );
- const {result, eventView} = spansTableResult;
- const columnsFromEventView = useMemo(() => eventView.getColumns(), [eventView]);
- const tableRef = useRef<HTMLTableElement>(null);
- const {initialTableStyles, onResizeMouseDown} = useTableStyles(
- visibleFields,
- tableRef,
- {
- minimumColumnWidth: 50,
- }
- );
- const meta = result.meta ?? {};
- const numberTags = useSpanTags('number');
- const stringTags = useSpanTags('string');
- return (
- <Fragment>
- <Table ref={tableRef} styles={initialTableStyles}>
- <TableHead>
- <TableRow>
- {visibleFields.map((field, i) => {
- // Hide column names before alignment is determined
- if (result.isPending) {
- return <TableHeadCell key={i} isFirst={i === 0} />;
- }
- const fieldType = meta.fields?.[field];
- const align = fieldAlignment(field, fieldType);
- const tag = stringTags[field] ?? numberTags[field] ?? null;
- const direction = sortBys.find(s => s.field === field)?.kind;
- function updateSort() {
- const kind = direction === 'desc' ? 'asc' : 'desc';
- setSortBys([{field, kind}]);
- }
- const label = tag?.name ?? prettifyTagKey(field);
- return (
- <TableHeadCell align={align} key={i} isFirst={i === 0}>
- <TableHeadCellContent onClick={updateSort}>
- <Tooltip showOnlyOnOverflow title={label}>
- {label}
- </Tooltip>
- {defined(direction) && (
- <IconArrow
- size="xs"
- direction={
- direction === 'desc'
- ? 'down'
- : direction === 'asc'
- ? 'up'
- : undefined
- }
- />
- )}
- </TableHeadCellContent>
- {i !== visibleFields.length - 1 && (
- <GridResizer
- dataRows={
- !result.isError && !result.isPending && result.data
- ? result.data.length
- : 0
- }
- onMouseDown={e => onResizeMouseDown(e, i)}
- />
- )}
- </TableHeadCell>
- );
- })}
- </TableRow>
- </TableHead>
- <TableBody>
- {result.isPending ? (
- <TableStatus>
- <LoadingIndicator />
- </TableStatus>
- ) : result.isError ? (
- <TableStatus>
- <IconWarning data-test-id="error-indicator" color="gray300" size="lg" />
- </TableStatus>
- ) : result.isFetched && result.data?.length ? (
- result.data?.map((row, i) => (
- <TableRow key={i}>
- {visibleFields.map((field, j) => {
- return (
- <TableBodyCell key={j}>
- <FieldRenderer
- column={columnsFromEventView[j]!}
- data={row}
- unit={meta?.units?.[field]}
- meta={meta}
- />
- </TableBodyCell>
- );
- })}
- </TableRow>
- ))
- ) : (
- <TableStatus>
- <EmptyStateWarning>
- <p>{t('No spans found')}</p>
- </EmptyStateWarning>
- </TableStatus>
- )}
- </TableBody>
- </Table>
- <Pagination pageLinks={result.pageLinks} />
- </Fragment>
- );
- }
|