Browse Source

feat(trends): Add most changed widget (#51692)

Replace "Most Regressed" and "Most Improved" widgets with a single "Most
Changed" widget. There's a single call going out to the trendsv2
endpoint where all changes are sorted by their net value.
Dameli Ushbayeva 1 year ago
parent
commit
83430bf9df

+ 8 - 5
static/app/views/performance/landing/views/allTransactionsView.tsx

@@ -14,11 +14,14 @@ export function AllTransactionsView(props: BasePerformanceViewProps) {
     props.organization.features.includes('performance-new-widget-designs') &&
     canUseMetricsData(props.organization);
 
-  const doubleChartRowCharts = [
-    PerformanceWidgetSetting.MOST_REGRESSED,
-    PerformanceWidgetSetting.MOST_RELATED_ISSUES,
-    PerformanceWidgetSetting.MOST_IMPROVED,
-  ];
+  const doubleChartRowCharts = [PerformanceWidgetSetting.MOST_RELATED_ISSUES];
+
+  if (props.organization.features.includes('performance-new-trends')) {
+    doubleChartRowCharts.unshift(PerformanceWidgetSetting.MOST_CHANGED);
+  } else {
+    doubleChartRowCharts.unshift(PerformanceWidgetSetting.MOST_REGRESSED);
+    doubleChartRowCharts.push(PerformanceWidgetSetting.MOST_IMPROVED);
+  }
 
   if (showSpanOperationsWidget) {
     doubleChartRowCharts.unshift(PerformanceWidgetSetting.SPAN_OPERATIONS);

+ 8 - 2
static/app/views/performance/landing/views/backendView.tsx

@@ -43,10 +43,16 @@ export function BackendView(props: BasePerformanceViewProps) {
   const doubleChartRowCharts = [
     PerformanceWidgetSetting.SLOW_HTTP_OPS,
     PerformanceWidgetSetting.SLOW_DB_OPS,
-    PerformanceWidgetSetting.MOST_IMPROVED,
-    PerformanceWidgetSetting.MOST_REGRESSED,
   ];
 
+  if (props.organization.features.includes('performance-new-trends')) {
+    doubleChartRowCharts.push(PerformanceWidgetSetting.MOST_CHANGED);
+  } else {
+    doubleChartRowCharts.push(
+      ...[PerformanceWidgetSetting.MOST_REGRESSED, PerformanceWidgetSetting.MOST_IMPROVED]
+    );
+  }
+
   if (showSpanOperationsWidget) {
     doubleChartRowCharts.unshift(PerformanceWidgetSetting.SPAN_OPERATIONS);
   }

+ 14 - 9
static/app/views/performance/landing/views/mobileView.tsx

@@ -23,6 +23,12 @@ export function MobileView(props: BasePerformanceViewProps) {
     PerformanceWidgetSetting.SLOW_FRAMES_AREA,
     PerformanceWidgetSetting.FROZEN_FRAMES_AREA,
   ];
+
+  const doubleRowAllowedCharts = [
+    PerformanceWidgetSetting.MOST_SLOW_FRAMES,
+    PerformanceWidgetSetting.MOST_FROZEN_FRAMES,
+  ];
+
   if (organization.features.includes('mobile-vitals')) {
     columnTitles = [...columnTitles.slice(0, 5), 'ttid', ...columnTitles.slice(5, 0)];
     allowedCharts.push(
@@ -32,18 +38,17 @@ export function MobileView(props: BasePerformanceViewProps) {
       ]
     );
   }
+  if (organization.features.includes('performance-new-trends')) {
+    doubleRowAllowedCharts.push(PerformanceWidgetSetting.MOST_CHANGED);
+  } else {
+    doubleRowAllowedCharts.push(
+      ...[PerformanceWidgetSetting.MOST_IMPROVED, PerformanceWidgetSetting.MOST_REGRESSED]
+    );
+  }
   return (
     <PerformanceDisplayProvider value={{performanceType: ProjectPerformanceType.ANY}}>
       <div>
-        <DoubleChartRow
-          {...props}
-          allowedCharts={[
-            PerformanceWidgetSetting.MOST_SLOW_FRAMES,
-            PerformanceWidgetSetting.MOST_FROZEN_FRAMES,
-            PerformanceWidgetSetting.MOST_IMPROVED,
-            PerformanceWidgetSetting.MOST_REGRESSED,
-          ]}
-        />
+        <DoubleChartRow {...props} allowedCharts={doubleRowAllowedCharts} />
         <TripleChartRow {...props} allowedCharts={allowedCharts} />
         <Table
           {...props}

+ 10 - 0
static/app/views/performance/landing/widgets/widgetDefinitions.tsx

@@ -41,6 +41,7 @@ export enum PerformanceWidgetSetting {
   WORST_FCP_VITALS = 'worst_fcp_vitals',
   WORST_CLS_VITALS = 'worst_cls_vitals',
   WORST_FID_VITALS = 'worst_fid_vitals',
+  MOST_CHANGED = 'most_changed',
   MOST_IMPROVED = 'most_improved',
   MOST_REGRESSED = 'most_regressed',
   MOST_RELATED_ERRORS = 'most_related_errors',
@@ -332,6 +333,15 @@ export const WIDGET_DEFINITIONS: ({
     fields: [],
     dataType: GenericPerformanceWidgetDataType.TRENDS,
   },
+  [PerformanceWidgetSetting.MOST_CHANGED]: {
+    title: t('Most Changed'),
+    titleTooltip: t(
+      'This compares the baseline (%s) of the past with the present.',
+      'changed'
+    ),
+    fields: [],
+    dataType: GenericPerformanceWidgetDataType.TRENDS,
+  },
   [PerformanceWidgetSetting.SPAN_OPERATIONS]: {
     title: t('Span Operations Breakdown'),
     titleTooltip: '',

+ 8 - 5
static/app/views/performance/landing/widgets/widgets/trendsWidget.tsx

@@ -61,6 +61,9 @@ export function TrendsWidget(props: PerformanceWidgetProps) {
     props.chartSetting === PerformanceWidgetSetting.MOST_IMPROVED
       ? TrendChangeType.IMPROVED
       : TrendChangeType.REGRESSION;
+  const derivedTrendChangeType = organization.features.includes('performance-new-trends')
+    ? TrendChangeType.ANY
+    : trendChangeType;
   const trendFunctionField = TrendFunctionField.AVG; // Average is the easiest chart to understand.
 
   const [selectedListIndex, setSelectListIndex] = useState<number>(0);
@@ -74,7 +77,7 @@ export function TrendsWidget(props: PerformanceWidgetProps) {
   eventView.fields = fields;
   eventView.sorts = [
     {
-      kind: trendChangeType === TrendChangeType.IMPROVED ? 'asc' : 'desc',
+      kind: derivedTrendChangeType === TrendChangeType.IMPROVED ? 'asc' : 'desc',
       field: 'trend_percentage()',
     },
   ];
@@ -96,7 +99,7 @@ export function TrendsWidget(props: PerformanceWidgetProps) {
           {...provided}
           eventView={provided.eventView}
           location={location}
-          trendChangeType={trendChangeType}
+          trendChangeType={derivedTrendChangeType}
           trendFunctionField={trendFunctionField}
           limit={3}
           cursor="0:0:1"
@@ -107,7 +110,7 @@ export function TrendsWidget(props: PerformanceWidgetProps) {
       transform: transformTrendsDiscover,
     }),
     // eslint-disable-next-line react-hooks/exhaustive-deps
-    [props.chartSetting, trendChangeType]
+    [props.chartSetting, derivedTrendChangeType]
   );
 
   const assembleAccordionItems = provided =>
@@ -128,7 +131,7 @@ export function TrendsWidget(props: PerformanceWidgetProps) {
           end={eventView.end}
           statsPeriod={eventView.statsPeriod}
           transaction={provided.widgetData.chart.transactionsList[selectedListIndex]}
-          trendChangeType={trendChangeType}
+          trendChangeType={derivedTrendChangeType}
           trendFunctionField={trendFunctionField}
           disableXAxis
           disableLegend
@@ -229,7 +232,7 @@ export function TrendsWidget(props: PerformanceWidgetProps) {
               end={eventView.end}
               statsPeriod={eventView.statsPeriod}
               transaction={provided.widgetData.chart.transactionsList[selectedListIndex]}
-              trendChangeType={trendChangeType}
+              trendChangeType={derivedTrendChangeType}
               trendFunctionField={trendFunctionField}
               disableXAxis
               disableLegend

+ 5 - 1
static/app/views/performance/trends/chart.tsx

@@ -101,6 +101,7 @@ export function Chart({
   height,
   projects,
   project,
+  organization,
 }: Props) {
   const location = useLocation();
   const router = useRouter();
@@ -124,7 +125,10 @@ export function Chart({
     browserHistory.push(to);
   };
 
-  const lineColor = trendToColor[trendChangeType || ''];
+  const derivedTrendChangeType = organization.features.includes('performance-new-trends')
+    ? transaction?.change
+    : trendChangeType;
+  const lineColor = trendToColor[derivedTrendChangeType || trendChangeType];
 
   const events =
     statsData && transaction?.project && transaction?.transaction

+ 3 - 0
static/app/views/performance/trends/types.tsx

@@ -88,6 +88,9 @@ export type TrendsTransaction = {
   trend_difference: number;
   trend_percentage: number;
   breakpoint?: number;
+  // TODO change type to TrendsChangeType
+  // once backend sends it
+  change?: string;
   count_percentage?: number;
   count_range_1?: number;
   count_range_2?: number;

+ 10 - 0
static/app/views/performance/trends/utils.tsx

@@ -115,6 +115,12 @@ export const trendToColor = {
     lighter: theme.red200,
     default: theme.red300,
   },
+  // TODO remove this once backend starts sending
+  // TrendChangeType.IMPROVED as change type
+  improvement: {
+    lighter: theme.green200,
+    default: theme.green300,
+  },
 };
 
 export const trendSelectedQueryKeys = {
@@ -270,6 +276,10 @@ export function modifyTrendView(
     if (query.hasFilter('transaction.duration')) {
       query.removeFilter('transaction.duration');
     }
+
+    if (trendParameter.column && query.hasFilter(trendParameter.column)) {
+      query.removeFilter(trendParameter.column);
+    }
     trendView.query = query.formatString();
   }