edit.tsx 3.7 KB

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