edit.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import {Fragment, useState} from 'react';
  2. import * as Layout from 'sentry/components/layouts/thirds';
  3. import LoadingIndicator from 'sentry/components/loadingIndicator';
  4. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  5. import {t} from 'sentry/locale';
  6. import type {RouteComponentProps} from 'sentry/types/legacyReactRouter';
  7. import type {Member, Organization} from 'sentry/types/organization';
  8. import type {Project} from 'sentry/types/project';
  9. import useRouteAnalyticsEventNames from 'sentry/utils/routeAnalytics/useRouteAnalyticsEventNames';
  10. import useRouteAnalyticsParams from 'sentry/utils/routeAnalytics/useRouteAnalyticsParams';
  11. import {useLocation} from 'sentry/utils/useLocation';
  12. import {useUserTeams} from 'sentry/utils/useUserTeams';
  13. import BuilderBreadCrumbs from 'sentry/views/alerts/builder/builderBreadCrumbs';
  14. import {CronRulesEdit} from './rules/crons/edit';
  15. import IssueEditor from './rules/issue';
  16. import {MetricRulesEdit} from './rules/metric/edit';
  17. import {UptimeRulesEdit} from './rules/uptime/edit';
  18. import {CombinedAlertType} from './types';
  19. type RouteParams = {
  20. projectId: string;
  21. ruleId: string;
  22. };
  23. type Props = RouteComponentProps<RouteParams, {}> & {
  24. hasMetricAlerts: boolean;
  25. hasUptimeAlerts: boolean;
  26. members: Member[] | undefined;
  27. organization: Organization;
  28. project: Project;
  29. };
  30. function ProjectAlertsEditor(props: Props) {
  31. const {members, organization, project} = props;
  32. const location = useLocation();
  33. const [title, setTitle] = useState('');
  34. const alertTypeUrls = [
  35. {url: '/alerts/metric-rules/', type: CombinedAlertType.METRIC},
  36. {url: '/alerts/uptime-rules/', type: CombinedAlertType.UPTIME},
  37. {url: '/alerts/crons-rules/', type: CombinedAlertType.CRONS},
  38. {url: '/alerts/rules/', type: CombinedAlertType.ISSUE},
  39. ] as const;
  40. const alertType =
  41. alertTypeUrls.find(({url}) => location.pathname.includes(url))?.type ??
  42. CombinedAlertType.ISSUE;
  43. useRouteAnalyticsEventNames('edit_alert_rule.viewed', 'Edit Alert Rule: Viewed');
  44. useRouteAnalyticsParams({
  45. organization,
  46. project_id: project.id,
  47. alert_type: alertType,
  48. });
  49. // Used to hide specific fields like actions while migrating metric alert rules.
  50. // Currently used to help people add `is:unresolved` to their metric alert query.
  51. const isMigration = location?.query?.migration === '1';
  52. const {teams, isLoading: teamsLoading} = useUserTeams();
  53. return (
  54. <Fragment>
  55. <SentryDocumentTitle
  56. title={title}
  57. orgSlug={organization.slug}
  58. projectSlug={project.slug}
  59. />
  60. <Layout.Header>
  61. <Layout.HeaderContent>
  62. <BuilderBreadCrumbs
  63. organization={organization}
  64. title={isMigration ? t('Review Thresholds') : t('Edit Alert Rule')}
  65. projectSlug={project.slug}
  66. />
  67. <Layout.Title>{title}</Layout.Title>
  68. </Layout.HeaderContent>
  69. </Layout.Header>
  70. <Layout.Body>
  71. {!teamsLoading ? (
  72. <Fragment>
  73. {alertType === CombinedAlertType.ISSUE && (
  74. <IssueEditor
  75. {...props}
  76. project={project}
  77. onChangeTitle={setTitle}
  78. userTeamIds={teams.map(({id}) => id)}
  79. members={members}
  80. />
  81. )}
  82. {alertType === CombinedAlertType.METRIC && (
  83. <MetricRulesEdit
  84. {...props}
  85. project={project}
  86. onChangeTitle={setTitle}
  87. userTeamIds={teams.map(({id}) => id)}
  88. />
  89. )}
  90. {alertType === CombinedAlertType.UPTIME && (
  91. <UptimeRulesEdit
  92. {...props}
  93. project={project}
  94. onChangeTitle={setTitle}
  95. userTeamIds={teams.map(({id}) => id)}
  96. />
  97. )}
  98. {alertType === CombinedAlertType.CRONS && (
  99. <CronRulesEdit {...props} project={project} onChangeTitle={setTitle} />
  100. )}
  101. </Fragment>
  102. ) : (
  103. <LoadingIndicator />
  104. )}
  105. </Layout.Body>
  106. </Fragment>
  107. );
  108. }
  109. export default ProjectAlertsEditor;