Browse Source

feat(insights): update headers and breadcrumbs on frontend domain view (#78945)

Work for https://github.com/getsentry/sentry/issues/77572

Similar to #78948 

This PR updates all of frontend domain view and modules so that they
contain the correct header titles and breadcrumbs.
Dominik Buszowiecki 4 months ago
parent
commit
dc07371e08

+ 11 - 1
static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx

@@ -119,7 +119,17 @@ function ResourceSummary() {
         </Layout.Header>
       )}
 
-      {isInDomainView && <FrontendHeader module={ModuleName.RESOURCE} />}
+      {isInDomainView && (
+        <FrontendHeader
+          headerTitle={spanMetrics[SpanMetricsField.SPAN_DESCRIPTION]}
+          breadcrumbs={[
+            {
+              label: tct('[dataType] Summary', {dataType: DATA_TYPE}),
+            },
+          ]}
+          module={ModuleName.RESOURCE}
+        />
+      )}
 
       <Layout.Body>
         <Layout.Main fullWidth>

+ 14 - 1
static/app/views/insights/browser/resources/views/resourcesLandingPage.tsx

@@ -63,7 +63,20 @@ function ResourcesLandingPage() {
           </Layout.Header>
         )}
 
-        {isInDomainView && <FrontendHeader module={ModuleName.RESOURCE} />}
+        {isInDomainView && (
+          <FrontendHeader
+            headerTitle={
+              <Fragment>
+                {MODULE_TITLE}
+                <PageHeadingQuestionTooltip
+                  docsUrl={MODULE_DOC_LINK}
+                  title={MODULE_DESCRIPTION}
+                />
+              </Fragment>
+            }
+            module={ModuleName.RESOURCE}
+          />
+        )}
         <Layout.Body>
           <Layout.Main fullWidth>
             <PageAlert />

+ 55 - 18
static/app/views/insights/browser/webVitals/views/pageOverview.tsx

@@ -1,4 +1,4 @@
-import React, {useMemo, useState} from 'react';
+import React, {Fragment, useMemo, useState} from 'react';
 import styled from '@emotion/styled';
 import omit from 'lodash/omit';
 
