2025-05-31 01:16:48 +08:00
import {
type QueryClient ,
type UseQueryOptions ,
useQuery ,
useQueryClient
} from '@tanstack/react-query' ;
import last from 'lodash/last' ;
2025-04-25 02:32:27 +08:00
import type {
BusterMetricData ,
IBusterMetric ,
IBusterMetricData
} from '@/api/asset_interfaces/metric' ;
2025-04-17 11:22:14 +08:00
import { metricsQueryKeys } from '@/api/query_keys/metric' ;
2025-05-31 01:16:48 +08:00
import { useBusterAssetsContextSelector } from '@/context/Assets/BusterAssetsProvider' ;
import { useOriginalMetricStore } from '@/context/Metrics/useOriginalMetricStore' ;
2025-04-17 11:22:14 +08:00
import { useMemoizedFn } from '@/hooks' ;
import { upgradeMetricToIMetric } from '@/lib/metrics' ;
2025-05-31 01:16:48 +08:00
import type { RustApiError } from '../errors' ;
import { useGetMetricVersionNumber , useMetricQueryStore } from './metricQueryStore' ;
import { getMetric , getMetricData } from './requests' ;
2025-04-17 11:22:14 +08:00
export const useGetMetric = < TData = IBusterMetric > (
{
id ,
versionNumber : versionNumberProp
} : {
id : string | undefined ;
versionNumber? : number | null ; //if null it will not use a params from the query params
} ,
params? : Omit < UseQueryOptions < IBusterMetric , RustApiError , TData > , 'queryKey' | 'queryFn' >
) = > {
const queryClient = useQueryClient ( ) ;
const setOriginalMetric = useOriginalMetricStore ( ( x ) = > x . setOriginalMetric ) ;
const getAssetPassword = useBusterAssetsContextSelector ( ( x ) = > x . getAssetPassword ) ;
2025-04-22 12:02:55 +08:00
const onSetLatestMetricVersion = useMetricQueryStore ( ( x ) = > x . onSetLatestMetricVersion ) ;
2025-04-17 11:22:14 +08:00
const setAssetPasswordError = useBusterAssetsContextSelector ( ( x ) = > x . setAssetPasswordError ) ;
2025-05-31 01:16:48 +08:00
const { password } = getAssetPassword ( id || '' ) ;
2025-04-17 11:22:14 +08:00
2025-04-17 12:40:10 +08:00
const { selectedVersionNumber , paramVersionNumber , latestVersionNumber } =
useGetMetricVersionNumber ( {
versionNumber : versionNumberProp
} ) ;
2025-04-17 11:22:14 +08:00
2025-05-31 01:16:48 +08:00
const initialOptions = metricsQueryKeys . metricsGetMetric ( id || '' , paramVersionNumber || null ) ;
2025-04-17 11:22:14 +08:00
2025-04-17 13:05:37 +08:00
const initialQueryFn = useMemoizedFn ( async ( version? : number | null ) = > {
2025-04-17 12:40:10 +08:00
const result = await getMetric ( {
2025-05-31 01:16:48 +08:00
id : id || '' ,
2025-04-17 12:40:10 +08:00
password ,
2025-04-17 13:05:37 +08:00
version_number : version === null ? undefined : version
2025-04-17 12:40:10 +08:00
} ) ;
const updatedMetric = upgradeMetricToIMetric ( result , null ) ;
2025-04-17 11:22:14 +08:00
const isLatestVersion =
updatedMetric . version_number === last ( updatedMetric . versions ) ? . version_number ;
2025-04-22 12:02:55 +08:00
if ( isLatestVersion ) {
setOriginalMetric ( updatedMetric ) ;
}
2025-05-31 01:16:48 +08:00
onSetLatestMetricVersion ( id || '' , last ( updatedMetric . versions ) ? . version_number || 0 ) ;
2025-04-18 01:39:30 +08:00
if ( result ? . version_number ) {
2025-04-17 11:22:14 +08:00
queryClient . setQueryData (
metricsQueryKeys . metricsGetMetric ( result . id , result . version_number ) . queryKey ,
updatedMetric
) ;
}
return updatedMetric ;
} ) ;
2025-04-17 12:40:10 +08:00
const { isFetched : isFetchedInitial , isError : isErrorInitial } = useQuery ( {
. . . initialOptions ,
queryFn : ( ) = > initialQueryFn ( paramVersionNumber ) ,
2025-04-17 11:22:14 +08:00
enabled : false , //In the year of our lord 2025, April 10, I, Nate Kelley, decided to disable this query in favor of explicityly fetching the data. May god have mercy on our souls.
2025-05-31 01:16:48 +08:00
retry ( _failureCount , error ) {
if ( error ? . message !== undefined && id ) {
setAssetPasswordError ( id , error . message || 'An error occurred' ) ;
2025-04-17 11:22:14 +08:00
}
return false ;
} ,
2025-04-17 12:40:10 +08:00
select : undefined ,
2025-04-17 11:22:14 +08:00
. . . params
} ) ;
2025-04-17 12:40:10 +08:00
return useQuery ( {
2025-05-31 01:16:48 +08:00
. . . metricsQueryKeys . metricsGetMetric ( id || '' , selectedVersionNumber ) ,
2025-04-17 13:05:37 +08:00
enabled : ! ! latestVersionNumber && isFetchedInitial && ! isErrorInitial ,
queryFn : ( ) = > initialQueryFn ( selectedVersionNumber ) ,
2025-04-17 12:40:10 +08:00
select : params?.select
} ) ;
2025-04-17 11:22:14 +08:00
} ;
export const usePrefetchGetMetricClient = ( ) = > {
const queryClient = useQueryClient ( ) ;
2025-04-17 12:40:10 +08:00
const { selectedVersionNumber } = useGetMetricVersionNumber ( ) ;
2025-04-17 11:22:14 +08:00
return useMemoizedFn (
async ( { id , versionNumber } : { id : string ; versionNumber : number | undefined } ) = > {
2025-04-22 04:10:57 +08:00
const options = metricsQueryKeys . metricsGetMetric ( id , versionNumber || selectedVersionNumber ) ;
2025-04-17 11:22:14 +08:00
const existingData = queryClient . getQueryData ( options . queryKey ) ;
if ( ! existingData ) {
await queryClient . prefetchQuery ( {
. . . options ,
queryFn : async ( ) = > {
const result = await getMetric ( { id , version_number : versionNumber } ) ;
return upgradeMetricToIMetric ( result , null ) ;
}
} ) ;
}
}
) ;
} ;
export const useGetMetricData = < TData = IBusterMetricData > (
{
id ,
versionNumber : versionNumberProp
} : {
id : string | undefined ;
versionNumber? : number ;
} ,
params? : Omit < UseQueryOptions < BusterMetricData , RustApiError , TData > , 'queryKey' | 'queryFn' >
) = > {
const getAssetPassword = useBusterAssetsContextSelector ( ( x ) = > x . getAssetPassword ) ;
2025-05-31 01:16:48 +08:00
const { password } = getAssetPassword ( id ) ;
2025-04-22 12:02:55 +08:00
const { selectedVersionNumber } = useGetMetricVersionNumber ( {
versionNumber : versionNumberProp
} ) ;
2025-04-17 11:22:14 +08:00
const {
isFetched : isFetchedMetric ,
isError : isErrorMetric ,
dataUpdatedAt ,
data : metric
} = useGetMetric (
2025-04-17 12:40:10 +08:00
{ id , versionNumber : selectedVersionNumber } ,
2025-04-17 11:22:14 +08:00
{ select : ( x ) = > ( { id : x.id , version_number : x.version_number } ) }
) ;
const queryFn = useMemoizedFn ( async ( ) = > {
const result = await getMetricData ( {
2025-05-31 01:16:48 +08:00
id : id || '' ,
2025-04-17 13:05:37 +08:00
version_number : selectedVersionNumber || undefined ,
2025-04-17 11:22:14 +08:00
password
} ) ;
return result ;
} ) ;
return useQuery ( {
2025-05-31 01:16:48 +08:00
. . . metricsQueryKeys . metricsGetData ( id || '' , selectedVersionNumber || 1 ) ,
2025-04-17 11:22:14 +08:00
queryFn ,
enabled : ( ) = > {
return (
! ! id &&
isFetchedMetric &&
! isErrorMetric &&
! ! metric ? . id &&
! ! dataUpdatedAt &&
2025-04-17 12:40:10 +08:00
! ! selectedVersionNumber
2025-04-17 11:22:14 +08:00
) ;
} ,
select : params?.select ,
. . . params
} ) ;
} ;
export const prefetchGetMetricDataClient = async (
2025-04-17 13:05:37 +08:00
{ id , version_number } : { id : string ; version_number : number } ,
2025-04-17 11:22:14 +08:00
queryClient : QueryClient
) = > {
const options = metricsQueryKeys . metricsGetData ( id , version_number ) ;
const existingData = queryClient . getQueryData ( options . queryKey ) ;
if ( ! existingData ) {
await queryClient . prefetchQuery ( {
. . . options ,
queryFn : ( ) = > getMetricData ( { id , version_number } )
} ) ;
}
} ;
export const usePrefetchGetMetricDataClient = ( ) = > {
const queryClient = useQueryClient ( ) ;
2025-04-17 13:05:37 +08:00
return useMemoizedFn ( ( { id , versionNumber } : { id : string ; versionNumber : number } ) = >
2025-04-17 11:22:14 +08:00
prefetchGetMetricDataClient ( { id , version_number : versionNumber } , queryClient )
) ;
} ;