modulePageProviders.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import {type ComponentProps, useEffect} from 'react';
  2. import * as qs from 'query-string';
  3. import Feature from 'sentry/components/acl/feature';
  4. import * as Layout from 'sentry/components/layouts/thirds';
  5. import NoProjectMessage from 'sentry/components/noProjectMessage';
  6. import PageFiltersContainer from 'sentry/components/organizations/pageFilters/container';
  7. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  8. import {useLocation} from 'sentry/utils/useLocation';
  9. import {useNavigate} from 'sentry/utils/useNavigate';
  10. import useOrganization from 'sentry/utils/useOrganization';
  11. import {NoAccess} from 'sentry/views/performance/database/noAccess';
  12. import {useInsightsTitle} from 'sentry/views/performance/utils/useInsightsTitle';
  13. import {useModuleTitle} from 'sentry/views/performance/utils/useModuleTitle';
  14. import type {ModuleName} from 'sentry/views/starfish/types';
  15. type ModuleNameStrings = `${ModuleName}`;
  16. type TitleableModuleNames = Exclude<ModuleNameStrings, '' | 'other'>;
  17. interface Props {
  18. children: React.ReactNode;
  19. features: ComponentProps<typeof Feature>['features'];
  20. moduleName: TitleableModuleNames;
  21. pageTitle?: string;
  22. }
  23. export function ModulePageProviders({moduleName, pageTitle, children, features}: Props) {
  24. const organization = useOrganization();
  25. const location = useLocation();
  26. const navigate = useNavigate();
  27. const insightsTitle = useInsightsTitle(moduleName);
  28. const moduleTitle = useModuleTitle(moduleName);
  29. const fullPageTitle = [pageTitle, moduleTitle, insightsTitle]
  30. .filter(Boolean)
  31. .join(' — ');
  32. const areInsightsEnabled = organization?.features?.includes('performance-insights');
  33. const isOnInsightsRoute = location.pathname.includes(`/insights/`);
  34. useEffect(() => {
  35. // If the Insights feature is enabled, redirect users to the `/insights/` equivalent URL!
  36. if (areInsightsEnabled && !isOnInsightsRoute) {
  37. const newPathname = location.pathname.replace(/\/performance\//g, '/insights/');
  38. navigate(`${newPathname}?${qs.stringify(location.query)}`);
  39. }
  40. }, [
  41. navigate,
  42. location.pathname,
  43. location.query,
  44. areInsightsEnabled,
  45. isOnInsightsRoute,
  46. ]);
  47. return (
  48. <PageFiltersContainer>
  49. <SentryDocumentTitle title={fullPageTitle} orgSlug={organization.slug}>
  50. <Layout.Page>
  51. <Feature
  52. features={features}
  53. organization={organization}
  54. renderDisabled={NoAccess}
  55. >
  56. <NoProjectMessage organization={organization}>{children}</NoProjectMessage>
  57. </Feature>
  58. </Layout.Page>
  59. </SentryDocumentTitle>
  60. </PageFiltersContainer>
  61. );
  62. }