traceActionsMenu.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import {openModal} from 'sentry/actionCreators/modal';
  2. import {Button} from 'sentry/components/button';
  3. import {DropdownMenu} from 'sentry/components/dropdownMenu';
  4. import {IconEllipsis} from 'sentry/icons';
  5. import {t} from 'sentry/locale';
  6. import type {EventTransaction} from 'sentry/types/event';
  7. import {trackAnalytics} from 'sentry/utils/analytics';
  8. import type EventView from 'sentry/utils/discover/eventView';
  9. import {SavedQueryDatasets} from 'sentry/utils/discover/types';
  10. import type {UseApiQueryResult} from 'sentry/utils/queryClient';
  11. import type RequestError from 'sentry/utils/requestError/requestError';
  12. import {useLocation} from 'sentry/utils/useLocation';
  13. import {useNavigate} from 'sentry/utils/useNavigate';
  14. import useOrganization from 'sentry/utils/useOrganization';
  15. import useProjects from 'sentry/utils/useProjects';
  16. import {hasDatasetSelector} from 'sentry/views/dashboards/utils';
  17. import {
  18. getSearchInExploreTarget,
  19. TraceDrawerActionKind,
  20. } from './traceDrawer/details/utils';
  21. import {traceAnalytics} from './traceAnalytics';
  22. import {getCustomInstrumentationLink} from './traceConfigurations';
  23. import {TraceShortcutsModal} from './traceShortcutsModal';
  24. import {useHasTraceNewUi} from './useHasTraceNewUi';
  25. function TraceActionsMenu({
  26. traceSlug,
  27. rootEventResults,
  28. traceEventView,
  29. }: {
  30. rootEventResults: UseApiQueryResult<EventTransaction, RequestError>;
  31. traceEventView: EventView;
  32. traceSlug: string | undefined;
  33. }) {
  34. const location = useLocation();
  35. const hasTraceNewUi = useHasTraceNewUi();
  36. const organization = useOrganization();
  37. const {projects} = useProjects();
  38. const navigate = useNavigate();
  39. const hasDrawerAction = organization.features.includes('trace-drawer-action');
  40. if (!hasTraceNewUi) {
  41. return null;
  42. }
  43. const traceProject = rootEventResults.data
  44. ? projects.find(p => p.id === rootEventResults.data.projectID)
  45. : undefined;
  46. return (
  47. <DropdownMenu
  48. items={[
  49. {
  50. key: 'open_trace_events',
  51. label: hasDrawerAction
  52. ? t('Open Events in Explore')
  53. : t('Open Events in Discover'),
  54. onAction: () => {
  55. let target;
  56. if (hasDrawerAction) {
  57. const key = 'trace';
  58. const value = traceSlug ?? '';
  59. traceAnalytics.trackExploreSearch(
  60. organization,
  61. 'trace',
  62. traceSlug ?? '',
  63. TraceDrawerActionKind.INCLUDE,
  64. 'toolbar_menu'
  65. );
  66. const {start, end, statsPeriod} = traceEventView;
  67. target = getSearchInExploreTarget(
  68. organization,
  69. {
  70. ...location,
  71. query: {
  72. start,
  73. end,
  74. statsPeriod: start && end ? null : statsPeriod, // We don't want statsPeriod to have precedence over start and end
  75. },
  76. },
  77. '-1',
  78. key,
  79. value,
  80. TraceDrawerActionKind.INCLUDE
  81. );
  82. } else {
  83. trackAnalytics('performance_views.trace_view.open_in_discover', {
  84. organization,
  85. });
  86. target = traceEventView.getResultsViewUrlTarget(
  87. organization,
  88. false,
  89. hasDatasetSelector(organization)
  90. ? SavedQueryDatasets.TRANSACTIONS
  91. : undefined
  92. );
  93. }
  94. navigate(target);
  95. },
  96. },
  97. {
  98. key: 'custom_instrumentation_button',
  99. label: t('Add Instrumentation'),
  100. onAction: () => {
  101. const docsLink = getCustomInstrumentationLink(traceProject);
  102. if (docsLink) {
  103. window.location.href = docsLink;
  104. }
  105. },
  106. },
  107. {
  108. key: 'shortcuts_button',
  109. label: t('See Shortcuts'),
  110. onAction: () => {
  111. traceAnalytics.trackViewShortcuts(organization);
  112. openModal(props => <TraceShortcutsModal {...props} />);
  113. },
  114. },
  115. ]}
  116. trigger={triggerProps => (
  117. <Button
  118. {...triggerProps}
  119. aria-label={t('Discover Context Menu')}
  120. size="xs"
  121. onClick={e => {
  122. e.stopPropagation();
  123. e.preventDefault();
  124. triggerProps.onClick?.(e);
  125. }}
  126. icon={<IconEllipsis />}
  127. />
  128. )}
  129. position="bottom-end"
  130. />
  131. );
  132. }
  133. export default TraceActionsMenu;