Просмотр исходного кода

feat(widget-builder): Add `legendAlias` to widget builder state object (#82544)

Added `legendAlias` as a state object. Also handles the conversion to
and from `Widget` type. Legend aliases are only available on chart
widgets.
Nikki Kapadia 2 месяцев назад
Родитель
Сommit
39c845f6f4

+ 27 - 0
static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.spec.tsx

@@ -680,4 +680,31 @@ describe('useWidgetBuilderState', () => {
       expect(result.current.state.limit).toEqual(10);
     });
   });
+
+  describe('legendAlias', () => {
+    it('can decode and update legendAlias', () => {
+      mockedUsedLocation.mockReturnValue(
+        LocationFixture({
+          query: {
+            legendAlias: ['test', 'test2'],
+          },
+        })
+      );
+
+      const {result} = renderHook(() => useWidgetBuilderState(), {
+        wrapper: WidgetBuilderProvider,
+      });
+
+      expect(result.current.state.legendAlias).toEqual(['test', 'test2']);
+
+      act(() => {
+        result.current.dispatch({
+          type: BuilderStateAction.SET_LEGEND_ALIAS,
+          payload: ['test3', 'test4'],
+        });
+      });
+
+      expect(result.current.state.legendAlias).toEqual(['test3', 'test4']);
+    });
+  });
 });

+ 39 - 3
static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.tsx

