index.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import styled from '@emotion/styled';
  2. import omit from 'lodash/omit';
  3. import type {Crumb} from 'sentry/components/breadcrumbs';
  4. import Breadcrumbs from 'sentry/components/breadcrumbs';
  5. import * as Layout from 'sentry/components/layouts/thirds';
  6. import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
  7. import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
  8. import PageFiltersContainer from 'sentry/components/organizations/pageFilters/container';
  9. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  10. import {t} from 'sentry/locale';
  11. import {space} from 'sentry/styles/space';
  12. import {PageAlert, PageAlertProvider} from 'sentry/utils/performance/contexts/pageAlert';
  13. import {useLocation} from 'sentry/utils/useLocation';
  14. import useOrganization from 'sentry/utils/useOrganization';
  15. import useRouter from 'sentry/utils/useRouter';
  16. import {normalizeUrl} from 'sentry/utils/withDomainRequired';
  17. import {SamplesTables} from 'sentry/views/performance/mobile/components/samplesTables';
  18. import {ScreenLoadSpanSamples} from 'sentry/views/performance/mobile/screenload/screenLoadSpans/samples';
  19. import {SpanOperationTable} from 'sentry/views/performance/mobile/ui/screenSummary/spanOperationTable';
  20. import {ReleaseComparisonSelector} from 'sentry/views/starfish/components/releaseSelector';
  21. import {SpanMetricsField} from 'sentry/views/starfish/types';
  22. import {QueryParameterNames} from 'sentry/views/starfish/views/queryParameters';
  23. type Query = {
  24. 'device.class': string;
  25. primaryRelease: string;
  26. project: string;
  27. secondaryRelease: string;
  28. spanDescription: string;
  29. spanGroup: string;
  30. spanOp: string;
  31. transaction: string;
  32. };
  33. function ScreenSummary() {
  34. const organization = useOrganization();
  35. const location = useLocation<Query>();
  36. const router = useRouter();
  37. const {
  38. transaction: transactionName,
  39. spanGroup,
  40. spanDescription,
  41. spanOp,
  42. 'device.class': deviceClass,
  43. } = location.query;
  44. const crumbs: Crumb[] = [
  45. {
  46. label: t('Performance'),
  47. to: normalizeUrl(`/organizations/${organization.slug}/performance/`),
  48. preservePageFilters: true,
  49. },
  50. {
  51. label: t('Mobile UI'),
  52. to: normalizeUrl({
  53. pathname: `/organizations/${organization.slug}/performance/mobile/ui/`,
  54. query: {
  55. ...omit(location.query, [
  56. QueryParameterNames.SPANS_SORT,
  57. 'transaction',
  58. SpanMetricsField.SPAN_OP,
  59. ]),
  60. },
  61. }),
  62. preservePageFilters: true,
  63. },
  64. {
  65. label: t('Screen Summary'),
  66. },
  67. ];
  68. return (
  69. <SentryDocumentTitle title={transactionName} orgSlug={organization.slug}>
  70. <Layout.Page>
  71. <PageAlertProvider>
  72. <Layout.Header>
  73. <Layout.HeaderContent>
  74. <Breadcrumbs crumbs={crumbs} />
  75. <Layout.Title>{transactionName}</Layout.Title>
  76. </Layout.HeaderContent>
  77. </Layout.Header>
  78. <Layout.Body>
  79. <Layout.Main fullWidth>
  80. <PageAlert />
  81. <PageFiltersContainer>
  82. <HeaderContainer>
  83. <ControlsContainer>
  84. <PageFilterBar condensed>
  85. <DatePageFilter />
  86. </PageFilterBar>
  87. <ReleaseComparisonSelector />
  88. </ControlsContainer>
  89. </HeaderContainer>
  90. <SamplesContainer>
  91. <SamplesTables
  92. transactionName={transactionName}
  93. SpanOperationTable={SpanOperationTable}
  94. // TODO(nar): Add event samples component specific to ui module
  95. EventSamples={_props => <div />}
  96. />
  97. </SamplesContainer>
  98. {spanGroup && spanOp && (
  99. <ScreenLoadSpanSamples
  100. additionalFilters={{
  101. ...(deviceClass
  102. ? {[SpanMetricsField.DEVICE_CLASS]: deviceClass}
  103. : {}),
  104. }}
  105. groupId={spanGroup}
  106. transactionName={transactionName}
  107. spanDescription={spanDescription}
  108. spanOp={spanOp}
  109. onClose={() => {
  110. router.replace({
  111. pathname: router.location.pathname,
  112. query: omit(
  113. router.location.query,
  114. 'spanGroup',
  115. 'transactionMethod',
  116. 'spanDescription',
  117. 'spanOp'
  118. ),
  119. });
  120. }}
  121. />
  122. )}
  123. </PageFiltersContainer>
  124. </Layout.Main>
  125. </Layout.Body>
  126. </PageAlertProvider>
  127. </Layout.Page>
  128. </SentryDocumentTitle>
  129. );
  130. }
  131. export default ScreenSummary;
  132. const ControlsContainer = styled('div')`
  133. display: flex;
  134. gap: ${space(1.5)};
  135. `;
  136. const HeaderContainer = styled('div')`
  137. display: flex;
  138. flex-wrap: wrap;
  139. gap: ${space(2)};
  140. justify-content: space-between;
  141. `;
  142. const SamplesContainer = styled('div')`
  143. margin-top: ${space(2)};
  144. `;