edit.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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. cacheTime: 0,
  39. staleTime: 0,
  40. });
  41. function onSubmitSuccess(data: Monitor) {
  42. setApiQueryData(queryClient, queryKey, data);
  43. browserHistory.push(
  44. normalizeUrl({
  45. pathname: `/organizations/${organization.slug}/crons/${data.slug}/`,
  46. query: {
  47. environment: selection.environments,
  48. project: selection.projects,
  49. },
  50. })
  51. );
  52. }
  53. function getTitle() {
  54. if (monitor) {
  55. return `${monitor.name} - Crons - ${organization.slug}`;
  56. }
  57. return `Crons - ${organization.slug}`;
  58. }
  59. if (isLoading) {
  60. return <LoadingIndicator />;
  61. }
  62. if (isError) {
  63. return <LoadingError onRetry={refetch} message="Failed to load monitor." />;
  64. }
  65. return (
  66. <SentryDocumentTitle title={getTitle()}>
  67. <Layout.Page>
  68. <Layout.Header>
  69. <Layout.HeaderContent>
  70. <Breadcrumbs
  71. crumbs={[
  72. {
  73. label: t('Crons'),
  74. to: normalizeUrl(`/organizations/${organization.slug}/crons/`),
  75. },
  76. {
  77. label: (
  78. <MonitorBreadcrumb>
  79. <IdBadge
  80. disableLink
  81. project={monitor.project}
  82. avatarSize={16}
  83. hideName
  84. avatarProps={{hasTooltip: true, tooltip: monitor.project.slug}}
  85. />
  86. {monitor.name}
  87. </MonitorBreadcrumb>
  88. ),
  89. to: normalizeUrl(
  90. `/organizations/${organization.slug}/crons/${monitor.slug}/`
  91. ),
  92. },
  93. {
  94. label: t('Edit'),
  95. },
  96. ]}
  97. />
  98. <Layout.Title>{t('Edit Monitor')}</Layout.Title>
  99. </Layout.HeaderContent>
  100. </Layout.Header>
  101. <Layout.Body>
  102. <Layout.Main fullWidth>
  103. <MonitorForm
  104. monitor={monitor}
  105. apiMethod="PUT"
  106. apiEndpoint={`/organizations/${organization.slug}/monitors/${monitor.slug}/`}
  107. onSubmitSuccess={onSubmitSuccess}
  108. />
  109. </Layout.Main>
  110. </Layout.Body>
  111. </Layout.Page>
  112. </SentryDocumentTitle>
  113. );
  114. }
  115. const MonitorBreadcrumb = styled('div')`
  116. display: flex;
  117. gap: ${space(1)};
  118. align-items: center;
  119. `;