Skip to content

Commit cc5d0cd

Browse files
authored
feat(trace-view): Add a new page for trace view (#24195)
This adds a new page for the trace view at `/organizations/:orgId/performance/trace/:traceSlug/`. This also splits the condition to enable quick trace by allowing either `trace-view-quick` or `trace-view-summary` instead of both.
1 parent 0f7b6f8 commit cc5d0cd

File tree

8 files changed

+147
-3
lines changed

8 files changed

+147
-3
lines changed

src/sentry/static/sentry/app/routes.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,6 +1810,24 @@ function routes() {
18101810
component={errorHandler(LazyLoad)}
18111811
/>
18121812
</Route>
1813+
<Route
1814+
path="/organizations/:orgId/performance/trace/:traceSlug/"
1815+
componentPromise={() =>
1816+
import(
1817+
/* webpackChunkName: "PerformanceContainer" */ 'app/views/performance'
1818+
)
1819+
}
1820+
component={errorHandler(LazyLoad)}
1821+
>
1822+
<IndexRoute
1823+
componentPromise={() =>
1824+
import(
1825+
/* webpackChunkName: "PerformanceTraceDetails" */ 'app/views/performance/traceDetails'
1826+
)
1827+
}
1828+
component={errorHandler(LazyLoad)}
1829+
/>
1830+
</Route>
18131831
<Route
18141832
path="/organizations/:orgId/performance/:eventSlug/"
18151833
componentPromise={() =>

src/sentry/static/sentry/app/views/eventsV2/eventDetails/content.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,8 @@ class EventDetailsContent extends AsyncComponent<Props, State> {
270270

271271
const hasQuickTraceView =
272272
event.type === 'transaction' &&
273-
organization.features.includes('trace-view-quick') &&
274-
organization.features.includes('trace-view-summary');
273+
(organization.features.includes('trace-view-quick') ||
274+
organization.features.includes('trace-view-summary'));
275275

276276
if (hasQuickTraceView) {
277277
return (

src/sentry/static/sentry/app/views/performance/breadcrumb.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type Props = {
1717
transactionName?: string;
1818
vitalName?: string;
1919
eventSlug?: string;
20+
traceSlug?: string;
2021
transactionComparison?: boolean;
2122
realUserMonitoring?: boolean;
2223
};
@@ -30,6 +31,7 @@ class Breadcrumb extends React.Component<Props> {
3031
transactionName,
3132
vitalName,
3233
eventSlug,
34+
traceSlug,
3335
transactionComparison,
3436
realUserMonitoring,
3537
} = this.props;
@@ -101,6 +103,11 @@ class Breadcrumb extends React.Component<Props> {
101103
to: '',
102104
label: t('Compare to Baseline'),
103105
});
106+
} else if (traceSlug) {
107+
crumbs.push({
108+
to: '',
109+
label: t('Trace View'),
110+
});
104111
}
105112

106113
return crumbs;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react';
2+
import {Params} from 'react-router/lib/Router';
3+
import {Location} from 'history';
4+
5+
import * as Layout from 'app/components/layouts/thirds';
6+
import {t} from 'app/locale';
7+
import {Organization} from 'app/types';
8+
import Breadcrumb from 'app/views/performance/breadcrumb';
9+
10+
type Props = {
11+
location: Location;
12+
organization: Organization;
13+
params: Params;
14+
traceSlug: string;
15+
};
16+
17+
class TraceDetailsContent extends React.Component<Props> {
18+
render() {
19+
const {organization, location, traceSlug} = this.props;
20+
21+
return (
22+
<React.Fragment>
23+
<Layout.Header>
24+
<Layout.HeaderContent>
25+
<Breadcrumb
26+
organization={organization}
27+
location={location}
28+
traceSlug={traceSlug}
29+
/>
30+
<Layout.Title data-test-id="trace-header">
31+
{t('Trace Id: %s', traceSlug)}
32+
</Layout.Title>
33+
</Layout.HeaderContent>
34+
</Layout.Header>
35+
<Layout.Body>
36+
<Layout.Main fullWidth>{null}</Layout.Main>
37+
</Layout.Body>
38+
</React.Fragment>
39+
);
40+
}
41+
}
42+
43+
export default TraceDetailsContent;
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import React from 'react';
2+
import {Params} from 'react-router/lib/Router';
3+
import styled from '@emotion/styled';
4+
import {Location} from 'history';
5+
6+
import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
7+
import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
8+
import {t} from 'app/locale';
9+
import {PageContent} from 'app/styles/organization';
10+
import {Organization} from 'app/types';
11+
import withOrganization from 'app/utils/withOrganization';
12+
13+
import TraceDetailsContent from './content';
14+
15+
type Props = {
16+
location: Location;
17+
organization: Organization;
18+
params: Params;
19+
};
20+
21+
class TraceSummary extends React.Component<Props> {
22+
getTraceSlug(): string {
23+
const {traceSlug} = this.props.params;
24+
return typeof traceSlug === 'string' ? traceSlug.trim() : '';
25+
}
26+
27+
getDocumentTitle(): string {
28+
return [t('Trace Details'), t('Performance')].join(' - ');
29+
}
30+
31+
render() {
32+
const {location, organization, params} = this.props;
33+
this.getTraceSlug();
34+
35+
return (
36+
<SentryDocumentTitle title={this.getDocumentTitle()} objSlug={organization.slug}>
37+
<StyledPageContent>
38+
<LightWeightNoProjectMessage organization={organization}>
39+
<TraceDetailsContent
40+
location={location}
41+
organization={organization}
42+
params={params}
43+
traceSlug={this.getTraceSlug()}
44+
/>
45+
</LightWeightNoProjectMessage>
46+
</StyledPageContent>
47+
</SentryDocumentTitle>
48+
);
49+
}
50+
}
51+
52+
export default withOrganization(TraceSummary);
53+
54+
const StyledPageContent = styled(PageContent)`
55+
padding: 0;
56+
`;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import {LocationDescriptor, Query} from 'history';
2+
3+
import {OrganizationSummary} from 'app/types';
4+
5+
export function getTraceSummaryUrl(
6+
organization: OrganizationSummary,
7+
traceSlug: string,
8+
query: Query
9+
): LocationDescriptor {
10+
return {
11+
pathname: `/organizations/${organization.slug}/performance/trace/${traceSlug}/`,
12+
query: {...query},
13+
};
14+
}

src/sentry/static/sentry/app/views/performance/transactionDetails/content.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ class EventDetailsContent extends AsyncComponent<Props, State> {
210210
);
211211

212212
const hasQuickTraceView =
213-
organization.features.includes('trace-view-quick') &&
213+
organization.features.includes('trace-view-quick') ||
214214
organization.features.includes('trace-view-summary');
215215

216216
if (hasQuickTraceView) {

src/sentry/static/sentry/app/views/performance/transactionDetails/utils.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {generateEventSlug} from 'app/utils/discover/urls';
99
import {EventLite} from 'app/utils/performance/quickTrace/types';
1010
import {QueryResults, stringifyQueryObject} from 'app/utils/tokenizeSearch';
1111

12+
import {getTraceSummaryUrl} from '../traceDetails/utils';
1213
import {getTransactionDetailsUrl} from '../utils';
1314

1415
export function generateSingleEventTarget(
@@ -72,6 +73,11 @@ export function generateTraceTarget(
7273
organization: OrganizationSummary
7374
): LocationDescriptor {
7475
const traceId = event.contexts?.trace?.trace_id ?? '';
76+
77+
if (organization.features.includes('trace-view-summary')) {
78+
return getTraceSummaryUrl(organization, traceId, {});
79+
}
80+
7581
const {start, end} = getTraceDateTimeRange({
7682
start: event.startTimestamp,
7783
end: event.endTimestamp,

0 commit comments

Comments
 (0)