From c003cdac79473535a3a3cdd1117d6dccb5f5d3b1 Mon Sep 17 00:00:00 2001 From: TkDodo Date: Tue, 7 Apr 2026 15:37:13 +0200 Subject: [PATCH] ref(tsc): move releaseCommitFiles endpoint to apiOptions --- .../detail/commitsAndFiles/filesChanged.tsx | 22 +++++--- .../releases/drawer/filesChangedList.tsx | 24 ++++++--- .../utils/releaseCommitFilesApiOptions.tsx | 49 +++++++++++++++++ .../releases/utils/useReleaseCommitFiles.tsx | 53 ------------------- 4 files changed, 79 insertions(+), 69 deletions(-) create mode 100644 static/app/views/releases/utils/releaseCommitFilesApiOptions.tsx delete mode 100644 static/app/views/releases/utils/useReleaseCommitFiles.tsx diff --git a/static/app/views/releases/detail/commitsAndFiles/filesChanged.tsx b/static/app/views/releases/detail/commitsAndFiles/filesChanged.tsx index 7cafd7376c9dff..97c69d0ade75e5 100644 --- a/static/app/views/releases/detail/commitsAndFiles/filesChanged.tsx +++ b/static/app/views/releases/detail/commitsAndFiles/filesChanged.tsx @@ -1,4 +1,5 @@ import {Fragment, useContext} from 'react'; +import {useQuery} from '@tanstack/react-query'; import * as Layout from 'sentry/components/layouts/thirds'; import {LoadingError} from 'sentry/components/loadingError'; @@ -12,6 +13,7 @@ import {t, tn} from 'sentry/locale'; import type {Repository} from 'sentry/types/integrations'; import type {Organization} from 'sentry/types/organization'; import type {Project} from 'sentry/types/project'; +import {selectJsonWithHeaders} from 'sentry/utils/api/apiOptions'; import {routeTitleGen} from 'sentry/utils/routeTitle'; import {useLocation} from 'sentry/utils/useLocation'; import {useOrganization} from 'sentry/utils/useOrganization'; @@ -25,7 +27,7 @@ import { getQuery, getReposToRender, } from 'sentry/views/releases/detail/utils'; -import {useReleaseCommitFiles} from 'sentry/views/releases/utils/useReleaseCommitFiles'; +import {releaseCommitFilesApiOptions} from 'sentry/views/releases/utils/releaseCommitFilesApiOptions'; import {EmptyState, NoReleaseRepos, NoRepositories} from './emptyState'; import {FileChange} from './fileChange'; @@ -45,20 +47,24 @@ function FilesChangedList({organization, releaseRepos, projectSlug}: FilesChange const query = getQuery({location}); const { - data: fileList = [], + data, isPending: isLoadingFileList, error: fileListError, refetch, - getResponseHeader, - } = useReleaseCommitFiles({ - release: params.release, - activeRepository: activeReleaseRepo, - ...query, + } = useQuery({ + ...releaseCommitFilesApiOptions({ + organization, + release: params.release, + activeRepository: activeReleaseRepo, + ...query, + }), + select: selectJsonWithHeaders, }); + const fileList = data?.json ?? []; const filesByRepository = getFilesByRepository(fileList); const reposToRender = getReposToRender(Object.keys(filesByRepository)); - const fileListPageLinks = getResponseHeader?.('Link'); + const fileListPageLinks = data?.headers.Link; return ( diff --git a/static/app/views/releases/drawer/filesChangedList.tsx b/static/app/views/releases/drawer/filesChangedList.tsx index b9e23729ae3a18..7e06fcae95e29c 100644 --- a/static/app/views/releases/drawer/filesChangedList.tsx +++ b/static/app/views/releases/drawer/filesChangedList.tsx @@ -1,4 +1,5 @@ import {Fragment} from 'react'; +import {useQuery} from '@tanstack/react-query'; import {Container} from '@sentry/scraps/layout'; @@ -10,15 +11,17 @@ import {PanelHeader} from 'sentry/components/panels/panelHeader'; import {Placeholder} from 'sentry/components/placeholder'; import {t, tn} from 'sentry/locale'; import type {Repository} from 'sentry/types/integrations'; +import {selectJsonWithHeaders} from 'sentry/utils/api/apiOptions'; import {decodeScalar} from 'sentry/utils/queryString'; import {useLocationQuery} from 'sentry/utils/url/useLocationQuery'; import {useNavigate} from 'sentry/utils/useNavigate'; +import {useOrganization} from 'sentry/utils/useOrganization'; import {EmptyState} from 'sentry/views/releases/detail/commitsAndFiles/emptyState'; import {FileChange} from 'sentry/views/releases/detail/commitsAndFiles/fileChange'; import {RepositorySwitcher} from 'sentry/views/releases/detail/commitsAndFiles/repositorySwitcher'; import {getFilesByRepository, getReposToRender} from 'sentry/views/releases/detail/utils'; import {ReleasesDrawerFields} from 'sentry/views/releases/drawer/utils'; -import {useReleaseCommitFiles} from 'sentry/views/releases/utils/useReleaseCommitFiles'; +import {releaseCommitFilesApiOptions} from 'sentry/views/releases/utils/releaseCommitFilesApiOptions'; interface FilesChangedProps { release: string; @@ -27,6 +30,7 @@ interface FilesChangedProps { export function FilesChangedList({releaseRepos, release}: FilesChangedProps) { const navigate = useNavigate(); + const organization = useOrganization(); const { [ReleasesDrawerFields.ACTIVE_REPO]: rdActiveRepo, [ReleasesDrawerFields.FILES_CURSOR]: rdFilesCursor, @@ -40,20 +44,24 @@ export function FilesChangedList({releaseRepos, release}: FilesChangedProps) { releaseRepos.find(repo => repo.name === rdActiveRepo) ?? releaseRepos[0]; const { - data: fileList = [], + data, isPending: isLoadingFileList, error: fileListError, refetch, - getResponseHeader, - } = useReleaseCommitFiles({ - release, - activeRepository: activeReleaseRepo, - cursor: rdFilesCursor, + } = useQuery({ + ...releaseCommitFilesApiOptions({ + organization, + release, + activeRepository: activeReleaseRepo, + cursor: rdFilesCursor, + }), + select: selectJsonWithHeaders, }); + const fileList = data?.json ?? []; const filesByRepository = getFilesByRepository(fileList); const reposToRender = getReposToRender(Object.keys(filesByRepository)); - const fileListPageLinks = getResponseHeader?.('Link'); + const fileListPageLinks = data?.headers.Link; return (
diff --git a/static/app/views/releases/utils/releaseCommitFilesApiOptions.tsx b/static/app/views/releases/utils/releaseCommitFilesApiOptions.tsx new file mode 100644 index 00000000000000..662a1302a9fc53 --- /dev/null +++ b/static/app/views/releases/utils/releaseCommitFilesApiOptions.tsx @@ -0,0 +1,49 @@ +import type {CommitFile, Repository} from 'sentry/types/integrations'; +import type {Organization} from 'sentry/types/organization'; +import {apiOptions} from 'sentry/utils/api/apiOptions'; + +// These are the URL params that our project/date/env picker generates (+ cursor for pagination) +type PageFilterUrlParams = + | 'start' + | 'end' + | 'utc' + | 'statsPeriod' + | 'project' + | 'environment'; +type OtherUrlParams = 'cursor' | 'perPage'; + +interface Params extends Partial< + Record< + PageFilterUrlParams | OtherUrlParams, + string | string[] | number | null | undefined + > +> { + organization: Organization; + release: string; + activeRepository?: Repository; +} +export function releaseCommitFilesApiOptions({ + release, + organization, + activeRepository, + perPage = 40, + ...query +}: Params) { + return apiOptions.as()( + '/organizations/$organizationIdOrSlug/releases/$version/commitfiles/', + { + path: {organizationIdOrSlug: organization.slug, version: release}, + query: { + ...query, + per_page: perPage, + ...(activeRepository + ? { + repo_id: activeRepository.externalId, + repo_name: activeRepository.name, + } + : {}), + }, + staleTime: Infinity, + } + ); +} diff --git a/static/app/views/releases/utils/useReleaseCommitFiles.tsx b/static/app/views/releases/utils/useReleaseCommitFiles.tsx deleted file mode 100644 index 562f539c94c69a..00000000000000 --- a/static/app/views/releases/utils/useReleaseCommitFiles.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import type {CommitFile, Repository} from 'sentry/types/integrations'; -import {getApiUrl} from 'sentry/utils/api/getApiUrl'; -import {useApiQuery, type UseApiQueryOptions} from 'sentry/utils/queryClient'; -import {useOrganization} from 'sentry/utils/useOrganization'; - -// These are the URL params that our project/date/env picker generates (+ cursor for pagination) -type PageFilterUrlParams = - | 'start' - | 'end' - | 'utc' - | 'statsPeriod' - | 'project' - | 'environment'; -type OtherUrlParams = 'cursor' | 'perPage'; - -interface UseReleaseCommitFilesParams extends Partial< - Record< - PageFilterUrlParams | OtherUrlParams, - string | string[] | number | null | undefined - > -> { - release: string; - activeRepository?: Repository; -} -export function useReleaseCommitFiles( - {release, activeRepository, perPage = 40, ...query}: UseReleaseCommitFilesParams, - queryOptions?: UseApiQueryOptions -) { - const organization = useOrganization(); - return useApiQuery( - [ - getApiUrl('/organizations/$organizationIdOrSlug/releases/$version/commitfiles/', { - path: {organizationIdOrSlug: organization.slug, version: release}, - }), - { - query: { - ...query, - per_page: perPage, - ...(activeRepository - ? { - repo_id: activeRepository.externalId, - repo_name: activeRepository.name, - } - : {}), - }, - }, - ], - { - staleTime: Infinity, - ...queryOptions, - } - ); -}