index.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import styled from '@emotion/styled';
  2. import {useFeedbackOnboardingDrawer} from 'sentry/components/feedback/feedbackOnboarding/sidebar';
  3. import Footer from 'sentry/components/footer';
  4. import HookOrDefault from 'sentry/components/hookOrDefault';
  5. import Nav from 'sentry/components/nav';
  6. import {NavContextProvider} from 'sentry/components/nav/context';
  7. import {useReplaysOnboardingDrawer} from 'sentry/components/replaysOnboarding/sidebar';
  8. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  9. import Sidebar from 'sentry/components/sidebar';
  10. import type {Organization} from 'sentry/types/organization';
  11. import useRouteAnalyticsHookSetup from 'sentry/utils/routeAnalytics/useRouteAnalyticsHookSetup';
  12. import useDevToolbar from 'sentry/utils/useDevToolbar';
  13. import {useIsSentryEmployee} from 'sentry/utils/useIsSentryEmployee';
  14. import useOrganization from 'sentry/utils/useOrganization';
  15. import {AppBodyContent} from 'sentry/views/app/appBodyContent';
  16. import OrganizationContainer from 'sentry/views/organizationContainer';
  17. import OrganizationDetailsBody from './body';
  18. interface Props {
  19. children: React.ReactNode;
  20. }
  21. const OrganizationHeader = HookOrDefault({
  22. hookName: 'component:organization-header',
  23. });
  24. function DevToolInit() {
  25. const isEmployee = useIsSentryEmployee();
  26. const organization = useOrganization();
  27. const showDevToolbar = organization.features.includes('devtoolbar');
  28. useDevToolbar({enabled: showDevToolbar && isEmployee});
  29. return null;
  30. }
  31. function OrganizationLayout({children}: Props) {
  32. useRouteAnalyticsHookSetup();
  33. // XXX(epurkhiser): The OrganizationContainer is responsible for ensuring the
  34. // oganization is loaded before rendering children. Organization may not be
  35. // loaded yet when this first renders.
  36. const organization = useOrganization({allowNull: true});
  37. const hasNavigationV2 = organization?.features.includes('navigation-sidebar-v2');
  38. const App = hasNavigationV2 ? AppLayout : LegacyAppLayout;
  39. return (
  40. <SentryDocumentTitle noSuffix title={organization?.name ?? 'Sentry'}>
  41. <OrganizationContainer>
  42. <App organization={organization}>{children}</App>
  43. </OrganizationContainer>
  44. </SentryDocumentTitle>
  45. );
  46. }
  47. interface LayoutProps extends Props {
  48. organization: Organization | null;
  49. }
  50. function AppLayout({children, organization}: LayoutProps) {
  51. useFeedbackOnboardingDrawer();
  52. useReplaysOnboardingDrawer();
  53. return (
  54. <NavContextProvider>
  55. <AppContainer>
  56. <Nav />
  57. {/* The `#main` selector is used to make the app content `inert` when an overlay is active */}
  58. <BodyContainer id="main">
  59. <AppBodyContent>
  60. {organization && <OrganizationHeader organization={organization} />}
  61. {organization && <DevToolInit />}
  62. <OrganizationDetailsBody>{children}</OrganizationDetailsBody>
  63. </AppBodyContent>
  64. <Footer />
  65. </BodyContainer>
  66. </AppContainer>
  67. </NavContextProvider>
  68. );
  69. }
  70. function LegacyAppLayout({children, organization}: LayoutProps) {
  71. return (
  72. <div className="app">
  73. {organization && <OrganizationHeader organization={organization} />}
  74. {organization && <DevToolInit />}
  75. <Sidebar />
  76. <AppBodyContent>
  77. <OrganizationDetailsBody>{children}</OrganizationDetailsBody>
  78. </AppBodyContent>
  79. <Footer />
  80. </div>
  81. );
  82. }
  83. const AppContainer = styled('div')`
  84. position: relative;
  85. display: flex;
  86. flex-direction: column;
  87. flex-grow: 1;
  88. @media (min-width: ${p => p.theme.breakpoints.medium}) {
  89. flex-direction: row;
  90. }
  91. `;
  92. const BodyContainer = styled('div')`
  93. display: flex;
  94. flex-direction: column;
  95. flex: 1;
  96. `;
  97. export default OrganizationLayout;