samplesTables.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import {useMemo, useState} from 'react';
  2. import styled from '@emotion/styled';
  3. import ErrorBoundary from 'sentry/components/errorBoundary';
  4. import {SegmentedControl} from 'sentry/components/segmentedControl';
  5. import {t} from 'sentry/locale';
  6. import {space} from 'sentry/styles/space';
  7. import {SpanOpSelector} from 'sentry/views/performance/mobile/appStarts/screenSummary/spanOpSelector';
  8. import {DeviceClassSelector} from 'sentry/views/performance/mobile/screenload/screenLoadSpans/deviceClassSelector';
  9. import {
  10. MobileCursors,
  11. MobileSortKeys,
  12. } from 'sentry/views/performance/mobile/screenload/screens/constants';
  13. import {useReleaseSelection} from 'sentry/views/starfish/queries/useReleases';
  14. const EVENT = 'event';
  15. const SPANS = 'spans';
  16. interface EventSamplesProps {
  17. cursorName: string;
  18. footerAlignedPagination: boolean;
  19. sortKey: string;
  20. transaction: string;
  21. release?: string;
  22. }
  23. export interface SpanOperationTableProps {
  24. transaction: string;
  25. primaryRelease?: string;
  26. secondaryRelease?: string;
  27. }
  28. interface SamplesTablesProps {
  29. EventSamples: React.ComponentType<EventSamplesProps>;
  30. SpanOperationTable: React.ComponentType<SpanOperationTableProps>;
  31. transactionName: string;
  32. }
  33. export function SamplesTables({
  34. transactionName,
  35. EventSamples,
  36. SpanOperationTable,
  37. }: SamplesTablesProps) {
  38. const [sampleType, setSampleType] = useState<typeof EVENT | typeof SPANS>(SPANS);
  39. const {primaryRelease, secondaryRelease} = useReleaseSelection();
  40. const content = useMemo(() => {
  41. if (sampleType === EVENT) {
  42. return (
  43. <EventSplitContainer>
  44. <ErrorBoundary mini>
  45. <EventSamples
  46. cursorName={MobileCursors.RELEASE_1_EVENT_SAMPLE_TABLE}
  47. sortKey={MobileSortKeys.RELEASE_1_EVENT_SAMPLE_TABLE}
  48. release={primaryRelease}
  49. transaction={transactionName}
  50. footerAlignedPagination
  51. />
  52. </ErrorBoundary>
  53. <ErrorBoundary mini>
  54. <EventSamples
  55. cursorName={MobileCursors.RELEASE_2_EVENT_SAMPLE_TABLE}
  56. sortKey={MobileSortKeys.RELEASE_2_EVENT_SAMPLE_TABLE}
  57. release={secondaryRelease}
  58. transaction={transactionName}
  59. footerAlignedPagination
  60. />
  61. </ErrorBoundary>
  62. </EventSplitContainer>
  63. );
  64. }
  65. return (
  66. <ErrorBoundary mini>
  67. <SpanOperationTable
  68. transaction={transactionName}
  69. primaryRelease={primaryRelease}
  70. secondaryRelease={secondaryRelease}
  71. />
  72. </ErrorBoundary>
  73. );
  74. }, [
  75. EventSamples,
  76. SpanOperationTable,
  77. primaryRelease,
  78. sampleType,
  79. secondaryRelease,
  80. transactionName,
  81. ]);
  82. return (
  83. <div>
  84. <Controls>
  85. <FiltersContainer>
  86. {sampleType === SPANS && (
  87. <SpanOpSelector
  88. primaryRelease={primaryRelease}
  89. transaction={transactionName}
  90. secondaryRelease={secondaryRelease}
  91. />
  92. )}
  93. <DeviceClassSelector size="md" clearSpansTableCursor />
  94. </FiltersContainer>
  95. <SegmentedControl
  96. onChange={value => setSampleType(value)}
  97. defaultValue={SPANS}
  98. label={t('Sample Type Selection')}
  99. >
  100. <SegmentedControl.Item key={SPANS} aria-label={t('By Spans')}>
  101. {t('By Spans')}
  102. </SegmentedControl.Item>
  103. <SegmentedControl.Item key={EVENT} aria-label={t('By Event')}>
  104. {t('By Event')}
  105. </SegmentedControl.Item>
  106. </SegmentedControl>
  107. </Controls>
  108. {content}
  109. </div>
  110. );
  111. }
  112. const EventSplitContainer = styled('div')`
  113. display: grid;
  114. grid-template-columns: 1fr 1fr;
  115. gap: ${space(1.5)};
  116. `;
  117. const Controls = styled('div')`
  118. display: flex;
  119. justify-content: space-between;
  120. align-items: center;
  121. margin-bottom: ${space(1)};
  122. `;
  123. const FiltersContainer = styled('div')`
  124. display: flex;
  125. gap: ${space(1)};
  126. align-items: center;
  127. `;