useMetricsMeta.tsx 3.3 KB

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