trace.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import {Fragment, useMemo} from 'react';
  2. import type {Tag} from 'sentry/actionCreators/events';
  3. import type {EventTransaction} from 'sentry/types/event';
  4. import {generateQueryWithTag} from 'sentry/utils';
  5. import type EventView from 'sentry/utils/discover/eventView';
  6. import {formatTagKey} from 'sentry/utils/discover/fields';
  7. import type {
  8. TraceFullDetailed,
  9. TraceSplitResults,
  10. } from 'sentry/utils/performance/quickTrace/types';
  11. import type {UseApiQueryResult} from 'sentry/utils/queryClient';
  12. import type RequestError from 'sentry/utils/requestError/requestError';
  13. import {useLocation} from 'sentry/utils/useLocation';
  14. import useOrganization from 'sentry/utils/useOrganization';
  15. import Tags from 'sentry/views/discover/tags';
  16. import {TraceWarnings} from 'sentry/views/performance/newTraceDetails/traceWarnings';
  17. import type {TraceType} from 'sentry/views/performance/traceDetails/newTraceDetailsContent';
  18. import {isTraceNode} from '../../guards';
  19. import type {TraceTree, TraceTreeNode} from '../../traceModels/traceTree';
  20. import {IssueList} from '../details/issues/issues';
  21. type TraceDetailsProps = {
  22. node: TraceTreeNode<TraceTree.NodeValue> | null;
  23. rootEventResults: UseApiQueryResult<EventTransaction, RequestError>;
  24. tagsQueryResults: UseApiQueryResult<Tag[], RequestError>;
  25. traceEventView: EventView;
  26. traceType: TraceType;
  27. traces: TraceSplitResults<TraceFullDetailed> | null;
  28. tree: TraceTree;
  29. };
  30. export function TraceDetails(props: TraceDetailsProps) {
  31. const location = useLocation();
  32. const organization = useOrganization();
  33. const issues = useMemo(() => {
  34. if (!props.node) {
  35. return [];
  36. }
  37. return [...props.node.errors, ...props.node.performance_issues];
  38. }, [props.node]);
  39. if (!props.node) {
  40. return null;
  41. }
  42. if (!(props.node && isTraceNode(props.node))) {
  43. throw new Error('Expected a trace node');
  44. }
  45. const {data: rootEvent} = props.rootEventResults;
  46. return (
  47. <Fragment>
  48. {props.tree.type === 'trace' ? <TraceWarnings type={props.traceType} /> : null}
  49. <IssueList issues={issues} node={props.node} organization={organization} />
  50. {rootEvent ? (
  51. <Tags
  52. tagsQueryResults={props.tagsQueryResults}
  53. generateUrl={(key: string, value: string) => {
  54. const url = props.traceEventView.getResultsViewUrlTarget(
  55. organization.slug,
  56. false
  57. );
  58. url.query = generateQueryWithTag(url.query, {
  59. key: formatTagKey(key),
  60. value,
  61. });
  62. return url;
  63. }}
  64. totalValues={props.tree.eventsCount}
  65. eventView={props.traceEventView}
  66. organization={organization}
  67. location={location}
  68. />
  69. ) : null}
  70. </Fragment>
  71. );
  72. }