123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- import { css, cx } from '@emotion/css';
- import React from 'react';
- import { GrafanaTheme2 } from '@grafana/data';
- import { useStyles2, Icon, HorizontalGroup } from '@grafana/ui';
- import { getLatestCompatibleVersion } from '../helpers';
- import { CatalogPlugin } from '../types';
- import { PluginDisabledBadge } from './Badges';
- import { GetStartedWithPlugin } from './GetStartedWithPlugin';
- import { InstallControls } from './InstallControls';
- import { PluginDetailsHeaderDependencies } from './PluginDetailsHeaderDependencies';
- import { PluginDetailsHeaderSignature } from './PluginDetailsHeaderSignature';
- import { PluginLogo } from './PluginLogo';
- type Props = {
- currentUrl: string;
- parentUrl: string;
- plugin: CatalogPlugin;
- };
- export function PluginDetailsHeader({ plugin, currentUrl, parentUrl }: Props): React.ReactElement {
- const styles = useStyles2(getStyles);
- const latestCompatibleVersion = getLatestCompatibleVersion(plugin.details?.versions);
- const version = plugin.installedVersion || latestCompatibleVersion?.version;
- return (
- <div>
- <div className="page-container">
- <div className={styles.headerContainer}>
- <PluginLogo
- alt={`${plugin.name} logo`}
- src={plugin.info.logos.small}
- className={css`
- object-fit: contain;
- width: 100%;
- height: 68px;
- max-width: 68px;
- `}
- />
- <div className={styles.headerWrapper}>
- {/* Title & navigation */}
- <nav className={styles.breadcrumb} aria-label="Breadcrumb">
- <ol>
- <li>
- <a className={styles.textUnderline} href={parentUrl}>
- Plugins
- </a>
- </li>
- <li>
- <a href={currentUrl} aria-current="page">
- {plugin.name}
- </a>
- </li>
- </ol>
- </nav>
- <div className={styles.headerInformationRow}>
- {/* Org name */}
- <span>{plugin.orgName}</span>
- {/* Links */}
- {plugin.details?.links.map((link: any) => (
- <a key={link.name} href={link.url}>
- {link.name}
- </a>
- ))}
- {/* Downloads */}
- {plugin.downloads > 0 && (
- <span>
- <Icon name="cloud-download" />
- {` ${new Intl.NumberFormat().format(plugin.downloads)}`}{' '}
- </span>
- )}
- {/* Version */}
- {Boolean(version) && <span>{version}</span>}
- {/* Signature information */}
- <PluginDetailsHeaderSignature plugin={plugin} />
- {plugin.isDisabled && <PluginDisabledBadge error={plugin.error!} />}
- </div>
- <PluginDetailsHeaderDependencies
- plugin={plugin}
- latestCompatibleVersion={latestCompatibleVersion}
- className={cx(styles.headerInformationRow, styles.headerInformationRowSecondary)}
- />
- <p>{plugin.description}</p>
- <HorizontalGroup height="auto">
- <InstallControls plugin={plugin} latestCompatibleVersion={latestCompatibleVersion} />
- <GetStartedWithPlugin plugin={plugin} />
- </HorizontalGroup>
- </div>
- </div>
- </div>
- </div>
- );
- }
- export const getStyles = (theme: GrafanaTheme2) => {
- return {
- headerContainer: css`
- display: flex;
- margin-bottom: ${theme.spacing(3)};
- margin-top: ${theme.spacing(3)};
- min-height: 120px;
- `,
- headerWrapper: css`
- margin-left: ${theme.spacing(3)};
- `,
- breadcrumb: css`
- font-size: ${theme.typography.h2.fontSize};
- li {
- display: inline;
- list-style: none;
- &::after {
- content: '/';
- padding: 0 0.25ch;
- }
- &:last-child::after {
- content: '';
- }
- }
- `,
- headerInformationRow: css`
- display: flex;
- align-items: center;
- margin-top: ${theme.spacing()};
- margin-bottom: ${theme.spacing()};
- flex-flow: wrap;
- & > * {
- &::after {
- content: '|';
- padding: 0 ${theme.spacing()};
- }
- &:last-child::after {
- content: '';
- padding-right: 0;
- }
- }
- font-size: ${theme.typography.h4.fontSize};
- a {
- &:hover {
- text-decoration: underline;
- }
- }
- `,
- headerInformationRowSecondary: css`
- font-size: ${theme.typography.body.fontSize};
- `,
- headerOrgName: css`
- font-size: ${theme.typography.h4.fontSize};
- `,
- signature: css`
- margin: ${theme.spacing(3)};
- margin-bottom: 0;
- `,
- textUnderline: css`
- text-decoration: underline;
- `,
- };
- };
|