Skip to content

Commit 2815b3d

Browse files
authored
feat(demo-mode): issues tour (#89399)
1 parent e625053 commit 2815b3d

File tree

8 files changed

+106
-118
lines changed

8 files changed

+106
-118
lines changed

static/app/components/onboardingWizard/content.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {space} from 'sentry/styles/space';
2929
import {type OnboardingTask, OnboardingTaskKey} from 'sentry/types/onboarding';
3030
import {trackAnalytics} from 'sentry/utils/analytics';
3131
import {isDemoModeActive} from 'sentry/utils/demoMode';
32-
import {DemoTour, DemoTourStep, useDemoTours} from 'sentry/utils/demoMode/demoTours';
32+
import {DemoTour, useDemoTours} from 'sentry/utils/demoMode/demoTours';
3333
import {updateDemoWalkthroughTask} from 'sentry/utils/demoMode/guides';
3434
import testableTransition from 'sentry/utils/testableTransition';
3535
import {useLocalStorageState} from 'sentry/utils/useLocalStorageState';
@@ -274,11 +274,12 @@ function Task({task, hidePanel, showWaitingIndicator}: TaskProps) {
274274
e.stopPropagation();
275275

276276
if (isDemoModeActive()) {
277-
// Performance guide is updated to use the new tour
278277
if (task.task === OnboardingTaskKey.PERFORMANCE_GUIDE) {
279-
tours?.[DemoTour.PERFORMANCE]?.startTour(DemoTourStep.PERFORMANCE_TABLE);
278+
tours?.[DemoTour.PERFORMANCE]?.startTour();
280279
} else if (task.task === OnboardingTaskKey.RELEASE_GUIDE) {
281280
tours?.[DemoTour.RELEASES]?.startTour();
281+
} else if (task.task === OnboardingTaskKey.ISSUE_GUIDE) {
282+
tours?.[DemoTour.ISSUES]?.startTour();
282283
} else {
283284
DemoWalkthroughStore.activateGuideAnchor(task.task);
284285
}

static/app/components/stream/group.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import TimeSince from 'sentry/components/timeSince';
2626
import {Tooltip} from 'sentry/components/tooltip';
2727
import {DEFAULT_STATS_PERIOD} from 'sentry/constants';
2828
import {t} from 'sentry/locale';
29-
import DemoWalkthroughStore from 'sentry/stores/demoWalkthroughStore';
3029
import GroupStore from 'sentry/stores/groupStore';
3130
import SelectedGroupStore from 'sentry/stores/selectedGroupStore';
3231
import {useLegacyStore} from 'sentry/stores/useLegacyStore';
@@ -42,7 +41,6 @@ import type {NewQuery} from 'sentry/types/organization';
4241
import type {User} from 'sentry/types/user';
4342
import {defined, percent} from 'sentry/utils';
4443
import {trackAnalytics} from 'sentry/utils/analytics';
45-
import {isDemoModeActive} from 'sentry/utils/demoMode';
4644
import EventView from 'sentry/utils/discover/eventView';
4745
import {SavedQueryDatasets} from 'sentry/utils/discover/types';
4846
import {isCtrlKeyPressed} from 'sentry/utils/isCtrlKeyPressed';
@@ -520,12 +518,6 @@ function StreamGroup({
520518
<Placeholder height="18px" />
521519
);
522520

523-
const issueStreamAnchor = isDemoModeActive() ? (
524-
<GuideAnchor target="issue_stream" disabled={!DemoWalkthroughStore.get('issue')} />
525-
) : (
526-
<GuideAnchor target="issue_stream" />
527-
);
528-
529521
const onClick = (e: React.MouseEvent<HTMLDivElement>) => {
530522
if (displayReprocessingLayout) {
531523
return;
@@ -581,7 +573,7 @@ function StreamGroup({
581573
<EventOrGroupHeader index={index} data={group} query={query} source={referrer} />
582574
<EventOrGroupExtraDetails data={group} showLifetime={false} />
583575
</GroupSummary>
584-
{hasGuideAnchor && issueStreamAnchor}
576+
{hasGuideAnchor && <GuideAnchor target="issue_stream" />}
585577

586578
{withColumns.includes('lastSeen') && (
587579
<LastSeenWrapper breakpoint={COLUMN_BREAKPOINTS.LAST_SEEN}>

static/app/utils/demoMode/demoTours.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ describe('DemoTours', () => {
6464
[DemoTour.ISSUES]: {
6565
currentStepId: null,
6666
isCompleted: false,
67-
orderedStepIds: [DemoTourStep.ISSUES_STREAM, DemoTourStep.ISSUES_TAGS],
67+
orderedStepIds: [DemoTourStep.ISSUES_STREAM, DemoTourStep.ISSUES_AGGREGATES],
6868
isRegistered: true,
6969
tourKey: DemoTour.ISSUES,
7070
},

static/app/utils/demoMode/demoTours.tsx

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ import {createContext, useCallback, useContext, useMemo} from 'react';
22

33
import {recordFinish} from 'sentry/actionCreators/guides';
44
import {
5+
TourElement,
56
TourElementContent,
67
type TourElementProps,
78
} from 'sentry/components/tours/components';
89
import {
910
type TourContextType,
11+
type TourEnumType,
1012
type TourState,
1113
useTourReducer,
1214
} from 'sentry/components/tours/tourContext';
@@ -31,9 +33,9 @@ export const enum DemoTourStep {
3133
SIDEBAR_DISCOVER = 'demo-tour-sidebar-discover',
3234
// Issues steps
3335
ISSUES_STREAM = 'demo-tour-issues-stream',
34-
ISSUES_TAGS = 'demo-tour-issues-tags',
35-
ISSUES_STACKTRACE = 'demo-tour-issues-stacktrace',
36-
ISSUES_BREADCRUMBS = 'demo-tour-issues-breadcrumbs',
36+
ISSUES_AGGREGATES = 'demo-tour-issues-aggregates',
37+
ISSUES_EVENT_DETAILS = 'demo-tour-issues-event-details',
38+
ISSUES_DETAIL_SIDEBAR = 'demo-tour-issues-detail-sidebar',
3739
// Releases steps
3840
RELEASES_COMPARE = 'demo-tour-releases-compare',
3941
RELEASES_DETAILS = 'demo-tour-releases-details',
@@ -80,9 +82,9 @@ const TOUR_STEPS: Record<DemoTour, DemoTourStep[]> = {
8082
],
8183
[DemoTour.ISSUES]: [
8284
DemoTourStep.ISSUES_STREAM,
83-
DemoTourStep.ISSUES_TAGS,
84-
DemoTourStep.ISSUES_STACKTRACE,
85-
DemoTourStep.ISSUES_BREADCRUMBS,
85+
DemoTourStep.ISSUES_AGGREGATES, // Metadata and metrics // view data in aggregate 1/6
86+
DemoTourStep.ISSUES_EVENT_DETAILS, // Explore details // Explore details 3/6
87+
DemoTourStep.ISSUES_DETAIL_SIDEBAR, // Share updates // 6/6
8688
],
8789
[DemoTour.RELEASES]: [
8890
DemoTourStep.RELEASES_COMPARE,
@@ -242,3 +244,38 @@ export function DemoTourElement({
242244
</TourElementContent>
243245
);
244246
}
247+
248+
/**
249+
* A component that renders either a DemoTourElement or regular TourElement depending on whether
250+
* demo mode is active. This allows the same tour content to be shared between demo mode and
251+
* regular product tours.
252+
*/
253+
export function SharedTourElement<T extends TourEnumType>({
254+
id,
255+
demoTourId,
256+
title,
257+
description,
258+
children,
259+
tourContext,
260+
...props
261+
}: TourElementProps<T> & {demoTourId: DemoTourStep}) {
262+
if (isDemoModeActive()) {
263+
return (
264+
<DemoTourElement id={demoTourId} title={title} description={description}>
265+
{children}
266+
</DemoTourElement>
267+
);
268+
}
269+
270+
return (
271+
<TourElement
272+
{...props}
273+
id={id}
274+
title={title}
275+
description={description}
276+
tourContext={tourContext}
277+
>
278+
{children}
279+
</TourElement>
280+
);
281+
}

static/app/utils/demoMode/guides.tsx

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ export function getTourTask(
5454
return {tour: 'tabs', task: OnboardingTaskKey.SIDEBAR_GUIDE};
5555
case 'issues':
5656
return {tour: 'issues', task: OnboardingTaskKey.ISSUE_GUIDE};
57-
// TODO(ogi): Remove this once we merge the new issues tour
58-
case 'issues_v3':
59-
return {tour: 'issues', task: OnboardingTaskKey.ISSUE_GUIDE};
6057
case 'releases':
6158
return {tour: 'releases', task: OnboardingTaskKey.RELEASE_GUIDE};
6259
case 'performance':
@@ -68,17 +65,7 @@ export function getTourTask(
6865
}
6966

7067
export function getDemoGuides() {
71-
return [
72-
{guide: 'sidebar_v2', seen: false},
73-
{guide: 'issues_v3', seen: false},
74-
{guide: 'releases', seen: false},
75-
// {guide: 'react-release', seen: false},
76-
// {guide: 'release-details_v2', seen: false},e
77-
{guide: 'performance', seen: false},
78-
// {guide: 'transaction_summary', seen: false},
79-
// {guide: 'transaction_details_v2', seen: false},
80-
{guide: 'issue_stream_v3', seen: false},
81-
];
68+
return [{guide: 'sidebar_v2', seen: false}];
8269
}
8370

8471
export function getDemoModeGuides(): GuidesContent {
@@ -127,48 +114,5 @@ export function getDemoModeGuides(): GuidesContent {
127114
},
128115
],
129116
},
130-
{
131-
guide: 'issue_stream_v3',
132-
requiredTargets: ['issue_stream'],
133-
steps: [
134-
{
135-
title: t('Issues'),
136-
target: 'issue_stream',
137-
description: t(
138-
`Sentry automatically groups similar events together into an issue. Similarity is
139-
determined by stack trace and other factors. Click on an issue to learn more.`
140-
),
141-
},
142-
],
143-
},
144-
{
145-
guide: 'issues_v3',
146-
requiredTargets: ['tags'],
147-
steps: [
148-
{
149-
title: t('Metadata and metrics'),
150-
target: 'tags',
151-
description: t(
152-
`See tags like specific users affected by the event, device, OS, and browser type.
153-
On the right side of the page you can view the number of affected users and exception frequency overtime.`
154-
),
155-
},
156-
{
157-
title: t('Find your broken code'),
158-
target: 'stacktrace',
159-
description: t(
160-
`View the stack trace to see the exact sequence of function calls leading to the error in question.`
161-
),
162-
},
163-
{
164-
title: t('Retrace your steps'),
165-
target: 'breadcrumbs',
166-
description: t(
167-
`Sentry automatically captures breadcrumbs for events so you can see the sequence of events leading up to the error.`
168-
),
169-
nextText: t('Got it'),
170-
},
171-
],
172-
},
173117
];
174118
}

static/app/views/issueDetails/streamline/groupDetailsLayout.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import {useTheme} from '@emotion/react';
22
import styled from '@emotion/styled';
33

4-
import {TourElement} from 'sentry/components/tours/components';
54
import {t} from 'sentry/locale';
65
import {space} from 'sentry/styles/space';
76
import type {Event} from 'sentry/types/event';
87
import type {Group} from 'sentry/types/group';
98
import type {Project} from 'sentry/types/project';
9+
import {DemoTourStep, SharedTourElement} from 'sentry/utils/demoMode/demoTours';
1010
import {getConfigForIssueType} from 'sentry/utils/issueTypeConfig';
1111
import useMedia from 'sentry/utils/useMedia';
1212
import {
@@ -58,20 +58,22 @@ export function GroupDetailsLayout({
5858
sidebarOpen={issueDetails.isSidebarOpen}
5959
>
6060
<div>
61-
<TourElement<IssueDetailsTour>
62-
tourContext={IssueDetailsTourContext}
61+
<SharedTourElement<IssueDetailsTour>
6362
id={IssueDetailsTour.AGGREGATES}
63+
demoTourId={DemoTourStep.ISSUES_AGGREGATES}
64+
tourContext={IssueDetailsTourContext}
6465
title={t('View data in aggregate')}
6566
description={t(
6667
'The top section of the page always displays data in aggregate, including trends over time or tag value distributions.'
6768
)}
6869
position="bottom"
6970
>
7071
<EventDetailsHeader event={event} group={group} project={project} />
71-
</TourElement>
72-
<TourElement<IssueDetailsTour>
73-
tourContext={IssueDetailsTourContext}
72+
</SharedTourElement>
73+
<SharedTourElement<IssueDetailsTour>
7474
id={IssueDetailsTour.EVENT_DETAILS}
75+
demoTourId={DemoTourStep.ISSUES_EVENT_DETAILS}
76+
tourContext={IssueDetailsTourContext}
7577
title={t('Explore details')}
7678
description={t(
7779
'Here we capture everything we know about this data example, like context, trace, breadcrumbs, replay, and tags.'
@@ -86,7 +88,7 @@ export function GroupDetailsLayout({
8688
</NavigationSidebarWrapper>
8789
<ContentPadding>{children}</ContentPadding>
8890
</GroupContent>
89-
</TourElement>
91+
</SharedTourElement>
9092
</div>
9193
{shouldDisplaySidebar ? (
9294
<StreamlinedSidebar group={group} event={event} project={project} />

static/app/views/issueDetails/streamline/sidebar/sidebar.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import styled from '@emotion/styled';
55
import ErrorBoundary from 'sentry/components/errorBoundary';
66
import * as Layout from 'sentry/components/layouts/thirds';
77
import * as SidebarSection from 'sentry/components/sidebarSection';
8-
import {TourElement} from 'sentry/components/tours/components';
98
import {t} from 'sentry/locale';
109
import {space} from 'sentry/styles/space';
1110
import type {Event} from 'sentry/types/event';
1211
import type {Group, TeamParticipant, UserParticipant} from 'sentry/types/group';
1312
import type {Project} from 'sentry/types/project';
13+
import {DemoTourStep, SharedTourElement} from 'sentry/utils/demoMode/demoTours';
1414
import {getConfigForIssueType} from 'sentry/utils/issueTypeConfig';
1515
import useMedia from 'sentry/utils/useMedia';
1616
import useOrganization from 'sentry/utils/useOrganization';
@@ -52,9 +52,10 @@ export default function StreamlinedSidebar({group, event, project}: Props) {
5252
const isBottomSidebar = useMedia(`(max-width: ${theme.breakpoints.large})`);
5353

5454
return (
55-
<TourElement<IssueDetailsTour>
55+
<SharedTourElement<IssueDetailsTour>
5656
tourContext={IssueDetailsTourContext}
5757
id={IssueDetailsTour.SIDEBAR}
58+
demoTourId={DemoTourStep.ISSUES_DETAIL_SIDEBAR}
5859
title={t('Share updates')}
5960
description={t(
6061
'Leave a comment for a teammate or link your favorite ticketing system - this area helps you collaborate and track progress on the issue.'
@@ -105,7 +106,7 @@ export default function StreamlinedSidebar({group, event, project}: Props) {
105106
</Fragment>
106107
)}
107108
</Side>
108-
</TourElement>
109+
</SharedTourElement>
109110
);
110111
}
111112

0 commit comments

Comments
 (0)