edit.tsx 3.6 KB

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