Files
supabase/apps/studio/hooks/misc/useUserProjectRegions.ts
T
Joshen Lim fe8b4df66d Chore/tiny refactor org limit (#51550)
## Context

Tiny refactor that I happened to pass by as I was reviewing other PRs

`useOrgProjectsInfiniteQuery` has a default `limit` value at 96 set in
the hook, 96 mainly for the home page to render a full row of cards
since cards are rendered in rows of 3

However, we have a couple of callsites for `useOrgProjectsInfiniteQuery`
that were passing a different `limit` value, hence these would be
triggered as a separate API request.

Am opting to remove the `limit` parameter from
`useOrgProjectsInfiniteQuery` so that the limit is standardized to 96
- So that data can be cached without having to invoke another API
request wherever `useOrgProjectsInfiniteQuery` is called
- I doubt that there'll be a need in a UI that will require calling
`useOrgProjectsInfiniteQuery` with a separate value for `limit` but
please do let me know otherwise if I might be overlooking anything!
2026-10-13 11:06:49 +08:00

67 lines
2.2 KiB
TypeScript

import { useQueries, type UseQueryResult } from '@tanstack/react-query'
import { useOrganizationsQuery } from '@/data/organizations/organizations-query'
import { projectKeys } from '@/data/projects/keys'
import {
getOrganizationProjects,
type OrgProjectsInfiniteData,
} from '@/data/projects/org-projects-infinite-query'
import { normalizeRegion, type UserRegionContext } from '@/lib/status-page/status-page.utils'
const PROJECTS_STALE_TIME_MS = 5 * 60 * 1000
const LOADING: UserProjectRegionsState = { status: 'loading' }
const FAIL_OPEN: UserProjectRegionsState = {
status: 'resolved',
context: { hasProjects: true, regions: new Set<string>(), isComplete: false },
}
export type UserProjectRegionsState =
| { status: 'loading' }
| { status: 'resolved'; context: UserRegionContext }
function combineOrgProjects(
results: Array<UseQueryResult<OrgProjectsInfiniteData>>
): UserProjectRegionsState {
if (results.some((r) => r.isPending)) return LOADING
const anyErrored = results.some((r) => r.isError)
const anyTruncated = results.some(
(r) => r.data !== undefined && r.data.pagination.count > r.data.projects.length
)
const projects = results.flatMap((r) => r.data?.projects ?? [])
const regions = new Set(
projects.flatMap((p) => p.databases.map((db) => normalizeRegion(db.region)))
)
return {
status: 'resolved',
context: {
hasProjects: projects.length > 0 || anyErrored,
regions,
isComplete: !anyErrored && !anyTruncated,
},
}
}
export function useUserProjectRegions({ enabled }: { enabled: boolean }): UserProjectRegionsState {
const { data: organizations, isError: isOrganizationsError } = useOrganizationsQuery({ enabled })
const projectsState = useQueries({
queries: (organizations ?? []).map((org) => ({
queryKey: projectKeys.bannerProjectsByOrg(org.slug),
queryFn: ({ signal }: { signal: AbortSignal }) =>
getOrganizationProjects({ slug: org.slug }, signal),
staleTime: PROJECTS_STALE_TIME_MS,
enabled,
})),
combine: combineOrgProjects,
})
if (!enabled) return LOADING
if (organizations === undefined) return isOrganizationsError ? FAIL_OPEN : LOADING
return projectsState
}