mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
* Add and configure eslint-plugin-import * Fix the lint:ts npm command * Autofix + prettier all the files * Manually fix remaining files * Move jquery code in jest-setup to external file to safely reorder imports * Resolve issue caused by circular dependencies within Prometheus * Update .betterer.results * Fix missing // @ts-ignore * ignore iconBundle.ts * Fix missing // @ts-ignore
267 lines
6.7 KiB
TypeScript
267 lines
6.7 KiB
TypeScript
import { css, cx } from '@emotion/css';
|
||
import React, { HTMLAttributes, useEffect } from 'react';
|
||
|
||
import { GrafanaTheme2 } from '@grafana/data';
|
||
import { reportExperimentView } from '@grafana/runtime/src';
|
||
import { Button, Icon, LinkButton, useStyles2 } from '@grafana/ui';
|
||
|
||
type ComponentSize = 'sm' | 'md';
|
||
|
||
export interface Props extends HTMLAttributes<HTMLOrSVGElement> {
|
||
featureName: string;
|
||
size?: ComponentSize;
|
||
text?: string;
|
||
eventVariant?: string;
|
||
featureId: string;
|
||
}
|
||
|
||
export const UpgradeBox = ({
|
||
featureName,
|
||
className,
|
||
children,
|
||
text,
|
||
featureId,
|
||
eventVariant = '',
|
||
size = 'md',
|
||
...htmlProps
|
||
}: Props) => {
|
||
const styles = useStyles2((theme) => getUpgradeBoxStyles(theme, size));
|
||
|
||
useEffect(() => {
|
||
reportExperimentView(`feature-highlights-${featureId}`, 'test', eventVariant);
|
||
}, [eventVariant, featureId]);
|
||
|
||
return (
|
||
<div className={cx(styles.box, className)} {...htmlProps}>
|
||
<Icon name={'rocket'} className={styles.icon} />
|
||
<div className={styles.inner}>
|
||
<p className={styles.text}>
|
||
You’ve discovered a Pro feature! {text || `Get the Grafana Pro plan to access ${featureName}.`}
|
||
</p>
|
||
<LinkButton
|
||
variant="secondary"
|
||
size={size}
|
||
className={styles.button}
|
||
href="https://grafana.com/profile/org/subscription"
|
||
target="__blank"
|
||
rel="noopener noreferrer"
|
||
>
|
||
Upgrade
|
||
</LinkButton>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
const getUpgradeBoxStyles = (theme: GrafanaTheme2, size: ComponentSize) => {
|
||
const borderRadius = theme.shape.borderRadius(2);
|
||
const fontBase = size === 'md' ? 'body' : 'bodySmall';
|
||
|
||
return {
|
||
box: css`
|
||
display: flex;
|
||
align-items: center;
|
||
position: relative;
|
||
border-radius: ${borderRadius};
|
||
background: ${theme.colors.success.transparent};
|
||
padding: ${theme.spacing(2)};
|
||
color: ${theme.colors.success.text};
|
||
font-size: ${theme.typography[fontBase].fontSize};
|
||
text-align: left;
|
||
line-height: 16px;
|
||
margin: ${theme.spacing(0, 'auto', 3, 'auto')};
|
||
max-width: ${theme.breakpoints.values.xxl}px;
|
||
width: 100%;
|
||
`,
|
||
inner: css`
|
||
display: flex;
|
||
align-items: center;
|
||
width: 100%;
|
||
justify-content: space-between;
|
||
`,
|
||
text: css`
|
||
margin: 0;
|
||
`,
|
||
button: css`
|
||
background-color: ${theme.colors.success.main};
|
||
font-weight: ${theme.typography.fontWeightLight};
|
||
color: white;
|
||
|
||
&:hover {
|
||
background-color: ${theme.colors.success.main};
|
||
}
|
||
|
||
&:focus-visible {
|
||
box-shadow: none;
|
||
color: ${theme.colors.text.primary};
|
||
outline: 2px solid ${theme.colors.primary.main};
|
||
}
|
||
`,
|
||
icon: css`
|
||
margin: ${theme.spacing(0.5, 1, 0.5, 0.5)};
|
||
`,
|
||
};
|
||
};
|
||
|
||
export interface UpgradeContentProps {
|
||
image: string;
|
||
featureUrl?: string;
|
||
featureName: string;
|
||
description?: string;
|
||
listItems: string[];
|
||
caption?: string;
|
||
action?: {
|
||
text: string;
|
||
link?: string;
|
||
onClick?: () => void;
|
||
};
|
||
}
|
||
|
||
export const UpgradeContent = ({
|
||
listItems,
|
||
image,
|
||
featureUrl,
|
||
featureName,
|
||
description,
|
||
caption,
|
||
action,
|
||
}: UpgradeContentProps) => {
|
||
const styles = useStyles2(getUpgradeContentStyles);
|
||
return (
|
||
<div className={styles.container}>
|
||
<div className={styles.content}>
|
||
<h3 className={styles.title}>Get started with {featureName}</h3>
|
||
{description && <h6 className={styles.description}>{description}</h6>}
|
||
<ul className={styles.list}>
|
||
{listItems.map((item, index) => (
|
||
<li key={index}>
|
||
<Icon name={'check'} size={'xl'} className={styles.icon} /> {item}
|
||
</li>
|
||
))}
|
||
</ul>
|
||
{action?.link && (
|
||
<LinkButton variant={'primary'} href={action.link}>
|
||
{action.text}
|
||
</LinkButton>
|
||
)}
|
||
{action?.onClick && (
|
||
<Button variant={'primary'} onClick={action.onClick}>
|
||
{action.text}
|
||
</Button>
|
||
)}
|
||
{featureUrl && (
|
||
<LinkButton fill={'text'} href={featureUrl} className={styles.link} target="_blank" rel="noreferrer noopener">
|
||
Learn more
|
||
</LinkButton>
|
||
)}
|
||
</div>
|
||
<div className={styles.media}>
|
||
<img src={getImgUrl(image)} alt={'Feature screenshot'} />
|
||
{caption && <p className={styles.caption}>{caption}</p>}
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
const getUpgradeContentStyles = (theme: GrafanaTheme2) => {
|
||
return {
|
||
container: css`
|
||
display: flex;
|
||
justify-content: space-between;
|
||
`,
|
||
content: css`
|
||
width: 45%;
|
||
margin-right: ${theme.spacing(4)};
|
||
`,
|
||
media: css`
|
||
width: 55%;
|
||
|
||
img {
|
||
width: 100%;
|
||
}
|
||
`,
|
||
title: css`
|
||
color: ${theme.colors.text.maxContrast};
|
||
`,
|
||
description: css`
|
||
color: ${theme.colors.text.primary};
|
||
font-weight: ${theme.typography.fontWeightLight};
|
||
`,
|
||
list: css`
|
||
list-style: none;
|
||
margin: ${theme.spacing(4, 0, 2, 0)};
|
||
|
||
li {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
color: ${theme.colors.text.primary};
|
||
padding: ${theme.spacing(1, 0)};
|
||
}
|
||
`,
|
||
icon: css`
|
||
color: ${theme.colors.success.main};
|
||
margin-right: ${theme.spacing(1)};
|
||
`,
|
||
link: css`
|
||
margin-left: ${theme.spacing(2)};
|
||
`,
|
||
caption: css`
|
||
font-weight: ${theme.typography.fontWeightLight};
|
||
margin: ${theme.spacing(1, 0, 0)};
|
||
`,
|
||
};
|
||
};
|
||
|
||
export const UpgradeContentVertical = ({
|
||
featureName,
|
||
description,
|
||
featureUrl,
|
||
image,
|
||
}: Omit<UpgradeContentProps, 'listItems' | 'caption'>) => {
|
||
const styles = useStyles2(getContentVerticalStyles);
|
||
return (
|
||
<div className={styles.container}>
|
||
<h3 className={styles.title}>Get started with {featureName}</h3>
|
||
{description && <h6 className={styles.description}>{description}</h6>}
|
||
<LinkButton fill={'text'} href={featureUrl} target="_blank" rel="noreferrer noopener">
|
||
Learn more
|
||
</LinkButton>
|
||
<div className={styles.media}>
|
||
<img src={getImgUrl(image)} alt={'Feature screenshot'} />
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
const getContentVerticalStyles = (theme: GrafanaTheme2) => {
|
||
return {
|
||
container: css`
|
||
overflow: auto;
|
||
height: 100%;
|
||
`,
|
||
title: css`
|
||
color: ${theme.colors.text.maxContrast};
|
||
`,
|
||
description: css`
|
||
color: ${theme.colors.text.primary};
|
||
font-weight: ${theme.typography.fontWeightLight};
|
||
`,
|
||
media: css`
|
||
width: 100%;
|
||
margin-top: ${theme.spacing(2)};
|
||
|
||
img {
|
||
width: 100%;
|
||
}
|
||
`,
|
||
};
|
||
};
|
||
|
||
const getImgUrl = (urlOrId: string) => {
|
||
if (urlOrId.startsWith('http')) {
|
||
return urlOrId;
|
||
}
|
||
|
||
return '/public/img/enterprise/highlights/' + urlOrId;
|
||
};
|