fieldRenderer.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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 {generateLinkToEventInTraceView} from 'sentry/utils/discover/urls';
  9. import {MutableSearch} from 'sentry/utils/tokenizeSearch';
  10. import {useLocation} from 'sentry/utils/useLocation';
  11. import useOrganization from 'sentry/utils/useOrganization';
  12. import CellAction, {updateQuery} from 'sentry/views/discover/table/cellAction';
  13. import type {TableColumn} from 'sentry/views/discover/table/types';
  14. import {TraceViewSources} from 'sentry/views/performance/newTraceDetails/traceHeader/breadcrumbs';
  15. import {getTraceDetailsUrl} from 'sentry/views/performance/traceDetails/utils';
  16. import {ALLOWED_CELL_ACTIONS} from '../components/table';
  17. import {useUserQuery} from '../hooks/useUserQuery';
  18. interface FieldProps {
  19. column: TableColumn<keyof TableDataRow>;
  20. data: EventData;
  21. meta: MetaType;
  22. unit?: string;
  23. }
  24. export function FieldRenderer({data, meta, unit, column}: FieldProps) {
  25. const location = useLocation();
  26. const organization = useOrganization();
  27. const [userQuery, setUserQuery] = useUserQuery();
  28. const dateSelection = EventView.fromLocation(location).normalizeDateSelection(location);
  29. const query = new MutableSearch(userQuery);
  30. const field = column.name;
  31. const renderer = getFieldRenderer(field, meta, false);
  32. let rendered = renderer(data, {
  33. location,
  34. organization,
  35. unit,
  36. });
  37. if (field === 'timestamp') {
  38. const date = new Date(data.timestamp);
  39. rendered = <StyledTimeSince unitStyle="extraShort" date={date} tooltipShowSeconds />;
  40. }
  41. if (field === 'trace') {
  42. const target = getTraceDetailsUrl({
  43. traceSlug: data.trace,
  44. timestamp: data.timestamp,
  45. organization,
  46. dateSelection,
  47. location,
  48. source: TraceViewSources.TRACES,
  49. });
  50. rendered = <Link to={target}>{rendered}</Link>;
  51. }
  52. if (['id', 'span_id', 'transaction.id'].includes(field)) {
  53. const spanId = field === 'transaction.id' ? undefined : data.span_id ?? data.id;
  54. const target = generateLinkToEventInTraceView({
  55. projectSlug: data.project,
  56. traceSlug: data.trace,
  57. timestamp: data.timestamp,
  58. targetId: data['transaction.span_id'],
  59. eventId: undefined,
  60. organization,
  61. location,
  62. spanId,
  63. source: TraceViewSources.TRACES,
  64. });
  65. rendered = <Link to={target}>{rendered}</Link>;
  66. }
  67. return (
  68. <CellAction
  69. column={column}
  70. dataRow={data as TableDataRow}
  71. handleCellAction={(actions, value) => {
  72. updateQuery(query, actions, column, value);
  73. setUserQuery(query.formatString());
  74. }}
  75. allowActions={ALLOWED_CELL_ACTIONS}
  76. >
  77. {rendered}
  78. </CellAction>
  79. );
  80. }
  81. const StyledTimeSince = styled(TimeSince)`
  82. width: fit-content;
  83. `;