useTransactionWebVitalsQuery.tsx 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import {useDiscoverQuery} from 'sentry/utils/discover/discoverQuery';
  2. import EventView from 'sentry/utils/discover/eventView';
  3. import {useLocation} from 'sentry/utils/useLocation';
  4. import useOrganization from 'sentry/utils/useOrganization';
  5. import usePageFilters from 'sentry/utils/usePageFilters';
  6. import {calculatePerformanceScore} from 'sentry/views/performance/browser/webVitals/utils/calculatePerformanceScore';
  7. import {mapWebVitalToOrderBy} from 'sentry/views/performance/browser/webVitals/utils/mapWebVitalToOrderBy';
  8. import {
  9. RowWithScore,
  10. WebVitals,
  11. } from 'sentry/views/performance/browser/webVitals/utils/types';
  12. type Props = {
  13. limit?: number;
  14. orderBy?: WebVitals | null;
  15. transaction?: string | null;
  16. };
  17. export const useTransactionWebVitalsQuery = ({orderBy, limit, transaction}: Props) => {
  18. const organization = useOrganization();
  19. const pageFilters = usePageFilters();
  20. const location = useLocation();
  21. const eventView = EventView.fromNewQueryWithPageFilters(
  22. {
  23. fields: [
  24. 'transaction',
  25. 'transaction.op',
  26. 'p75(measurements.lcp)',
  27. 'p75(measurements.fcp)',
  28. 'p75(measurements.cls)',
  29. 'p75(measurements.ttfb)',
  30. 'p75(measurements.fid)',
  31. 'count()',
  32. ],
  33. name: 'Web Vitals',
  34. query:
  35. 'transaction.op:pageload' + (transaction ? ` transaction:"${transaction}"` : ''),
  36. orderby: mapWebVitalToOrderBy(orderBy, 'p75') ?? '-count',
  37. version: 2,
  38. },
  39. pageFilters.selection
  40. );
  41. const {data, isLoading, ...rest} = useDiscoverQuery({
  42. eventView,
  43. limit: limit ?? 50,
  44. location,
  45. orgSlug: organization.slug,
  46. options: {
  47. enabled: pageFilters.isReady,
  48. refetchOnWindowFocus: false,
  49. },
  50. });
  51. const tableData: RowWithScore[] =
  52. !isLoading && data?.data.length
  53. ? data.data
  54. .map(row => ({
  55. transaction: row.transaction?.toString(),
  56. 'transaction.op': row['transaction.op']?.toString(),
  57. 'p75(measurements.lcp)': row['p75(measurements.lcp)'] as number,
  58. 'p75(measurements.fcp)': row['p75(measurements.fcp)'] as number,
  59. 'p75(measurements.cls)': row['p75(measurements.cls)'] as number,
  60. 'p75(measurements.ttfb)': row['p75(measurements.ttfb)'] as number,
  61. 'p75(measurements.fid)': row['p75(measurements.fid)'] as number,
  62. 'count()': row['count()'] as number,
  63. }))
  64. .map(row => {
  65. const {totalScore, clsScore, fcpScore, lcpScore, ttfbScore, fidScore} =
  66. calculatePerformanceScore({
  67. lcp: row['p75(measurements.lcp)'],
  68. fcp: row['p75(measurements.fcp)'],
  69. cls: row['p75(measurements.cls)'],
  70. ttfb: row['p75(measurements.ttfb)'],
  71. fid: row['p75(measurements.fid)'],
  72. });
  73. return {
  74. ...row,
  75. score: totalScore,
  76. clsScore,
  77. fcpScore,
  78. lcpScore,
  79. ttfbScore,
  80. fidScore,
  81. };
  82. })
  83. : [];
  84. return {
  85. data: tableData,
  86. isLoading,
  87. ...rest,
  88. };
  89. };