useInpSpanSamplesWebVitalsQuery.tsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import {
  2. DEFAULT_INDEXED_INTERACTION_SORT,
  3. type InteractionSpanSampleRowWithScore,
  4. SORTABLE_INDEXED_INTERACTION_FIELDS,
  5. } from 'sentry/views/performance/browser/webVitals/utils/types';
  6. import {useWebVitalsSort} from 'sentry/views/performance/browser/webVitals/utils/useWebVitalsSort';
  7. import {
  8. type Filters,
  9. useIndexedSpans,
  10. } from 'sentry/views/starfish/queries/useIndexedSpans';
  11. import {SpanIndexedField} from 'sentry/views/starfish/types';
  12. export function useInpSpanSamplesWebVitalsQuery({
  13. transaction,
  14. limit,
  15. enabled,
  16. filters = {},
  17. sortName,
  18. }: {
  19. limit: number;
  20. enabled?: boolean;
  21. filters?: Filters;
  22. sortName?: string;
  23. transaction?: string;
  24. }) {
  25. const filteredSortableFields = SORTABLE_INDEXED_INTERACTION_FIELDS;
  26. const sort = useWebVitalsSort({
  27. sortName,
  28. defaultSort: DEFAULT_INDEXED_INTERACTION_SORT,
  29. sortableFields: filteredSortableFields as unknown as string[],
  30. });
  31. const {data, isLoading, ...rest} = useIndexedSpans({
  32. filters: {
  33. 'span.op': 'ui.interaction.click',
  34. 'measurements.score.weight.inp': '>0',
  35. ...(transaction !== undefined
  36. ? {[SpanIndexedField.ORIGIN_TRANSACTION]: transaction}
  37. : {}),
  38. ...filters,
  39. },
  40. sorts: [sort],
  41. fields: [
  42. SpanIndexedField.INP,
  43. SpanIndexedField.INP_SCORE,
  44. SpanIndexedField.INP_SCORE_WEIGHT,
  45. SpanIndexedField.TOTAL_SCORE,
  46. SpanIndexedField.ID,
  47. SpanIndexedField.TIMESTAMP,
  48. SpanIndexedField.PROFILE_ID,
  49. SpanIndexedField.REPLAY_ID,
  50. SpanIndexedField.USER,
  51. SpanIndexedField.ORIGIN_TRANSACTION,
  52. SpanIndexedField.PROJECT,
  53. SpanIndexedField.BROWSER_NAME,
  54. SpanIndexedField.SPAN_SELF_TIME,
  55. SpanIndexedField.SPAN_DESCRIPTION,
  56. ],
  57. enabled,
  58. limit,
  59. referrer: 'api.performance.browser.web-vitals.spans',
  60. });
  61. const tableData: InteractionSpanSampleRowWithScore[] =
  62. !isLoading && data?.length
  63. ? data.map(row => {
  64. return {
  65. ...row,
  66. 'measurements.inp': row[SpanIndexedField.INP],
  67. 'user.display': row[SpanIndexedField.USER],
  68. replayId: row[SpanIndexedField.REPLAY_ID],
  69. 'profile.id': row[SpanIndexedField.PROFILE_ID],
  70. inpScore: Math.round(
  71. ((row[`measurements.score.inp`] ?? 0) /
  72. (row[`measurements.score.weight.inp`] ?? 0)) *
  73. 100
  74. ),
  75. totalScore: Math.round(row[`measurements.score.total`] ?? 0),
  76. projectSlug: row[SpanIndexedField.PROJECT],
  77. };
  78. })
  79. : [];
  80. return {
  81. data: tableData,
  82. isLoading,
  83. ...rest,
  84. };
  85. }