webVitalsLandingPage.tsx 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import {useState} from 'react';
  2. import Breadcrumbs from 'sentry/components/breadcrumbs';
  3. import DatePageFilter from 'sentry/components/datePageFilter';
  4. import FeatureBadge from 'sentry/components/featureBadge';
  5. import * as Layout from 'sentry/components/layouts/thirds';
  6. import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
  7. import ProjectPageFilter from 'sentry/components/projectPageFilter';
  8. import {t} from 'sentry/locale';
  9. import useOrganization from 'sentry/utils/useOrganization';
  10. import {normalizeUrl} from 'sentry/utils/withDomainRequired';
  11. import WebVitalMeters from 'sentry/views/performance/browser/webVitals/components/webVitalMeters';
  12. import {PagePerformanceTable} from 'sentry/views/performance/browser/webVitals/pagePerformanceTable';
  13. import {PerformanceScoreChart} from 'sentry/views/performance/browser/webVitals/performanceScoreChart';
  14. import {calculatePerformanceScore} from 'sentry/views/performance/browser/webVitals/utils/calculatePerformanceScore';
  15. import {WebVitals} from 'sentry/views/performance/browser/webVitals/utils/types';
  16. import {useProjectWebVitalsQuery} from 'sentry/views/performance/browser/webVitals/utils/useProjectWebVitalsQuery';
  17. import {WebVitalsDetailPanel} from 'sentry/views/performance/browser/webVitals/webVitalsDetailPanel';
  18. import {ModulePageProviders} from 'sentry/views/performance/database/modulePageProviders';
  19. export default function WebVitalsLandingPage() {
  20. const organization = useOrganization();
  21. const [state, setState] = useState<{webVital: WebVitals | null}>({
  22. webVital: null,
  23. });
  24. const {data: projectData} = useProjectWebVitalsQuery();
  25. const projectScore = calculatePerformanceScore({
  26. lcp: projectData?.data[0]['p75(measurements.lcp)'] as number,
  27. fcp: projectData?.data[0]['p75(measurements.fcp)'] as number,
  28. cls: projectData?.data[0]['p75(measurements.cls)'] as number,
  29. ttfb: projectData?.data[0]['p75(measurements.ttfb)'] as number,
  30. fid: projectData?.data[0]['p75(measurements.fid)'] as number,
  31. });
  32. return (
  33. <ModulePageProviders title={[t('Performance'), t('Page Loads')].join(' — ')}>
  34. <Layout.Header>
  35. <Layout.HeaderContent>
  36. <Breadcrumbs
  37. crumbs={[
  38. {
  39. label: 'Performance',
  40. to: normalizeUrl(`/organizations/${organization.slug}/performance/`),
  41. preservePageFilters: true,
  42. },
  43. {
  44. label: 'Page Loads',
  45. },
  46. ]}
  47. />
  48. <Layout.Title>
  49. {t('Page Loads')}
  50. <FeatureBadge type="alpha" />
  51. </Layout.Title>
  52. </Layout.HeaderContent>
  53. </Layout.Header>
  54. <Layout.Body>
  55. <Layout.Main fullWidth>
  56. <PageFilterBar condensed>
  57. <ProjectPageFilter />
  58. <DatePageFilter alignDropdown="left" />
  59. </PageFilterBar>
  60. <PerformanceScoreChart projectScore={projectScore} />
  61. <WebVitalMeters
  62. projectData={projectData}
  63. projectScore={projectScore}
  64. onClick={webVital => setState({...state, webVital})}
  65. />
  66. <PagePerformanceTable />
  67. </Layout.Main>
  68. </Layout.Body>
  69. <WebVitalsDetailPanel
  70. webVital={state.webVital}
  71. onClose={() => {
  72. setState({...state, webVital: null});
  73. }}
  74. />
  75. </ModulePageProviders>
  76. );
  77. }