Browse Source

feat(performance): Pass team url param to other event endpoints as ne… (#26532)

Team key transactions require a team to be able to generate the query. This
change ensures that the team url param is passed where needed and that it
defaults to "My Teams" when it is not specified to align with the project url
param.
Tony Xiao 3 years ago
parent
commit
8f6cc4cdd8

+ 0 - 8
src/sentry/api/bases/organization.py

@@ -5,7 +5,6 @@ from rest_framework.exceptions import ParseError, PermissionDenied
 from sentry.api.base import Endpoint
 from sentry.api.exceptions import ResourceDoesNotExist
 from sentry.api.helpers.environments import get_environments
-from sentry.api.helpers.teams import get_teams
 from sentry.api.permissions import SentryPermission
 from sentry.api.utils import (
     InvalidParams,
@@ -258,9 +257,6 @@ class OrganizationEndpoint(Endpoint):
     def get_environments(self, request, organization):
         return get_environments(request, organization)
 
-    def get_teams(self, request, organization):
-        return get_teams(request, organization)
-
     def get_filter_params(
         self, request, organization, date_filter_optional=False, project_ids=None
     ):
@@ -326,10 +322,6 @@ class OrganizationEndpoint(Endpoint):
             params["environment"] = [env.name for env in environments]
             params["environment_objects"] = environments
 
-        teams = self.get_teams(request, organization)
-        if teams:
-            params["team_id"] = [team.id for team in teams]
-
         return params
 
     def convert_args(self, request, organization_slug, *args, **kwargs):

+ 6 - 0
src/sentry/api/bases/organization_events.py

@@ -8,9 +8,11 @@ from sentry_relay.consts import SPAN_STATUS_CODE_TO_NAME
 from sentry import features
 from sentry.api.base import LINK_HEADER
 from sentry.api.bases import NoProjects, OrganizationEndpoint
+from sentry.api.helpers.teams import get_teams
 from sentry.api.serializers.snuba import SnubaTSResultSerializer
 from sentry.discover.arithmetic import ArithmeticError
 from sentry.exceptions import InvalidSearchQuery
+from sentry.models import Team
 from sentry.models.group import Group
 from sentry.models.transaction_threshold import ProjectTransactionThreshold
 from sentry.search.events.constants import DEFAULT_PROJECT_THRESHOLD
@@ -62,6 +64,10 @@ class OrganizationEventsEndpointBase(OrganizationEndpoint):
             params = self.get_filter_params(request, organization)
             params = self.quantize_date_params(request, params)
             params["user_id"] = request.user.id if request.user else None
+            teams = get_teams(request, organization)
+            if not teams:
+                teams = Team.objects.get_for_user(organization, request.user)
+            params["team_id"] = [team.id for team in teams]
 
             if check_global_views:
                 has_global_views = features.has(

+ 7 - 3
static/app/actionCreators/events.tsx

@@ -3,7 +3,6 @@ import pick from 'lodash/pick';
 
 import {Client} from 'app/api';
 import {canIncludePreviousPeriod} from 'app/components/charts/utils';
-import {URL_PARAM} from 'app/constants/globalSelectionHeader';
 import {
   DateString,
   EventsStats,
@@ -12,11 +11,13 @@ import {
 } from 'app/types';
 import {LocationQuery} from 'app/utils/discover/eventView';
 import {getPeriod} from 'app/utils/getPeriod';
+import {PERFORMANCE_URL_PARAM} from 'app/utils/performance/constants';
 
 type Options = {
   organization: OrganizationSummary;
   project?: Readonly<number[]>;
   environment?: Readonly<string[]>;
+  team?: Readonly<string | string[]>;
   period?: string;
   start?: DateString;
   end?: DateString;
@@ -39,6 +40,7 @@ type Options = {
  * @param {Object} options.organization Organization object
  * @param {Number[]} options.project List of project ids
  * @param {String[]} options.environment List of environments to query for
+ * @param {String[]} options.team List of teams to query for
  * @param {String} options.period Time period to query for, in the format: <integer><units> where units are "d" or "h"
  * @param {String} options.interval Time interval to group results in, in the format: <integer><units> where units are "d", "h", "m", "s"
  * @param {Boolean} options.includePrevious Should request also return reqsults for previous period?
@@ -51,6 +53,7 @@ export const doEventsRequest = (
     organization,
     project,
     environment,
+    team,
     period,
     start,
     end,
@@ -70,6 +73,7 @@ export const doEventsRequest = (
       interval,
       project,
       environment,
+      team,
       query,
       yAxis,
       field,
@@ -126,7 +130,7 @@ export async function fetchTagFacets(
   orgSlug: string,
   query: EventQuery
 ): Promise<Tag[]> {
-  const urlParams = pick(query, Object.values(URL_PARAM));
+  const urlParams = pick(query, Object.values(PERFORMANCE_URL_PARAM));
 
   const queryOption = {...urlParams, query: query.query};
 
@@ -143,7 +147,7 @@ export async function fetchTotalCount(
   orgSlug: String,
   query: EventQuery & LocationQuery
 ): Promise<number> {
-  const urlParams = pick(query, Object.values(URL_PARAM));
+  const urlParams = pick(query, Object.values(PERFORMANCE_URL_PARAM));
 
   const queryOption = {...urlParams, query: query.query};
 

+ 4 - 0
static/app/components/charts/eventsRequest.tsx

@@ -97,6 +97,10 @@ type EventsRequestPartialProps = {
    * List of environments to query
    */
   environment?: Readonly<string[]>;
+  /**
+   * List of team ids to query
+   */
+  team?: Readonly<string | string[]>;
   /**
    * List of fields to group with when doing a topEvents request.
    */

+ 4 - 0
static/app/utils/performance/constants.tsx

@@ -1 +1,5 @@
+import {URL_PARAM} from 'app/constants/globalSelectionHeader';
+
 export const MAX_TEAM_KEY_TRANSACTIONS = 100;
+
+export const PERFORMANCE_URL_PARAM = ['team', ...Object.values(URL_PARAM)];

+ 2 - 2
static/app/utils/performance/vitals/vitalsCardsDiscoverQuery.tsx

@@ -1,13 +1,13 @@
 import * as React from 'react';
 import pick from 'lodash/pick';
 
-import {URL_PARAM} from 'app/constants/globalSelectionHeader';
 import {MetaType} from 'app/utils/discover/eventView';
 import {WebVital} from 'app/utils/discover/fields';
 import GenericDiscoverQuery, {
   DiscoverQueryProps,
   GenericChildrenProps,
 } from 'app/utils/discover/genericDiscoverQuery';
+import {PERFORMANCE_URL_PARAM} from 'app/utils/performance/constants';
 import withApi from 'app/utils/withApi';
 
 export type TableDataRow = {
@@ -49,7 +49,7 @@ function getRequestPayload(props: RequestProps) {
   const apiPayload = eventView?.getEventsAPIPayload(props.location);
   return {
     vital: vitals,
-    ...pick(apiPayload, ['query', ...Object.values(URL_PARAM)]),
+    ...pick(apiPayload, ['query', ...Object.values(PERFORMANCE_URL_PARAM)]),
   };
 }
 

+ 4 - 1
static/app/views/performance/charts/index.tsx

@@ -57,6 +57,8 @@ class Container extends Component<Props> {
     const {utc} = getParams(location.query);
     const axisOptions = this.getChartParameters();
 
+    const apiPayload = eventView.getEventsAPIPayload(location);
+
     return (
       <Panel>
         <EventsRequest
@@ -65,6 +67,7 @@ class Container extends Component<Props> {
           period={globalSelection.datetime.period}
           project={globalSelection.projects}
           environment={globalSelection.environments}
+          team={apiPayload.team}
           start={start}
           end={end}
           interval={getInterval(
@@ -76,7 +79,7 @@ class Container extends Component<Props> {
             true
           )}
           showLoading={false}
-          query={eventView.getEventsAPIPayload(location).query}
+          query={apiPayload.query}
           includePrevious={false}
           yAxis={axisOptions.map(opt => opt.value)}
           partial

+ 6 - 20
static/app/views/performance/data.tsx

@@ -583,7 +583,7 @@ export function generatePerformanceEventView(
   projects,
   isTrends = false
 ) {
-  let eventView = generateGenericPerformanceEventView(organization, location);
+  const eventView = generateGenericPerformanceEventView(organization, location);
   if (isTrends) {
     return eventView;
   }
@@ -591,22 +591,13 @@ export function generatePerformanceEventView(
   const display = getCurrentLandingDisplay(location, projects, eventView);
   switch (display?.field) {
     case LandingDisplayField.FRONTEND_PAGELOAD:
-      eventView = generateFrontendPageloadPerformanceEventView(organization, location);
-      break;
+      return generateFrontendPageloadPerformanceEventView(organization, location);
     case LandingDisplayField.FRONTEND_OTHER:
-      eventView = generateFrontendOtherPerformanceEventView(organization, location);
-      break;
+      return generateFrontendOtherPerformanceEventView(organization, location);
     case LandingDisplayField.BACKEND:
-      eventView = generateBackendPerformanceEventView(organization, location);
-      break;
+      return generateBackendPerformanceEventView(organization, location);
     default:
-      break;
-  }
-
-  if (organization.features.includes('team-key-transactions')) {
-    return eventView.withTeams(['myteams']);
-  } else {
-    return eventView;
+      return eventView;
   }
 }
 
@@ -661,10 +652,5 @@ export function generatePerformanceVitalDetailView(
   eventView.additionalConditions
     .addTagValues('event.type', ['transaction'])
     .addTagValues('has', [vitalName]);
-
-  if (organization.features.includes('team-key-transactions')) {
-    return eventView.withTeams(['myteams']);
-  } else {
-    return eventView;
-  }
+  return eventView;
 }

+ 4 - 1
static/app/views/performance/landing/chart/durationChart.tsx

@@ -65,6 +65,8 @@ function DurationChart(props: Props) {
 
   const _backupField = backupField ? [backupField] : [];
 
+  const apiPayload = eventView.getEventsAPIPayload(location);
+
   return (
     <EventsRequest
       organization={organization}
@@ -72,6 +74,7 @@ function DurationChart(props: Props) {
       period={globalSelection.datetime.period}
       project={globalSelection.projects}
       environment={globalSelection.environments}
+      team={apiPayload.team}
       start={start}
       end={end}
       interval={getInterval(
@@ -83,7 +86,7 @@ function DurationChart(props: Props) {
         true
       )}
       showLoading={false}
-      query={eventView.getEventsAPIPayload(location).query}
+      query={apiPayload.query}
       includePrevious={false}
       yAxis={[field, ..._backupField]}
       partial

+ 3 - 1
static/app/views/performance/landing/vitalsCards.tsx

@@ -149,6 +149,7 @@ function _BackendCards(props: BackendCardsProps) {
   const end = globalSelection.datetime.end
     ? getUtcToLocalDateObject(globalSelection.datetime.end)
     : undefined;
+  const apiPayload = eventView.getEventsAPIPayload(location);
 
   return (
     <DiscoverQuery
@@ -165,6 +166,7 @@ function _BackendCards(props: BackendCardsProps) {
           period={globalSelection.datetime.period}
           project={globalSelection.projects}
           environment={globalSelection.environments}
+          team={apiPayload.team}
           start={start}
           end={end}
           interval={getInterval({
@@ -172,7 +174,7 @@ function _BackendCards(props: BackendCardsProps) {
             end: end || null,
             period: globalSelection.datetime.period,
           })}
-          query={eventView.getEventsAPIPayload(location).query}
+          query={apiPayload.query}
           includePrevious={false}
           yAxis={eventView.getFields()}
           partial

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