Connections console: Add Angular badge for Angular plugins (#70789)

* Angular deprecation: Add Angular badge in plugin catalog page

* Angular deprecation: Add alert in plugin details page

* Angular deprecation: Disable install button if for Angular plugins

* removed extra console.log

* Add tests for Angular badge

* Add tests for PluginDetailsAngularDeprecation

* Add tests for InstallControlsButton

* Add tests for ExternallyManagedButton

* Table tests

* Catalog: Update angular deprecation message

* PR review feedback

* Update tests

* Update copy for angular tooltip and alert

* Update tests

* Fix test warnings

* Fix angularDetected not being set for remote catalog plugins

* Dynamic alert text based on grafana config

* Connections: Add Angular badge to Angular plugins

* Add test for connections console angular badge

* Fix tests

* Fix tests

* Moved tests

* PR review: Use ternary operator instead of &&

* Fixes to how to use Card component

* comment out desc

* Do not use deprecated theme.v1 and theme.typography.size

* pr review feedback

---------

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
Giuseppe Guerra 2023-07-11 10:12:09 +02:00 committed by GitHub
parent e05c0062f2
commit 9945c02405
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 38 deletions

View File

@ -3,43 +3,58 @@ import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Card, useStyles2 } from '@grafana/ui';
import { PluginAngularBadge } from 'app/features/plugins/admin/components/Badges';
const getStyles = (theme: GrafanaTheme2) => ({
sourcesList: css`
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
gap: 12px;
list-style: none;
margin-bottom: 80px;
`,
card: css`
height: 90px;
padding: 0px 24px;
margin-bottom: 0;
`,
cardContent: css`
display: flex;
align-items: center;
`,
logoWrapper: css`
display: flex;
justify-content: center;
margin-right: 8px;
width: 32px;
height: 32px;
img {
max-width: 100%;
max-height: 100%;
align-self: center;
}
`,
label: css`
color: ${theme.colors.text.primary};
margin-bottom: 0;
`,
heading: css({
fontSize: theme.typography.h5.fontSize,
fontWeight: 'inherit',
}),
figure: css({
width: 'inherit',
marginRight: '0px',
'> img': {
width: theme.spacing(7),
},
}),
meta: css({
marginTop: '6px',
position: 'relative',
}),
description: css({
margin: '0px',
fontSize: theme.typography.bodySmall.fontSize,
}),
card: css({
gridTemplateAreas: `
"Figure Heading Actions"
"Figure Description Actions"
"Figure Meta Actions"
"Figure - Actions"`,
}),
logo: css({
marginRight: theme.spacing(3),
marginLeft: theme.spacing(1),
width: theme.spacing(7),
maxHeight: theme.spacing(7),
}),
});
export type CardGridItem = { id: string; name: string; description: string; url: string; logo?: string };
export type CardGridItem = {
id: string;
name: string;
description: string;
url: string;
logo?: string;
angularDetected?: boolean;
};
export interface CardGridProps {
items: CardGridItem[];
onClickItem?: (e: React.MouseEvent<HTMLElement>, item: CardGridItem) => void;
@ -61,16 +76,17 @@ export const CardGrid = ({ items, onClickItem }: CardGridProps) => {
}
}}
>
<Card.Heading>
<div className={styles.cardContent}>
{item.logo && (
<div className={styles.logoWrapper}>
<img src={item.logo} alt={`logo of ${item.name}`} />
</div>
)}
<h4 className={styles.label}>{item.name}</h4>
</div>
</Card.Heading>
<Card.Heading className={styles.heading}>{item.name}</Card.Heading>
<Card.Figure align="center" className={styles.figure}>
<img className={styles.logo} src={item.logo} alt="" />
</Card.Figure>
{item.angularDetected ? (
<Card.Meta className={styles.meta}>
<PluginAngularBadge />
</Card.Meta>
) : null}
</Card>
))}
</ul>

View File

@ -1,4 +1,4 @@
import { fireEvent, render, RenderResult, screen } from '@testing-library/react';
import { fireEvent, render, RenderResult, screen, waitFor } from '@testing-library/react';
import React from 'react';
import { Provider } from 'react-redux';
@ -32,6 +32,38 @@ const mockCatalogDataSourcePlugin = getCatalogPluginMock({
const originalHasPermission = contextSrv.hasPermission;
describe('Angular badge', () => {
test('does not show angular badge for non-angular plugins', async () => {
renderPage([
getCatalogPluginMock({
id: 'react-plugin',
name: 'React Plugin',
type: PluginType.datasource,
angularDetected: false,
}),
]);
await waitFor(() => {
expect(screen.queryByText('React Plugin')).toBeInTheDocument();
});
expect(screen.queryByText('Angular')).not.toBeInTheDocument();
});
test('shows angular badge for angular plugins', async () => {
renderPage([
getCatalogPluginMock({
id: 'legacy-plugin',
name: 'Legacy Plugin',
type: PluginType.datasource,
angularDetected: true,
}),
]);
await waitFor(() => {
expect(screen.queryByText('Legacy Plugin')).toBeInTheDocument();
});
expect(screen.queryByText('Angular')).toBeInTheDocument();
});
});
describe('Add new connection', () => {
beforeEach(() => {
contextSrv.hasPermission = originalHasPermission;

View File

@ -52,6 +52,7 @@ export function AddNewConnection() {
description: plugin.description,
logo: plugin.info.logos.small,
url: ROUTES.DataSourcesDetails.replace(':id', plugin.id),
angularDetected: plugin.angularDetected,
})),
[plugins]
);