@ -1,4 +1,4 @@
import React , { ReactNode , HTMLAttributes } from 'react' ;
import React , { HTMLAttributes } from 'react' ;
import { css , cx } from '@emotion/css' ;
import { Icon , LinkButton , useStyles2 } from '@grafana/ui' ;
import { GrafanaTheme2 } from '@grafana/data' ;
@ -6,48 +6,30 @@ import { GrafanaTheme2 } from '@grafana/data';
type ComponentSize = 'sm' | 'md' ;
export interface Props extends HTMLAttributes < HTMLOrSVGElement > {
text? : string ;
featureName : string ;
size? : ComponentSize ;
children? : ReactNode ;
secondaryAction ? : {
url : string ;
text : string ;
} ;
}
export const UpgradeBox = ( { text , className , children , secondaryActio n , size = 'md' , . . . htmlProps } : Props ) = > {
export const UpgradeBox = ( { featureName , className , children , size = 'md' , . . . htmlProps } : Props ) = > {
const styles = useStyles2 ( ( theme ) = > getUpgradeBoxStyles ( theme , size ) ) ;
return (
< div className = { cx ( styles . box , className ) } { ...htmlProps } >
< Icon name = { 'rocket' } className = { styles . icon } / >
< div >
< h4 > You ’ ve found a Pro feature ! < / h4 >
{ text && < p className = { styles . text } > { text } < / p > }
{ children }
< div className = { styles . inner } >
< p className = { styles . text } >
You ’ ve discovered a Pro feature ! Get the Grafana Pro plan to access { featureName } .
< / p >
< LinkButton
variant = "prim ary"
variant = "second ary"
size = { size }
className = { styles . button }
href = "https://grafana.com/profile/org/subscription"
target = "__blank"
rel = "noopener noreferrer"
>
Upgrade to Pro
Upgrade
< / LinkButton >
{ secondaryAction && (
< LinkButton
variant = "link"
size = { size }
className = { cx ( styles . button , styles . buttonSecondary ) }
href = { secondaryAction . url }
target = "__blank"
rel = "noopener noreferrer"
>
{ secondaryAction . text }
< / LinkButton >
) }
< / div >
< / div >
) ;
@ -60,26 +42,35 @@ const getUpgradeBoxStyles = (theme: GrafanaTheme2, size: ComponentSize) => {
return {
box : css `
display : flex ;
align - items : center ;
position : relative ;
border - radius : $ { borderRadius } ;
background : $ { theme . colors . primary . transparent } ;
border : 1px solid $ { theme . colors . primary . shade } ;
background : $ { theme . colors . success . transparent } ;
padding : $ { theme . spacing ( 2 ) } ;
color : $ { theme . colors . primary . text } ;
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 - bottom : 0 ;
padding : $ { theme . spacing ( 2 , 0 ) } ;
line - height : 1.5 ;
margin : 0 ;
` ,
button : css `
margin - top : $ { theme . spacing ( 2 ) } ;
background - color : $ { theme . colors . success . main } ;
font - weight : $ { theme . typography . fontWeightLight } ;
color : white ;
& : first - of - type {
margin - right : $ { theme . spacing ( 1 ) } ;
& : hover {
background - color : $ { theme . colors . success . main } ;
}
& : focus - visible {
@ -88,11 +79,154 @@ const getUpgradeBoxStyles = (theme: GrafanaTheme2, size: ComponentSize) => {
outline : 2px solid $ { theme . colors . primary . main } ;
}
` ,
buttonSecondary : css `
color : $ { theme . colors . text . secondary } ;
` ,
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 ;
}
export const UpgradeContent = ( {
listItems ,
image ,
featureUrl ,
featureName ,
description ,
caption ,
} : 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 >
{ 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 % ;
}
` ,
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 ) } ;
` ,
title : css `
color : $ { theme . colors . text . maxContrast } ;
` ,
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 ;
} ;