From 872ed0061b5720e4ab22e3bea2b94a7db09d48ed Mon Sep 17 00:00:00 2001 From: Priscila Oliveira Date: Tue, 16 Sep 2025 08:14:56 +0200 Subject: [PATCH 1/2] fix: Pagination not working on Client Keys page --- .../project/projectKeys/list/index.spec.tsx | 48 +++++++++++++++++++ .../project/projectKeys/list/index.tsx | 17 +++++-- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/static/app/views/settings/project/projectKeys/list/index.spec.tsx b/static/app/views/settings/project/projectKeys/list/index.spec.tsx index 22bf1f110874f7..59507fe6c1d183 100644 --- a/static/app/views/settings/project/projectKeys/list/index.spec.tsx +++ b/static/app/views/settings/project/projectKeys/list/index.spec.tsx @@ -255,4 +255,52 @@ describe('ProjectKeys', () => { }) ); }); + + it('shows pagination when there are multiple pages', async () => { + const response = { + url: `/projects/${organization.slug}/${project.slug}/keys/`, + method: 'GET', + body: projectKeys, + headers: { + Link: + `; rel="next"; results="true"; cursor="2:0:0",` + + `; rel="previous"; results="false"; cursor="1:0:0"`, + }, + }; + + MockApiClient.addMockResponse({ + ...response, + match: [MockApiClient.matchQuery({cursor: undefined})], + }); + + const nextResponse = MockApiClient.addMockResponse({ + ...response, + match: [MockApiClient.matchQuery({cursor: '2:0:0'})], + }); + + const {router} = render(, { + initialRouterConfig, + }); + + const nextButton = await screen.findByRole('button', {name: 'Next'}); + expect(screen.getByRole('button', {name: 'Previous'})).toBeDisabled(); + + await userEvent.click(nextButton); + + await waitFor(() => { + expect(router.location.query.cursor).toBe('2:0:0'); + }); + + expect(nextResponse).toHaveBeenCalled(); + }); + + it('hides pagination when there is none', async () => { + render(, { + initialRouterConfig, + }); + + await screen.findByRole('heading', {name: 'Client Keys'}); + expect(screen.queryByRole('button', {name: 'Previous'})).not.toBeInTheDocument(); + expect(screen.queryByRole('button', {name: 'Next'})).not.toBeInTheDocument(); + }); }); diff --git a/static/app/views/settings/project/projectKeys/list/index.tsx b/static/app/views/settings/project/projectKeys/list/index.tsx index 487a60600eceab..b7f6cc0ad996c6 100644 --- a/static/app/views/settings/project/projectKeys/list/index.tsx +++ b/static/app/views/settings/project/projectKeys/list/index.tsx @@ -18,6 +18,7 @@ import {IconAdd, IconFlag} from 'sentry/icons'; import {t, tct} from 'sentry/locale'; import type {Project, ProjectKey} from 'sentry/types/project'; import {useApiQuery, useMutation} from 'sentry/utils/queryClient'; +import {decodeScalar} from 'sentry/utils/queryString'; import useApi from 'sentry/utils/useApi'; import {useLocation} from 'sentry/utils/useLocation'; import useOrganization from 'sentry/utils/useOrganization'; @@ -49,9 +50,19 @@ function ProjectKeys({project}: Props) { isError, refetch, getResponseHeader, - } = useApiQuery([`/projects/${organization.slug}/${projectId}/keys/`], { - staleTime: 0, - }); + } = useApiQuery( + [ + `/projects/${organization.slug}/${projectId}/keys/`, + { + query: { + cursor: decodeScalar(location.query.cursor), + }, + }, + ], + { + staleTime: 0, + } + ); /** * Optimistically remove key From 1f7a551523f22565a0d4cc4fa6701edd3dc59f97 Mon Sep 17 00:00:00 2001 From: Priscila Oliveira Date: Wed, 17 Sep 2025 13:42:49 +0200 Subject: [PATCH 2/2] feedback --- static/app/views/settings/project/projectKeys/list/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/static/app/views/settings/project/projectKeys/list/index.tsx b/static/app/views/settings/project/projectKeys/list/index.tsx index b7f6cc0ad996c6..99c72872908f17 100644 --- a/static/app/views/settings/project/projectKeys/list/index.tsx +++ b/static/app/views/settings/project/projectKeys/list/index.tsx @@ -56,6 +56,7 @@ function ProjectKeys({project}: Props) { { query: { cursor: decodeScalar(location.query.cursor), + per_page: 100, }, }, ],