@@ -135,24 +135,23 @@ export function PageOverview() {
       ? undefined
       : calculatePerformanceScoreFromStoredTableDataRow(projectScores?.data?.[0]);
 
+  const handleTabChange = (value: string) => {
+    trackAnalytics('insight.vital.overview.toggle_tab', {
+      organization,
+      tab: value,
+    });
+    browserHistory.push({
+      ...location,
+      query: {
+        ...location.query,
+        tab: value,
+      },
+    });
+  };
+
   return (
     <React.Fragment>
-      <Tabs
-        value={tab}
-        onChange={value => {
-          trackAnalytics('insight.vital.overview.toggle_tab', {
-            organization,
-            tab: value,
-          });
-          browserHistory.push({
-            ...location,
-            query: {
-              ...location.query,
-              tab: value,
-            },
-          });
-        }}
-      >
+      <Tabs value={tab} onChange={handleTabChange}>
         {!isInDomainView && (
           <Layout.Header>
             <Layout.HeaderContent>
@@ -189,7 +188,45 @@ export function PageOverview() {
             </TabList>
           </Layout.Header>
         )}
-        {isInDomainView && <FrontendHeader module={ModuleName.VITAL} />}
+        {isInDomainView && (
+          <FrontendHeader
+            headerTitle={
+              <Fragment>
+                {transaction && project && <ProjectAvatar project={project} size={24} />}
+                {transaction ?? t('Page Loads')}
+              </Fragment>
+            }
+            headerActions={
+              transactionSummaryTarget && (
+                <LinkButton
+                  to={transactionSummaryTarget}
+                  onClick={() => {
+                    trackAnalytics('insight.vital.overview.open_transaction_summary', {
+                      organization,
+                    });
+                  }}
+                  size="sm"
+                >
+                  {t('View Transaction Summary')}
+                </LinkButton>
+              )
+            }
+            hideDefaultTabs
+            tabs={{
+              value: tab,
+              onTabChange: handleTabChange,
+              tabList: (
+                <TabList hideBorder>
+                  {LANDING_DISPLAYS.map(({label, field}) => (
+                    <TabList.Item key={field}>{label}</TabList.Item>
+                  ))}
+                </TabList>
+              ),
+            }}
+            breadcrumbs={transaction ? [{label: 'Page Summary'}] : []}
+            module={ModuleName.VITAL}
+          />
+        )}
         {tab === LandingDisplayField.SPANS ? (
           <Layout.Body>
             <Layout.Main fullWidth>

+ 14 - 1
static/app/views/insights/browser/webVitals/views/webVitalsLandingPage.tsx

@@ -95,7 +95,20 @@ export function WebVitalsLandingPage() {
         </Layout.Header>
       )}
 
-      {isInDomainView && <FrontendHeader module={ModuleName.VITAL} />}
+      {isInDomainView && (
+        <FrontendHeader
+          headerTitle={
+            <Fragment>
+              {MODULE_TITLE}
+              <PageHeadingQuestionTooltip
+                docsUrl={MODULE_DOC_LINK}
+                title={MODULE_DESCRIPTION}
+              />
+            </Fragment>
+          }
+          module={ModuleName.VITAL}
+        />
+      )}
       <Layout.Body>
         <Layout.Main fullWidth>
           <TopMenuContainer>

+ 15 - 1
static/app/views/insights/http/views/httpDomainSummaryPage.tsx

@@ -223,7 +223,21 @@ export function HTTPDomainSummaryPage() {
       )}
 
       {isInDomainView && view === FRONTEND_LANDING_SUB_PATH && (
-        <FrontendHeader module={ModuleName.HTTP} />
+        <FrontendHeader
+          headerTitle={
+            <Fragment>
+              {project && <ProjectAvatar project={project} size={36} />}
+              {domain || NULL_DOMAIN_DESCRIPTION}
+              <DomainStatusLink domain={domain} />
+            </Fragment>
+          }
+          breadcrumbs={[
+            {
+              label: 'Domain Summary',
+            },
+          ]}
+          module={ModuleName.HTTP}
+        />
       )}
 
       {isInDomainView && view === BACKEND_LANDING_SUB_PATH && (

+ 12 - 1
static/app/views/insights/http/views/httpLandingPage.tsx

@@ -189,7 +189,18 @@ export function HTTPLandingPage() {
       )}
 
       {isInDomainView && view === FRONTEND_LANDING_SUB_PATH && (
-        <FrontendHeader module={ModuleName.HTTP} />
+        <FrontendHeader
+          headerTitle={
+            <Fragment>
+              {MODULE_TITLE}
+              <PageHeadingQuestionTooltip
+                docsUrl={MODULE_DOC_LINK}
+                title={MODULE_DESCRIPTION}
+              />
+            </Fragment>
+          }
+          module={ModuleName.HTTP}
+        />
       )}
 
       {isInDomainView && view === BACKEND_LANDING_SUB_PATH && (

+ 8 - 2
static/app/views/insights/pages/frontend/frontendOverviewPage.tsx

@@ -30,7 +30,10 @@ import {ToolRibbon} from 'sentry/views/insights/common/components/ribbon';
 import {ViewTrendsButton} from 'sentry/views/insights/common/components/viewTrendsButton';
 import {useOnboardingProject} from 'sentry/views/insights/common/queries/useOnboardingProject';
 import {FrontendHeader} from 'sentry/views/insights/pages/frontend/frontendPageHeader';
-import {OVERVIEW_PAGE_ALLOWED_OPS} from 'sentry/views/insights/pages/frontend/settings';
+import {
+  FRONTEND_LANDING_TITLE,
+  OVERVIEW_PAGE_ALLOWED_OPS,
+} from 'sentry/views/insights/pages/frontend/settings';
 import {OVERVIEW_PAGE_TITLE} from 'sentry/views/insights/pages/settings';
 import {generateFrontendOtherPerformanceEventView} from 'sentry/views/performance/data';
 import {
@@ -160,7 +163,10 @@ function FrontendOverviewPage() {
       organization={organization}
       renderDisabled={NoAccess}
     >
-      <FrontendHeader headerActions={<ViewTrendsButton />} />
+      <FrontendHeader
+        headerTitle={FRONTEND_LANDING_TITLE}
+        headerActions={<ViewTrendsButton />}
+      />
       <Layout.Body>
         <Layout.Main fullWidth>
           <ModuleLayout.Layout>

+ 22 - 5
static/app/views/insights/pages/frontend/frontendPageHeader.tsx

@@ -1,6 +1,9 @@
 import normalizeUrl from 'sentry/utils/url/normalizeUrl';
 import useOrganization from 'sentry/utils/useOrganization';
-import {DomainViewHeader} from 'sentry/views/insights/pages/domainViewHeader';
+import {
+  DomainViewHeader,
+  type Props as HeaderProps,
+} from 'sentry/views/insights/pages/domainViewHeader';
 import {
   FRONTEND_LANDING_SUB_PATH,
   FRONTEND_LANDING_TITLE,
@@ -9,12 +12,23 @@ import {DOMAIN_VIEW_BASE_URL} from 'sentry/views/insights/pages/settings';
 import {ModuleName} from 'sentry/views/insights/types';
 
 type Props = {
-  headerActions?: React.ReactNode;
-  module?: ModuleName;
+  headerTitle: HeaderProps['headerTitle'];
+  breadcrumbs?: HeaderProps['additionalBreadCrumbs'];
+  headerActions?: HeaderProps['additonalHeaderActions'];
+  hideDefaultTabs?: HeaderProps['hideDefaultTabs'];
+  module?: HeaderProps['selectedModule'];
+  tabs?: HeaderProps['tabs'];
 };
 
 // TODO - add props to append to breadcrumbs and change title
-export function FrontendHeader({module, headerActions}: Props) {
+export function FrontendHeader({
+  module,
+  headerActions,
+  headerTitle,
+  breadcrumbs,
+  tabs,
+  hideDefaultTabs,
+}: Props) {
   const {slug} = useOrganization();
 
   const frontendBaseUrl = normalizeUrl(
@@ -29,8 +43,11 @@ export function FrontendHeader({module, headerActions}: Props) {
       domainTitle={FRONTEND_LANDING_TITLE}
       modules={modules}
       selectedModule={module}
+      additionalBreadCrumbs={breadcrumbs}
       additonalHeaderActions={headerActions}
-      headerTitle={FRONTEND_LANDING_TITLE}
+      headerTitle={headerTitle}
+      tabs={tabs}
+      hideDefaultTabs={hideDefaultTabs}
     />
   );
 }