Browse Source

ref(insights): Create sidebar links using `useModuleURL` (#71373)

Doesn't make sense to have a `useModuleURL` helper if I can't use it to
generate links to the modules in the sidebar. This adds a _slightly
lower level_ helper, so that the same function makes _all_ links to
module. Which, you guessed it, will make it easier to change all the
URLs behind a feature flag.

## Changes

- **Allow creating bare module URLs**
- **Split `useModuleURL` into a builder and a wrapper**
- **Remove leading slash from insights base URL**
- **Link sidebar items using `useModuleURLBuilder`**
George Gritsouk 9 months ago
parent
commit
7f14483b71

+ 13 - 13
static/app/components/sidebar/index.tsx

@@ -67,8 +67,7 @@ import {
   MODULE_TITLE as QUEUES_MODULE_TITLE,
   releaseLevelAsBadgeProps as QueuesModuleBadgeProps,
 } from 'sentry/views/performance/queues/settings';
-import {MODULE_BASE_URLS} from 'sentry/views/performance/utils/useModuleURL';
-import {ModuleName} from 'sentry/views/starfish/types';
+import {useModuleURLBuilder} from 'sentry/views/performance/utils/useModuleURL';
 
 import {ProfilingOnboardingSidebar} from '../profiling/ProfilingOnboarding/profilingOnboardingSidebar';
 
@@ -246,6 +245,8 @@ function Sidebar() {
     </Feature>
   );
 
+  const moduleURLBuilder = useModuleURLBuilder(true);
+
   const performance = hasOrganization && (
     <Feature
       hookName="feature-disabled:performance-sidebar-item"
@@ -276,7 +277,7 @@ function Sidebar() {
                       {t('Queries')}
                     </GuideAnchor>
                   }
-                  to={`/organizations/${organization.slug}/performance/${MODULE_BASE_URLS[ModuleName.DB]}/`}
+                  to={`/organizations/${organization.slug}/${moduleURLBuilder('db')}/`}
                   id="performance-database"
                   // collapsed controls whether the dot is visible or not.
                   // We always want it visible for these sidebar items so force it to true.
@@ -291,7 +292,7 @@ function Sidebar() {
                       {HTTP_MODULE_TITLE}
                     </GuideAnchor>
                   }
-                  to={`/organizations/${organization.slug}/performance/${MODULE_BASE_URLS[ModuleName.HTTP]}/`}
+                  to={`/organizations/${organization.slug}/${moduleURLBuilder('http')}/`}
                   id="performance-http"
                   icon={<SubitemDot collapsed />}
                   {...HTTPModuleBadgeProps}
@@ -305,7 +306,7 @@ function Sidebar() {
                       {CACHE_MODULE_TITLE}
                     </GuideAnchor>
                   }
-                  to={`/organizations/${organization.slug}/performance/${MODULE_BASE_URLS[ModuleName.CACHE]}/`}
+                  to={`/organizations/${organization.slug}/${moduleURLBuilder('cache')}/`}
                   id="performance-cache"
                   icon={<SubitemDot collapsed />}
                   {...CacheModuleBadgeProps}
@@ -319,7 +320,7 @@ function Sidebar() {
                       {t('Web Vitals')}
                     </GuideAnchor>
                   }
-                  to={`/organizations/${organization.slug}/performance/${MODULE_BASE_URLS[ModuleName.VITAL]}/`}
+                  to={`/organizations/${organization.slug}/${moduleURLBuilder('vital')}/`}
                   id="performance-webvitals"
                   icon={<SubitemDot collapsed />}
                 />
@@ -333,7 +334,7 @@ function Sidebar() {
                     </GuideAnchor>
                   }
                   {...QueuesModuleBadgeProps}
-                  to={`/organizations/${organization.slug}/performance/${MODULE_BASE_URLS[ModuleName.QUEUE]}/`}
+                  to={`/organizations/${organization.slug}/${moduleURLBuilder('queue')}/`}
                   id="performance-queues"
                   icon={<SubitemDot collapsed />}
                 />
@@ -342,7 +343,7 @@ function Sidebar() {
                 <SidebarItem
                   {...sidebarItemProps}
                   label={t('Screen Loads')}
-                  to={`/organizations/${organization.slug}/performance/${MODULE_BASE_URLS[ModuleName.SCREEN_LOAD]}/`}
+                  to={`/organizations/${organization.slug}/${moduleURLBuilder('screen_load')}/`}
                   id="performance-mobile-screens"
                   icon={<SubitemDot collapsed />}
                 />
@@ -351,7 +352,7 @@ function Sidebar() {
                 <SidebarItem
                   {...sidebarItemProps}
                   label={t('App Starts')}
-                  to={`/organizations/${organization.slug}/performance/${MODULE_BASE_URLS[ModuleName.APP_START]}/`}
+                  to={`/organizations/${organization.slug}/${moduleURLBuilder('app_start')}/`}
                   id="performance-mobile-app-startup"
                   icon={<SubitemDot collapsed />}
                 />
@@ -363,7 +364,7 @@ function Sidebar() {
                 <SidebarItem
                   {...sidebarItemProps}
                   label={t('Mobile UI')}
-                  to={`/organizations/${organization.slug}/performance/${MODULE_BASE_URLS[ModuleName.MOBILE_UI]}/`}
+                  to={`/organizations/${organization.slug}/${moduleURLBuilder('mobile-ui')}/`}
                   id="performance-mobile-ui"
                   icon={<SubitemDot collapsed />}
                   isAlpha
@@ -373,7 +374,7 @@ function Sidebar() {
                 <SidebarItem
                   {...sidebarItemProps}
                   label={<GuideAnchor target="starfish">{t('Resources')}</GuideAnchor>}
-                  to={`/organizations/${organization.slug}/performance/${MODULE_BASE_URLS[ModuleName.RESOURCE]}/`}
+                  to={`/organizations/${organization.slug}/${moduleURLBuilder('resource')}/`}
                   id="performance-browser-resources"
                   icon={<SubitemDot collapsed />}
                 />
@@ -424,8 +425,7 @@ function Sidebar() {
         label={t('LLM Monitoring')}
         isAlpha
         variant="short"
-        // NOTE: This doesn't include the insights base bath because LLM monitoring lives at `/llm-monitoring`
-        to={`/organizations/${organization.slug}/${MODULE_BASE_URLS[ModuleName.AI]}/`}
+        to={`/organizations/${organization.slug}/${moduleURLBuilder('ai')}/`}
         id="llm-monitoring"
       />
     </Feature>

+ 1 - 1
static/app/views/performance/settings.ts

@@ -1,4 +1,4 @@
 import {t} from 'sentry/locale';
 
 export const INSIGHTS_LABEL = t('Performance');
-export const INSIGHTS_BASE_URL = '/performance';
+export const INSIGHTS_BASE_URL = 'performance';

+ 1 - 1
static/app/views/performance/utils/useModuleBreadcrumbs.tsx

@@ -29,7 +29,7 @@ export function useModuleBreadcrumbs(moduleName: RoutableModuleNames): Crumb[] {
   return [
     {
       label: INSIGHTS_LABEL,
-      to: normalizeUrl(`/organizations/${organization.slug}${INSIGHTS_BASE_URL}/`),
+      to: normalizeUrl(`/organizations/${organization.slug}/${INSIGHTS_BASE_URL}/`),
       preservePageFilters: true,
     },
     {

+ 32 - 9
static/app/views/performance/utils/useModuleURL.tsx

@@ -31,15 +31,38 @@ export const MODULE_BASE_URLS: Record<ModuleName, string> = {
 type ModuleNameStrings = `${ModuleName}`;
 type RoutableModuleNames = Exclude<ModuleNameStrings, '' | 'other'>;
 
-export const useModuleURL = (moduleName: RoutableModuleNames): string => {
-  const {slug} = useOrganization();
+export const useModuleURL = (
+  moduleName: RoutableModuleNames,
+  bare: boolean = false
+): string => {
+  const builder = useModuleURLBuilder(bare);
+  return builder(moduleName);
+};
+
+type URLBuilder = (moduleName: RoutableModuleNames) => string;
+
+export function useModuleURLBuilder(bare: boolean = false): URLBuilder {
+  const organization = useOrganization({allowNull: true}); // Some parts of the app, like the main sidebar, render even if the organization isn't available (during loading, or at all).
 
-  if (moduleName === ModuleName.AI) {
-    // AI Doesn't live under "/performance"
-    return normalizeUrl(`/organizations/${slug}/${AI_BASE_URL}`);
+  if (!organization) {
+    // If there isn't an organization, items that link to modules won't be visible, so this is a fallback just-in-case, and isn't trying too hard to be useful
+    return () => INSIGHTS_BASE_URL;
   }
 
-  return normalizeUrl(
-    `/organizations/${slug}${INSIGHTS_BASE_URL}/${MODULE_BASE_URLS[moduleName]}`
-  );
-};
+  const {slug} = organization;
+
+  return function (moduleName: RoutableModuleNames) {
+    if (moduleName === ModuleName.AI) {
+      // AI Doesn't live under "/performance"
+      return bare
+        ? `${AI_BASE_URL}`
+        : normalizeUrl(`/organizations/${slug}/${AI_BASE_URL}`);
+    }
+
+    return bare
+      ? `${INSIGHTS_BASE_URL}/${MODULE_BASE_URLS[moduleName]}`
+      : normalizeUrl(
+          `/organizations/${slug}/${INSIGHTS_BASE_URL}/${MODULE_BASE_URLS[moduleName]}`
+        );
+  };
+}