diff --git a/static/app/views/issueDetails/issuePreview/issuePreview.spec.tsx b/static/app/views/issueDetails/issuePreview/issuePreview.spec.tsx
index 0635c5af386d..44448a7e02a2 100644
--- a/static/app/views/issueDetails/issuePreview/issuePreview.spec.tsx
+++ b/static/app/views/issueDetails/issuePreview/issuePreview.spec.tsx
@@ -64,7 +64,7 @@ describe('IssuePreview', () => {
});
});
- it('links to an open user pull request without an Autofix state', async () => {
+ it('links to an open user pull request and shows the next Autofix step', async () => {
MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/issues/${group.id}/autofix/`,
body: ExplorerAutofixResponseFixture({autofix: null}),
@@ -93,6 +93,7 @@ describe('IssuePreview', () => {
expect(
await screen.findByRole('button', {name: 'View example/repo-name#10'})
).toHaveAttribute('href', 'https://github.com/example/repo-name/pull/10');
+ expect(screen.getByRole('button', {name: 'Find Root Cause'})).toBeInTheDocument();
});
it('offers to restart Autofix after PR creation when the linked PR is closed', async () => {
diff --git a/static/app/views/issueDetails/issuePreview/issuePreviewActions.tsx b/static/app/views/issueDetails/issuePreview/issuePreviewActions.tsx
index 8c4be3175e5e..2ebd35920d63 100644
--- a/static/app/views/issueDetails/issuePreview/issuePreviewActions.tsx
+++ b/static/app/views/issueDetails/issuePreview/issuePreviewActions.tsx
@@ -1,4 +1,4 @@
-import {useState, type ReactNode} from 'react';
+import {Fragment, useState, type ReactNode} from 'react';
import {Button, ButtonBar, LinkButton, type ButtonProps} from '@sentry/scraps/button';
import {MenuComponents} from '@sentry/scraps/compactSelect';
@@ -77,6 +77,7 @@ function getAutofixActionProps({
}
function StartAutofixAction({
+ variant = 'primary',
action,
analyticsAction,
analyticsEventKey,
@@ -100,6 +101,7 @@ function StartAutofixAction({
codingAgentStep?: 'root_cause' | 'solution';
icon?: ReactNode;
tooltip?: string | null;
+ variant?: 'primary' | 'secondary';
}) {
const organization = useOrganization();
const [isStartingAction, setIsStartingAction] = useState(false);
@@ -160,6 +162,7 @@ function StartAutofixAction({
disabled={disabled || busy}
onClick={handleClick}
tooltipProps={tooltip ? {title: tooltip} : undefined}
+ variant={variant}
>
{label}
@@ -178,7 +181,7 @@ function StartAutofixAction({
trigger={(triggerProps, isOpen) => (
}
aria-label={t('More code fix options')}
@@ -203,39 +206,21 @@ function StartAutofixAction({
);
}
-function ActionButtons({
+function NextAutofixStepButton({
autofix,
disabled,
group,
- linkedPullRequestsData,
onContinueInSeer,
-}: AutofixActionProps) {
+ variant = 'primary',
+}: Omit & {
+ autofix: ExplorerAutofix;
+ group: Group;
+ onContinueInSeer: () => void;
+ disabled?: boolean;
+ variant?: 'primary' | 'secondary';
+}) {
const {runState} = autofix;
const sections = getOrderedAutofixSections(runState);
- const latestOpenPullRequest = linkedPullRequestsData?.pullRequests
- .filter(
- pullRequest => pullRequest.status === 'open' || pullRequest.status === 'draft'
- )
- .toSorted((a, b) => Date.parse(b.dateCreated) - Date.parse(a.dateCreated))[0];
-
- if (latestOpenPullRequest) {
- return (
- }
- >
- {t('View %s#%s', latestOpenPullRequest.repository.name, latestOpenPullRequest.id)}
-
- );
- }
if (!runState || sections.length === 0) {
return (
@@ -249,6 +234,7 @@ function ActionButtons({
group={group}
label={t('Find Root Cause')}
onContinueInSeer={onContinueInSeer}
+ variant={variant}
/>
);
}
@@ -271,6 +257,7 @@ function ActionButtons({
disabled={disabled || autofix.isPolling}
icon={}
onClick={onContinueInSeer}
+ variant={variant}
>
{runState.pending_user_input?.input_type === 'file_change_approval'
? t('Review Changes')
@@ -300,6 +287,7 @@ function ActionButtons({
label={t('Retry PR in %s', failedPullRequest.repo_name)}
onContinueInSeer={onContinueInSeer}
tooltip={failedPullRequest.pr_creation_error}
+ variant={variant}
/>
);
}
@@ -327,6 +315,7 @@ function ActionButtons({
disabled={disabled}
href={resultLink.url}
icon={}
+ variant={variant}
>
{resultLink.label}
@@ -349,6 +338,7 @@ function ActionButtons({
disabled={disabled}
href={codingAgent.agent_url}
icon={}
+ variant={variant}
>
{t('Open in %s', getCodingAgentName(codingAgent.provider))}
@@ -356,7 +346,6 @@ function ActionButtons({
}
const nextStep = getAutofixNextStep({sections});
-
switch (nextStep?.action) {
case 'create_pr':
return (
@@ -371,6 +360,7 @@ function ActionButtons({
group={group}
label={t('Create PR')}
onContinueInSeer={onContinueInSeer}
+ variant={variant}
/>
);
case 'code_changes':
@@ -386,6 +376,7 @@ function ActionButtons({
codingAgentStep="solution"
label={t('Write a Code Fix')}
onContinueInSeer={onContinueInSeer}
+ variant={variant}
/>
);
case 'solution':
@@ -401,6 +392,7 @@ function ActionButtons({
codingAgentStep="root_cause"
label={t('Make a Plan')}
onContinueInSeer={onContinueInSeer}
+ variant={variant}
/>
);
// We are not yet supporting PR iteration
@@ -418,11 +410,67 @@ function ActionButtons({
icon={}
label={t('Restart Autofix')}
onContinueInSeer={onContinueInSeer}
+ variant={variant}
/>
);
}
}
+function ActionButtons({
+ autofix,
+ disabled,
+ group,
+ linkedPullRequestsData,
+ onContinueInSeer,
+}: AutofixActionProps) {
+ const latestOpenPullRequest = linkedPullRequestsData?.pullRequests
+ .filter(
+ pullRequest => pullRequest.status === 'open' || pullRequest.status === 'draft'
+ )
+ .toSorted((a, b) => Date.parse(b.dateCreated) - Date.parse(a.dateCreated))[0];
+
+ if (latestOpenPullRequest) {
+ return (
+
+ }
+ >
+ {t(
+ 'View %s#%s',
+ latestOpenPullRequest.repository.name,
+ latestOpenPullRequest.id
+ )}
+
+
+
+ );
+ }
+
+ return (
+
+ );
+}
+
export function IssuePreviewActions({
autofix,
disabled,
@@ -437,12 +485,14 @@ export function IssuePreviewActions({
}
return (
-
+
+ {' '}
+
);
}