Skip to content

Commit 7e9059e

Browse files
authored
fix(autofix): Fix onboarding bug (#94240)
Fixes showing the wrong step first, and fixes missing next/back buttons. Also adding a subtle animation so its less jarring when it pops in.
1 parent 884e504 commit 7e9059e

File tree

2 files changed

+157
-142
lines changed

2 files changed

+157
-142
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ describe('SeerNotices', function () {
104104
expect(screen.queryByText('Unleash Automation')).not.toBeInTheDocument();
105105
});
106106

107-
it('shows fixability view step if automation is allowed and view not starred', () => {
107+
it('shows fixability view step if automation is allowed and view not starred', async () => {
108108
MockApiClient.addMockResponse({
109109
url: `/organizations/${organization.slug}/group-search-views/`,
110110
body: [],
@@ -130,8 +130,9 @@ describe('SeerNotices', function () {
130130
features: ['trigger-autofix-on-issue-summary'],
131131
},
132132
});
133-
expect(screen.getByText('Get Some Quick Wins')).toBeInTheDocument();
134-
expect(screen.getByText('Star Recommended View')).toBeInTheDocument();
133+
await waitFor(() => {
134+
expect(screen.getByText('Get Some Quick Wins')).toBeInTheDocument();
135+
});
135136
});
136137

137138
it('does not render guided steps if all onboarding steps are complete', () => {

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

Lines changed: 153 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {Fragment} from 'react';
22
import styled from '@emotion/styled';
3+
import {AnimatePresence, motion} from 'framer-motion';
34

45
import addIntegrationProvider from 'sentry-images/spot/add-integration-provider.svg';
56
import feedbackOnboardingImg from 'sentry-images/spot/feedback-onboarding.svg';
@@ -88,10 +89,7 @@ export function SeerNotices({groupId, hasGithubIntegration, project}: SeerNotice
8889
// Onboarding conditions
8990
const needsGithubIntegration = !hasGithubIntegration;
9091
const needsRepoSelection =
91-
repos.length === 0 &&
92-
!preference?.repositories?.length &&
93-
!codeMappingRepos?.length &&
94-
!isLoadingPreferences;
92+
repos.length === 0 && !preference?.repositories?.length && !codeMappingRepos?.length;
9593
const needsAutomation =
9694
detailedProject?.data &&
9795
(detailedProject?.data?.autofixAutomationTuning === 'off' ||
@@ -131,7 +129,7 @@ export function SeerNotices({groupId, hasGithubIntegration, project}: SeerNotice
131129
return (
132130
<NoticesContainer>
133131
{/* Collapsed summary */}
134-
{anyStepIncomplete && stepsCollapsed && (
132+
{!isLoadingPreferences && anyStepIncomplete && stepsCollapsed && (
135133
<CollapsedSummaryCard onClick={() => setStepsCollapsed(false)}>
136134
<IconSeer variant="waiting" size="lg" style={{marginRight: 8}} />
137135
<span>
@@ -145,184 +143,199 @@ export function SeerNotices({groupId, hasGithubIntegration, project}: SeerNotice
145143
</CollapsedSummaryCard>
146144
)}
147145
{/* Full guided steps */}
148-
{anyStepIncomplete && !stepsCollapsed && (
149-
<Fragment>
150-
<StepsHeader>
151-
<IconSeer variant="waiting" size="xl" />
152-
Debug Faster with Seer
153-
</StepsHeader>
154-
<GuidedSteps>
155-
{/* Step 1: GitHub Integration */}
156-
<GuidedSteps.Step
157-
key="github-setup"
158-
stepKey="github-setup"
159-
title={t('Set Up the GitHub Integration')}
160-
isCompleted={!needsGithubIntegration}
161-
>
162-
<StepContentRow>
163-
<StepTextCol>
164-
<CardDescription>
165-
<span>
166-
{tct(
167-
'Seer is [bold:a lot better] when it has your codebase as context.',
168-
{
169-
bold: <b />,
170-
}
171-
)}
172-
</span>
173-
<span>
174-
{tct(
175-
'Set up the [integrationLink:GitHub Integration] to allow Seer to find the most accurate root causes, solutions, and code changes for your issues.',
176-
{
177-
integrationLink: (
178-
<ExternalLink
179-
href={`/settings/${organization.slug}/integrations/github/`}
180-
/>
181-
),
182-
}
183-
)}
184-
</span>
185-
</CardDescription>
186-
</StepTextCol>
187-
<StepImageCol>
188-
<CardIllustration src={addIntegrationProvider} alt="Add Integration" />
189-
</StepImageCol>
190-
</StepContentRow>
191-
<CustomStepButtons
192-
showBack={false}
193-
showNext={firstIncompleteIdx !== 0}
194-
showSkip={false}
195-
>
196-
<LinkButton
197-
href={`/settings/${organization.slug}/integrations/github/`}
198-
size="sm"
199-
priority="primary"
200-
>
201-
{t('Set Up Integration')}
202-
</LinkButton>
203-
</CustomStepButtons>
204-
</GuidedSteps.Step>
205-
206-
{/* Step 2: Repo Selection */}
207-
<GuidedSteps.Step
208-
key="repo-selection"
209-
stepKey="repo-selection"
210-
title={t('Pick Repositories to Work In')}
211-
isCompleted={!needsRepoSelection}
212-
>
213-
<StepContentRow>
214-
<StepTextCol>
215-
<CardDescription>
216-
<span>{t('Select the repos Seer can explore in this project.')}</span>
217-
<span>
218-
{t(
219-
'You can also configure working branches and custom instructions so Seer fits your unique workflow.'
220-
)}
221-
</span>
222-
</CardDescription>
223-
</StepTextCol>
224-
<StepImageCol>
225-
<CardIllustration src={onboardingCompass} alt="Compass" />
226-
</StepImageCol>
227-
</StepContentRow>
228-
<CustomStepButtons
229-
showBack={firstIncompleteIdx !== 1 && incompleteStepIndices.includes(1)}
230-
showNext={lastIncompleteIdx !== 1 && incompleteStepIndices.includes(1)}
231-
showSkip={lastIncompleteIdx === 1}
232-
onSkip={() => setStepsCollapsed(true)}
233-
>
234-
<LinkButton
235-
to={`/settings/${organization.slug}/projects/${project.slug}/seer/`}
236-
size="sm"
237-
priority="primary"
238-
>
239-
{t('Configure Repos')}
240-
</LinkButton>
241-
</CustomStepButtons>
242-
</GuidedSteps.Step>
243-
244-
{/* Step 3: Unleash Automation */}
245-
{isAutomationAllowed && (
146+
{!isLoadingPreferences && anyStepIncomplete && !stepsCollapsed && (
147+
<AnimatePresence>
148+
<motion.div
149+
initial={{opacity: 0, y: 10, height: 0}}
150+
animate={{opacity: 1, y: 0, height: 'auto'}}
151+
exit={{opacity: 0, y: 10, height: 0}}
152+
transition={{duration: 0.2}}
153+
>
154+
<StepsHeader>
155+
<IconSeer variant="waiting" size="xl" />
156+
Debug Faster with Seer
157+
</StepsHeader>
158+
<GuidedSteps>
159+
{/* Step 1: GitHub Integration */}
246160
<GuidedSteps.Step
247-
key="unleash-automation"
248-
stepKey="unleash-automation"
249-
title={t('Unleash Automation')}
250-
isCompleted={!needsAutomation}
161+
key="github-setup"
162+
stepKey="github-setup"
163+
title={t('Set Up the GitHub Integration')}
164+
isCompleted={!needsGithubIntegration}
251165
>
252166
<StepContentRow>
253167
<StepTextCol>
254168
<CardDescription>
255169
<span>
256-
{t(
257-
'Let Seer automatically deep dive into incoming issues, so you wake up to solutions, not headaches.'
170+
{tct(
171+
'Seer is [bold:a lot better] when it has your codebase as context.',
172+
{
173+
bold: <b />,
174+
}
175+
)}
176+
</span>
177+
<span>
178+
{tct(
179+
'Set up the [integrationLink:GitHub Integration] to allow Seer to find the most accurate root causes, solutions, and code changes for your issues.',
180+
{
181+
integrationLink: (
182+
<ExternalLink
183+
href={`/settings/${organization.slug}/integrations/github/`}
184+
/>
185+
),
186+
}
258187
)}
259188
</span>
260189
</CardDescription>
261190
</StepTextCol>
262191
<StepImageCol>
263-
<CardIllustration src={waitingForEventImg} alt="Waiting for Event" />
192+
<CardIllustration
193+
src={addIntegrationProvider}
194+
alt="Add Integration"
195+
/>
264196
</StepImageCol>
265197
</StepContentRow>
266198
<CustomStepButtons
267-
showBack={firstIncompleteIdx !== 2 && incompleteStepIndices.includes(2)}
268-
showNext={lastIncompleteIdx !== 2 && incompleteStepIndices.includes(2)}
269-
showSkip={lastIncompleteIdx === 2}
270-
onSkip={() => setStepsCollapsed(true)}
199+
showBack={false}
200+
showNext={firstIncompleteIdx !== 0}
201+
showSkip={false}
271202
>
272203
<LinkButton
273-
to={`/settings/${organization.slug}/projects/${project.slug}/seer/`}
204+
href={`/settings/${organization.slug}/integrations/github/`}
274205
size="sm"
275206
priority="primary"
276207
>
277-
{t('Enable Automation')}
208+
{t('Set Up Integration')}
278209
</LinkButton>
279210
</CustomStepButtons>
280211
</GuidedSteps.Step>
281-
)}
282212

283-
{/* Step 4: Fixability View */}
284-
{isAutomationAllowed && isStarredViewAllowed && (
213+
{/* Step 2: Repo Selection */}
285214
<GuidedSteps.Step
286-
key="fixability-view"
287-
stepKey="fixability-view"
288-
title={t('Get Some Quick Wins')}
289-
isCompleted={!needsFixabilityView}
215+
key="repo-selection"
216+
stepKey="repo-selection"
217+
title={t('Pick Repositories to Work In')}
218+
isCompleted={!needsRepoSelection}
290219
>
291220
<StepContentRow>
292221
<StepTextCol>
293222
<CardDescription>
294223
<span>
295-
{t(
296-
'Seer scans all your issues and highlights the ones that are likely quick to fix.'
297-
)}
224+
{t('Select the repos Seer can explore in this project.')}
298225
</span>
299226
<span>
300227
{t(
301-
'Star the recommended issue view to keep an eye on quick debugging opportunities. You can customize the view later.'
228+
'You can also configure working branches and custom instructions so Seer fits your unique workflow.'
302229
)}
303230
</span>
304231
</CardDescription>
305232
</StepTextCol>
306233
<StepImageCol>
307-
<CardIllustration src={feedbackOnboardingImg} alt="Feedback" />
234+
<CardIllustration src={onboardingCompass} alt="Compass" />
308235
</StepImageCol>
309236
</StepContentRow>
310237
<CustomStepButtons
311-
showBack={firstIncompleteIdx !== 3 && incompleteStepIndices.includes(3)}
312-
showNext={lastIncompleteIdx !== 3 && incompleteStepIndices.includes(3)}
313-
showSkip={lastIncompleteIdx === 3}
238+
showBack={firstIncompleteIdx !== 1}
239+
showNext={lastIncompleteIdx !== 1}
240+
showSkip={lastIncompleteIdx === 1}
314241
onSkip={() => setStepsCollapsed(true)}
315242
>
316-
<StarFixabilityViewButton
317-
isCompleted={!needsFixabilityView}
318-
project={project}
319-
/>
243+
<LinkButton
244+
to={`/settings/${organization.slug}/projects/${project.slug}/seer/`}
245+
size="sm"
246+
priority="primary"
247+
>
248+
{t('Configure Repos')}
249+
</LinkButton>
320250
</CustomStepButtons>
321251
</GuidedSteps.Step>
322-
)}
323-
</GuidedSteps>
324-
<StepsDivider />
325-
</Fragment>
252+
253+
{/* Step 3: Unleash Automation */}
254+
{isAutomationAllowed && (
255+
<GuidedSteps.Step
256+
key="unleash-automation"
257+
stepKey="unleash-automation"
258+
title={t('Unleash Automation')}
259+
isCompleted={!needsAutomation}
260+
>
261+
<StepContentRow>
262+
<StepTextCol>
263+
<CardDescription>
264+
<span>
265+
{t(
266+
'Let Seer automatically deep dive into incoming issues, so you wake up to solutions, not headaches.'
267+
)}
268+
</span>
269+
</CardDescription>
270+
</StepTextCol>
271+
<StepImageCol>
272+
<CardIllustration
273+
src={waitingForEventImg}
274+
alt="Waiting for Event"
275+
/>
276+
</StepImageCol>
277+
</StepContentRow>
278+
<CustomStepButtons
279+
showBack={firstIncompleteIdx !== 2}
280+
showNext={lastIncompleteIdx !== 2}
281+
showSkip={lastIncompleteIdx === 2}
282+
onSkip={() => setStepsCollapsed(true)}
283+
>
284+
<LinkButton
285+
to={`/settings/${organization.slug}/projects/${project.slug}/seer/`}
286+
size="sm"
287+
priority="primary"
288+
>
289+
{t('Enable Automation')}
290+
</LinkButton>
291+
</CustomStepButtons>
292+
</GuidedSteps.Step>
293+
)}
294+
295+
{/* Step 4: Fixability View */}
296+
{isAutomationAllowed && isStarredViewAllowed && (
297+
<GuidedSteps.Step
298+
key="fixability-view"
299+
stepKey="fixability-view"
300+
title={t('Get Some Quick Wins')}
301+
isCompleted={!needsFixabilityView}
302+
>
303+
<StepContentRow>
304+
<StepTextCol>
305+
<CardDescription>
306+
<span>
307+
{t(
308+
'Seer scans all your issues and highlights the ones that are likely quick to fix.'
309+
)}
310+
</span>
311+
<span>
312+
{t(
313+
'Star the recommended issue view to keep an eye on quick debugging opportunities. You can customize the view later.'
314+
)}
315+
</span>
316+
</CardDescription>
317+
</StepTextCol>
318+
<StepImageCol>
319+
<CardIllustration src={feedbackOnboardingImg} alt="Feedback" />
320+
</StepImageCol>
321+
</StepContentRow>
322+
<CustomStepButtons
323+
showBack={firstIncompleteIdx !== 3}
324+
showNext={lastIncompleteIdx !== 3}
325+
showSkip={lastIncompleteIdx === 3}
326+
onSkip={() => setStepsCollapsed(true)}
327+
>
328+
<StarFixabilityViewButton
329+
isCompleted={!needsFixabilityView}
330+
project={project}
331+
/>
332+
</CustomStepButtons>
333+
</GuidedSteps.Step>
334+
)}
335+
</GuidedSteps>
336+
<StepsDivider />
337+
</motion.div>
338+
</AnimatePresence>
326339
)}
327340
{/* Banners for unreadable repos */}
328341
{hasMultipleUnreadableRepos && (
@@ -430,6 +443,7 @@ const StepsHeader = styled('h3')`
430443
gap: ${space(1)};
431444
font-size: ${p => p.theme.fontSizeExtraLarge};
432445
margin-bottom: ${space(0.5)};
446+
margin-left: 1px;
433447
`;
434448

435449
const StepsDivider = styled('hr')`

0 commit comments

Comments
 (0)