spanOpSelector.tsx 3.0 KB

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