useBlockMetric.tsx 2.6 KB

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