From 3ad5ee87a37d0fa270c0d3c9517d0194e8d66daa Mon Sep 17 00:00:00 2001 From: Levente Balogh Date: Thu, 30 Sep 2021 17:23:40 +0200 Subject: [PATCH] Plugins Catalog: fix overflowing text in plugin cards (#39862) * refactor(Plugins/Admin): add a "badge" for displaying available updates * refactor(Plugins/Admin): rename component * refactor(Plugins/Admin): use the PluginListItemBadges component --- .../Badges/PluginUpdateAvailableBadge.tsx | 33 +++++++++++++++++++ .../plugins/admin/components/Badges/index.ts | 1 + ...test.tsx => PluginListItemBadges.test.tsx} | 14 ++++---- ...istBadges.tsx => PluginListItemBadges.tsx} | 10 +++--- .../admin/components/PluginListItemCard.tsx | 22 +++++++------ .../admin/components/PluginListItemRow.tsx | 22 +++++++------ 6 files changed, 71 insertions(+), 31 deletions(-) create mode 100644 public/app/features/plugins/admin/components/Badges/PluginUpdateAvailableBadge.tsx rename public/app/features/plugins/admin/components/{PluginListBadges.test.tsx => PluginListItemBadges.test.tsx} (79%) rename public/app/features/plugins/admin/components/{PluginListBadges.tsx => PluginListItemBadges.tsx} (68%) diff --git a/public/app/features/plugins/admin/components/Badges/PluginUpdateAvailableBadge.tsx b/public/app/features/plugins/admin/components/Badges/PluginUpdateAvailableBadge.tsx new file mode 100644 index 00000000000..de1d244ca2b --- /dev/null +++ b/public/app/features/plugins/admin/components/Badges/PluginUpdateAvailableBadge.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { Tooltip, useStyles2 } from '@grafana/ui'; +import { CatalogPlugin } from '../../types'; + +type Props = { + plugin: CatalogPlugin; +}; + +export function PluginUpdateAvailableBadge({ plugin }: Props): React.ReactElement | null { + const styles = useStyles2(getStyles); + + if (plugin.hasUpdate && !plugin.isCore) { + return ( + +

Update available!

+
+ ); + } + + return null; +} + +export const getStyles = (theme: GrafanaTheme2) => { + return { + hasUpdate: css` + color: ${theme.colors.text.secondary}; + font-size: ${theme.typography.bodySmall.fontSize}; + margin-bottom: 0; + `, + }; +}; diff --git a/public/app/features/plugins/admin/components/Badges/index.ts b/public/app/features/plugins/admin/components/Badges/index.ts index 12190d31a30..8a8e0a822e2 100644 --- a/public/app/features/plugins/admin/components/Badges/index.ts +++ b/public/app/features/plugins/admin/components/Badges/index.ts @@ -1,3 +1,4 @@ export { PluginDisabledBadge } from './PluginDisabledBadge'; export { PluginInstalledBadge } from './PluginInstallBadge'; export { PluginEnterpriseBadge } from './PluginEnterpriseBadge'; +export { PluginUpdateAvailableBadge } from './PluginUpdateAvailableBadge'; diff --git a/public/app/features/plugins/admin/components/PluginListBadges.test.tsx b/public/app/features/plugins/admin/components/PluginListItemBadges.test.tsx similarity index 79% rename from public/app/features/plugins/admin/components/PluginListBadges.test.tsx rename to public/app/features/plugins/admin/components/PluginListItemBadges.test.tsx index dad2778311f..24ade179cc5 100644 --- a/public/app/features/plugins/admin/components/PluginListBadges.test.tsx +++ b/public/app/features/plugins/admin/components/PluginListItemBadges.test.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import { PluginErrorCode, PluginSignatureStatus } from '@grafana/data'; -import { PluginListBadges } from './PluginListBadges'; +import { PluginListItemBadges } from './PluginListItemBadges'; import { CatalogPlugin } from '../types'; import { config } from '@grafana/runtime'; -describe('PluginBadges', () => { +describe('PluginListItemBadges', () => { const plugin: CatalogPlugin = { description: 'The test plugin', downloads: 5, @@ -36,13 +36,13 @@ describe('PluginBadges', () => { }); it('renders a plugin signature badge', () => { - render(); + render(); expect(screen.getByText(/signed/i)).toBeVisible(); }); it('renders an installed badge', () => { - render(); + render(); expect(screen.getByText(/signed/i)).toBeVisible(); expect(screen.getByText(/installed/i)).toBeVisible(); @@ -50,21 +50,21 @@ describe('PluginBadges', () => { it('renders an enterprise badge (when a license is valid)', () => { config.licenseInfo.hasValidLicense = true; - render(); + render(); expect(screen.getByText(/enterprise/i)).toBeVisible(); expect(screen.queryByRole('button', { name: /learn more/i })).not.toBeInTheDocument(); }); it('renders an enterprise badge with icon and link (when a license is invalid)', () => { config.licenseInfo.hasValidLicense = false; - render(); + render(); expect(screen.getByText(/enterprise/i)).toBeVisible(); expect(screen.getByLabelText(/lock icon/i)).toBeInTheDocument(); expect(screen.getByRole('button', { name: /learn more/i })).toBeInTheDocument(); }); it('renders a error badge (when plugin has an error', () => { - render(); + render(); expect(screen.getByText(/disabled/i)).toBeVisible(); }); }); diff --git a/public/app/features/plugins/admin/components/PluginListBadges.tsx b/public/app/features/plugins/admin/components/PluginListItemBadges.tsx similarity index 68% rename from public/app/features/plugins/admin/components/PluginListBadges.tsx rename to public/app/features/plugins/admin/components/PluginListItemBadges.tsx index 0cca9557459..e96c9b8431b 100644 --- a/public/app/features/plugins/admin/components/PluginListBadges.tsx +++ b/public/app/features/plugins/admin/components/PluginListItemBadges.tsx @@ -1,27 +1,29 @@ import React from 'react'; import { HorizontalGroup, PluginSignatureBadge } from '@grafana/ui'; import { CatalogPlugin } from '../types'; -import { PluginEnterpriseBadge, PluginDisabledBadge, PluginInstalledBadge } from './Badges'; +import { PluginEnterpriseBadge, PluginDisabledBadge, PluginInstalledBadge, PluginUpdateAvailableBadge } from './Badges'; type PluginBadgeType = { plugin: CatalogPlugin; }; -export function PluginListBadges({ plugin }: PluginBadgeType) { +export function PluginListItemBadges({ plugin }: PluginBadgeType) { if (plugin.isEnterprise) { return ( - + {plugin.isDisabled && } + ); } return ( - + {plugin.isDisabled && } {plugin.isInstalled && } + ); } diff --git a/public/app/features/plugins/admin/components/PluginListItemCard.tsx b/public/app/features/plugins/admin/components/PluginListItemCard.tsx index 94fed6e6a39..5ba03839988 100644 --- a/public/app/features/plugins/admin/components/PluginListItemCard.tsx +++ b/public/app/features/plugins/admin/components/PluginListItemCard.tsx @@ -1,8 +1,8 @@ import React from 'react'; -import { Icon, useStyles2, HorizontalGroup, Tooltip, CardContainer, VerticalGroup } from '@grafana/ui'; +import { Icon, useStyles2, CardContainer, VerticalGroup } from '@grafana/ui'; import { CatalogPlugin, PluginIconName, PluginListDisplayMode, PluginTabIds } from '../types'; import { PluginLogo } from './PluginLogo'; -import { PluginListBadges } from './PluginListBadges'; +import { PluginListItemBadges } from './PluginListItemBadges'; import { getStyles, LOGO_SIZE } from './PluginListItem'; type Props = { @@ -17,28 +17,30 @@ export function PluginListItemCard({ plugin, pathName }: Props) {
+ {/* Logo */} + + {/* Name */}

{plugin.name}

+ + {/* Type Icon */} {plugin.type && (
)}
+ + {/* Org */}

By {plugin.orgName}

- - - {plugin.hasUpdate && !plugin.isCore ? ( - -

Update available!

-
- ) : null} -
+ + {/* Badges */} +
); diff --git a/public/app/features/plugins/admin/components/PluginListItemRow.tsx b/public/app/features/plugins/admin/components/PluginListItemRow.tsx index f6fda00a918..bc599daf661 100644 --- a/public/app/features/plugins/admin/components/PluginListItemRow.tsx +++ b/public/app/features/plugins/admin/components/PluginListItemRow.tsx @@ -1,8 +1,8 @@ import React from 'react'; -import { Icon, useStyles2, HorizontalGroup, Tooltip, CardContainer, VerticalGroup } from '@grafana/ui'; +import { Icon, useStyles2, CardContainer, VerticalGroup } from '@grafana/ui'; import { CatalogPlugin, PluginIconName, PluginListDisplayMode, PluginTabIds } from '../types'; import { PluginLogo } from './PluginLogo'; -import { PluginListBadges } from './PluginListBadges'; +import { PluginListItemBadges } from './PluginListItemBadges'; import { getStyles, LOGO_SIZE } from './PluginListItem'; type Props = { @@ -17,24 +17,26 @@ export function PluginListItemRow({ plugin, pathName }: Props) {
+ {/* Logo */} +
+ {/* Name */}

{plugin.name}

+ + {/* Org */}

By {plugin.orgName}

- - - {plugin.hasUpdate && !plugin.isCore && ( - -

Update available!

-
- )} -
+ + {/* Badges */} +
+ + {/* Type Icon */} {plugin.type && (