edit.tsx 3.8 KB

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