From 953b430259b8ec26215228b19193b3f1747abb9b Mon Sep 17 00:00:00 2001 From: nikkikapadia Date: Tue, 10 Dec 2024 16:42:18 -0500 Subject: [PATCH 1/3] add limit field to widget builder hook --- .../hooks/useWidgetBuilderState.spec.tsx | 25 ++++++++++++++ .../hooks/useWidgetBuilderState.tsx | 34 ++++++++++++++++--- .../widgetBuilder/widgetBuilder.tsx | 1 + 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.spec.tsx b/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.spec.tsx index 20ef2fe084e354..73c1c9646df23c 100644 --- a/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.spec.tsx +++ b/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.spec.tsx @@ -243,4 +243,29 @@ describe('useWidgetBuilderState', () => { expect(result.current.state.sort).toEqual([{field: 'testField', kind: 'asc'}]); }); }); + + describe('limit', () => { + it('can decode and update limit', () => { + mockedUsedLocation.mockReturnValue( + LocationFixture({ + query: { + limit: '4', + }, + }) + ); + + const {result} = renderHook(() => useWidgetBuilderState()); + + expect(result.current.state.limit).toEqual(4); + + act(() => { + result.current.dispatch({ + type: BuilderStateAction.SET_LIMIT, + payload: 10, + }); + }); + + expect(result.current.state.limit).toEqual(10); + }); + }); }); diff --git a/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.tsx b/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.tsx index a0aa5412c524a3..4926dd86dd61a0 100644 --- a/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.tsx +++ b/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.tsx @@ -6,9 +6,15 @@ import { generateFieldAsString, type Sort, } from 'sentry/utils/discover/fields'; -import {decodeList, decodeSorts} from 'sentry/utils/queryString'; +import { + decodeInteger, + decodeList, + decodeScalar, + decodeSorts, +} from 'sentry/utils/queryString'; import {DisplayType, WidgetType} from 'sentry/views/dashboards/types'; import {useQueryParamState} from 'sentry/views/dashboards/widgetBuilder/hooks/useQueryParamState'; +import {DEFAULT_RESULTS_LIMIT} from 'sentry/views/dashboards/widgetBuilder/utils'; export type WidgetBuilderStateQueryParams = { dataset?: WidgetType; @@ -30,6 +36,7 @@ export const BuilderStateAction = { SET_Y_AXIS: 'SET_Y_AXIS', SET_QUERY: 'SET_QUERY', SET_SORT: 'SET_SORT', + SET_LIMIT: 'SET_LIMIT', } as const; type WidgetAction = @@ -40,13 +47,15 @@ type WidgetAction = | {payload: Column[]; type: typeof BuilderStateAction.SET_FIELDS} | {payload: Column[]; type: typeof BuilderStateAction.SET_Y_AXIS} | {payload: string[]; type: typeof BuilderStateAction.SET_QUERY} - | {payload: Sort[]; type: typeof BuilderStateAction.SET_SORT}; + | {payload: Sort[]; type: typeof BuilderStateAction.SET_SORT} + | {payload: number; type: typeof BuilderStateAction.SET_LIMIT}; export interface WidgetBuilderState { dataset?: WidgetType; description?: string; displayType?: DisplayType; fields?: Column[]; + limit?: number; query?: string[]; sort?: Sort[]; title?: string; @@ -90,10 +99,15 @@ function useWidgetBuilderState(): { decoder: decodeSorts, serializer: serializeSorts, }); + const [limit, setLimit] = useQueryParamState({ + fieldName: 'limit', + decoder: decodeScalar, + deserializer: deserializeLimit, + }); const state = useMemo( - () => ({title, description, displayType, dataset, fields, yAxis, query, sort}), - [title, description, displayType, dataset, fields, yAxis, query, sort] + () => ({title, description, displayType, dataset, fields, yAxis, query, sort, limit}), + [title, description, displayType, dataset, fields, yAxis, query, sort, limit] ); const dispatch = useCallback( @@ -126,6 +140,9 @@ function useWidgetBuilderState(): { case BuilderStateAction.SET_SORT: setSort(action.payload); break; + case BuilderStateAction.SET_LIMIT: + setLimit(action.payload); + break; default: break; } @@ -139,6 +156,7 @@ function useWidgetBuilderState(): { setYAxis, setQuery, setSort, + setLimit, ] ); @@ -193,4 +211,12 @@ function serializeSorts(sorts: Sort[]): string[] { }); } +/** + * Decodes the limit from the query params + * Returns the default limit if the value is not a valid limit + */ +function deserializeLimit(value: string): number { + return decodeInteger(value, DEFAULT_RESULTS_LIMIT); +} + export default useWidgetBuilderState; diff --git a/static/app/views/dashboards/widgetBuilder/widgetBuilder.tsx b/static/app/views/dashboards/widgetBuilder/widgetBuilder.tsx index f9a20b234a3ea0..ce297ab1821824 100644 --- a/static/app/views/dashboards/widgetBuilder/widgetBuilder.tsx +++ b/static/app/views/dashboards/widgetBuilder/widgetBuilder.tsx @@ -760,6 +760,7 @@ function WidgetBuilder({ // The grouping was cleared, so clear the orderby newQuery.orderby = ''; } else if (!newQuery.orderby) { + // THIS ONE ############################# const orderOptions = generateOrderOptions({ widgetType: widgetType ?? defaultWidgetType, columns: query.columns, From 3e3a72d03fd935781fce50a9977e0fc3473e7aec Mon Sep 17 00:00:00 2001 From: nikkikapadia Date: Tue, 10 Dec 2024 16:57:20 -0500 Subject: [PATCH 2/3] ffs i left in a comment --- static/app/views/dashboards/widgetBuilder/widgetBuilder.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/static/app/views/dashboards/widgetBuilder/widgetBuilder.tsx b/static/app/views/dashboards/widgetBuilder/widgetBuilder.tsx index ce297ab1821824..f9a20b234a3ea0 100644 --- a/static/app/views/dashboards/widgetBuilder/widgetBuilder.tsx +++ b/static/app/views/dashboards/widgetBuilder/widgetBuilder.tsx @@ -760,7 +760,6 @@ function WidgetBuilder({ // The grouping was cleared, so clear the orderby newQuery.orderby = ''; } else if (!newQuery.orderby) { - // THIS ONE ############################# const orderOptions = generateOrderOptions({ widgetType: widgetType ?? defaultWidgetType, columns: query.columns, From 3751a752735d9f768c2fd2eeebc0654b0884a2bf Mon Sep 17 00:00:00 2001 From: nikkikapadia Date: Wed, 11 Dec 2024 10:21:49 -0500 Subject: [PATCH 3/3] add provider to limit test --- .../widgetBuilder/hooks/useWidgetBuilderState.spec.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.spec.tsx b/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.spec.tsx index 437233bfbe2e15..bae91b456810f3 100644 --- a/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.spec.tsx +++ b/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState.spec.tsx @@ -277,7 +277,9 @@ describe('useWidgetBuilderState', () => { }) ); - const {result} = renderHook(() => useWidgetBuilderState()); + const {result} = renderHook(() => useWidgetBuilderState(), { + wrapper: WidgetBuilderProvider, + }); expect(result.current.state.limit).toEqual(4);