fieldRenderer.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import styled from '@emotion/styled';
  2. import Link from 'sentry/components/links/link';
  3. import TimeSince from 'sentry/components/timeSince';
  4. import type {TableDataRow} from 'sentry/utils/discover/discoverQuery';
  5. import type {EventData, MetaType} from 'sentry/utils/discover/eventView';
  6. import EventView from 'sentry/utils/discover/eventView';
  7. import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
  8. import {Container} from 'sentry/utils/discover/styles';
  9. import {generateLinkToEventInTraceView} from 'sentry/utils/discover/urls';
  10. import {getShortEventId} from 'sentry/utils/events';
  11. import {MutableSearch} from 'sentry/utils/tokenizeSearch';
  12. import {useLocation} from 'sentry/utils/useLocation';
  13. import useOrganization from 'sentry/utils/useOrganization';
  14. import CellAction, {updateQuery} from 'sentry/views/discover/table/cellAction';
  15. import type {TableColumn} from 'sentry/views/discover/table/types';
  16. import {TraceViewSources} from 'sentry/views/performance/newTraceDetails/traceHeader/breadcrumbs';
  17. import {getTraceDetailsUrl} from 'sentry/views/performance/traceDetails/utils';
  18. import {ALLOWED_CELL_ACTIONS} from '../components/table';
  19. import {useUserQuery} from '../hooks/useUserQuery';
  20. interface FieldProps {
  21. column: TableColumn<keyof TableDataRow>;
  22. data: EventData;
  23. meta: MetaType;
  24. unit?: string;
  25. }
  26. export function FieldRenderer({data, meta, unit, column}: FieldProps) {
  27. const location = useLocation();
  28. const organization = useOrganization();
  29. const [userQuery, setUserQuery] = useUserQuery();
  30. const dateSelection = EventView.fromLocation(location).normalizeDateSelection(location);
  31. const query = new MutableSearch(userQuery);
  32. const field = column.name;
  33. const renderer = getExploreFieldRenderer(field, meta);
  34. let rendered = renderer(data, {
  35. location,
  36. organization,
  37. unit,
  38. });
  39. if (field === 'timestamp') {
  40. const date = new Date(data.timestamp);
  41. rendered = <StyledTimeSince unitStyle="extraShort" date={date} tooltipShowSeconds />;
  42. }
  43. if (field === 'trace') {
  44. const target = getTraceDetailsUrl({
  45. traceSlug: data.trace,
  46. timestamp: data.timestamp,
  47. organization,
  48. dateSelection,
  49. location,
  50. source: TraceViewSources.TRACES,
  51. });
  52. rendered = <Link to={target}>{rendered}</Link>;
  53. }
  54. if (['id', 'span_id', 'transaction.id'].includes(field)) {
  55. const spanId = field === 'transaction.id' ? undefined : data.span_id ?? data.id;
  56. const target = generateLinkToEventInTraceView({
  57. projectSlug: data.project,
  58. traceSlug: data.trace,
  59. timestamp: data.timestamp,
  60. targetId: data['transaction.span_id'],
  61. eventId: undefined,
  62. organization,
  63. location,
  64. spanId,
  65. source: TraceViewSources.TRACES,
  66. });
  67. rendered = <Link to={target}>{rendered}</Link>;
  68. }
  69. return (
  70. <CellAction
  71. column={column}
  72. dataRow={data as TableDataRow}
  73. handleCellAction={(actions, value) => {
  74. updateQuery(query, actions, column, value);
  75. setUserQuery(query.formatString());
  76. }}
  77. allowActions={ALLOWED_CELL_ACTIONS}
  78. >
  79. {rendered}
  80. </CellAction>
  81. );
  82. }
  83. function getExploreFieldRenderer(
  84. field: string,
  85. meta: MetaType
  86. ): ReturnType<typeof getFieldRenderer> {
  87. if (field === 'id' || field === 'span_id') {
  88. return eventIdRenderFunc(field);
  89. }
  90. return getFieldRenderer(field, meta, false);
  91. }
  92. function eventIdRenderFunc(field: string) {
  93. function renderer(data: EventData) {
  94. const spanId: string | unknown = data?.[field];
  95. if (typeof spanId !== 'string') {
  96. return null;
  97. }
  98. return <Container>{getShortEventId(spanId)}</Container>;
  99. }
  100. return renderer;
  101. }
  102. const StyledTimeSince = styled(TimeSince)`
  103. width: fit-content;
  104. `;