Просмотр исходного кода

fix(insights): fix transaction links from domain views (#79984)

1. Fixes several links from module -> transaction by taking them to the
correct domain view transaction summary. The main contenders are
- the `View transaction summary` button in web vitals
- The transaction name at the top of the span samples panel.

2. Fixes several cases where the transaction summary url is hardcoded.
Dominik Buszowiecki 4 месяцев назад
Родитель
Сommit
52ab78bdc0

+ 2 - 1
static/app/components/events/eventTags/eventTagContent.tsx

@@ -11,6 +11,7 @@ import {IconOpen} from 'sentry/icons';
 import type {EventTag} from 'sentry/types/event';
 import type {Organization} from 'sentry/types/organization';
 import {isUrl} from 'sentry/utils/string/isUrl';
+import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils';
 
 const iconStyle = css`
   position: relative;
@@ -58,7 +59,7 @@ function EventTagsContent({
           <EventTagsValue
             tag={tag}
             meta={meta?.value?.['']}
-            streamPath={`/organizations/${organization.slug}/performance/summary/`}
+            streamPath={`${getTransactionSummaryBaseUrl(organization.slug)}/`}
             locationSearch={`?${qs.stringify({
               project: projectId,
               transaction: value,

+ 3 - 2
static/app/components/events/eventTags/eventTagsTreeRow.tsx

@@ -23,6 +23,7 @@ import {isUrl} from 'sentry/utils/string/isUrl';
 import useCopyToClipboard from 'sentry/utils/useCopyToClipboard';
 import useMutateProject from 'sentry/utils/useMutateProject';
 import useOrganization from 'sentry/utils/useOrganization';
+import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils';
 
 interface EventTagTreeRowConfig {
   // Omits the dropdown of actions applicable to this tag
@@ -204,7 +205,7 @@ function EventTagsTreeRowDropdown({
           to:
             originalTag.key === 'transaction'
               ? {
-                  pathname: `/organizations/${organization.slug}/performance/summary/`,
+                  pathname: `${getTransactionSummaryBaseUrl(organization.slug)}/`,
                   query: {
                     project: event.projectID,
                     transaction: content.value,
@@ -281,7 +282,7 @@ function EventTagsTreeValue({
         transaction: content.value,
         referrer,
       });
-      const transactionDestination = `/organizations/${organization.slug}/performance/summary/?${transactionQuery}`;
+      const transactionDestination = `${getTransactionSummaryBaseUrl(organization.slug)}/?${transactionQuery}`;
       tagValue = (
         <TagLinkText>
           <Link to={transactionDestination}>{content.value}</Link>

+ 2 - 1
static/app/views/insights/browser/webVitals/views/pageOverview.tsx

@@ -77,7 +77,7 @@ export function PageOverview() {
   const location = useLocation();
   const {projects} = useProjects();
   const router = useRouter();
-  const {isInDomainView} = useDomainViewFilters();
+  const {isInDomainView, view} = useDomainViewFilters();
   const transaction = location.query.transaction
     ? Array.isArray(location.query.transaction)
       ? location.query.transaction[0]
@@ -128,6 +128,7 @@ export function PageOverview() {
       transaction,
       query: {...location.query},
       projectID: project.id,
+      view,
     });
 
   const projectScore =

+ 4 - 1
static/app/views/insights/cache/components/samplePanel.tsx

@@ -45,6 +45,7 @@ import {
   getThroughputTitle,
 } from 'sentry/views/insights/common/views/spans/types';
 import {useDebouncedState} from 'sentry/views/insights/http/utils/useDebouncedState';
+import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters';
 import {
   MetricsFields,
   type MetricsQueryFilters,
@@ -56,6 +57,7 @@ import {
   SpanMetricsField,
   type SpanMetricsQueryFilters,
 } from 'sentry/views/insights/types';
+import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils';
 
 // This is similar to http sample table, its difficult to use the generic span samples sidebar as we require a bunch of custom things.
 export function CacheSamplePanel() {
@@ -63,6 +65,7 @@ export function CacheSamplePanel() {
   const location = useLocation();
   const organization = useOrganization();
   const {selection} = usePageFilters();
+  const {view} = useDomainViewFilters();
 
   const query = useLocationQuery({
     fields: {
@@ -279,7 +282,7 @@ export function CacheSamplePanel() {
               <Title>
                 <Link
                   to={normalizeUrl(
-                    `/organizations/${organization.slug}/performance/summary?${qs.stringify(
+                    `${getTransactionSummaryBaseUrl(organization.slug, view)}?${qs.stringify(
                       {
                         project: query.project,
                         transaction: query.transaction,

+ 7 - 2
static/app/views/insights/common/views/spanSummaryPage/sampleList/index.tsx

@@ -27,12 +27,14 @@ import {DEFAULT_COLUMN_ORDER} from 'sentry/views/insights/common/components/samp
 import DurationChart from 'sentry/views/insights/common/views/spanSummaryPage/sampleList/durationChart';
 import SampleInfo from 'sentry/views/insights/common/views/spanSummaryPage/sampleList/sampleInfo';
 import SampleTable from 'sentry/views/insights/common/views/spanSummaryPage/sampleList/sampleTable/sampleTable';
+import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters';
 import {
   ModuleName,
   SpanIndexedField,
   SpanMetricsField,
   type SubregionCode,
 } from 'sentry/views/insights/types';
+import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils';
 
 const {HTTP_RESPONSE_CONTENT_LENGTH, SPAN_DESCRIPTION} = SpanMetricsField;
 
@@ -54,14 +56,18 @@ export function SampleList({
   transactionMethod,
   subregions,
   onClose,
-  transactionRoute = '/performance/summary/',
+  transactionRoute,
   referrer,
 }: Props) {
+  const organization = useOrganization();
+  const {view} = useDomainViewFilters();
   const router = useRouter();
   const [highlightedSpanId, setHighlightedSpanId] = useState<string | undefined>(
     undefined
   );
 
+  transactionRoute ??= `/${getTransactionSummaryBaseUrl(organization.slug, view, true)}`;
+
   // A a transaction name is required to show the panel, but a transaction
   // method is not
   const detailKey = transactionName
@@ -76,7 +82,6 @@ export function SampleList({
     []
   );
 
-  const organization = useOrganization();
   const {selection} = usePageFilters();
   const location = useLocation();
   const {projects} = useProjects();

+ 9 - 9
static/app/views/insights/http/components/httpSamplesPanel.tsx

@@ -19,7 +19,6 @@ import {
   escapeFilterValue,
   MutableSearch,
 } from 'sentry/utils/tokenizeSearch';
-import normalizeUrl from 'sentry/utils/url/normalizeUrl';
 import useLocationQuery from 'sentry/utils/url/useLocationQuery';
 import {useLocation} from 'sentry/utils/useLocation';
 import {useNavigate} from 'sentry/utils/useNavigate';
@@ -55,6 +54,7 @@ import {BASE_FILTERS} from 'sentry/views/insights/http/settings';
 import decodePanel from 'sentry/views/insights/http/utils/queryParameterDecoders/panel';
 import decodeResponseCodeClass from 'sentry/views/insights/http/utils/queryParameterDecoders/responseCodeClass';
 import {useDebouncedState} from 'sentry/views/insights/http/utils/useDebouncedState';
+import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters';
 import {
   ModuleName,
   SpanFunction,
@@ -63,6 +63,7 @@ import {
   type SpanMetricsQueryFilters,
 } from 'sentry/views/insights/types';
 import {TraceViewSources} from 'sentry/views/performance/newTraceDetails/traceHeader/breadcrumbs';
+import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils';
 
 export function HTTPSamplesPanel() {
   const navigate = useNavigate();
@@ -82,6 +83,7 @@ export function HTTPSamplesPanel() {
   });
 
   const organization = useOrganization();
+  const {view} = useDomainViewFilters();
 
   const {projects} = useProjects();
   const {selection} = usePageFilters();
@@ -328,14 +330,12 @@ export function HTTPSamplesPanel() {
               )}
               <Title>
                 <Link
-                  to={normalizeUrl(
-                    `/organizations/${organization.slug}/performance/summary?${qs.stringify(
-                      {
-                        project: query.project,
-                        transaction: query.transaction,
-                      }
-                    )}`
-                  )}
+                  to={`${getTransactionSummaryBaseUrl(organization.slug, view)}?${qs.stringify(
+                    {
+                      project: query.project,
+                      transaction: query.transaction,
+                    }
+                  )}`}
                 >
                   {query.transaction &&
                   query.transactionMethod &&

+ 7 - 2
static/app/views/insights/mobile/common/components/spanSamplesPanel.tsx

@@ -17,7 +17,9 @@ import DetailPanel from 'sentry/views/insights/common/components/detailPanel';
 import {useReleaseSelection} from 'sentry/views/insights/common/queries/useReleases';
 import {SpanSamplesContainer} from 'sentry/views/insights/mobile/common/components/spanSamplesPanelContainer';
 import useCrossPlatformProject from 'sentry/views/insights/mobile/common/queries/useCrossPlatformProject';
+import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters';
 import type {ModuleName} from 'sentry/views/insights/types';
+import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils';
 
 type Props = {
   groupId: string;
@@ -41,11 +43,15 @@ export function SpanSamplesPanel({
   transactionMethod,
   spanDescription,
   onClose,
-  transactionRoute = '/performance/summary/',
+  transactionRoute,
   spanOp,
   additionalFilters,
 }: Props) {
   const router = useRouter();
+  const organization = useOrganization();
+  const {view} = useDomainViewFilters();
+
+  transactionRoute ??= getTransactionSummaryBaseUrl(organization.slug, view);
 
   const {primaryRelease, secondaryRelease} = useReleaseSelection();
 
@@ -55,7 +61,6 @@ export function SpanSamplesPanel({
     ? [groupId, transactionName, transactionMethod].filter(Boolean).join(':')
     : undefined;
 
-  const organization = useOrganization();
   const {query} = useLocation();
   const {project} = useCrossPlatformProject();
 

+ 9 - 9
static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx

@@ -14,7 +14,6 @@ import {DurationUnit, SizeUnit} from 'sentry/utils/discover/fields';
 import {PageAlertProvider} from 'sentry/utils/performance/contexts/pageAlert';
 import {decodeScalar} from 'sentry/utils/queryString';
 import {MutableSearch} from 'sentry/utils/tokenizeSearch';
-import normalizeUrl from 'sentry/utils/url/normalizeUrl';
 import useLocationQuery from 'sentry/utils/url/useLocationQuery';
 import {useLocation} from 'sentry/utils/useLocation';
 import {useNavigate} from 'sentry/utils/useNavigate';
@@ -32,6 +31,7 @@ import {useSampleScatterPlotSeries} from 'sentry/views/insights/common/views/spa
 import {DurationChart} from 'sentry/views/insights/http/components/charts/durationChart';
 import {useSpanSamples} from 'sentry/views/insights/http/queries/useSpanSamples';
 import {useDebouncedState} from 'sentry/views/insights/http/utils/useDebouncedState';
+import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters';
 import {MessageSpanSamplesTable} from 'sentry/views/insights/queues/components/tables/messageSpanSamplesTable';
 import {useQueuesMetricsQuery} from 'sentry/views/insights/queues/queries/useQueuesMetricsQuery';
 import {Referrer} from 'sentry/views/insights/queues/referrers';
@@ -49,6 +49,7 @@ import {
   SpanIndexedField,
   type SpanMetricsResponse,
 } from 'sentry/views/insights/types';
+import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils';
 import {Subtitle} from 'sentry/views/profiling/landing/styles';
 
 export function MessageSpanSamplesPanel() {
@@ -71,6 +72,7 @@ export function MessageSpanSamplesPanel() {
   const project = projects.find(p => query.project === p.id);
 
   const organization = useOrganization();
+  const {view} = useDomainViewFilters();
 
   const [highlightedSpanId, setHighlightedSpanId] = useDebouncedState<string | undefined>(
     undefined,
@@ -271,14 +273,12 @@ export function MessageSpanSamplesPanel() {
                 </Subtitle>
                 <Title>
                   <Link
-                    to={normalizeUrl(
-                      `/organizations/${organization.slug}/performance/summary?${qs.stringify(
-                        {
-                          project: query.project,
-                          transaction: query.transaction,
-                        }
-                      )}`
-                    )}
+                    to={`${getTransactionSummaryBaseUrl(organization.slug, view)}?${qs.stringify(
+                      {
+                        project: query.project,
+                        transaction: query.transaction,
+                      }
+                    )}`}
                   >
                     {query.transaction}
                   </Link>

+ 2 - 1
static/app/views/performance/transactionSummary/transactionVitals/utils.tsx

@@ -5,11 +5,12 @@ import type {WebVital} from 'sentry/utils/fields';
 import type {HistogramData} from 'sentry/utils/performance/histogram/types';
 import {getBucketWidth} from 'sentry/utils/performance/histogram/utils';
 import type {VitalsData} from 'sentry/utils/performance/vitals/vitalsCardsDiscoverQuery';
+import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils';
 
 import type {Point, Rectangle} from './types';
 
 export function generateVitalsRoute({orgSlug}: {orgSlug: string}): string {
-  return `/organizations/${orgSlug}/performance/summary/vitals/`;
+  return `${getTransactionSummaryBaseUrl(orgSlug)}/vitals/`;
 }
 
 export function vitalsRouteWithQuery({

+ 7 - 3
static/app/views/performance/transactionSummary/utils.tsx

@@ -45,7 +45,7 @@ export function generateTransactionSummaryRoute({
   subPath?: string;
   view?: DomainView; // TODO - this should be mantatory once we release domain view
 }): string {
-  return `${getPerformanceBaseUrl(orgSlug, view)}/summary/${subPath ? `${subPath}/` : ''}`;
+  return `${getTransactionSummaryBaseUrl(orgSlug, view)}/${subPath ? `${subPath}/` : ''}`;
 }
 
 // normalizes search conditions by removing any redundant search conditions before presenting them in:
@@ -265,8 +265,12 @@ export function generateReplayLink(routes: PlainRoute<any>[]) {
   };
 }
 
-export function getTransactionSummaryBaseUrl(orgSlug: string, view?: DomainView) {
-  return `${getPerformanceBaseUrl(orgSlug, view)}/summary`;
+export function getTransactionSummaryBaseUrl(
+  orgSlug: string,
+  view?: DomainView,
+  bare: boolean = false
+) {
+  return `${getPerformanceBaseUrl(orgSlug, view, bare)}/summary`;
 }
 
 export const SidebarSpacer = styled('div')`

Некоторые файлы не были показаны из-за большого количества измененных файлов