spanOpSelector.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import styled from '@emotion/styled';
  2. import {CompactSelect} from 'sentry/components/compactSelect';
  3. import {t} from 'sentry/locale';
  4. import {space} from 'sentry/styles/space';
  5. import type {NewQuery} from 'sentry/types/organization';
  6. import {trackAnalytics} from 'sentry/utils/analytics';
  7. import {browserHistory} from 'sentry/utils/browserHistory';
  8. import EventView from 'sentry/utils/discover/eventView';
  9. import {DiscoverDatasets} from 'sentry/utils/discover/types';
  10. import {decodeScalar} from 'sentry/utils/queryString';
  11. import {MutableSearch} from 'sentry/utils/tokenizeSearch';
  12. import {useLocation} from 'sentry/utils/useLocation';
  13. import useOrganization from 'sentry/utils/useOrganization';
  14. import usePageFilters from 'sentry/utils/usePageFilters';
  15. import {appendReleaseFilters} from 'sentry/views/insights/common/utils/releaseComparison';
  16. import {useTableQuery} from 'sentry/views/insights/mobile/screenload/components/tables/screensTable';
  17. import {MobileCursors} from 'sentry/views/insights/mobile/screenload/constants';
  18. import {SpanMetricsField} from 'sentry/views/insights/types';
  19. export const TTID_CONTRIBUTING_SPAN_OPS = [
  20. 'file.read',
  21. 'file.write',
  22. 'ui.load',
  23. 'http.client',
  24. 'db',
  25. 'db.sql.room',
  26. 'db.sql.query',
  27. 'db.sql.transaction',
  28. ];
  29. type Props = {
  30. primaryRelease?: string;
  31. secondaryRelease?: string;
  32. transaction?: string;
  33. };
  34. export function SpanOpSelector({transaction, primaryRelease, secondaryRelease}: Props) {
  35. const location = useLocation();
  36. const organization = useOrganization();
  37. const {selection} = usePageFilters();
  38. const value = decodeScalar(location.query[SpanMetricsField.SPAN_OP]) ?? '';
  39. const searchQuery = new MutableSearch([
  40. 'transaction.op:ui.load',
  41. `transaction:${transaction}`,
  42. `span.op:[${TTID_CONTRIBUTING_SPAN_OPS.join(',')}]`,
  43. 'has:span.description',
  44. ]);
  45. const queryStringPrimary = appendReleaseFilters(
  46. searchQuery,
  47. primaryRelease,
  48. secondaryRelease
  49. );
  50. const newQuery: NewQuery = {
  51. name: '',
  52. fields: [SpanMetricsField.SPAN_OP, 'count()'],
  53. query: queryStringPrimary,
  54. dataset: DiscoverDatasets.SPANS_METRICS,
  55. version: 2,
  56. projects: selection.projects,
  57. };
  58. const eventView = EventView.fromNewQueryWithLocation(newQuery, location);
  59. const {data} = useTableQuery({
  60. eventView,
  61. enabled: true,
  62. limit: 25,
  63. referrer: 'api.starfish.get-span-operations',
  64. });
  65. const options = [
  66. {value: '', label: t('All')},
  67. ...(data?.data ?? [])
  68. .filter(datum => Boolean(datum[SpanMetricsField.SPAN_OP]))
  69. .map(datum => {
  70. return {
  71. value: datum[SpanMetricsField.SPAN_OP],
  72. label: datum[SpanMetricsField.SPAN_OP],
  73. };
  74. }),
  75. ];
  76. return (
  77. <StyledCompactSelect
  78. triggerProps={{prefix: t('Operation'), size: 'xs'}}
  79. value={value}
  80. options={options ?? []}
  81. onChange={newValue => {
  82. trackAnalytics('insight.screen_load.spans.filter_by_operation', {
  83. organization,
  84. filter: newValue.value as string,
  85. });
  86. browserHistory.push({
  87. ...location,
  88. query: {
  89. ...location.query,
  90. [SpanMetricsField.SPAN_OP]: newValue.value,
  91. [MobileCursors.SPANS_TABLE]: undefined,
  92. },
  93. });
  94. }}
  95. />
  96. );
  97. }
  98. const StyledCompactSelect = styled(CompactSelect)`
  99. margin-bottom: ${space(1)};
  100. `;