Browse Source

feat(browser-starfish): hookup prod interaction transactions (#55797)

Hook up the interactions table to prod interaction transactions. Rn we
are just indexed data as metrics data isn't yet available afaik

Also just using the DOM selector instead of component name.

<img width="916" alt="image"
src="https://github.com/getsentry/sentry/assets/44422760/2c3e674b-57fc-42f0-88b4-086d28f2a43c">
Dominik Buszowiecki 1 year ago
parent
commit
3ae7b4c8a3

+ 23 - 10
static/app/views/performance/browser/interactionTable.tsx

@@ -7,6 +7,7 @@ import GridEditable, {
   GridColumnSortBy,
 } from 'sentry/components/gridEditable';
 import {useLocation} from 'sentry/utils/useLocation';
+import {useInteractionsQuery} from 'sentry/views/performance/browser/useInteractionsQuery';
 
 type Row = {
   component: string;
@@ -25,15 +26,17 @@ function InteractionsTable() {
     {key: 'page', width: COL_WIDTH_UNDEFINED, name: 'Page'},
     {key: 'p75', width: COL_WIDTH_UNDEFINED, name: 'Duration (p75)'},
   ];
-  const data: Row[] = [
-    {
-      'span.group': 'Button',
-      component: '<DownloadButton/>',
-      p75: 23,
-      page: '/performance',
-      'span.action': 'click',
-    },
-  ];
+  const {data, isLoading} = useInteractionsQuery();
+  const tableData: Row[] =
+    !isLoading && data.length
+      ? data.map(row => ({
+          'span.group': 'NOT IMPLEMENTED',
+          component: row.interactionElement,
+          p75: row['p75(transaction.duration)'],
+          page: row.transaction,
+          'span.action': getFriendlyActionName(row['transaction.op']),
+        }))
+      : [];
 
   const sort: GridColumnSortBy<keyof Row> = {key: 'p75', order: 'desc'};
 
@@ -56,7 +59,8 @@ function InteractionsTable() {
 
   return (
     <GridEditable
-      data={data}
+      data={tableData}
+      isLoading={isLoading}
       columnOrder={columnOrder}
       columnSortBy={[sort]}
       grid={{renderHeadCell, renderBodyCell}}
@@ -65,4 +69,13 @@ function InteractionsTable() {
   );
 }
 
+const getFriendlyActionName = (action: string) => {
+  switch (action) {
+    case 'ui.action.click':
+      return 'Click';
+    default:
+      return action;
+  }
+};
+
 export default InteractionsTable;

+ 47 - 0
static/app/views/performance/browser/useInteractionsQuery.ts

@@ -0,0 +1,47 @@
+import {useDiscoverQuery} from 'sentry/utils/discover/discoverQuery';
+import EventView from 'sentry/utils/discover/eventView';
+import {useLocation} from 'sentry/utils/useLocation';
+import useOrganization from 'sentry/utils/useOrganization';
+import usePageFilters from 'sentry/utils/usePageFilters';
+import {useBrowserModuleFilters} from 'sentry/views/performance/browser/useBrowserFilters';
+
+export const useInteractionsQuery = () => {
+  const pageFilters = usePageFilters();
+  const browserFilters = useBrowserModuleFilters();
+  const location = useLocation();
+  const {slug: orgSlug} = useOrganization();
+  const queryConditions = [
+    'has:interactionElement',
+    browserFilters.page ? `transaction:${browserFilters.page}` : '',
+  ];
+
+  // TODO - we should be using metrics data here
+  const eventView = EventView.fromNewQueryWithPageFilters(
+    {
+      fields: [
+        'interactionElement',
+        'transaction',
+        'transaction.op',
+        'p75(transaction.duration)',
+        'count()',
+      ],
+      name: 'Interaction module - interactions table',
+      query: queryConditions.join(' '),
+      orderby: '-count',
+      version: 2,
+    },
+    pageFilters.selection
+  );
+
+  const result = useDiscoverQuery({eventView, limit: 50, location, orgSlug});
+
+  const data = result?.data?.data.map(row => ({
+    transaction: row.transaction.toString(),
+    interactionElement: row.interactionElement.toString(),
+    'transaction.op': row['transaction.op'].toString(),
+    'p75(transaction.duration)': row['p75(transaction.duration)'] as number,
+    'count()': row['count()'] as number,
+  }));
+
+  return {...result, data: data || []};
+};