@@ -25,6 +25,7 @@ export type WidgetBuilderStateQueryParams = {
   description?: string;
   displayType?: DisplayType;
   field?: (string | undefined)[];
+  legendAlias?: string[];
   limit?: number;
   query?: string[];
   sort?: string[];
@@ -42,6 +43,7 @@ export const BuilderStateAction = {
   SET_QUERY: 'SET_QUERY',
   SET_SORT: 'SET_SORT',
   SET_LIMIT: 'SET_LIMIT',
+  SET_LEGEND_ALIAS: 'SET_LEGEND_ALIAS',
 } as const;
 
 type WidgetAction =
@@ -53,13 +55,15 @@ type WidgetAction =
   | {payload: Column[]; type: typeof BuilderStateAction.SET_Y_AXIS}
   | {payload: string[]; type: typeof BuilderStateAction.SET_QUERY}
   | {payload: Sort[]; type: typeof BuilderStateAction.SET_SORT}
-  | {payload: number; type: typeof BuilderStateAction.SET_LIMIT};
+  | {payload: number; type: typeof BuilderStateAction.SET_LIMIT}
+  | {payload: string[]; type: typeof BuilderStateAction.SET_LEGEND_ALIAS};
 
 export interface WidgetBuilderState {
   dataset?: WidgetType;
   description?: string;
   displayType?: DisplayType;
   fields?: Column[];
+  legendAlias?: string[];
   limit?: number;
   query?: string[];
   sort?: Sort[];
@@ -109,10 +113,36 @@ function useWidgetBuilderState(): {
     decoder: decodeScalar,
     deserializer: deserializeLimit,
   });
+  const [legendAlias, setLegendAlias] = useQueryParamState<string[]>({
+    fieldName: 'legendAlias',
+    decoder: decodeList,
+  });
 
   const state = useMemo(
-    () => ({title, description, displayType, dataset, fields, yAxis, query, sort, limit}),
-    [title, description, displayType, dataset, fields, yAxis, query, sort, limit]
+    () => ({
+      title,
+      description,
+      displayType,
+      dataset,
+      fields,
+      yAxis,
+      query,
+      sort,
+      limit,
+      legendAlias,
+    }),
+    [
+      title,
+      description,
+      displayType,
+      dataset,
+      fields,
+      yAxis,
+      query,
+      sort,
+      limit,
+      legendAlias,
+    ]
   );
 
   const dispatch = useCallback(
@@ -128,6 +158,7 @@ function useWidgetBuilderState(): {
           setDisplayType(action.payload);
           if (action.payload === DisplayType.BIG_NUMBER) {
             setSort([]);
+            setLegendAlias([]);
           }
           const [aggregates, columns] = partition(fields, field => {
             const fieldString = generateFieldAsString(field);
@@ -136,6 +167,7 @@ function useWidgetBuilderState(): {
           if (action.payload === DisplayType.TABLE) {
             setYAxis([]);
             setFields([...columns, ...aggregates, ...(yAxis ?? [])]);
+            setLegendAlias([]);
           } else {
             setFields(columns);
             setYAxis([
@@ -185,6 +217,9 @@ function useWidgetBuilderState(): {
         case BuilderStateAction.SET_LIMIT:
           setLimit(action.payload);
           break;
+        case BuilderStateAction.SET_LEGEND_ALIAS:
+          setLegendAlias(action.payload);
+          break;
         default:
           break;
       }
@@ -199,6 +234,7 @@ function useWidgetBuilderState(): {
       setQuery,
       setSort,
       setLimit,
+      setLegendAlias,
       fields,
       yAxis,
       displayType,

+ 14 - 0
static/app/views/dashboards/widgetBuilder/utils/convertBuilderStateToWidget.spec.tsx

@@ -85,4 +85,18 @@ describe('convertBuilderStateToWidget', function () {
 
     expect(widget.queries[0].fieldAliases).toEqual(['test', '', 'another one']);
   });
+
+  it('adds legend aliases to the widget queries', function () {
+    const mockState: WidgetBuilderState = {
+      legendAlias: ['test', 'test2'],
+      query: ['transaction.duration:>100', 'transaction.duration:>50'],
+    };
+
+    const widget = convertBuilderStateToWidget(mockState);
+
+    expect(widget.queries[0].name).toEqual('test');
+    expect(widget.queries[0].conditions).toEqual('transaction.duration:>100');
+    expect(widget.queries[1].name).toEqual('test2');
+    expect(widget.queries[1].conditions).toEqual('transaction.duration:>50');
+  });
 });

+ 4 - 1
static/app/views/dashboards/widgetBuilder/utils/convertBuilderStateToWidget.ts

@@ -16,6 +16,8 @@ export function convertBuilderStateToWidget(state: WidgetBuilderState): Widget {
   const defaultQuery = datasetConfig.defaultWidgetQuery;
 
   const queries = defined(state.query) && state.query.length > 0 ? state.query : [''];
+  const legendAlias =
+    defined(state.legendAlias) && state.legendAlias.length > 0 ? state.legendAlias : [];
 
   const fields = state.fields?.map(generateFieldAsString);
   const fieldAliases = state.fields?.map(field => field.alias ?? '');
@@ -40,7 +42,7 @@ export function convertBuilderStateToWidget(state: WidgetBuilderState): Widget {
       ? _formatSort(state.sort[0])
       : defaultSort;
 
-  const widgetQueries: WidgetQuery[] = queries.map(query => {
+  const widgetQueries: WidgetQuery[] = queries.map((query, index) => {
     return {
       ...defaultQuery,
       fields,
@@ -49,6 +51,7 @@ export function convertBuilderStateToWidget(state: WidgetBuilderState): Widget {
       conditions: query,
       orderby: sort,
       fieldAliases: fieldAliases ?? [],
+      name: legendAlias[index] ?? '',
     };
   });
 

+ 26 - 1
static/app/views/dashboards/widgetBuilder/utils/convertWidgetToBuilderStateParams.spec.tsx

@@ -1,4 +1,4 @@
-import {WidgetType} from 'sentry/views/dashboards/types';
+import {DisplayType, WidgetType} from 'sentry/views/dashboards/types';
 import {convertWidgetToBuilderStateParams} from 'sentry/views/dashboards/widgetBuilder/utils/convertWidgetToBuilderStateParams';
 import {getDefaultWidget} from 'sentry/views/dashboards/widgetBuilder/utils/getDefaultWidget';
 
@@ -28,4 +28,29 @@ describe('convertWidgetToBuilderStateParams', () => {
     const params = convertWidgetToBuilderStateParams(widget);
     expect(params.field).toEqual(['{"field":"geo.country","alias":"test"}']);
   });
+
+  it('adds legend aliases to the builder params on charts', () => {
+    const widget = {
+      ...getDefaultWidget(WidgetType.ERRORS),
+      displayType: DisplayType.AREA,
+      queries: [
+        {
+          aggregates: [],
+          columns: [],
+          conditions: 'transaction.duration:>100',
+          orderby: '',
+          name: 'test',
+        },
+        {
+          aggregates: [],
+          columns: [],
+          conditions: 'transaction.duration:>50',
+          orderby: '',
+          name: 'test2',
+        },
+      ],
+    };
+    const params = convertWidgetToBuilderStateParams(widget);
+    expect(params.legendAlias).toEqual(['test', 'test2']);
+  });
 });

+ 3 - 0
static/app/views/dashboards/widgetBuilder/utils/convertWidgetToBuilderStateParams.ts

@@ -30,6 +30,7 @@ export function convertWidgetToBuilderStateParams(
   let yAxis = widget.queries.flatMap(q => q.aggregates);
   const query = widget.queries.flatMap(q => q.conditions);
   const sort = widget.queries.flatMap(q => q.orderby);
+  let legendAlias = widget.queries.flatMap(q => q.name);
 
   let field: string[] = [];
   if (
@@ -38,6 +39,7 @@ export function convertWidgetToBuilderStateParams(
   ) {
     field = widget.queries.flatMap(widgetQuery => stringifyFields(widgetQuery, 'fields'));
     yAxis = [];
+    legendAlias = [];
   } else {
     field = widget.queries.flatMap(widgetQuery =>
       stringifyFields(widgetQuery, 'columns')
@@ -54,5 +56,6 @@ export function convertWidgetToBuilderStateParams(
     yAxis,
     query,
     sort,
+    legendAlias,
   };
 }