metricsDataSwitcherAlert.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import {useCallback, useMemo} from 'react';
  2. import {WithRouterProps} from 'react-router';
  3. import {Location} from 'history';
  4. import {updateProjects} from 'sentry/actionCreators/pageFilters';
  5. import Alert from 'sentry/components/alert';
  6. import {GlobalSdkUpdateAlert} from 'sentry/components/globalSdkUpdateAlert';
  7. import ExternalLink from 'sentry/components/links/externalLink';
  8. import Link from 'sentry/components/links/link';
  9. import {SidebarPanelKey} from 'sentry/components/sidebar/types';
  10. import {t, tct} from 'sentry/locale';
  11. import SidebarPanelStore from 'sentry/stores/sidebarPanelStore';
  12. import {Organization, Project} from 'sentry/types';
  13. import EventView from 'sentry/utils/discover/eventView';
  14. import {MetricDataSwitcherOutcome} from 'sentry/utils/performance/contexts/metricsCardinality';
  15. import {
  16. areMultipleProjectsSelected,
  17. createUnnamedTransactionsDiscoverTarget,
  18. getSelectedProjectPlatformsArray,
  19. } from '../utils';
  20. interface MetricEnhancedDataAlertProps extends MetricDataSwitcherOutcome {
  21. eventView: EventView;
  22. location: Location;
  23. organization: Organization;
  24. projects: Project[];
  25. router: WithRouterProps['router'];
  26. }
  27. /**
  28. * From
  29. * https://github.com/getsentry/sentry-docs/blob/master/src/platforms/common/enriching-events/transaction-name.mdx
  30. */
  31. const SUPPORTED_TRANSACTION_NAME_DOCS = [
  32. 'javascript',
  33. 'node',
  34. 'python',
  35. 'ruby',
  36. 'native',
  37. 'react-native',
  38. 'dotnet',
  39. 'unity',
  40. 'flutter',
  41. 'dart',
  42. 'java',
  43. 'android',
  44. ];
  45. const UNSUPPORTED_TRANSACTION_NAME_DOCS = [
  46. 'javascript.cordova',
  47. 'javascript.nextjs',
  48. 'native.minidumps',
  49. ];
  50. export function MetricsDataSwitcherAlert(
  51. props: MetricEnhancedDataAlertProps
  52. ): React.ReactElement | null {
  53. const handleReviewUpdatesClick = useCallback(() => {
  54. SidebarPanelStore.activatePanel(SidebarPanelKey.Broadcasts);
  55. }, []);
  56. const docsLink = useMemo(() => {
  57. const platforms = getSelectedProjectPlatformsArray(props.location, props.projects);
  58. if (platforms.length < 1) {
  59. return null;
  60. }
  61. const platform = platforms[0];
  62. if (UNSUPPORTED_TRANSACTION_NAME_DOCS.includes(platform)) {
  63. return null;
  64. }
  65. const supportedPlatform = SUPPORTED_TRANSACTION_NAME_DOCS.find(platformBase =>
  66. platform.includes(platformBase)
  67. );
  68. if (!supportedPlatform) {
  69. return null;
  70. }
  71. return `https://docs.sentry.io/platforms/${supportedPlatform}/enriching-events/transaction-name/`;
  72. }, [props.location, props.projects]);
  73. const handleSwitchToCompatibleProjects = useCallback(() => {
  74. updateProjects(props.compatibleProjects || [], props.router);
  75. }, [props.compatibleProjects, props.router]);
  76. if (!props.shouldNotifyUnnamedTransactions && !props.shouldWarnIncompatibleSDK) {
  77. // Control showing generic sdk-alert here since stacking alerts is noisy.
  78. return <GlobalSdkUpdateAlert />;
  79. }
  80. const discoverTarget = createUnnamedTransactionsDiscoverTarget(props);
  81. if (props.shouldWarnIncompatibleSDK) {
  82. const updateSDK = (
  83. <Link to="" onClick={handleReviewUpdatesClick}>
  84. {t('update your SDK version')}
  85. </Link>
  86. );
  87. if (areMultipleProjectsSelected(props.eventView)) {
  88. if ((props.compatibleProjects ?? []).length === 0) {
  89. return (
  90. <Alert
  91. type="warning"
  92. showIcon
  93. data-test-id="landing-mep-alert-multi-project-all-incompatible"
  94. >
  95. {tct(
  96. `A few projects are incompatible with server side sampling. To enable this feature [updateSDK].`,
  97. {
  98. updateSDK,
  99. }
  100. )}
  101. </Alert>
  102. );
  103. }
  104. return (
  105. <Alert
  106. type="warning"
  107. showIcon
  108. data-test-id="landing-mep-alert-multi-project-incompatible"
  109. >
  110. {tct(
  111. `A few projects are incompatible with server side sampling. You can either [updateSDK] or [onlyViewCompatible]`,
  112. {
  113. updateSDK,
  114. onlyViewCompatible: (
  115. <Link to="" onClick={handleSwitchToCompatibleProjects}>
  116. {t('only view compatible projects.')}
  117. </Link>
  118. ),
  119. }
  120. )}
  121. </Alert>
  122. );
  123. }
  124. return (
  125. <Alert
  126. type="warning"
  127. showIcon
  128. data-test-id="landing-mep-alert-single-project-incompatible"
  129. >
  130. {tct(
  131. `Your project has an outdated SDK which is incompatible with server side sampling. To enable this feature [updateSDK].`,
  132. {
  133. updateSDK,
  134. }
  135. )}
  136. </Alert>
  137. );
  138. }
  139. if (props.shouldNotifyUnnamedTransactions) {
  140. const discover = <Link to={discoverTarget}>{t('open them in Discover.')}</Link>;
  141. if (!docsLink) {
  142. return (
  143. <Alert type="warning" showIcon data-test-id="landing-mep-alert-unnamed-discover">
  144. {tct(
  145. `You have some unparameterized transactions which are incompatible with server side sampling. You can [discover]`,
  146. {
  147. discover,
  148. }
  149. )}
  150. </Alert>
  151. );
  152. }
  153. return (
  154. <Alert
  155. type="warning"
  156. showIcon
  157. data-test-id="landing-mep-alert-unnamed-discover-or-set"
  158. >
  159. {tct(
  160. `You have some unparameterized transactions which are incompatible with server side sampling. You can either [setNames] or [discover]`,
  161. {
  162. setNames: (
  163. <ExternalLink href={docsLink}>{t('set names manually')}</ExternalLink>
  164. ),
  165. discover,
  166. }
  167. )}
  168. </Alert>
  169. );
  170. }
  171. return null;
  172. }