edit.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import {browserHistory} from 'react-router';
  2. import styled from '@emotion/styled';
  3. import Breadcrumbs from 'sentry/components/breadcrumbs';
  4. import IdBadge from 'sentry/components/idBadge';
  5. import * as Layout from 'sentry/components/layouts/thirds';
  6. import LoadingError from 'sentry/components/loadingError';
  7. import LoadingIndicator from 'sentry/components/loadingIndicator';
  8. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  9. import {t} from 'sentry/locale';
  10. import {space} from 'sentry/styles/space';
  11. import {
  12. ApiQueryKey,
  13. setApiQueryData,
  14. useApiQuery,
  15. useQueryClient,
  16. } from 'sentry/utils/queryClient';
  17. import useOrganization from 'sentry/utils/useOrganization';
  18. import usePageFilters from 'sentry/utils/usePageFilters';
  19. import {useParams} from 'sentry/utils/useParams';
  20. import {normalizeUrl} from 'sentry/utils/withDomainRequired';
  21. import MonitorForm from './components/monitorForm';
  22. import {Monitor} from './types';
  23. export default function EditMonitor() {
  24. const {monitorSlug} = useParams();
  25. const {selection} = usePageFilters();
  26. const organization = useOrganization();
  27. const queryClient = useQueryClient();
  28. const queryKey: ApiQueryKey = [
  29. `/organizations/${organization.slug}/monitors/${monitorSlug}/`,
  30. {query: {expand: ['alertRule']}},
  31. ];
  32. const {
  33. isLoading,
  34. isError,
  35. data: monitor,
  36. refetch,
  37. } = useApiQuery<Monitor>(queryKey, {
  38. staleTime: 0,
  39. });
  40. function onSubmitSuccess(data: Monitor) {
  41. setApiQueryData(queryClient, queryKey, data);
  42. browserHistory.push(
  43. normalizeUrl({
  44. pathname: `/organizations/${organization.slug}/crons/${data.slug}/`,
  45. query: {environment: selection.environments},
  46. })
  47. );
  48. }
  49. function getTitle() {
  50. if (monitor) {
  51. return `${monitor.name} - Crons - ${organization.slug}`;
  52. }
  53. return `Crons - ${organization.slug}`;
  54. }
  55. if (isLoading) {
  56. return <LoadingIndicator />;
  57. }
  58. if (isError) {
  59. return <LoadingError onRetry={refetch} message="Failed to load monitor." />;
  60. }
  61. return (
  62. <SentryDocumentTitle title={getTitle()}>
  63. <Layout.Page>
  64. <Layout.Header>
  65. <Layout.HeaderContent>
  66. <Breadcrumbs
  67. crumbs={[
  68. {
  69. label: t('Crons'),
  70. to: normalizeUrl(`/organizations/${organization.slug}/crons/`),
  71. },
  72. {
  73. label: (
  74. <MonitorBreadcrumb>
  75. <IdBadge
  76. disableLink
  77. project={monitor.project}
  78. avatarSize={16}
  79. hideName
  80. avatarProps={{hasTooltip: true, tooltip: monitor.project.slug}}
  81. />
  82. {monitor.name}
  83. </MonitorBreadcrumb>
  84. ),
  85. to: normalizeUrl(
  86. `/organizations/${organization.slug}/crons/${monitor.slug}/`
  87. ),
  88. },
  89. {
  90. label: t('Edit'),
  91. },
  92. ]}
  93. />
  94. <Layout.Title>{t('Edit Monitor')}</Layout.Title>
  95. </Layout.HeaderContent>
  96. </Layout.Header>
  97. <Layout.Body>
  98. <Layout.Main fullWidth>
  99. <MonitorForm
  100. monitor={monitor}
  101. apiMethod="PUT"
  102. apiEndpoint={`/organizations/${organization.slug}/monitors/${monitor.slug}/`}
  103. onSubmitSuccess={onSubmitSuccess}
  104. />
  105. </Layout.Main>
  106. </Layout.Body>
  107. </Layout.Page>
  108. </SentryDocumentTitle>
  109. );
  110. }
  111. const MonitorBreadcrumb = styled('div')`
  112. display: flex;
  113. gap: ${space(1)};
  114. align-items: center;
  115. `;