customMeasurementsProvider.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import {useEffect, useState} from 'react';
  2. import {Query} from 'history';
  3. import {addErrorMessage} from 'sentry/actionCreators/indicator';
  4. import {Client} from 'sentry/api';
  5. import {getFieldTypeFromUnit} from 'sentry/components/events/eventCustomPerformanceMetrics';
  6. import {normalizeDateTimeParams} from 'sentry/components/organizations/pageFilters/parse';
  7. import {t} from 'sentry/locale';
  8. import {Organization, PageFilters} from 'sentry/types';
  9. import {CustomMeasurementCollection} from 'sentry/utils/customMeasurements/customMeasurements';
  10. import {handleXhrErrorResponse} from 'sentry/utils/handleXhrErrorResponse';
  11. import RequestError from 'sentry/utils/requestError/requestError';
  12. import useApi from 'sentry/utils/useApi';
  13. import {
  14. CustomMeasurementsContext,
  15. CustomMeasurementsContextValue,
  16. } from './customMeasurementsContext';
  17. type MeasurementsMetaResponse = {
  18. [x: string]: {functions: string[]; unit: string};
  19. };
  20. function fetchCustomMeasurements(
  21. api: Client,
  22. organization: Organization,
  23. selection?: PageFilters
  24. ): Promise<MeasurementsMetaResponse> {
  25. const query: Query = selection?.datetime
  26. ? {...normalizeDateTimeParams(selection.datetime)}
  27. : {};
  28. if (selection?.projects) {
  29. query.project = selection.projects.map(String);
  30. }
  31. return api.requestPromise(`/organizations/${organization.slug}/measurements-meta/`, {
  32. method: 'GET',
  33. query,
  34. });
  35. }
  36. type CustomMeasurementsProviderProps = {
  37. children:
  38. | React.ReactNode
  39. | ((props: CustomMeasurementsContextValue) => React.ReactNode);
  40. organization: Organization;
  41. selection?: PageFilters;
  42. };
  43. export function CustomMeasurementsProvider({
  44. children,
  45. organization,
  46. selection,
  47. }: CustomMeasurementsProviderProps) {
  48. const api = useApi();
  49. const [state, setState] = useState({customMeasurements: {}});
  50. useEffect(() => {
  51. let shouldCancelRequest = false;
  52. if (
  53. organization.features.includes('dashboards-mep') ||
  54. organization.features.includes('mep-rollout-flag')
  55. ) {
  56. fetchCustomMeasurements(api, organization, selection)
  57. .then(response => {
  58. if (shouldCancelRequest) {
  59. return;
  60. }
  61. const newCustomMeasurements = Object.keys(
  62. response
  63. ).reduce<CustomMeasurementCollection>((acc, customMeasurement) => {
  64. acc[customMeasurement] = {
  65. key: customMeasurement,
  66. name: customMeasurement,
  67. functions: response[customMeasurement].functions,
  68. unit: response[customMeasurement].unit,
  69. fieldType: getFieldTypeFromUnit(response[customMeasurement].unit),
  70. };
  71. return acc;
  72. }, {});
  73. setState({customMeasurements: newCustomMeasurements});
  74. })
  75. .catch((e: RequestError) => {
  76. if (shouldCancelRequest) {
  77. return;
  78. }
  79. const errorResponse = t('Unable to fetch custom performance metrics');
  80. addErrorMessage(errorResponse);
  81. handleXhrErrorResponse(errorResponse, e);
  82. });
  83. }
  84. return () => {
  85. shouldCancelRequest = true;
  86. };
  87. }, [selection, api, organization]);
  88. return (
  89. <CustomMeasurementsContext.Provider value={state}>
  90. {typeof children === 'function' ? children(state) : children}
  91. </CustomMeasurementsContext.Provider>
  92. );
  93. }