import type {PageFilters} from 'sentry/types/core'; import EventView from 'sentry/utils/discover/eventView'; import type {Sort} from 'sentry/utils/discover/fields'; import {DiscoverDatasets} from 'sentry/utils/discover/types'; import type {MutableSearch} from 'sentry/utils/tokenizeSearch'; import usePageFilters from 'sentry/utils/usePageFilters'; import {useWrappedDiscoverQuery} from 'sentry/views/insights/common/queries/useSpansQuery'; import type { MetricsProperty, MetricsResponse, SpanIndexedField, SpanIndexedResponse, SpanMetricsProperty, SpanMetricsResponse, } from 'sentry/views/insights/types'; interface UseMetricsOptions { cursor?: string; enabled?: boolean; fields?: Fields; limit?: number; noPagination?: boolean; pageFilters?: PageFilters; search?: MutableSearch | string; // TODO - ideally this probably would be only `Mutable Search`, but it doesn't handle some situations well sorts?: Sort[]; } export const useSpansIndexed = ( options: UseMetricsOptions = {}, referrer: string ) => { return useDiscover( options, DiscoverDatasets.SPANS_INDEXED, referrer ); }; export const useSpanMetrics = ( options: UseMetricsOptions = {}, referrer: string ) => { return useDiscover( options, DiscoverDatasets.SPANS_METRICS, referrer ); }; export const useMetrics = ( options: UseMetricsOptions = {}, referrer: string ) => { return useDiscover( options, DiscoverDatasets.METRICS, referrer ); }; const useDiscover = [], ResponseType>( options: UseMetricsOptions = {}, dataset: DiscoverDatasets, referrer: string ) => { const { fields = [], search = undefined, sorts = [], limit, cursor, pageFilters: pageFiltersFromOptions, noPagination, } = options; const pageFilters = usePageFilters(); const eventView = getEventView( search, fields, sorts, pageFiltersFromOptions ?? pageFilters.selection, dataset ); const result = useWrappedDiscoverQuery({ eventView, initialData: [], limit, enabled: options.enabled, referrer, cursor, noPagination, }); // This type is a little awkward but it explicitly states that the response could be empty. This doesn't enable unchecked access errors, but it at least indicates that it's possible that there's no data // eslint-disable-next-line @typescript-eslint/ban-types const data = (result?.data ?? []) as Pick[]; return { ...result, data, isEnabled: options.enabled, }; }; function getEventView( search: MutableSearch | string | undefined, fields: string[] = [], sorts: Sort[] = [], pageFilters: PageFilters, dataset: DiscoverDatasets ) { const query = typeof search === 'string' ? search : search?.formatString() ?? ''; const eventView = EventView.fromNewQueryWithPageFilters( { name: '', query, fields, dataset, version: 2, }, pageFilters ); if (sorts.length > 0) { eventView.sorts = sorts; } return eventView; }