first commit

This commit is contained in:
Zakaria
2026-09-22 16:13:21 -04:00
commit 7e49be27f1
297 changed files with 63162 additions and 0 deletions
@@ -0,0 +1,118 @@
import {useMemo} from 'react'
import {useQueries} from '@tanstack/react-query'
import {listCloudResources} from '@/api/cloudProxyClient'
import {
cloudQueryKeys,
useCloudServicesQuery,
useCloudStatusQuery,
useCloudsQuery,
} from '@/api/queries/cloudQueries'
import {serviceIcon} from '@/components/serviceIcons'
import {
resourceDetailFor,
runtimeClassFor,
runtimeDetailFor,
runtimeEndpointLabel,
runtimeLabelFor,
serviceMetaLabel,
} from './cloudConsoleHome.utils'
import type {CloudProvider} from '@/types/cloud'
import type {ConsoleServiceCard} from './types'
/**
* Console home is driven entirely by `GET /clouds/:cloud/services`.
*
* It previously hardcoded three resource queries, spliced in a Secrets Manager
* card for AWS with a hardcoded "available", and appended two permanent
* placeholder cards — so it could disagree with both the sidebar and the API.
*/
export function useCloudConsoleHomeData(cloud: CloudProvider) {
const cloudsQuery = useCloudsQuery()
const servicesQuery = useCloudServicesQuery(cloud)
const statusQuery = useCloudStatusQuery(cloud)
const status = statusQuery.data
const services = useMemo(() => servicesQuery.data ?? [], [servicesQuery.data])
// Availability is derived from adapter registration, so an available service
// always has the generic list endpoint. Route shape only decides where the
// card links, not whether it can be counted -- a legacy absolute-route page
// (AWS Secrets Manager) is still counted through its adapter.
const countable = useMemo(
() => services.filter((service) => service.availability === 'available'),
[services],
)
const runtimeReachable = status?.runtime === 'reachable'
const countQueries = useQueries({
queries: countable.map((service) => ({
queryKey: cloudQueryKeys.resources(cloud, service.service),
queryFn: ({signal}: {signal?: AbortSignal}) =>
listCloudResources(cloud, service.service, undefined, signal),
enabled: runtimeReachable,
staleTime: 30_000,
})),
})
const countsByService = useMemo(() => {
const map = new Map<string, {count?: number; isLoading: boolean; isError: boolean}>()
countable.forEach((service, index) => {
const query = countQueries[index]
map.set(service.service, {
count: query?.data?.length,
isLoading: query?.isLoading ?? false,
isError: query?.isError ?? false,
})
})
return map
}, [countable, countQueries])
const serviceCards = useMemo<ConsoleServiceCard[]>(
() =>
services.map((service): ConsoleServiceCard => {
const counts = countsByService.get(service.service)
const isLegacyPage = service.route.startsWith('/')
return {
id: service.service,
label: service.displayName,
status: service.availability,
count: counts?.count,
icon: serviceIcon(service.iconKey),
route:
service.availability === 'available'
? isLegacyPage
? service.route
: `/cloud-explorer/${cloud}/${service.route}`
: undefined,
meta:
service.availability === 'available'
? isLegacyPage
? 'open service'
: serviceMetaLabel(status, counts?.isLoading ?? false, 'resources')
: 'coming soon',
}
}),
[cloud, countsByService, services, status],
)
const resourcesLoading = countQueries.some((query) => query.isLoading)
const resourcesError = countQueries.some((query) => query.isError)
const resourceCount = countQueries.reduce((total, query) => total + (query.data?.length ?? 0), 0)
const activeServices = services.filter((service) => service.availability === 'available').length
return {
cloudsQuery,
status,
runtimeLabel: runtimeEndpointLabel(status),
runtimeState: runtimeLabelFor(status, statusQuery.isLoading),
runtimeClass: runtimeClassFor(status, statusQuery.isLoading),
runtimeDetail: status?.error ?? runtimeDetailFor(cloud, status),
activeServices,
// Counted rather than asserted: the old copy claimed a fixed service list.
activeServicesDetail: servicesQuery.isSuccess
? `${activeServices} of ${services.length} services available`
: 'Loading services',
resourceCount,
resourceDetail: resourceDetailFor(status, statusQuery.isLoading, resourcesLoading, resourcesError),
serviceCards,
}
}