extractMetric.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import {Fragment, useCallback} from 'react';
  2. import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
  3. import Alert from 'sentry/components/alert';
  4. import Panel from 'sentry/components/panels/panel';
  5. import PanelBody from 'sentry/components/panels/panelBody';
  6. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  7. import {t} from 'sentry/locale';
  8. import type {MetricsExtractionRule} from 'sentry/types/metrics';
  9. import type {Project} from 'sentry/types/project';
  10. import {hasCustomMetricsExtractionRules} from 'sentry/utils/metrics/features';
  11. import routeTitleGen from 'sentry/utils/routeTitle';
  12. import {useNavigate} from 'sentry/utils/useNavigate';
  13. import useOrganization from 'sentry/utils/useOrganization';
  14. import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
  15. import TextBlock from 'sentry/views/settings/components/text/textBlock';
  16. import {
  17. createCondition,
  18. explodeAggregateGroup,
  19. type FormData,
  20. MetricsExtractionRuleForm,
  21. } from 'sentry/views/settings/projectMetrics/metricsExtractionRuleForm';
  22. import {useCreateMetricsExtractionRules} from 'sentry/views/settings/projectMetrics/utils/api';
  23. const INITIAL_DATA: FormData = {
  24. spanAttribute: null,
  25. aggregates: ['count'],
  26. tags: ['release', 'environment'],
  27. conditions: [createCondition()],
  28. };
  29. const PAGE_TITLE = t('Configure Metric');
  30. function ExtractMetric({project}: {project: Project}) {
  31. const navigate = useNavigate();
  32. const organization = useOrganization();
  33. const createExtractionRuleMutation = useCreateMetricsExtractionRules(
  34. organization.slug,
  35. project.slug
  36. );
  37. const handleSubmit = useCallback(
  38. (
  39. formData: FormData,
  40. onSubmitSuccess: (data: FormData) => void,
  41. onSubmitError: (error: any) => void
  42. ) => {
  43. const data = formData as FormData;
  44. const extractionRule: MetricsExtractionRule = {
  45. spanAttribute: data.spanAttribute!,
  46. tags: data.tags,
  47. aggregates: data.aggregates.flatMap(explodeAggregateGroup),
  48. unit: 'none',
  49. conditions: data.conditions,
  50. };
  51. createExtractionRuleMutation.mutate(
  52. {
  53. metricsExtractionRules: [extractionRule],
  54. },
  55. {
  56. onSuccess: () => {
  57. onSubmitSuccess(data);
  58. addSuccessMessage(t('Metric extraction rule created'));
  59. navigate(-1);
  60. },
  61. onError: error => {
  62. const message = error?.responseJSON?.detail
  63. ? (error.responseJSON.detail as string)
  64. : t('Unable to save your changes.');
  65. onSubmitError(message);
  66. addErrorMessage(message);
  67. },
  68. }
  69. );
  70. onSubmitSuccess(data);
  71. },
  72. [createExtractionRuleMutation, navigate]
  73. );
  74. if (!hasCustomMetricsExtractionRules(organization)) {
  75. return <Alert type="warning">{t("You don't have access to this feature")}</Alert>;
  76. }
  77. return (
  78. <Fragment>
  79. <SentryDocumentTitle title={routeTitleGen(PAGE_TITLE, project.slug, false)} />
  80. <SettingsPageHeader title={PAGE_TITLE} />
  81. <TextBlock>{t('Configure tracking of span attributes as metrics.')}</TextBlock>
  82. <Panel>
  83. <PanelBody>
  84. <MetricsExtractionRuleForm
  85. project={project}
  86. initialData={INITIAL_DATA}
  87. onCancel={() => navigate(-1)}
  88. submitLabel={t('Confirm')}
  89. onSubmit={handleSubmit}
  90. requireChanges
  91. />
  92. </PanelBody>
  93. </Panel>
  94. </Fragment>
  95. );
  96. }
  97. export default ExtractMetric;