UpgradePage.tsx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. import { css } from '@emotion/css';
  2. import React from 'react';
  3. import { connect } from 'react-redux';
  4. import { GrafanaTheme2, NavModel } from '@grafana/data';
  5. import { LinkButton, useStyles2 } from '@grafana/ui';
  6. import Page from '../../core/components/Page/Page';
  7. import { getNavModel } from '../../core/selectors/navModel';
  8. import { StoreState } from '../../types';
  9. import { LicenseChrome } from './LicenseChrome';
  10. import { ServerStats } from './ServerStats';
  11. interface Props {
  12. navModel: NavModel;
  13. }
  14. export function UpgradePage({ navModel }: Props) {
  15. return (
  16. <Page navModel={navModel}>
  17. <Page.Contents>
  18. <ServerStats />
  19. <UpgradeInfo
  20. editionNotice="You are running the open-source version of Grafana.
  21. You have to install the Enterprise edition in order enable Enterprise features."
  22. />
  23. </Page.Contents>
  24. </Page>
  25. );
  26. }
  27. const titleStyles = { fontWeight: 500, fontSize: '26px', lineHeight: '123%' };
  28. interface UpgradeInfoProps {
  29. editionNotice?: string;
  30. }
  31. export const UpgradeInfo: React.FC<UpgradeInfoProps> = ({ editionNotice }) => {
  32. const styles = useStyles2(getStyles);
  33. return (
  34. <>
  35. <h2 className={styles.title}>Enterprise license</h2>
  36. <LicenseChrome header="Grafana Enterprise" subheader="Get your free trial" editionNotice={editionNotice}>
  37. <div className={styles.column}>
  38. <FeatureInfo />
  39. <ServiceInfo />
  40. </div>
  41. </LicenseChrome>
  42. </>
  43. );
  44. };
  45. const getStyles = (theme: GrafanaTheme2) => {
  46. return {
  47. column: css`
  48. display: grid;
  49. grid-template-columns: 100%;
  50. column-gap: 20px;
  51. row-gap: 40px;
  52. @media (min-width: 1050px) {
  53. grid-template-columns: 50% 50%;
  54. }
  55. `,
  56. title: css`
  57. margin: ${theme.spacing(4)} 0;
  58. `,
  59. };
  60. };
  61. const GetEnterprise: React.FC = () => {
  62. return (
  63. <div style={{ marginTop: '40px', marginBottom: '30px' }}>
  64. <h2 style={titleStyles}>Get Grafana Enterprise</h2>
  65. <CallToAction />
  66. <p style={{ paddingTop: '12px' }}>
  67. You can use the trial version for free for 30 days. We will remind you about it five days before the trial
  68. period ends.
  69. </p>
  70. </div>
  71. );
  72. };
  73. const CallToAction: React.FC = () => {
  74. return (
  75. <LinkButton
  76. variant="primary"
  77. size="lg"
  78. href="https://grafana.com/contact?about=grafana-enterprise&utm_source=grafana-upgrade-page"
  79. >
  80. Contact us and get a free trial
  81. </LinkButton>
  82. );
  83. };
  84. const ServiceInfo: React.FC = () => {
  85. return (
  86. <div>
  87. <h4>At your service</h4>
  88. <List>
  89. <Item title="Enterprise Plugins" image="public/img/licensing/plugin_enterprise.svg" />
  90. <Item title="Critical SLA: 2 hours" image="public/img/licensing/sla.svg" />
  91. <Item title="Unlimited Expert Support" image="public/img/licensing/customer_support.svg">
  92. 24 x 7 x 365 support via
  93. <List nested={true}>
  94. <Item title="Email" />
  95. <Item title="Private Slack channel" />
  96. <Item title="Phone" />
  97. </List>
  98. </Item>
  99. <Item title="Hand-in-hand support" image="public/img/licensing/handinhand_support.svg">
  100. in the upgrade process
  101. </Item>
  102. </List>
  103. <div style={{ marginTop: '20px' }}>
  104. <strong>Also included:</strong>
  105. <br />
  106. Indemnification, working with Grafana Labs on future prioritization, and training from the core Grafana team.
  107. </div>
  108. <GetEnterprise />
  109. </div>
  110. );
  111. };
  112. const FeatureInfo: React.FC = () => {
  113. return (
  114. <div style={{ paddingRight: '11px' }}>
  115. <h4>Enhanced functionality</h4>
  116. <FeatureListing />
  117. </div>
  118. );
  119. };
  120. const FeatureListing: React.FC = () => {
  121. return (
  122. <List>
  123. <Item title="Data source permissions" />
  124. <Item title="Reporting" />
  125. <Item title="SAML authentication" />
  126. <Item title="Enhanced LDAP integration" />
  127. <Item title="Team Sync">LDAP, GitHub OAuth, Auth Proxy, Okta</Item>
  128. <Item title="White labeling" />
  129. <Item title="Auditing" />
  130. <Item title="Settings updates at runtime" />
  131. <Item title="Grafana usage insights">
  132. <List nested={true}>
  133. <Item title="Sort dashboards by popularity in search" />
  134. <Item title="Find unused dashboards" />
  135. <Item title="Dashboard usage stats drawer" />
  136. <Item title="Dashboard presence indicators" />
  137. </List>
  138. </Item>
  139. <Item title="Enterprise plugins">
  140. <List nested={true}>
  141. <Item title="Oracle" />
  142. <Item title="Splunk" />
  143. <Item title="Service Now" />
  144. <Item title="Dynatrace" />
  145. <Item title="New Relic" />
  146. <Item title="DataDog" />
  147. <Item title="AppDynamics" />
  148. <Item title="SAP HANA®" />
  149. <Item title="Gitlab" />
  150. <Item title="Honeycomb" />
  151. <Item title="Jira" />
  152. <Item title="MongoDB" />
  153. <Item title="Salesforce" />
  154. <Item title="Snowflake" />
  155. <Item title="Wavefront" />
  156. </List>
  157. </Item>
  158. </List>
  159. );
  160. };
  161. interface ListProps {
  162. nested?: boolean;
  163. }
  164. const List: React.FC<ListProps> = ({ children, nested }) => {
  165. const listStyle = css`
  166. display: flex;
  167. flex-direction: column;
  168. padding-top: 8px;
  169. > div {
  170. margin-bottom: ${nested ? 0 : 8}px;
  171. }
  172. `;
  173. return <div className={listStyle}>{children}</div>;
  174. };
  175. interface ItemProps {
  176. title: string;
  177. image?: string;
  178. }
  179. const Item: React.FC<ItemProps> = ({ children, title, image }) => {
  180. const imageUrl = image ? image : 'public/img/licensing/checkmark.svg';
  181. const itemStyle = css`
  182. display: flex;
  183. > img {
  184. display: block;
  185. height: 22px;
  186. flex-grow: 0;
  187. padding-right: 12px;
  188. }
  189. `;
  190. const titleStyle = css`
  191. font-weight: 500;
  192. line-height: 1.7;
  193. `;
  194. return (
  195. <div className={itemStyle}>
  196. <img src={imageUrl} alt="" />
  197. <div>
  198. <div className={titleStyle}>{title}</div>
  199. {children}
  200. </div>
  201. </div>
  202. );
  203. };
  204. const mapStateToProps = (state: StoreState) => ({
  205. navModel: getNavModel(state.navIndex, 'upgrading'),
  206. });
  207. export default connect(mapStateToProps)(UpgradePage);