header.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import {InjectedRouter} from 'react-router';
  2. import styled from '@emotion/styled';
  3. import {navigateTo} from 'sentry/actionCreators/navigation';
  4. import Button from 'sentry/components/button';
  5. import ButtonBar from 'sentry/components/buttonBar';
  6. import CreateAlertButton from 'sentry/components/createAlertButton';
  7. import GlobalSelectionLink from 'sentry/components/globalSelectionLink';
  8. import * as Layout from 'sentry/components/layouts/thirds';
  9. import ExternalLink from 'sentry/components/links/externalLink';
  10. import {PageHeadingQuestionTooltip} from 'sentry/components/pageHeadingQuestionTooltip';
  11. import {IconSettings} from 'sentry/icons';
  12. import {t, tct} from 'sentry/locale';
  13. import ProjectsStore from 'sentry/stores/projectsStore';
  14. import space from 'sentry/styles/space';
  15. import useOrganization from 'sentry/utils/useOrganization';
  16. import usePageFilters from 'sentry/utils/usePageFilters';
  17. type Props = {
  18. activeTab: 'stream' | 'rules';
  19. router: InjectedRouter;
  20. };
  21. const AlertHeader = ({router, activeTab}: Props) => {
  22. const organization = useOrganization();
  23. const {selection} = usePageFilters();
  24. /**
  25. * Incidents list is currently at the organization level, but the link needs to
  26. * go down to a specific project scope.
  27. */
  28. const handleNavigateToSettings = (e: React.MouseEvent) => {
  29. e.preventDefault();
  30. navigateTo(`/settings/${organization.slug}/projects/:projectId/alerts/`, router);
  31. };
  32. const alertRulesLink = (
  33. <li className={activeTab === 'rules' ? 'active' : ''}>
  34. <GlobalSelectionLink to={`/organizations/${organization.slug}/alerts/rules/`}>
  35. {t('Alert Rules')}
  36. </GlobalSelectionLink>
  37. </li>
  38. );
  39. return (
  40. <Layout.Header>
  41. <Layout.HeaderContent>
  42. <StyledLayoutTitle>
  43. {t('Alerts')}
  44. <PageHeadingQuestionTooltip
  45. title={tct(
  46. 'Real-time visibility into problems with your code and the impact on your users, along with a view of your existing alert rules, their status, project, team, and creation date. [link: Read the docs].',
  47. {link: <ExternalLink href="https://docs.sentry.io/product/alerts/" />}
  48. )}
  49. />
  50. </StyledLayoutTitle>
  51. </Layout.HeaderContent>
  52. <Layout.HeaderActions>
  53. <Actions gap={1}>
  54. <CreateAlertButton
  55. organization={organization}
  56. iconProps={{size: 'sm'}}
  57. size="sm"
  58. priority="primary"
  59. referrer="alert_stream"
  60. showPermissionGuide
  61. projectSlug={
  62. selection.projects.length === 1
  63. ? ProjectsStore.getById(`${selection.projects[0]}`)?.slug
  64. : undefined
  65. }
  66. >
  67. {t('Create Alert')}
  68. </CreateAlertButton>
  69. <Button
  70. size="sm"
  71. onClick={handleNavigateToSettings}
  72. href="#"
  73. icon={<IconSettings size="sm" />}
  74. aria-label={t('Settings')}
  75. />
  76. </Actions>
  77. </Layout.HeaderActions>
  78. <Layout.HeaderNavTabs underlined>
  79. {alertRulesLink}
  80. <li className={activeTab === 'stream' ? 'active' : ''}>
  81. <GlobalSelectionLink to={`/organizations/${organization.slug}/alerts/`}>
  82. {t('History')}
  83. </GlobalSelectionLink>
  84. </li>
  85. </Layout.HeaderNavTabs>
  86. </Layout.Header>
  87. );
  88. };
  89. export default AlertHeader;
  90. const StyledLayoutTitle = styled(Layout.Title)`
  91. margin-top: ${space(0.5)};
  92. `;
  93. const Actions = styled(ButtonBar)`
  94. height: 32px;
  95. `;