indexedEventsSelectionAlert.tsx 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import styled from '@emotion/styled';
  2. import Alert from 'sentry/components/alert';
  3. import ExternalLink from 'sentry/components/links/externalLink';
  4. import {parseSearch} from 'sentry/components/searchSyntax/parser';
  5. import {tct} from 'sentry/locale';
  6. import {space} from 'sentry/styles/space';
  7. import {parseFunction} from 'sentry/utils/discover/fields';
  8. import {
  9. MEPConsumer,
  10. MEPState,
  11. } from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
  12. import useOrganization from 'sentry/utils/useOrganization';
  13. import {DashboardsMEPConsumer} from './widgetCard/dashboardsMEPContext';
  14. import {type Widget, WidgetType} from './types';
  15. type SearchFilterKey = {key?: {value: string}};
  16. interface IndexedEventsSelectionAlertProps {
  17. widget: Widget;
  18. }
  19. const ERROR_FIELDS = [
  20. 'error.handled',
  21. 'error.unhandled',
  22. 'error.mechanism',
  23. 'error.type',
  24. 'error.value',
  25. ];
  26. export function IndexedEventsSelectionAlert({widget}: IndexedEventsSelectionAlertProps) {
  27. const organization = useOrganization();
  28. if (organization.features.includes('performance-mep-bannerless-ui')) {
  29. return null;
  30. }
  31. const widgetContainsErrorFields = widget.queries.some(
  32. ({columns, aggregates, conditions}) =>
  33. ERROR_FIELDS.some(
  34. errorField =>
  35. columns.includes(errorField) ||
  36. aggregates.some(aggregate =>
  37. parseFunction(aggregate)?.arguments.includes(errorField)
  38. ) ||
  39. parseSearch(conditions)?.some(
  40. filter => (filter as SearchFilterKey).key?.value === errorField
  41. )
  42. )
  43. );
  44. return (
  45. <MEPConsumer>
  46. {metricSettingContext => {
  47. return (
  48. <DashboardsMEPConsumer>
  49. {({isMetricsData}) => {
  50. if (
  51. isMetricsData === false &&
  52. widget.widgetType === WidgetType.DISCOVER &&
  53. metricSettingContext &&
  54. metricSettingContext.metricSettingState !== MEPState.TRANSACTIONS_ONLY
  55. ) {
  56. if (!widgetContainsErrorFields) {
  57. return (
  58. <StoredDataAlert showIcon>
  59. {tct(
  60. "Your selection is only applicable to [indexedData: indexed event data]. We've automatically adjusted your results.",
  61. {
  62. indexedData: (
  63. <ExternalLink href="https://docs.sentry.io/product/dashboards/widget-builder/#transactions" />
  64. ),
  65. }
  66. )}
  67. </StoredDataAlert>
  68. );
  69. }
  70. }
  71. return null;
  72. }}
  73. </DashboardsMEPConsumer>
  74. );
  75. }}
  76. </MEPConsumer>
  77. );
  78. }
  79. const StoredDataAlert = styled(Alert)`
  80. margin-top: ${space(1)};
  81. margin-bottom: 0;
  82. `;