Skip to content

Commit 0890679

Browse files
authored
alerts: initialize a default variant for alerts (#105588)
Backend types alerts as any dict, and frontend wrongly types the props are AlertProps. When typed as unknown, the variant problem only shows up in the reported view (the test verifies that the fix solve the issue)
1 parent bb00c09 commit 0890679

File tree

4 files changed

+64
-5
lines changed

4 files changed

+64
-5
lines changed

static/app/types/integrations.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,14 @@ export type DocIntegration = {
365365
};
366366

367367
type IntegrationAspects = {
368-
alerts?: Array<AlertProps & {text: string; icon?: string | React.ReactNode}>;
368+
// This was previously passed to us
369+
alerts?: Array<
370+
unknown & {
371+
text: string;
372+
icon?: string | React.ReactNode;
373+
variant?: AlertProps['variant'];
374+
}
375+
>;
369376
configure_integration?: {
370377
title: string;
371378
};

static/app/views/settings/organizationIntegrations/detailedView/integrationLayout.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ function InformationCard({
254254
{permissions}
255255
{alerts.map((alert, i) => (
256256
<Alert.Container key={i}>
257-
<Alert key={i} variant={alert.variant}>
257+
<Alert variant={alert.variant}>
258258
<span
259259
dangerouslySetInnerHTML={{__html: singleLineRenderer(alert.text)}}
260260
/>
@@ -269,8 +269,8 @@ function InformationCard({
269269
<div>{author}</div>
270270
</AuthorInfo>
271271
)}
272-
{resourceLinks.map(({title, url}) => (
273-
<ExternalLinkContainer key={url}>
272+
{resourceLinks.map(({title, url}, index) => (
273+
<ExternalLinkContainer key={index}>
274274
<ResourceIcon title={title} />
275275
<ExternalLink href={url}>{title}</ExternalLink>
276276
</ExternalLinkContainer>

static/app/views/settings/organizationIntegrations/integrationDetailedView.spec.tsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,4 +270,50 @@ describe('IntegrationDetailedView', () => {
270270
);
271271
});
272272
});
273+
274+
it('renders alerts without crashing when variant is not provided', async () => {
275+
MockApiClient.addMockResponse({
276+
url: `/organizations/${organization.slug}/config/integrations/`,
277+
match: [],
278+
body: {
279+
providers: [
280+
{
281+
canAdd: true,
282+
canDisable: false,
283+
features: [],
284+
key: 'test-integration',
285+
metadata: {
286+
aspects: {
287+
alerts: [
288+
{text: 'Alert without variant'},
289+
{text: 'Alert with explicit variant', variant: 'warning'},
290+
],
291+
},
292+
author: 'Test Author',
293+
description: 'Test integration',
294+
features: [],
295+
noun: 'Installation',
296+
},
297+
name: 'Test Integration',
298+
slug: 'test-integration',
299+
},
300+
],
301+
},
302+
});
303+
MockApiClient.addMockResponse({
304+
url: `/organizations/${organization.slug}/integrations/`,
305+
match: [
306+
MockApiClient.matchQuery({provider_key: 'test-integration', includeConfig: 0}),
307+
],
308+
body: [],
309+
});
310+
311+
render(<IntegrationDetailedView />, {
312+
initialRouterConfig: createRouterConfig('test-integration'),
313+
organization,
314+
});
315+
316+
expect(await screen.findByText('Alert without variant')).toBeInTheDocument();
317+
expect(await screen.findByText('Alert with explicit variant')).toBeInTheDocument();
318+
});
273319
});

static/app/views/settings/organizationIntegrations/integrationDetailedView.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,13 @@ export default function IntegrationDetailedView() {
139139
// The server response for integration installations includes old icon CSS classes
140140
// We map those to the currently in use values to their react equivalents
141141
// and fallback to IconFlag just in case.
142-
const alertList = provider?.metadata.aspects.alerts || [];
142+
const alertList: AlertType[] = (provider?.metadata.aspects.alerts || []).map(
143+
alert => ({
144+
variant: alert.variant ?? 'muted',
145+
text: alert.text,
146+
icon: alert.icon,
147+
})
148+
);
143149

144150
if (!provider?.canAdd && provider?.metadata.aspects.externalInstall) {
145151
alertList.push({

0 commit comments

Comments
 (0)