useMetricsMeta.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import type {PageFilters} from 'sentry/types';
  2. import {formatMRI, getUseCaseFromMRI} from 'sentry/utils/metrics/mri';
  3. import type {ApiQueryKey, UseApiQueryOptions} from 'sentry/utils/queryClient';
  4. import {useApiQuery} from 'sentry/utils/queryClient';
  5. import useOrganization from 'sentry/utils/useOrganization';
  6. import type {MetricMeta, MRI, UseCase} from '../../types/metrics';
  7. import {getMetaDateTimeParams} from './index';
  8. const EMPTY_ARRAY: MetricMeta[] = [];
  9. const DEFAULT_USE_CASES = ['sessions', 'transactions', 'custom', 'spans'];
  10. export function getMetricsMetaQueryKeys(
  11. orgSlug: string,
  12. projects: PageFilters['projects'],
  13. useCases?: UseCase[]
  14. ): ApiQueryKey[] {
  15. return (
  16. useCases?.map(useCase => getMetricsMetaQueryKey(orgSlug, {projects}, useCase)) ?? []
  17. );
  18. }
  19. export function getMetricsMetaQueryKey(
  20. orgSlug: string,
  21. {projects, datetime}: Partial<PageFilters>,
  22. useCase: UseCase
  23. ): ApiQueryKey {
  24. const queryParams = projects?.length
  25. ? {useCase, project: projects, ...getMetaDateTimeParams(datetime)}
  26. : {useCase, ...getMetaDateTimeParams(datetime)};
  27. return [`/organizations/${orgSlug}/metrics/meta/`, {query: queryParams}];
  28. }
  29. function useMetaUseCase(
  30. useCase: UseCase,
  31. pageFilters: Partial<PageFilters>,
  32. options: Omit<UseApiQueryOptions<MetricMeta[]>, 'staleTime'>
  33. ) {
  34. const {slug} = useOrganization();
  35. const apiQueryResult = useApiQuery<MetricMeta[]>(
  36. getMetricsMetaQueryKey(slug, pageFilters, useCase),
  37. {
  38. ...options,
  39. staleTime: 2000, // 2 seconds to cover page load
  40. }
  41. );
  42. return apiQueryResult;
  43. }
  44. export function useMetricsMeta(
  45. pageFilters: Partial<PageFilters>,
  46. useCases?: UseCase[],
  47. filterBlockedMetrics = true
  48. ): {data: MetricMeta[]; isLoading: boolean} {
  49. const enabledUseCases = useCases ?? DEFAULT_USE_CASES;
  50. const {data: sessionMeta = [], ...sessionsReq} = useMetaUseCase(
  51. 'sessions',
  52. pageFilters,
  53. {
  54. enabled: enabledUseCases.includes('sessions'),
  55. }
  56. );
  57. const {data: txnsMeta = [], ...txnsReq} = useMetaUseCase('transactions', pageFilters, {
  58. enabled: enabledUseCases.includes('transactions'),
  59. });
  60. const {data: customMeta = [], ...customReq} = useMetaUseCase('custom', pageFilters, {
  61. enabled: enabledUseCases.includes('custom'),
  62. });
  63. const {data: spansMeta = [], ...spansReq} = useMetaUseCase('spans', pageFilters, {
  64. enabled: enabledUseCases.includes('spans'),
  65. });
  66. const isLoading =
  67. (sessionsReq.isLoading && sessionsReq.fetchStatus !== 'idle') ||
  68. (txnsReq.isLoading && txnsReq.fetchStatus !== 'idle') ||
  69. (customReq.isLoading && customReq.fetchStatus !== 'idle') ||
  70. (spansReq.isLoading && spansReq.fetchStatus !== 'idle');
  71. const data = [
  72. ...(enabledUseCases.includes('sessions') ? sessionMeta : []),
  73. ...(enabledUseCases.includes('transactions') ? txnsMeta : []),
  74. ...(enabledUseCases.includes('custom') ? customMeta : []),
  75. ...(enabledUseCases.includes('spans') ? spansMeta : []),
  76. ].sort((a, b) => formatMRI(a.mri).localeCompare(formatMRI(b.mri)));
  77. if (!filterBlockedMetrics) {
  78. return {data, isLoading};
  79. }
  80. return {
  81. data: isLoading
  82. ? EMPTY_ARRAY
  83. : data.filter(meta => {
  84. return meta.blockingStatus?.every(({isBlocked}) => !isBlocked) ?? true;
  85. }),
  86. isLoading,
  87. };
  88. }
  89. export function useProjectMetric(mri: MRI, projectId: number) {
  90. const useCase = getUseCaseFromMRI(mri);
  91. const res = useMetricsMeta({projects: [projectId]}, [useCase ?? 'custom'], false);
  92. const metricMeta = res.data?.find(({mri: metaMri}) => metaMri === mri);
  93. const blockingStatus = metricMeta?.blockingStatus?.[0];
  94. return {...res, data: {...metricMeta, blockingStatus}};
  95. }