details.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import styled from '@emotion/styled';
  2. import ActorAvatar from 'sentry/components/avatar/actorAvatar';
  3. import Breadcrumbs from 'sentry/components/breadcrumbs';
  4. import {LinkButton} from 'sentry/components/button';
  5. import ButtonBar from 'sentry/components/buttonBar';
  6. import {SectionHeading} from 'sentry/components/charts/styles';
  7. import IdBadge from 'sentry/components/idBadge';
  8. import {KeyValueTable, KeyValueTableRow} from 'sentry/components/keyValueTable';
  9. import * as Layout from 'sentry/components/layouts/thirds';
  10. import LoadingError from 'sentry/components/loadingError';
  11. import LoadingIndicator from 'sentry/components/loadingIndicator';
  12. import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
  13. import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter';
  14. import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
  15. import {IconEdit} from 'sentry/icons';
  16. import {t} from 'sentry/locale';
  17. import {space} from 'sentry/styles/space';
  18. import type {RouteComponentProps} from 'sentry/types/legacyReactRouter';
  19. import {type ApiQueryKey, useApiQuery} from 'sentry/utils/queryClient';
  20. import useOrganization from 'sentry/utils/useOrganization';
  21. import useProjects from 'sentry/utils/useProjects';
  22. import type {UptimeRule} from 'sentry/views/alerts/rules/uptime/types';
  23. import {UptimeIssues} from './uptimeIssues';
  24. interface UptimeAlertDetailsProps
  25. extends RouteComponentProps<{projectId: string; uptimeRuleId: string}, {}> {}
  26. export default function UptimeAlertDetails({params}: UptimeAlertDetailsProps) {
  27. const organization = useOrganization();
  28. const {projectId, uptimeRuleId} = params;
  29. const {projects, fetching: loadingProject} = useProjects({slugs: [projectId]});
  30. const project = projects.find(({slug}) => slug === projectId);
  31. const queryKey: ApiQueryKey = [
  32. `/projects/${organization.slug}/${projectId}/uptime/${uptimeRuleId}/`,
  33. ];
  34. const {
  35. data: uptimeRule,
  36. isPending,
  37. isError,
  38. } = useApiQuery<UptimeRule>(queryKey, {staleTime: 0});
  39. if (isError) {
  40. return (
  41. <LoadingError
  42. message={t('The uptime alert rule you were looking for was not found.')}
  43. />
  44. );
  45. }
  46. if (isPending || loadingProject) {
  47. return (
  48. <Layout.Body>
  49. <Layout.Main fullWidth>
  50. <LoadingIndicator />
  51. </Layout.Main>
  52. </Layout.Body>
  53. );
  54. }
  55. if (!project) {
  56. return (
  57. <LoadingError message={t('The project you were looking for was not found.')} />
  58. );
  59. }
  60. return (
  61. <Layout.Page>
  62. <Layout.Header>
  63. <Layout.HeaderContent>
  64. <Breadcrumbs
  65. crumbs={[
  66. {
  67. label: t('Alerts'),
  68. to: `/organizations/${organization.slug}/alerts/rules/`,
  69. },
  70. {
  71. label: uptimeRule.name,
  72. to: null,
  73. },
  74. ]}
  75. />
  76. <Layout.Title>
  77. <IdBadge
  78. project={project}
  79. avatarSize={28}
  80. hideName
  81. avatarProps={{hasTooltip: true, tooltip: project.slug}}
  82. />
  83. {uptimeRule.name}
  84. </Layout.Title>
  85. </Layout.HeaderContent>
  86. <Layout.HeaderActions>
  87. <ButtonBar gap={1}>
  88. <LinkButton
  89. size="sm"
  90. icon={<IconEdit />}
  91. to={`/organizations/${organization.slug}/alerts/uptime-rules/${project.slug}/${uptimeRuleId}/`}
  92. >
  93. {t('Edit Rule')}
  94. </LinkButton>
  95. </ButtonBar>
  96. </Layout.HeaderActions>
  97. </Layout.Header>
  98. <Layout.Body>
  99. <Layout.Main>
  100. <StyledPageFilterBar condensed>
  101. <DatePageFilter />
  102. <EnvironmentPageFilter />
  103. </StyledPageFilterBar>
  104. <UptimeIssues project={project} ruleId={uptimeRuleId} />
  105. </Layout.Main>
  106. <Layout.Side>
  107. <SectionHeading>{t('Uptime Alert Details')}</SectionHeading>
  108. <KeyValueTable>
  109. <KeyValueTableRow keyName={t('URL')} value={uptimeRule.url} />
  110. <KeyValueTableRow
  111. keyName={t('Owner')}
  112. value={
  113. uptimeRule.owner ? (
  114. <ActorAvatar actor={uptimeRule.owner} />
  115. ) : (
  116. t('Unassigned')
  117. )
  118. }
  119. />
  120. </KeyValueTable>
  121. </Layout.Side>
  122. </Layout.Body>
  123. </Layout.Page>
  124. );
  125. }
  126. const StyledPageFilterBar = styled(PageFilterBar)`
  127. margin-bottom: ${space(2)};
  128. `;