webVitalsLandingPage.tsx 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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 usePageFilters from 'sentry/utils/usePageFilters';
  11. import {normalizeUrl} from 'sentry/utils/withDomainRequired';
  12. import {PagePerformanceTables} from 'sentry/views/performance/browser/webVitals/pagePerformanceTables';
  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 WebVitalMeters from 'sentry/views/performance/browser/webVitals/webVitalMeters';
  18. import {WebVitalsDetailPanel} from 'sentry/views/performance/browser/webVitals/webVitalsDetailPanel';
  19. import {ModulePageProviders} from 'sentry/views/performance/database/modulePageProviders';
  20. export default function WebVitalsLandingPage() {
  21. const organization = useOrganization();
  22. const pageFilters = usePageFilters();
  23. const [state, setState] = useState<{webVital: WebVitals | null}>({
  24. webVital: null,
  25. });
  26. const {data: projectData} = useProjectWebVitalsQuery({pageFilters});
  27. const projectScore = calculatePerformanceScore({
  28. 'p75(measurements.lcp)': projectData?.data[0]['p75(measurements.lcp)'] as number,
  29. 'p75(measurements.fcp)': projectData?.data[0]['p75(measurements.fcp)'] as number,
  30. 'p75(measurements.cls)': projectData?.data[0]['p75(measurements.cls)'] as number,
  31. 'p75(measurements.app_init_long_tasks)': projectData?.data[0][
  32. 'p75(measurements.app_init_long_tasks)'
  33. ] as number,
  34. });
  35. return (
  36. <ModulePageProviders title={[t('Performance'), t('Page Loads')].join(' — ')}>
  37. <Layout.Header>
  38. <Layout.HeaderContent>
  39. <Breadcrumbs
  40. crumbs={[
  41. {
  42. label: 'Performance',
  43. to: normalizeUrl(`/organizations/${organization.slug}/performance/`),
  44. preservePageFilters: true,
  45. },
  46. {
  47. label: 'Page Loads',
  48. },
  49. ]}
  50. />
  51. <Layout.Title>
  52. {t('Page Loads')}
  53. <FeatureBadge type="alpha" />
  54. </Layout.Title>
  55. </Layout.HeaderContent>
  56. </Layout.Header>
  57. <Layout.Body>
  58. <Layout.Main fullWidth>
  59. <PageFilterBar condensed>
  60. <ProjectPageFilter />
  61. <DatePageFilter alignDropdown="left" />
  62. </PageFilterBar>
  63. <PerformanceScoreChart projectScore={projectScore} />
  64. <WebVitalMeters
  65. projectData={projectData}
  66. projectScore={projectScore}
  67. onClick={webVital => setState({...state, webVital})}
  68. />
  69. <PagePerformanceTables />
  70. </Layout.Main>
  71. </Layout.Body>
  72. <WebVitalsDetailPanel
  73. webVital={state.webVital}
  74. onClose={() => {
  75. setState({...state, webVital: null});
  76. }}
  77. />
  78. </ModulePageProviders>
  79. );
  80. }