useBlockMetric.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
  2. import {t} from 'sentry/locale';
  3. import type {MetricMeta, MRI} from 'sentry/types/metrics';
  4. import type {Project} from 'sentry/types/project';
  5. import {useMutation, useQueryClient} from 'sentry/utils/queryClient';
  6. import useApi from 'sentry/utils/useApi';
  7. import useOrganization from 'sentry/utils/useOrganization';
  8. import {getMetricsMetaQueryKey} from './useMetricsMeta';
  9. type BlockMetricResponse = [MetricMeta[], unknown, unknown] | undefined;
  10. interface MetricMetricMutationData {
  11. mri: MRI;
  12. operationType: 'blockMetric' | 'unblockMetric';
  13. }
  14. interface MetricTagsMutationData {
  15. mri: MRI;
  16. operationType: 'blockTags' | 'unblockTags';
  17. tags: string[];
  18. }
  19. type BlockMutationData = MetricMetricMutationData | MetricTagsMutationData;
  20. function isTagOp(opts: BlockMutationData): opts is MetricTagsMutationData {
  21. return 'tags' in opts;
  22. }
  23. export const useBlockMetric = (project: Project) => {
  24. const api = useApi();
  25. const {slug} = useOrganization();
  26. const queryClient = useQueryClient();
  27. const options = {
  28. mutationFn: (data: BlockMutationData) => {
  29. return api.requestPromise(`/projects/${slug}/${project.slug}/metrics/visibility/`, {
  30. method: 'PUT',
  31. query: {project: project.id},
  32. data: {
  33. metricMri: data.mri,
  34. project: project.id,
  35. operationType: data.operationType,
  36. tags: isTagOp(data) ? data.tags : undefined,
  37. },
  38. });
  39. },
  40. onSuccess: data => {
  41. const metaQueryKey = getMetricsMetaQueryKey(slug, {});
  42. // Only match the endpoint, to search in all insances of the query
  43. const queryKeyFilter = {queryKey: [metaQueryKey[0]]};
  44. queryClient.setQueriesData(
  45. queryKeyFilter,
  46. (oldData: BlockMetricResponse): BlockMetricResponse => {
  47. if (!oldData) {
  48. return undefined;
  49. }
  50. const oldMeta = oldData[0];
  51. const index = oldMeta.findIndex(
  52. metric =>
  53. metric.mri === data.metricMri &&
  54. metric.projectIds.includes(Number(project.id))
  55. );
  56. if (index !== undefined && index !== -1) {
  57. const newMeta = [...oldMeta];
  58. newMeta[index] = {
  59. ...newMeta[index],
  60. blockingStatus: [{...data, project: project.id}],
  61. };
  62. return [newMeta, oldData[1], oldData[2]];
  63. }
  64. return oldData;
  65. }
  66. );
  67. addSuccessMessage(t('Metric updated'));
  68. queryClient.invalidateQueries(queryKeyFilter);
  69. },
  70. onError: () => {
  71. addErrorMessage(t('An error occurred while updating the metric'));
  72. },
  73. };
  74. return useMutation(options);
  75. };