Skip to content

Commit f7390a6

Browse files
authored
fix(issues): allow rendering of annotations in both formats (#74645)
1 parent 9f1bdb5 commit f7390a6

File tree

5 files changed

+49
-16
lines changed

5 files changed

+49
-16
lines changed

static/app/components/eventOrGroupExtraDetails.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import TimesTag from 'sentry/components/group/inboxBadges/timesTag';
77
import UnhandledTag from 'sentry/components/group/inboxBadges/unhandledTag';
88
import IssueReplayCount from 'sentry/components/group/issueReplayCount';
99
import ProjectBadge from 'sentry/components/idBadge/projectBadge';
10+
import ExternalLink from 'sentry/components/links/externalLink';
1011
import Link from 'sentry/components/links/link';
1112
import Placeholder from 'sentry/components/placeholder';
1213
import {IconChat} from 'sentry/icons';
@@ -94,14 +95,20 @@ function EventOrGroupExtraDetails({data, showAssignee, organization}: Props) {
9495
</GlobalSelectionLink>
9596
</LoggerAnnotation>
9697
)}
97-
{annotations?.map((annotation, key) => (
98-
<AnnotationNoMargin
99-
dangerouslySetInnerHTML={{
100-
__html: annotation,
101-
}}
102-
key={key}
103-
/>
104-
))}
98+
{annotations?.map((annotation, key) =>
99+
typeof annotation === 'string' ? (
100+
<AnnotationNoMargin
101+
dangerouslySetInnerHTML={{
102+
__html: annotation,
103+
}}
104+
key={key}
105+
/>
106+
) : (
107+
<AnnotationNoMargin key={key}>
108+
<ExternalLink href={annotation.url}>{annotation.displayName}</ExternalLink>
109+
</AnnotationNoMargin>
110+
)
111+
)}
105112

106113
{showAssignee && assignedTo && (
107114
<div>{tct('Assigned to [name]', {name: assignedTo.name})}</div>

static/app/types/group.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,11 @@ export type TagWithTopValues = {
299299
/**
300300
* Inbox, issue owners and Activity
301301
*/
302+
export type Annotation = {
303+
displayName: string;
304+
url: string;
305+
};
306+
302307
export type InboxReasonDetails = {
303308
count?: number | null;
304309
until?: string | null;
@@ -777,7 +782,7 @@ export const enum PriorityLevel {
777782
// TODO(ts): incomplete
778783
export interface BaseGroup {
779784
activity: GroupActivity[];
780-
annotations: string[];
785+
annotations: string[] | Annotation[];
781786
assignedTo: Actor | null;
782787
culprit: string;
783788
firstSeen: string;

static/app/utils/dashboards/issueFieldRenderers.spec.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ describe('getIssueFieldRenderer', function () {
5252
filteredEvents: 3000,
5353
events: 6000,
5454
period: '7d',
55-
links: ['<a href="sentry.io">ANNO-123</a>'],
55+
links: '<a href="sentry.io">ANNO-123</a>',
5656
};
5757

5858
MockApiClient.addMockResponse({
@@ -152,10 +152,7 @@ describe('getIssueFieldRenderer', function () {
152152
{
153153
data,
154154
...{
155-
links: [
156-
'<a href="sentry.io">ANNO-123</a>',
157-
'<a href="sentry.io">ANNO-456</a>',
158-
],
155+
links: '<a href="sentry.io">ANNO-123</a>, <a href="sentry.io">ANNO-456</a>',
159156
},
160157
},
161158
{

static/app/utils/dashboards/issueFieldRenderers.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ import type {Location} from 'history';
55

66
import Count from 'sentry/components/count';
77
import DeprecatedAssigneeSelector from 'sentry/components/deprecatedAssigneeSelector';
8+
import ExternalLink from 'sentry/components/links/externalLink';
89
import Link from 'sentry/components/links/link';
910
import {getRelativeSummary} from 'sentry/components/timeRangeSelector/utils';
1011
import {Tooltip} from 'sentry/components/tooltip';
1112
import {DEFAULT_STATS_PERIOD} from 'sentry/constants';
1213
import {t} from 'sentry/locale';
1314
import MemberListStore from 'sentry/stores/memberListStore';
1415
import {space} from 'sentry/styles/space';
16+
import type {Annotation} from 'sentry/types/group';
1517
import type {Organization} from 'sentry/types/organization';
1618
import type {EventData} from 'sentry/utils/discover/eventView';
1719
import EventView from 'sentry/utils/discover/eventView';
@@ -141,7 +143,23 @@ const SPECIAL_FIELDS: SpecialFields = {
141143
},
142144
links: {
143145
sortField: null,
144-
renderFunc: ({links}) => <LinksContainer dangerouslySetInnerHTML={{__html: links}} />,
146+
renderFunc: ({links}) => {
147+
if (typeof links === 'string') {
148+
return <LinksContainer dangerouslySetInnerHTML={{__html: links}} />;
149+
}
150+
if (isLinkAnnotation(links)) {
151+
return (
152+
<LinksContainer>
153+
{links.map((link, index) => (
154+
<ExternalLink key={index} href={link.url}>
155+
{link.displayName}
156+
</ExternalLink>
157+
))}
158+
</LinksContainer>
159+
);
160+
}
161+
return <LinksContainer />;
162+
},
145163
},
146164
};
147165

@@ -241,6 +259,10 @@ export function getSortField(field: string): string | null {
241259
}
242260
}
243261

262+
function isLinkAnnotation(value: unknown): value is Annotation[] {
263+
return Array.isArray(value) && value.every(v => typeof v === 'object');
264+
}
265+
244266
const contentStyle = css`
245267
width: 100%;
246268
justify-content: space-between;

static/app/views/dashboards/datasetConfig/issues.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ export function transformIssuesResponseToTable(
122122
issue: shortId,
123123
title,
124124
project: project.slug,
125-
links: annotations?.join(', '),
125+
links: annotations?.every(a => typeof a === 'string')
126+
? annotations.join(', ')
127+
: ((annotations ?? []) as any),
126128
};
127129

128130
// Get lifetime stats

0 commit comments

Comments
 (0)