header.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import {useState} from 'react';
  2. import {InjectedRouter} from 'react-router';
  3. import styled from '@emotion/styled';
  4. import * as Layout from 'sentry/components/layouts/thirds';
  5. import {PageHeadingQuestionTooltip} from 'sentry/components/pageHeadingQuestionTooltip';
  6. import {TabList, Tabs} from 'sentry/components/tabs';
  7. import {Tooltip} from 'sentry/components/tooltip';
  8. import {SLOW_TOOLTIP_DELAY} from 'sentry/constants';
  9. import {t} from 'sentry/locale';
  10. import {Organization} from 'sentry/types';
  11. import {normalizeUrl} from 'sentry/utils/withDomainRequired';
  12. type Props = {
  13. organization: Organization;
  14. router: InjectedRouter;
  15. hasV2ReleaseUIEnabled?: boolean;
  16. };
  17. function Header({router, hasV2ReleaseUIEnabled = false, organization}: Props) {
  18. const [selected, setSelected] = useState(router.location.pathname);
  19. const location = router.location;
  20. const {
  21. cursor: _cursor,
  22. page: _page,
  23. view: _view,
  24. ...queryParams
  25. } = location?.query ?? {};
  26. const tabs = hasV2ReleaseUIEnabled
  27. ? [
  28. {
  29. label: t('Monitor'),
  30. description: '',
  31. path: normalizeUrl(`/organizations/${organization.slug}/releases/`),
  32. to: normalizeUrl({
  33. query: {
  34. ...queryParams,
  35. },
  36. pathname: `/organizations/${organization.slug}/releases/`,
  37. }),
  38. },
  39. {
  40. label: t('Thresholds'),
  41. description:
  42. 'thresholds represent action alerts that will trigger once a threshold has been breached',
  43. path: normalizeUrl(`/organizations/${organization.slug}/release-thresholds/`),
  44. to: normalizeUrl({
  45. query: {
  46. ...queryParams,
  47. },
  48. pathname: `/organizations/${organization.slug}/release-thresholds/`,
  49. }),
  50. },
  51. ]
  52. : [];
  53. const onTabSelect = key => {
  54. setSelected(key);
  55. };
  56. return (
  57. <Layout.Header noActionWrap>
  58. <Layout.HeaderContent>
  59. <Layout.Title>
  60. {t('Releases')}
  61. <PageHeadingQuestionTooltip
  62. docsUrl="https://docs.sentry.io/product/releases/"
  63. title={t(
  64. 'A visualization of your release adoption from the past 24 hours, providing a high-level view of the adoption stage, percentage of crash-free users and sessions, and more.'
  65. )}
  66. />
  67. </Layout.Title>
  68. </Layout.HeaderContent>
  69. {hasV2ReleaseUIEnabled && (
  70. <StyledTabs value={selected} onChange={onTabSelect}>
  71. <TabList hideBorder>
  72. {tabs.map(({label, description, path, to}) => {
  73. return (
  74. <TabList.Item key={path} to={to} textValue={label}>
  75. <Tooltip
  76. title={description}
  77. position="bottom"
  78. isHoverable
  79. delay={SLOW_TOOLTIP_DELAY}
  80. >
  81. {label}
  82. </Tooltip>
  83. </TabList.Item>
  84. );
  85. })}
  86. </TabList>
  87. </StyledTabs>
  88. )}
  89. </Layout.Header>
  90. );
  91. }
  92. export default Header;
  93. const StyledTabs = styled(Tabs)`
  94. grid-column: 1/-1;
  95. `;