import { css } from '@emotion/css'; import { Fragment } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; import { config } from '@grafana/runtime'; import { Alert, Stack, useStyles2 } from '@grafana/ui'; import { InstallControlsWarning } from '../components/InstallControls'; import { getLatestCompatibleVersion, hasInstallControlWarning } from '../helpers'; import { useInstallStatus, useIsRemotePluginsAvailable } from '../state/hooks'; import { CatalogPlugin, PluginStatus } from '../types'; interface Props { plugin?: CatalogPlugin; } type PluginSubtitleExtension = (props: Props) => JSX.Element | null; const pluginSubtitleExtensions: PluginSubtitleExtension[] = []; export const registerPluginSubtitleExtension = (extension: PluginSubtitleExtension) => { pluginSubtitleExtensions.push(extension); }; export const PluginSubtitle = ({ plugin }: Props) => { const isRemotePluginsAvailable = useIsRemotePluginsAvailable(); const styles = useStyles2(getStyles); const { error: errorInstalling } = useInstallStatus(); if (!plugin) { return null; } const latestCompatibleVersion = getLatestCompatibleVersion(plugin.details?.versions); const pluginStatus = plugin.isInstalled ? plugin.hasUpdate ? PluginStatus.UPDATE : PluginStatus.UNINSTALL : PluginStatus.INSTALL; return (
{errorInstalling && ( {typeof errorInstalling === 'string' ? errorInstalling : errorInstalling.error} )}
{plugin?.description &&
{plugin?.description}
} {!config.featureToggles.pluginsDetailsRightPanel && !!plugin?.details?.links?.length && ( {plugin.details.links.map((link, index) => ( {index > 0 && ' | '} {link.name} ))} )} {hasInstallControlWarning(plugin, isRemotePluginsAvailable, latestCompatibleVersion) && ( )}
{pluginSubtitleExtensions.map((extension) => { return {extension({ plugin })}; })}
); }; export const getStyles = (theme: GrafanaTheme2) => { return { subtitle: css({ display: 'flex', flexDirection: 'column', gap: theme.spacing(1), }), }; };