metricsExtractionRuleEditModal.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import {Fragment, useCallback, useMemo} from 'react';
  2. import {css} from '@emotion/react';
  3. import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
  4. import type {ModalRenderProps} from 'sentry/actionCreators/modal';
  5. import {t} from 'sentry/locale';
  6. import type {MetricsExtractionRule} from 'sentry/types/metrics';
  7. import type {Project} from 'sentry/types/project';
  8. import useOrganization from 'sentry/utils/useOrganization';
  9. import {
  10. aggregatesToGroups,
  11. createCondition as createExtractionCondition,
  12. explodeAggregateGroup,
  13. type FormData,
  14. MetricsExtractionRuleForm,
  15. } from 'sentry/views/settings/projectMetrics/metricsExtractionRuleForm';
  16. import {useUpdateMetricsExtractionRules} from 'sentry/views/settings/projectMetrics/utils/api';
  17. interface Props extends ModalRenderProps {
  18. metricExtractionRule: MetricsExtractionRule;
  19. project: Project;
  20. }
  21. export function MetricsExtractionRuleEditModal({
  22. Header,
  23. Body,
  24. closeModal,
  25. CloseButton,
  26. metricExtractionRule,
  27. project,
  28. }: Props) {
  29. const organization = useOrganization();
  30. const updateExtractionRuleMutation = useUpdateMetricsExtractionRules(
  31. organization.slug,
  32. project.slug
  33. );
  34. const initialData: FormData = useMemo(() => {
  35. return {
  36. spanAttribute: metricExtractionRule.spanAttribute,
  37. aggregates: aggregatesToGroups(metricExtractionRule.aggregates),
  38. tags: metricExtractionRule.tags,
  39. conditions: metricExtractionRule.conditions.length
  40. ? metricExtractionRule.conditions
  41. : [createExtractionCondition()],
  42. };
  43. }, [metricExtractionRule]);
  44. const handleSubmit = useCallback(
  45. (
  46. data: FormData,
  47. onSubmitSuccess: (data: FormData) => void,
  48. onSubmitError: (error: any) => void
  49. ) => {
  50. const extractionRule: MetricsExtractionRule = {
  51. spanAttribute: data.spanAttribute!,
  52. tags: data.tags,
  53. aggregates: data.aggregates.flatMap(explodeAggregateGroup),
  54. unit: 'none',
  55. conditions: data.conditions,
  56. };
  57. updateExtractionRuleMutation.mutate(
  58. {
  59. metricsExtractionRules: [extractionRule],
  60. },
  61. {
  62. onSuccess: () => {
  63. onSubmitSuccess(data);
  64. addSuccessMessage(t('Metric extraction rule updated'));
  65. closeModal();
  66. },
  67. onError: error => {
  68. const message = error?.responseJSON?.detail
  69. ? (error.responseJSON.detail as string)
  70. : t('Unable to save your changes.');
  71. onSubmitError(message);
  72. addErrorMessage(message);
  73. },
  74. }
  75. );
  76. onSubmitSuccess(data);
  77. },
  78. [closeModal, updateExtractionRuleMutation]
  79. );
  80. return (
  81. <Fragment>
  82. <Header>
  83. <h4>{metricExtractionRule.spanAttribute}</h4>
  84. </Header>
  85. <CloseButton />
  86. <Body>
  87. <MetricsExtractionRuleForm
  88. initialData={initialData}
  89. project={project}
  90. submitLabel={t('Update')}
  91. cancelLabel={t('Cancel')}
  92. onCancel={closeModal}
  93. onSubmit={handleSubmit}
  94. isEdit
  95. requireChanges
  96. />
  97. </Body>
  98. </Fragment>
  99. );
  100. }
  101. export const modalCss = css`
  102. width: 100%;
  103. max-width: 1000px;
  104. `;