Skip to content

Commit 1a042e7

Browse files
jennmuengscttcper
andauthored
feat(autofix): Check specific autofix enabled option (#80785)
Should be merged after #80717 to avoid conflicts. Before, the autofix setup steps will disappear once the required steps are completed. Now we check for a specific option that autofix is enabled. This way the steps don't disappear until you enable it. --------- Co-authored-by: Scott Cooper <[email protected]>
1 parent 27429d5 commit 1a042e7

File tree

6 files changed

+81
-12
lines changed

6 files changed

+81
-12
lines changed

static/app/components/events/autofix/autofixSetupModal.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,10 @@ function AutofixGithubIntegrationStep({
179179
size="sm"
180180
disabled={!canStartAutofix}
181181
onClick={handleClose}
182+
analyticsEventName="Autofix Setup Enable Autofix"
183+
analyticsEventKey="autofix.setup_enable_autofix"
182184
>
183-
{t("Let's Go!")}
185+
{t('Enable Autofix')}
184186
</Button>
185187
)}
186188
</GuidedSteps.StepButtons>
@@ -255,6 +257,8 @@ function AutofixGithubIntegrationStep({
255257
size="sm"
256258
disabled={!canStartAutofix}
257259
onClick={handleClose}
260+
analyticsEventName="Autofix Setup Skip & Enable Autofix"
261+
analyticsEventKey="autofix.setup_skip_enable_autofix"
258262
>
259263
{t('Skip & Enable Autofix')}
260264
</Button>

static/app/components/events/autofix/useAutofixSetup.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ export interface AutofixSetupRepoDefinition extends AutofixRepoDefinition {
1111
}
1212

1313
export type AutofixSetupResponse = {
14+
autofixEnabled: {
15+
ok: boolean;
16+
};
1417
genAIConsent: {
1518
ok: boolean;
1619
};

static/app/types/organization.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import type {User} from './user';
1919
*/
2020
export interface OrganizationSummary {
2121
aiSuggestedSolution: boolean;
22+
autofixEnabled: boolean;
2223
avatar: Avatar;
2324
codecovAccess: boolean;
2425
dateCreated: string;

static/app/views/issueDetails/streamline/solutionsHubDrawer.spec.tsx

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ describe('SolutionsHubDrawer', () => {
4343
genAIConsent: {ok: true},
4444
integration: {ok: true},
4545
githubWriteIntegration: {ok: true},
46+
autofixEnabled: {ok: true},
4647
},
4748
});
4849
MockApiClient.addMockResponse({
@@ -64,6 +65,7 @@ describe('SolutionsHubDrawer', () => {
6465
genAIConsent: {ok: false},
6566
integration: {ok: false},
6667
githubWriteIntegration: {ok: false},
68+
autofixEnabled: {ok: false},
6769
},
6870
});
6971
MockApiClient.addMockResponse({
@@ -106,8 +108,6 @@ describe('SolutionsHubDrawer', () => {
106108
screen.queryByTestId('ai-setup-loading-indicator')
107109
);
108110

109-
expect(screen.getByText(mockEvent.id)).toBeInTheDocument();
110-
111111
expect(screen.getByRole('heading', {name: 'Solutions Hub'})).toBeInTheDocument();
112112

113113
const startButton = screen.getByRole('button', {name: 'Start Autofix'});
@@ -180,4 +180,39 @@ describe('SolutionsHubDrawer', () => {
180180
expect(screen.getByRole('button', {name: 'Start Autofix'})).toBeInTheDocument();
181181
});
182182
});
183+
184+
it('continues to show setup if autofix is not enabled', async () => {
185+
MockApiClient.addMockResponse({
186+
url: `/issues/${mockGroup.id}/autofix/setup/`,
187+
body: {
188+
genAIConsent: {ok: true},
189+
integration: {ok: true},
190+
githubWriteIntegration: {ok: false, repos: []},
191+
autofixEnabled: {ok: false},
192+
},
193+
});
194+
MockApiClient.addMockResponse({
195+
url: `/issues/${mockGroup.id}/autofix/`,
196+
body: {autofix: null},
197+
});
198+
199+
render(
200+
<SolutionsHubDrawer event={mockEvent} group={mockGroup} project={mockProject} />,
201+
{organization}
202+
);
203+
204+
expect(screen.getByTestId('ai-setup-loading-indicator')).toBeInTheDocument();
205+
206+
await waitForElementToBeRemoved(() =>
207+
screen.queryByTestId('ai-setup-loading-indicator')
208+
);
209+
210+
expect(screen.getByRole('heading', {name: 'Solutions Hub'})).toBeInTheDocument();
211+
212+
expect(screen.queryByRole('button', {name: 'Start Autofix'})).not.toBeInTheDocument();
213+
214+
expect(
215+
screen.getByRole('button', {name: 'Skip & Enable Autofix'})
216+
).toBeInTheDocument();
217+
});
183218
});

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

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ import AutofixFeedback from 'sentry/components/events/autofix/autofixFeedback';
1212
import {AutofixSetupContent} from 'sentry/components/events/autofix/autofixSetupModal';
1313
import {AutofixSteps} from 'sentry/components/events/autofix/autofixSteps';
1414
import {useAiAutofix} from 'sentry/components/events/autofix/useAutofix';
15-
import {useAutofixSetup} from 'sentry/components/events/autofix/useAutofixSetup';
15+
import {
16+
makeAutofixSetupQueryKey,
17+
useAutofixSetup,
18+
} from 'sentry/components/events/autofix/useAutofixSetup';
1619
import {DrawerBody, DrawerHeader} from 'sentry/components/globalDrawer/components';
1720
import {GroupSummaryBody, useGroupSummary} from 'sentry/components/group/groupSummary';
1821
import HookOrDefault from 'sentry/components/hookOrDefault';
@@ -30,8 +33,10 @@ import {
3033
getConfigForIssueType,
3134
shouldShowCustomErrorResourceConfig,
3235
} from 'sentry/utils/issueTypeConfig';
36+
import {useMutation, useQueryClient} from 'sentry/utils/queryClient';
3337
import {getRegionDataFromOrganization} from 'sentry/utils/regions';
3438
import useRouteAnalyticsParams from 'sentry/utils/routeAnalytics/useRouteAnalyticsParams';
39+
import useApi from 'sentry/utils/useApi';
3540
import useOrganization from 'sentry/utils/useOrganization';
3641
import {MIN_NAV_HEIGHT} from 'sentry/views/issueDetails/streamline/eventTitle';
3742
import Resources from 'sentry/views/issueDetails/streamline/resources';
@@ -141,20 +146,37 @@ const AiSetupDataConsent = HookOrDefault({
141146
defaultComponent: () => <div data-test-id="ai-setup-data-consent" />,
142147
});
143148

149+
const useEnableAutofix = (groupId: string) => {
150+
const api = useApi({persistInFlight: true});
151+
const queryClient = useQueryClient();
152+
153+
const organization = useOrganization();
154+
return useMutation({
155+
mutationFn: () => {
156+
return api.requestPromise(`/organizations/${organization.slug}/`, {
157+
method: 'PUT',
158+
data: {
159+
autofixEnabled: true,
160+
},
161+
});
162+
},
163+
onSuccess: () => {
164+
queryClient.invalidateQueries({queryKey: makeAutofixSetupQueryKey(groupId)});
165+
},
166+
});
167+
};
168+
144169
export function SolutionsHubDrawer({group, project, event}: SolutionsHubDrawerProps) {
145170
const {autofixData, triggerAutofix, reset} = useAiAutofix(group, event);
146171
const {
147172
data: summaryData,
148173
isError,
149174
isPending: isSummaryLoading,
150175
} = useGroupSummary(group.id, group.issueCategory);
151-
const {
152-
data: setupData,
153-
isPending: isSetupLoading,
154-
refetch: refetchSetup,
155-
} = useAutofixSetup({
176+
const {data: setupData, isPending: isSetupLoading} = useAutofixSetup({
156177
groupId: group.id,
157178
});
179+
const enableAutofixMutation = useEnableAutofix(group.id);
158180

159181
useRouteAnalyticsParams({
160182
autofix_status: autofixData?.status ?? 'none',
@@ -164,6 +186,7 @@ export function SolutionsHubDrawer({group, project, event}: SolutionsHubDrawerPr
164186

165187
const hasConsent = Boolean(setupData?.genAIConsent.ok);
166188
const isAutofixSetupComplete = setupData?.integration.ok && hasConsent;
189+
const autofixEnabled = setupData?.autofixEnabled.ok;
167190

168191
const hasSummary = summaryData && !isError && hasConsent;
169192

@@ -245,7 +268,7 @@ export function SolutionsHubDrawer({group, project, event}: SolutionsHubDrawerPr
245268
</ButtonBar>
246269
)}
247270
</HeaderText>
248-
{isSetupLoading ? (
271+
{isSetupLoading || enableAutofixMutation.isPending ? (
249272
<div data-test-id="ai-setup-loading-indicator">
250273
<LoadingIndicator />
251274
</div>
@@ -264,11 +287,13 @@ export function SolutionsHubDrawer({group, project, event}: SolutionsHubDrawerPr
264287
)}
265288
{displayAiAutofix && (
266289
<Fragment>
267-
{!isAutofixSetupComplete ? (
290+
{!isAutofixSetupComplete || !autofixEnabled ? (
268291
<AutofixSetupContent
269292
groupId={group.id}
270293
projectId={project.id}
271-
onComplete={refetchSetup}
294+
onComplete={() => {
295+
enableAutofixMutation.mutate();
296+
}}
272297
/>
273298
) : !autofixData ? (
274299
<AutofixStartBox onSend={triggerAutofix} groupId={group.id} />

tests/js/fixtures/organization.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export function OrganizationFixture( params: Partial<Organization> = {}): Organi
6464
githubOpenPRBot: false,
6565
githubPRBot: false,
6666
hideAiFeatures: false,
67+
autofixEnabled: false,
6768
isDefault: false,
6869
isDynamicallySampled: true,
6970
isEarlyAdopter: false,

0 commit comments

Comments
 (0)