Browse Source

chore(perf): Remove "Interactions" module (#69580)

Interactions are now part of the Web Vitals view! The future of
interactions will be something else interesting, but this inaccessible
module can go.
George Gritsouk 10 months ago
parent
commit
e7ef6a342b

+ 0 - 13
static/app/routes.tsx

@@ -1547,19 +1547,6 @@ function buildRoutes() {
         />
       </Route>
       <Route path="browser/">
-        <Route path="interactions/">
-          <IndexRoute
-            component={make(
-              () => import('sentry/views/performance/browser/interactionsLandingPage')
-            )}
-          />
-          <Route
-            path="summary/"
-            component={make(
-              () => import('sentry/views/performance/browser/interactionSummary/index')
-            )}
-          />
-        </Route>
         <Route path="pageloads/">
           <IndexRoute
             component={make(

+ 0 - 82
static/app/views/performance/browser/interactionSummary/index.tsx

@@ -1,82 +0,0 @@
-import FeatureBadge from 'sentry/components/badge/featureBadge';
-import {Breadcrumbs} from 'sentry/components/breadcrumbs';
-import * as Layout from 'sentry/components/layouts/thirds';
-import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
-import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
-import {t} from 'sentry/locale';
-import useOrganization from 'sentry/utils/useOrganization';
-import {normalizeUrl} from 'sentry/utils/withDomainRequired';
-import {PaddedContainer} from 'sentry/views/performance/browser/interactionsLandingPage';
-import {InteractionBreakdownChart} from 'sentry/views/performance/browser/interactionSummary/interactionBreakdownChart';
-import InteractionSampleTable from 'sentry/views/performance/browser/interactionSummary/sampleTable';
-import {getActionName} from 'sentry/views/performance/browser/interactionTable';
-import {
-  BrowserStarfishFields,
-  useBrowserModuleFilters,
-} from 'sentry/views/performance/browser/useBrowserFilters';
-import {ModulePageProviders} from 'sentry/views/performance/modulePageProviders';
-
-function InteractionSummary() {
-  const organization = useOrganization();
-  const browserFilters = useBrowserModuleFilters();
-
-  const operation = browserFilters?.[BrowserStarfishFields.TRANSACTION_OP] ?? '';
-  const page = browserFilters?.[BrowserStarfishFields.PAGE] ?? '';
-  const element = browserFilters?.[BrowserStarfishFields.COMPONENT] ?? '';
-
-  return (
-    <ModulePageProviders
-      title={[t('Performance'), t('Interactions')].join(' — ')}
-      baseURL="/performance/browser/interactions"
-      features="starfish-view"
-    >
-      <Layout.Header>
-        <Layout.HeaderContent>
-          <Breadcrumbs
-            crumbs={[
-              {
-                label: 'Performance',
-                to: normalizeUrl(`/organizations/${organization.slug}/performance/`),
-                preservePageFilters: true,
-              },
-              {
-                label: 'Interactions',
-                to: normalizeUrl(
-                  `/organizations/${organization.slug}/performance/browser/interactions/`
-                ),
-                preservePageFilters: true,
-              },
-              {
-                label: 'Interaction Summary',
-              },
-            ]}
-          />
-
-          <Layout.Title>
-            {getActionName(browserFilters?.['transaction.op'] || '')}
-            {` ${browserFilters.component} on ${browserFilters.page}`}
-            <FeatureBadge type="alpha" />
-          </Layout.Title>
-        </Layout.HeaderContent>
-      </Layout.Header>
-
-      <Layout.Body>
-        <Layout.Main fullWidth>
-          <PaddedContainer>
-            <PageFilterBar condensed>
-              <DatePageFilter />
-            </PageFilterBar>
-          </PaddedContainer>
-          <InteractionBreakdownChart
-            operation={operation}
-            page={page}
-            element={element}
-          />
-          <InteractionSampleTable />
-        </Layout.Main>
-      </Layout.Body>
-    </ModulePageProviders>
-  );
-}
-
-export default InteractionSummary;

+ 0 - 48
static/app/views/performance/browser/interactionSummary/interactionBreakdownChart.tsx

@@ -1,48 +0,0 @@
-import styled from '@emotion/styled';
-
-import {CHART_PALETTE} from 'sentry/constants/chartPalette';
-import {space} from 'sentry/styles/space';
-import {getDurationUnit} from 'sentry/utils/discover/charts';
-import {useInteractionBreakdownTimeseriesQuery} from 'sentry/views/performance/browser/interactionSummary/useInteractionBreakdownTimeseriesQuery';
-import Chart, {ChartType} from 'sentry/views/starfish/components/chart';
-
-type Props = {
-  element: string;
-  operation: string;
-  page: string;
-};
-
-export function InteractionBreakdownChart({operation, element, page}: Props) {
-  const {data, isLoading} = useInteractionBreakdownTimeseriesQuery({
-    operation,
-    element,
-    page,
-  });
-
-  return (
-    <ChartContainer>
-      <Chart
-        height={200}
-        data={data}
-        loading={isLoading}
-        chartColors={[CHART_PALETTE[0][0]]}
-        durationUnit={getDurationUnit(data)}
-        aggregateOutputFormat="duration"
-        type={ChartType.AREA}
-        grid={{
-          left: 20,
-          right: 50,
-          top: 30,
-          bottom: 10,
-        }}
-      />
-    </ChartContainer>
-  );
-}
-
-const ChartContainer = styled('div')`
-  flex: 1;
-  border: 1px solid ${p => p.theme.gray200};
-  border-radius: ${p => p.theme.borderRadius};
-  margin-bottom: ${space(4)};
-`;

+ 0 - 66
static/app/views/performance/browser/interactionSummary/sampleTable.tsx

@@ -1,66 +0,0 @@
-import {Fragment} from 'react';
-import {Link} from 'react-router';
-
-import type {GridColumnHeader, GridColumnOrder} from 'sentry/components/gridEditable';
-import GridEditable, {COL_WIDTH_UNDEFINED} from 'sentry/components/gridEditable';
-import Pagination from 'sentry/components/pagination';
-import {useLocation} from 'sentry/utils/useLocation';
-import {useInteractionQuery} from 'sentry/views/performance/browser/interactionSummary/useInteractionQuery';
-import {DurationCell} from 'sentry/views/starfish/components/tableCells/durationCell';
-import {renderHeadCell} from 'sentry/views/starfish/components/tableCells/renderHeadCell';
-
-type Row = {
-  eventId: string;
-  project: string;
-  'transaction.duration': number;
-};
-
-type Column = GridColumnHeader<keyof Row>;
-
-function InteractionSampleTable() {
-  const location = useLocation();
-  const columnOrder: GridColumnOrder<keyof Row>[] = [
-    {key: 'eventId', width: COL_WIDTH_UNDEFINED, name: 'event'},
-    {key: 'transaction.duration', width: COL_WIDTH_UNDEFINED, name: 'duration'},
-  ];
-  const {data, isLoading, pageLinks} = useInteractionQuery();
-  const tableData: Row[] = data.length ? data : [];
-
-  const renderBodyCell = (col: Column, row: Row) => {
-    const {key} = col;
-    if (key === 'transaction.duration') {
-      return <DurationCell milliseconds={row[key]} />;
-    }
-    if (key === 'eventId') {
-      return (
-        <Link to={`/performance/${row.project}:${row.eventId}`}>
-          {row.eventId.slice(0, 8)}
-        </Link>
-      );
-    }
-    return <span>{row[key]}</span>;
-  };
-
-  return (
-    <Fragment>
-      <GridEditable
-        data={tableData}
-        isLoading={isLoading}
-        columnOrder={columnOrder}
-        columnSortBy={[]}
-        grid={{
-          renderHeadCell: column =>
-            renderHeadCell({
-              column,
-              location,
-            }),
-          renderBodyCell,
-        }}
-        location={location}
-      />
-      <Pagination pageLinks={pageLinks} />
-    </Fragment>
-  );
-}
-
-export default InteractionSampleTable;

+ 0 - 82
static/app/views/performance/browser/interactionSummary/useInteractionBreakdownTimeseriesQuery.tsx

@@ -1,82 +0,0 @@
-import {getInterval} from 'sentry/components/charts/utils';
-import type {Series} from 'sentry/types/echarts';
-import type {MetaType} from 'sentry/utils/discover/eventView';
-import EventView from 'sentry/utils/discover/eventView';
-import type {DiscoverQueryProps} from 'sentry/utils/discover/genericDiscoverQuery';
-import {useGenericDiscoverQuery} from 'sentry/utils/discover/genericDiscoverQuery';
-import {DiscoverDatasets} from 'sentry/utils/discover/types';
-import {MutableSearch} from 'sentry/utils/tokenizeSearch';
-import {useLocation} from 'sentry/utils/useLocation';
-import useOrganization from 'sentry/utils/useOrganization';
-import usePageFilters from 'sentry/utils/usePageFilters';
-
-type Props = {
-  element: string;
-  operation: string;
-  page: string;
-};
-
-export const useInteractionBreakdownTimeseriesQuery = ({
-  operation,
-  element,
-  page,
-}: Props): {data: Series[]; isLoading: boolean} => {
-  const pageFilters = usePageFilters();
-  const location = useLocation();
-  const organization = useOrganization();
-  const search = new MutableSearch(
-    `transaction.op:${operation} transaction:${page} interactionElement:${element}`
-  );
-  const projectTimeSeriesEventView = EventView.fromNewQueryWithPageFilters(
-    {
-      yAxis: [`p75(transaction.duration)`],
-      name: 'Interaction Duration',
-      query: search.formatString(),
-      version: 2,
-      fields: [],
-      interval: getInterval(pageFilters.selection.datetime, 'low'),
-      dataset: DiscoverDatasets.DISCOVER,
-    },
-    pageFilters.selection
-  );
-
-  const result = useGenericDiscoverQuery<
-    {
-      data: any[];
-      meta: MetaType;
-    },
-    DiscoverQueryProps
-  >({
-    route: 'events-stats',
-    eventView: projectTimeSeriesEventView,
-    location,
-    orgSlug: organization.slug,
-    getRequestPayload: () => ({
-      ...projectTimeSeriesEventView.getEventsAPIPayload(location),
-      yAxis: projectTimeSeriesEventView.yAxis,
-      topEvents: projectTimeSeriesEventView.topEvents,
-      excludeOther: 0,
-      partial: 1,
-      orderby: undefined,
-      interval: projectTimeSeriesEventView.interval,
-    }),
-    options: {
-      enabled: pageFilters.isReady,
-      refetchOnWindowFocus: false,
-    },
-  });
-
-  const seriesData: Series = {
-    seriesName: 'p75(duration)',
-    data: [],
-  };
-
-  const transformedData = result?.data?.data.map(data => ({
-    name: data[0] as string,
-    value: data[1][0].count,
-  }));
-
-  seriesData.data = transformedData ?? [];
-
-  return {data: [seriesData], isLoading: result.isLoading};
-};

+ 0 - 39
static/app/views/performance/browser/interactionSummary/useInteractionQuery.ts

@@ -1,39 +0,0 @@
-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 useInteractionQuery = () => {
-  const pageFilters = usePageFilters();
-  const browserFilters = useBrowserModuleFilters();
-  const location = useLocation();
-  const {slug: orgSlug} = useOrganization();
-  const queryConditions = [
-    `transaction:"${browserFilters.page}"`,
-    `interactionElement:"${browserFilters.component?.replaceAll('"', '\\"')}"`,
-  ];
-
-  // TODO - we should be using metrics data here
-  const eventView = EventView.fromNewQueryWithPageFilters(
-    {
-      fields: ['id', 'transaction.duration', 'project'],
-      name: 'Interaction module - interactions table',
-      query: queryConditions.join(' '),
-      orderby: '-transaction.duration',
-      version: 2,
-    },
-    pageFilters.selection
-  );
-
-  const result = useDiscoverQuery({eventView, limit: 15, location, orgSlug});
-
-  const data = result?.data?.data.map(row => ({
-    eventId: row.id.toString(),
-    project: row.project.toString(),
-    'transaction.duration': row['transaction.duration'] as number,
-  }));
-
-  return {...result, data: data || []};
-};

+ 0 - 114
static/app/views/performance/browser/interactionTable.tsx

@@ -1,114 +0,0 @@
-import {Fragment} from 'react';
-import {Link} from 'react-router';
-import * as qs from 'query-string';
-
-import type {GridColumnHeader, GridColumnOrder} from 'sentry/components/gridEditable';
-import GridEditable, {COL_WIDTH_UNDEFINED} from 'sentry/components/gridEditable';
-import Pagination from 'sentry/components/pagination';
-import {useLocation} from 'sentry/utils/useLocation';
-import {BrowserStarfishFields} from 'sentry/views/performance/browser/useBrowserFilters';
-import type {ValidSort} from 'sentry/views/performance/browser/useBrowserSort';
-import {useInteractionsQuery} from 'sentry/views/performance/browser/useInteractionsQuery';
-import {DurationCell} from 'sentry/views/starfish/components/tableCells/durationCell';
-import {renderHeadCell} from 'sentry/views/starfish/components/tableCells/renderHeadCell';
-import {TextAlignRight} from 'sentry/views/starfish/components/textAlign';
-
-type Row = {
-  'count()': number;
-  interactionElement: string;
-  'p75(transaction.duration)': number;
-  'span.group': string;
-  transaction: string;
-  'transaction.op': string;
-};
-
-type Column = GridColumnHeader<keyof Row>;
-
-type Props = {
-  sort: ValidSort;
-};
-
-function InteractionsTable({sort}: Props) {
-  const location = useLocation();
-  const columnOrder: GridColumnOrder<keyof Row>[] = [
-    {key: 'span.group', width: COL_WIDTH_UNDEFINED, name: 'Interaction'},
-    {key: 'transaction', width: COL_WIDTH_UNDEFINED, name: 'Page'},
-    {key: 'count()', width: COL_WIDTH_UNDEFINED, name: 'Count'},
-    {
-      key: 'p75(transaction.duration)',
-      width: COL_WIDTH_UNDEFINED,
-      name: 'Duration (p75)',
-    },
-  ];
-  const {data, isLoading, pageLinks} = useInteractionsQuery({sort});
-  const tableData: Row[] =
-    !isLoading && data.length
-      ? data.map(row => ({
-          'span.group': 'NOT IMPLEMENTED',
-          ...row,
-        }))
-      : [];
-
-  const renderBodyCell = (col: Column, row: Row) => {
-    const {key} = col;
-    if (key === 'span.group') {
-      return (
-        <Link
-          to={`/performance/browser/interactions/summary/?${qs.stringify({
-            [BrowserStarfishFields.COMPONENT]: row.interactionElement,
-            [BrowserStarfishFields.PAGE]: row.transaction,
-            [BrowserStarfishFields.TRANSACTION_OP]: row['transaction.op'],
-          })}`}
-        >
-          {getActionName(row['transaction.op'])}
-          <span style={{fontWeight: 'bold'}}> {row.interactionElement}</span>
-        </Link>
-      );
-    }
-    if (key === 'p75(transaction.duration)') {
-      return <DurationCell milliseconds={row[key]} />;
-    }
-    if (key === 'count()') {
-      return <TextAlignRight>{row[key]}</TextAlignRight>;
-    }
-    return <span>{row[key]}</span>;
-  };
-
-  return (
-    <Fragment>
-      <GridEditable
-        data={tableData}
-        isLoading={isLoading}
-        columnOrder={columnOrder}
-        columnSortBy={[
-          {
-            key: sort.field,
-            order: sort.kind,
-          },
-        ]}
-        grid={{
-          renderHeadCell: column =>
-            renderHeadCell({
-              column,
-              location,
-              sort,
-            }),
-          renderBodyCell,
-        }}
-        location={location}
-      />
-      <Pagination pageLinks={pageLinks} />
-    </Fragment>
-  );
-}
-
-export const getActionName = (transactionOp: string) => {
-  switch (transactionOp) {
-    case 'ui.action.click':
-      return 'Click';
-    default:
-      return transactionOp;
-  }
-};
-
-export default InteractionsTable;

+ 0 - 199
static/app/views/performance/browser/interactionsLandingPage.tsx

@@ -1,199 +0,0 @@
-import {browserHistory} from 'react-router';
-import styled from '@emotion/styled';
-
-import FeatureBadge from 'sentry/components/badge/featureBadge';
-import {Breadcrumbs} from 'sentry/components/breadcrumbs';
-import type {ControlProps} from 'sentry/components/forms/controls/selectControl';
-import SelectControl from 'sentry/components/forms/controls/selectControl';
-import * as Layout from 'sentry/components/layouts/thirds';
-import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
-import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
-import {ProjectPageFilter} from 'sentry/components/organizations/projectPageFilter';
-import {t} from 'sentry/locale';
-import {space} from 'sentry/styles/space';
-import {useLocation} from 'sentry/utils/useLocation';
-import useOrganization from 'sentry/utils/useOrganization';
-import {normalizeUrl} from 'sentry/utils/withDomainRequired';
-import InteractionsTable from 'sentry/views/performance/browser/interactionTable';
-import {
-  BrowserStarfishFields,
-  useBrowserModuleFilters,
-} from 'sentry/views/performance/browser/useBrowserFilters';
-import {useBrowserSort} from 'sentry/views/performance/browser/useBrowserSort';
-import {useInteractionElementQuery} from 'sentry/views/performance/browser/useInteractionElementQuery';
-import {usePagesQuery} from 'sentry/views/performance/browser/usePageQuery';
-import {ModulePageProviders} from 'sentry/views/performance/modulePageProviders';
-
-const {COMPONENT, PAGE, TRANSACTION_OP} = BrowserStarfishFields;
-
-type Option = {
-  label: string;
-  value: string;
-};
-
-function InteractionsLandingPage() {
-  const organization = useOrganization();
-  const filters = useBrowserModuleFilters();
-  const sort = useBrowserSort();
-
-  return (
-    <ModulePageProviders
-      title={[t('Performance'), t('Interactions')].join(' — ')}
-      baseURL="/performance/browser/interactions"
-      features="starfish-view "
-    >
-      <Layout.Header>
-        <Layout.HeaderContent>
-          <Breadcrumbs
-            crumbs={[
-              {
-                label: 'Performance',
-                to: normalizeUrl(`/organizations/${organization.slug}/performance/`),
-                preservePageFilters: true,
-              },
-              {
-                label: 'Interactions',
-              },
-            ]}
-          />
-
-          <Layout.Title>
-            {t('Interactions')}
-            <FeatureBadge type="alpha" />
-          </Layout.Title>
-        </Layout.HeaderContent>
-      </Layout.Header>
-
-      <Layout.Body>
-        <Layout.Main fullWidth>
-          <PaddedContainer>
-            <PageFilterBar condensed>
-              <ProjectPageFilter />
-              <DatePageFilter />
-            </PageFilterBar>
-          </PaddedContainer>
-
-          <FilterOptionsContainer>
-            <ComponentSelector value={filters[COMPONENT] || ''} />
-            <ActionSelector value={filters[TRANSACTION_OP] || ''} />
-            <PageSelector value={filters[PAGE] || ''} />
-          </FilterOptionsContainer>
-
-          <InteractionsTable sort={sort} />
-        </Layout.Main>
-      </Layout.Body>
-    </ModulePageProviders>
-  );
-}
-
-function ComponentSelector({value}: {value?: string}) {
-  const location = useLocation();
-
-  const {data, isLoading} = useInteractionElementQuery();
-
-  const options: Option[] =
-    !isLoading && data.length
-      ? [
-          {label: 'All', value: ''},
-          ...data.map(element => ({
-            label: element,
-            value: element,
-          })),
-        ]
-      : [];
-
-  return (
-    <SelectControlWithProps
-      inFieldLabel={`${t('Component')}:`}
-      options={options}
-      value={value}
-      onChange={newValue => {
-        browserHistory.push({
-          ...location,
-          query: {
-            ...location.query,
-            [COMPONENT]: newValue?.value,
-          },
-        });
-      }}
-    />
-  );
-}
-
-function ActionSelector({value}: {value?: string}) {
-  const location = useLocation();
-
-  const options: Option[] = [
-    {value: '', label: 'All'},
-    {value: 'ui.action.click', label: 'Click'},
-    {value: 'ui.action.right.click', label: 'Right Click'},
-  ];
-  return (
-    <SelectControlWithProps
-      inFieldLabel={`${t('Action')}:`}
-      options={options}
-      value={value}
-      onChange={newValue => {
-        browserHistory.push({
-          ...location,
-          query: {
-            ...location.query,
-            [TRANSACTION_OP]: newValue?.value,
-          },
-        });
-      }}
-    />
-  );
-}
-
-function PageSelector({value}: {value?: string}) {
-  const location = useLocation();
-
-  const {data: pages, isLoading} = usePagesQuery();
-
-  const options: Option[] =
-    !isLoading && pages.length
-      ? [
-          {label: 'All', value: ''},
-          ...pages.map(page => ({
-            value: page,
-            label: page,
-          })),
-        ]
-      : [];
-
-  return (
-    <SelectControlWithProps
-      inFieldLabel={`${t('Page')}:`}
-      options={options}
-      value={value}
-      onChange={newValue => {
-        browserHistory.push({
-          ...location,
-          query: {
-            ...location.query,
-            [PAGE]: newValue?.value,
-          },
-        });
-      }}
-    />
-  );
-}
-
-function SelectControlWithProps(props: ControlProps & {options: Option[]}) {
-  return <SelectControl {...props} />;
-}
-
-export const PaddedContainer = styled('div')`
-  margin-bottom: ${space(2)};
-`;
-
-const FilterOptionsContainer = styled('div')`
-  display: grid;
-  grid-template-columns: repeat(3, 1fr);
-  gap: ${space(2)};
-  margin-bottom: ${space(2)};
-  max-width: 800px;
-`;
-
-export default InteractionsLandingPage;

+ 0 - 25
static/app/views/performance/browser/useBrowserFilters.ts

@@ -1,25 +0,0 @@
-import pick from 'lodash/pick';
-
-import {useLocation} from 'sentry/utils/useLocation';
-
-export enum BrowserStarfishFields {
-  TRANSACTION_OP = 'transaction.op',
-  COMPONENT = 'component',
-  PAGE = 'page',
-}
-
-export type ModuleFilters = {
-  [BrowserStarfishFields.TRANSACTION_OP]?: string;
-  [BrowserStarfishFields.COMPONENT]?: string;
-  [BrowserStarfishFields.PAGE]?: string;
-};
-
-export const useBrowserModuleFilters = () => {
-  const location = useLocation<ModuleFilters>();
-
-  return pick(location.query, [
-    BrowserStarfishFields.TRANSACTION_OP,
-    BrowserStarfishFields.COMPONENT,
-    BrowserStarfishFields.PAGE,
-  ]);
-};

+ 0 - 38
static/app/views/performance/browser/useBrowserSort.ts

@@ -1,38 +0,0 @@
-import type {Sort} from 'sentry/utils/discover/fields';
-import {decodeSorts} from 'sentry/utils/queryString';
-import {useLocation} from 'sentry/utils/useLocation';
-import type {QueryParameterNames} from 'sentry/views/starfish/views/queryParameters';
-
-type Query = {
-  sort?: string;
-};
-
-const SORTABLE_FIELDS = ['count()', 'p75(transaction.duration)', 'transaction'] as const;
-
-export type ValidSort = Sort & {
-  field: (typeof SORTABLE_FIELDS)[number];
-};
-
-/**
- * Parses a `Sort` object from the URL. In case of multiple specified sorts
- * picks the first one, since span module UIs only support one sort at a time.
- */
-export function useBrowserSort(
-  sortParameterName: QueryParameterNames | 'sort' = 'sort',
-  fallback: Sort = DEFAULT_SORT
-) {
-  const location = useLocation<Query>();
-
-  return (
-    decodeSorts(location.query[sortParameterName]).filter(isAValidSort)[0] ?? fallback
-  );
-}
-
-const DEFAULT_SORT: Sort = {
-  kind: 'desc',
-  field: SORTABLE_FIELDS[0],
-};
-
-function isAValidSort(sort: Sort): sort is ValidSort {
-  return (SORTABLE_FIELDS as unknown as string[]).includes(sort.field);
-}

Some files were not shown because too many files changed in this diff