Skip to content

Commit 21cc736

Browse files
roagascttcper
andauthored
feat(seer): Add quick fix labels to issue stream and issue details (#91837)
Adjusts the Autofix badge in the issue stream to also say "Quick Fix" and have a different tooltip if the fixability score is very high. In the header of Issue Details, also show a Quick Fix badge only if the fixability score is very high (does not show anything about Autofix). (design approved by @vuluongj20 ) <img width="467" alt="Screenshot 2025-05-16 at 2 31 06 PM" src="https://github.com/user-attachments/assets/b40cdfcd-2f13-42df-8be1-b30bb469bac5" /> <img width="503" alt="Screenshot 2025-05-16 at 2 13 05 PM" src="https://github.com/user-attachments/assets/a03097cd-0f6a-400d-80f0-d153f2ee5aa8" /> <img width="757" alt="Screenshot 2025-05-16 at 2 23 27 PM" src="https://github.com/user-attachments/assets/8ae17792-356d-4a89-b489-e9e939547732" /> --------- Co-authored-by: Scott Cooper <scttcper@gmail.com>
1 parent 2048098 commit 21cc736

File tree

5 files changed

+119
-15
lines changed

5 files changed

+119
-15
lines changed

static/app/components/eventOrGroupExtraDetails.tsx

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import {Fragment} from 'react';
22
import styled from '@emotion/styled';
33

4-
import {SeerIcon} from 'sentry/components/ai/SeerIcon';
5-
import {Tooltip} from 'sentry/components/core/tooltip';
6-
import {getAutofixRunExists} from 'sentry/components/events/autofix/utils';
74
import EventAnnotation from 'sentry/components/events/eventAnnotation';
85
import GlobalSelectionLink from 'sentry/components/globalSelectionLink';
96
import ShortId from 'sentry/components/group/inboxBadges/shortId';
107
import TimesTag from 'sentry/components/group/inboxBadges/timesTag';
118
import UnhandledTag from 'sentry/components/group/inboxBadges/unhandledTag';
129
import IssueReplayCount from 'sentry/components/group/issueReplayCount';
10+
import IssueSeerBadge from 'sentry/components/group/issueSeerBadge';
1311
import ProjectBadge from 'sentry/components/idBadge/projectBadge';
1412
import ExternalLink from 'sentry/components/links/externalLink';
1513
import Link from 'sentry/components/links/link';
@@ -78,11 +76,6 @@ function EventOrGroupExtraDetails({data, showAssignee, showLifetime = true}: Pro
7876
data.issueCategory &&
7977
!!getReplayCountForIssue(data.id, data.issueCategory);
8078

81-
const showSeer =
82-
organization.features.includes('gen-ai-features') &&
83-
!organization.hideAiFeatures &&
84-
getAutofixRunExists(data as Group);
85-
8679
const {subtitle} = getTitle(data);
8780

8881
const items = [
@@ -115,13 +108,7 @@ function EventOrGroupExtraDetails({data, showAssignee, showLifetime = true}: Pro
115108
</CommentsLink>
116109
) : null,
117110
showReplayCount ? <IssueReplayCount group={data as Group} /> : null,
118-
showSeer ? (
119-
<Tooltip title="Seer has a potential fix for this issue" skipWrapper>
120-
<CommentsLink to={{pathname: `${issuesPath}${id}`, query: {seerDrawer: true}}}>
121-
<SeerIcon size="sm" />
122-
</CommentsLink>
123-
</Tooltip>
124-
) : null,
111+
<IssueSeerBadge group={data as Group} key="issue-seer-badge" />,
125112
logger ? (
126113
<LoggerAnnotation>
127114
<GlobalSelectionLink

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,7 @@ export function getAutofixRunExists(group: Group) {
183183

184184
return autofixRanWithinTtl;
185185
}
186+
187+
export function isIssueQuickFixable(group: Group) {
188+
return group.seerFixabilityScore && group.seerFixabilityScore > 0.72;
189+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import styled from '@emotion/styled';
2+
3+
import {SeerIcon} from 'sentry/components/ai/SeerIcon';
4+
import {Tooltip} from 'sentry/components/core/tooltip';
5+
import {
6+
getAutofixRunExists,
7+
isIssueQuickFixable,
8+
} from 'sentry/components/events/autofix/utils';
9+
import Link from 'sentry/components/links/link';
10+
import {t} from 'sentry/locale';
11+
import {space} from 'sentry/styles/space';
12+
import type {Group} from 'sentry/types/group';
13+
import {useLocation} from 'sentry/utils/useLocation';
14+
import useOrganization from 'sentry/utils/useOrganization';
15+
16+
interface IssueSeerBadgeProps {
17+
group: Group;
18+
}
19+
20+
function IssueSeerBadge({group}: IssueSeerBadgeProps) {
21+
const organization = useOrganization();
22+
const issuesPath = `/organizations/${organization.slug}/issues/`;
23+
const location = useLocation();
24+
25+
const autofixRunExists = getAutofixRunExists(group);
26+
const seerFixable = isIssueQuickFixable(group);
27+
const showSeer =
28+
organization.features.includes('gen-ai-features') &&
29+
!organization.hideAiFeatures &&
30+
(autofixRunExists || seerFixable);
31+
32+
let seerTitle = null;
33+
if (autofixRunExists && seerFixable) {
34+
seerTitle = t('Seer has a potential quick fix for this issue');
35+
} else if (autofixRunExists) {
36+
seerTitle = t('Seer has insight into this issue');
37+
} else if (seerFixable) {
38+
seerTitle = t('This issue might be quick to fix');
39+
}
40+
41+
if (!showSeer) {
42+
return null;
43+
}
44+
45+
return (
46+
<Tooltip title={seerTitle} skipWrapper>
47+
<SeerLink
48+
to={{
49+
pathname: `${issuesPath}${group.id}/`,
50+
query: {...location.query, seerDrawer: true},
51+
}}
52+
>
53+
<SeerIcon size="sm" />
54+
{seerFixable && <p>{t('Quick Fix')}</p>}
55+
</SeerLink>
56+
</Tooltip>
57+
);
58+
}
59+
60+
const SeerLink = styled(Link)`
61+
display: inline-grid;
62+
gap: ${space(0.5)};
63+
align-items: center;
64+
grid-auto-flow: column;
65+
color: ${p => p.theme.textColor};
66+
position: relative;
67+
`;
68+
69+
export default IssueSeerBadge;

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {GroupHeaderAssigneeSelector} from 'sentry/views/issueDetails/streamline/
4040
import {AttachmentsBadge} from 'sentry/views/issueDetails/streamline/header/attachmentsBadge';
4141
import {IssueIdBreadcrumb} from 'sentry/views/issueDetails/streamline/header/issueIdBreadcrumb';
4242
import {ReplayBadge} from 'sentry/views/issueDetails/streamline/header/replayBadge';
43+
import SeerBadge from 'sentry/views/issueDetails/streamline/header/seerBadge';
4344
import {UserFeedbackBadge} from 'sentry/views/issueDetails/streamline/header/userFeedbackBadge';
4445
import {Tab, TabPaths} from 'sentry/views/issueDetails/types';
4546
import {useGroupDetailsRoute} from 'sentry/views/issueDetails/useGroupDetailsRoute';
@@ -193,6 +194,7 @@ export default function StreamlinedGroupHeader({
193194
<AttachmentsBadge group={group} />
194195
<UserFeedbackBadge group={group} project={project} />
195196
<ReplayBadge group={group} project={project} />
197+
<SeerBadge group={group} />
196198
</ErrorBoundary>
197199
</Flex>
198200
</HeaderGrid>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import styled from '@emotion/styled';
2+
3+
import {SeerIcon} from 'sentry/components/ai/SeerIcon';
4+
import {Tooltip} from 'sentry/components/core/tooltip';
5+
import {isIssueQuickFixable} from 'sentry/components/events/autofix/utils';
6+
import {t} from 'sentry/locale';
7+
import {space} from 'sentry/styles/space';
8+
import type {Group} from 'sentry/types/group';
9+
import useOrganization from 'sentry/utils/useOrganization';
10+
import {Divider} from 'sentry/views/issueDetails/divider';
11+
12+
function SeerBadge({group}: {group: Group}) {
13+
const organization = useOrganization();
14+
const seerFixable = isIssueQuickFixable(group);
15+
16+
if (
17+
!organization.features.includes('gen-ai-features') ||
18+
organization.hideAiFeatures ||
19+
!seerFixable
20+
) {
21+
return null;
22+
}
23+
24+
return (
25+
<Tooltip title={t('This issue might be quick to fix')} skipWrapper>
26+
<Wrapper>
27+
<Divider />
28+
<SeerIcon size="sm" />
29+
{seerFixable && <span>{t('Quick Fix')}</span>}
30+
</Wrapper>
31+
</Tooltip>
32+
);
33+
}
34+
35+
const Wrapper = styled('div')`
36+
display: flex;
37+
align-items: center;
38+
gap: ${space(0.5)};
39+
color: ${p => p.theme.subText};
40+
`;
41+
42+
export default SeerBadge;

0 commit comments

Comments
 (0)