Skip to content

Commit a864884

Browse files
Abdkhan14Abdullah Khan
authored andcommitted
feat(new-trace-issues): Updating designs for trace preview in issue details (#83430)
- Added 'View Full Trace' action - Made full waterfall clickable, removed darkened bg effect - Updated title <img width="881" alt="Screenshot 2025-01-14 at 3 20 20 PM" src="https://github.com/user-attachments/assets/2690e9d7-f620-4304-8438-bde5a51c056a" /> --------- Co-authored-by: Abdullah Khan <[email protected]>
1 parent 660ada4 commit a864884

File tree

3 files changed

+58
-56
lines changed

3 files changed

+58
-56
lines changed

static/app/components/events/interfaces/performance/eventTraceView.spec.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ describe('EventTraceView', () => {
156156
render(
157157
<EventTraceView group={perfGroup} event={perfEvent} organization={organization} />
158158
);
159-
expect(await screen.findByText('Trace')).toBeInTheDocument();
159+
expect(await screen.findByText('Trace Preview')).toBeInTheDocument();
160160
expect(
161161
await screen.findByRole('link', {name: 'View Full Trace'})
162162
).toBeInTheDocument();
@@ -192,6 +192,6 @@ describe('EventTraceView', () => {
192192

193193
render(<EventTraceView group={group} event={event} organization={organization} />);
194194

195-
expect(await screen.findByText('Trace')).toBeInTheDocument();
195+
expect(await screen.findByText('Trace Preview')).toBeInTheDocument();
196196
});
197197
});

static/app/components/events/interfaces/performance/eventTraceView.tsx

+53-54
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import styled from '@emotion/styled';
33
import type {LocationDescriptor} from 'history';
44

55
import {LinkButton} from 'sentry/components/button';
6+
import ExternalLink from 'sentry/components/links/externalLink';
67
import Link from 'sentry/components/links/link';
78
import {generateTraceTarget} from 'sentry/components/quickTrace/utils';
89
import {IconOpen} from 'sentry/icons';
@@ -11,6 +12,7 @@ import type {Event} from 'sentry/types/event';
1112
import {type Group, IssueCategory} from 'sentry/types/group';
1213
import type {Organization} from 'sentry/types/organization';
1314
import {defined} from 'sentry/utils';
15+
import {trackAnalytics} from 'sentry/utils/analytics';
1416
import useRouteAnalyticsParams from 'sentry/utils/routeAnalytics/useRouteAnalyticsParams';
1517
import {useLocation} from 'sentry/utils/useLocation';
1618
import useOrganization from 'sentry/utils/useOrganization';
@@ -58,9 +60,15 @@ interface EventTraceViewInnerProps {
5860
event: Event;
5961
organization: Organization;
6062
traceId: string;
63+
traceTarget: LocationDescriptor;
6164
}
6265

63-
function EventTraceViewInner({event, organization, traceId}: EventTraceViewInnerProps) {
66+
function EventTraceViewInner({
67+
event,
68+
organization,
69+
traceId,
70+
traceTarget,
71+
}: EventTraceViewInnerProps) {
6472
const timestamp = new Date(event.dateReceived).getTime() / 1e3;
6573

6674
const trace = useTrace({
@@ -108,7 +116,14 @@ function EventTraceViewInner({event, organization, traceId}: EventTraceViewInner
108116
replay={null}
109117
event={event}
110118
/>
111-
<IssuesTraceOverlay event={event} />
119+
<IssuesTraceOverlayContainer
120+
href={getHrefFromTraceTarget(traceTarget)}
121+
onClick={() => {
122+
trackAnalytics('issue_details.view_full_trace_waterfall_clicked', {
123+
organization,
124+
});
125+
}}
126+
/>
112127
</IssuesTraceContainer>
113128
</TraceStateProvider>
114129
);
@@ -129,39 +144,6 @@ function getHrefFromTraceTarget(traceTarget: LocationDescriptor) {
129144
return `${traceTarget.pathname}?${searchParams.toString()}`;
130145
}
131146

132-
function IssuesTraceOverlay({event}: {event: Event}) {
133-
const location = useLocation();
134-
const organization = useOrganization();
135-
136-
const traceTarget = generateTraceTarget(
137-
event,
138-
organization,
139-
{
140-
...location,
141-
query: {
142-
...location.query,
143-
groupId: event.groupID,
144-
},
145-
},
146-
TraceViewSources.ISSUE_DETAILS
147-
);
148-
149-
return (
150-
<IssuesTraceOverlayContainer>
151-
<LinkButton
152-
size="sm"
153-
icon={<IconOpen />}
154-
href={getHrefFromTraceTarget(traceTarget)}
155-
external
156-
analyticsEventName="Issue Details: View Full Trace"
157-
analyticsEventKey="issue_details.view_full_trace"
158-
>
159-
{t('View Full Trace')}
160-
</LinkButton>
161-
</IssuesTraceOverlayContainer>
162-
);
163-
}
164-
165147
function OneOtherIssueEvent({event}: {event: Event}) {
166148
const location = useLocation();
167149
const organization = useOrganization();
@@ -200,52 +182,69 @@ const IssuesTraceContainer = styled('div')`
200182
position: relative;
201183
`;
202184

203-
const IssuesTraceOverlayContainer = styled('div')`
185+
const IssuesTraceOverlayContainer = styled(ExternalLink)`
204186
position: absolute;
205187
inset: 0;
206188
z-index: 10;
207-
208-
a {
209-
display: none;
210-
position: absolute;
211-
top: 50%;
212-
left: 50%;
213-
transform: translate(-50%, -50%);
214-
}
215-
216-
&:hover {
217-
background-color: rgba(128, 128, 128, 0.4);
218-
219-
a {
220-
display: block;
221-
}
222-
}
223189
`;
224190

225-
interface EventTraceViewProps extends Omit<EventTraceViewInnerProps, 'traceId'> {
191+
interface EventTraceViewProps {
192+
event: Event;
226193
group: Group;
194+
organization: Organization;
227195
}
228196

229197
export function EventTraceView({group, event, organization}: EventTraceViewProps) {
230198
const traceId = event.contexts.trace?.trace_id;
199+
const location = useLocation();
200+
231201
if (!traceId) {
232202
return null;
233203
}
234204

205+
const traceTarget = generateTraceTarget(
206+
event,
207+
organization,
208+
{
209+
...location,
210+
query: {
211+
...location.query,
212+
groupId: event.groupID,
213+
},
214+
},
215+
TraceViewSources.ISSUE_DETAILS
216+
);
217+
235218
const hasProfilingFeature = organization.features.includes('profiling');
236219
const hasTracePreviewFeature =
237220
hasProfilingFeature &&
238221
// Only display this for error or default events since performance events are handled elsewhere
239222
group.issueCategory !== IssueCategory.PERFORMANCE;
240223

241224
return (
242-
<InterimSection type={SectionKey.TRACE} title={t('Trace')}>
225+
<InterimSection
226+
type={SectionKey.TRACE}
227+
title={t('Trace Preview')}
228+
actions={
229+
<LinkButton
230+
size="xs"
231+
icon={<IconOpen />}
232+
href={getHrefFromTraceTarget(traceTarget)}
233+
external
234+
analyticsEventName="Issue Details: View Full Trace Action Button Clicked"
235+
analyticsEventKey="issue_details.view_full_trace_action_button_clicked"
236+
>
237+
{t('View Full Trace')}
238+
</LinkButton>
239+
}
240+
>
243241
<OneOtherIssueEvent event={event} />
244242
{hasTracePreviewFeature && (
245243
<EventTraceViewInner
246244
event={event}
247245
organization={organization}
248246
traceId={traceId}
247+
traceTarget={traceTarget}
249248
/>
250249
)}
251250
</InterimSection>

static/app/utils/analytics/issueAnalyticsEvents.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ export type IssueEventParameters = {
168168
'issue_details.streamline_ui_toggle': {
169169
isEnabled: boolean;
170170
};
171+
'issue_details.view_full_trace_waterfall_clicked': {};
171172
'issue_details.view_hierarchy.hover_rendering_system': {
172173
platform?: string;
173174
user_org_role?: string;
@@ -463,6 +464,8 @@ export const issueEventMap: Record<IssueEventKey, string | null> = {
463464
'Issue Group Details: Tags distribution value bar clicked',
464465
'integrations.integration_reinstall_clicked': 'Integration Reinstall Button Clicked',
465466
'one_other_related_trace_issue.clicked': 'One Other Related Trace Issue Clicked',
467+
'issue_details.view_full_trace_waterfall_clicked':
468+
' Issue Details: View Full Trace Waterfall Clicked',
466469

467470
// Performance Issue specific events here
468471
'issue_details.performance.autogrouped_siblings_toggle':

0 commit comments

Comments
 (0)