edit.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import {useCallback} from 'react';
  2. import type {RouteComponentProps} from 'react-router';
  3. import {addErrorMessage} from 'sentry/actionCreators/indicator';
  4. import {Alert} from 'sentry/components/alert';
  5. import LoadingError from 'sentry/components/loadingError';
  6. import LoadingIndicator from 'sentry/components/loadingIndicator';
  7. import {t} from 'sentry/locale';
  8. import type {Organization} from 'sentry/types/organization';
  9. import type {Project} from 'sentry/types/project';
  10. import {metric} from 'sentry/utils/analytics';
  11. import {useApiQuery} from 'sentry/utils/queryClient';
  12. import normalizeUrl from 'sentry/utils/url/normalizeUrl';
  13. import {useNavigate} from 'sentry/utils/useNavigate';
  14. import RuleForm from 'sentry/views/alerts/rules/metric/ruleForm';
  15. import type {MetricRule} from 'sentry/views/alerts/rules/metric/types';
  16. type RouteParams = {
  17. projectId: string;
  18. ruleId: string;
  19. };
  20. type Props = {
  21. onChangeTitle: (data: string) => void;
  22. organization: Organization;
  23. project: Project;
  24. userTeamIds: string[];
  25. } & RouteComponentProps<RouteParams, {}>;
  26. export function MetricRulesEdit({
  27. organization,
  28. params,
  29. project,
  30. userTeamIds,
  31. onChangeTitle,
  32. ...props
  33. }: Props) {
  34. const navigate = useNavigate();
  35. const {
  36. isLoading,
  37. isError,
  38. data: rule,
  39. error,
  40. } = useApiQuery<MetricRule>(
  41. [`/organizations/${organization.slug}/alert-rules/${params.ruleId}/`],
  42. {
  43. staleTime: 0,
  44. retry: false,
  45. onSuccess: data => {
  46. onChangeTitle(data[0]?.name ?? '');
  47. },
  48. onError: ({responseText}) => {
  49. const {detail} = JSON.parse(responseText ?? '');
  50. if (detail) {
  51. addErrorMessage(detail);
  52. }
  53. },
  54. }
  55. );
  56. const handleSubmitSuccess = useCallback(() => {
  57. metric.endSpan({name: 'saveAlertRule'});
  58. navigate(
  59. normalizeUrl({
  60. pathname: `/organizations/${organization.slug}/alerts/rules/details/${params.ruleId}/`,
  61. })
  62. );
  63. }, [params.ruleId, navigate, organization.slug]);
  64. if (isLoading) {
  65. return <LoadingIndicator />;
  66. }
  67. if (isError) {
  68. if (error?.status === 404) {
  69. return (
  70. <Alert type="error" showIcon>
  71. {t('This alert rule could not be found.')}
  72. </Alert>
  73. );
  74. }
  75. return <LoadingError />;
  76. }
  77. return (
  78. <RuleForm
  79. {...props}
  80. params={params}
  81. project={project}
  82. userTeamIds={userTeamIds}
  83. organization={organization}
  84. ruleId={params.ruleId}
  85. rule={rule}
  86. onSubmitSuccess={handleSubmitSuccess}
  87. disableProjectSelector
  88. />
  89. );
  90. }