diff --git a/public/app/features/admin/migrate-to-cloud/EmptyState/CallToAction.tsx b/public/app/features/admin/migrate-to-cloud/EmptyState/CallToAction.tsx new file mode 100644 index 00000000000..b44796c8c11 --- /dev/null +++ b/public/app/features/admin/migrate-to-cloud/EmptyState/CallToAction.tsx @@ -0,0 +1,23 @@ +import React from 'react'; + +import { Box, Button, Stack, Text } from '@grafana/ui'; +import { Trans } from 'app/core/internationalization'; + +export const CallToAction = () => { + const onClickMigrate = () => { + console.log('TODO migration!'); + }; + + return ( + + + + Let us manage your Grafana stack + + + + + ); +}; diff --git a/public/app/features/admin/migrate-to-cloud/EmptyState/EmptyState.tsx b/public/app/features/admin/migrate-to-cloud/EmptyState/EmptyState.tsx new file mode 100644 index 00000000000..3e405b06257 --- /dev/null +++ b/public/app/features/admin/migrate-to-cloud/EmptyState/EmptyState.tsx @@ -0,0 +1,37 @@ +import { css } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Grid, Stack, useStyles2 } from '@grafana/ui'; + +import { CallToAction } from './CallToAction'; +import { InfoPane1 } from './InfoPane1'; +import { InfoPane2 } from './InfoPane2'; + +export const EmptyState = () => { + const styles = useStyles2(getStyles); + + return ( +
+ + + + + + + +
+ ); +}; + +const getStyles = (theme: GrafanaTheme2) => ({ + container: css({ + maxWidth: theme.breakpoints.values.xl, + }), +}); diff --git a/public/app/features/admin/migrate-to-cloud/EmptyState/InfoItem.tsx b/public/app/features/admin/migrate-to-cloud/EmptyState/InfoItem.tsx new file mode 100644 index 00000000000..5c107d8bf80 --- /dev/null +++ b/public/app/features/admin/migrate-to-cloud/EmptyState/InfoItem.tsx @@ -0,0 +1,26 @@ +import React, { ReactNode } from 'react'; + +import { Stack, Text, TextLink } from '@grafana/ui'; + +interface Props { + children: NonNullable; + title: string; + linkTitle?: string; + linkHref?: string; +} + +export const InfoItem = ({ children, title, linkHref, linkTitle }: Props) => { + return ( + + {title} + + {children} + + {linkHref && ( + + {linkTitle ?? linkHref} + + )} + + ); +}; diff --git a/public/app/features/admin/migrate-to-cloud/EmptyState/InfoPane1.tsx b/public/app/features/admin/migrate-to-cloud/EmptyState/InfoPane1.tsx new file mode 100644 index 00000000000..bb010fb485f --- /dev/null +++ b/public/app/features/admin/migrate-to-cloud/EmptyState/InfoPane1.tsx @@ -0,0 +1,47 @@ +import React from 'react'; + +import { Box, Stack } from '@grafana/ui'; +import { t, Trans } from 'app/core/internationalization'; + +import { InfoItem } from './InfoItem'; + +export const InfoPane1 = () => { + return ( + + + + + { + "Grafana cloud is a fully managed cloud-hosted observability platform ideal for cloud native environments. It's everything you love about Grafana without the overhead of maintaining, upgrading, and supporting an installation." + } + + + + + In addition to the convenience of managed hosting, Grafana Cloud includes many cloud-exclusive features like + SLOs, incident management, machine learning, and powerful observability integrations. + + + + + { + "Grafana Labs is committed to maintaining the highest standards of data privacy and security. By implementing industry-standard security technologies and procedures, we help protect our customers' data from unauthorized access, use, or disclosure." + } + + + + + ); +}; diff --git a/public/app/features/admin/migrate-to-cloud/EmptyState/InfoPane2.tsx b/public/app/features/admin/migrate-to-cloud/EmptyState/InfoPane2.tsx new file mode 100644 index 00000000000..986d9711734 --- /dev/null +++ b/public/app/features/admin/migrate-to-cloud/EmptyState/InfoPane2.tsx @@ -0,0 +1,47 @@ +import React from 'react'; + +import { Box, Stack } from '@grafana/ui'; +import { t, Trans } from 'app/core/internationalization'; + +import { InfoItem } from './InfoItem'; + +export const InfoPane2 = () => { + return ( + + + + + Exposing your data sources to the internet can raise security concerns. Private data source connect (PDC) + allows Grafana Cloud to access your existing data sources over a secure network tunnel. + + + + + { + "Grafana Cloud has a generous free plan and a 14 day unlimited usage trial. After your trial expires, you'll be billed based on usage over the free plan limits." + } + + + + + { + "Once you connect this installation to a cloud stack, you'll be able to upload data sources and dashboards." + } + + + + + ); +}; diff --git a/public/app/features/admin/migrate-to-cloud/MigrateToCloud.tsx b/public/app/features/admin/migrate-to-cloud/MigrateToCloud.tsx index a213fe2ae60..a30d26fd97e 100644 --- a/public/app/features/admin/migrate-to-cloud/MigrateToCloud.tsx +++ b/public/app/features/admin/migrate-to-cloud/MigrateToCloud.tsx @@ -2,6 +2,12 @@ import React from 'react'; import { Page } from 'app/core/components/Page/Page'; +import { EmptyState } from './EmptyState/EmptyState'; + export default function MigrateToCloud() { - return TODO; + return ( + + + + ); } diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index d2c4ad33cd4..25f334e26f1 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -691,6 +691,42 @@ "new-to-question": "New to Grafana?" } }, + "migrate-to-cloud": { + "can-i-move": { + "body": "Once you connect this installation to a cloud stack, you'll be able to upload data sources and dashboards.", + "link-title": "Learn about migrating other settings", + "title": "Can I move this installation to Grafana Cloud?" + }, + "cta": { + "button": "Migrate this instance to Cloud", + "header": "Let us manage your Grafana stack" + }, + "is-it-secure": { + "body": "Grafana Labs is committed to maintaining the highest standards of data privacy and security. By implementing industry-standard security technologies and procedures, we help protect our customers' data from unauthorized access, use, or disclosure.", + "link-title": "Grafana Labs Trust Center", + "title": "Is it secure?" + }, + "pdc": { + "body": "Exposing your data sources to the internet can raise security concerns. Private data source connect (PDC) allows Grafana Cloud to access your existing data sources over a secure network tunnel.", + "link-title": "Learn about PDC", + "title": "Not all my data sources are on the public internet" + }, + "pricing": { + "body": "Grafana Cloud has a generous free plan and a 14 day unlimited usage trial. After your trial expires, you'll be billed based on usage over the free plan limits.", + "link-title": "Grafana Cloud pricing", + "title": "How much does it cost?" + }, + "what-is-cloud": { + "body": "Grafana cloud is a fully managed cloud-hosted observability platform ideal for cloud native environments. It's everything you love about Grafana without the overhead of maintaining, upgrading, and supporting an installation.", + "link-title": "Learn about cloud features", + "title": "What is Grafana Cloud?" + }, + "why-host": { + "body": "In addition to the convenience of managed hosting, Grafana Cloud includes many cloud-exclusive features like SLOs, incident management, machine learning, and powerful observability integrations.", + "link-title": "More questions? Talk to an expert", + "title": "Why host with Grafana?" + } + }, "nav": { "add-new-connections": { "title": "Add new connection" diff --git a/public/locales/pseudo-LOCALE/grafana.json b/public/locales/pseudo-LOCALE/grafana.json index 9b2428d3450..a5665a5c79f 100644 --- a/public/locales/pseudo-LOCALE/grafana.json +++ b/public/locales/pseudo-LOCALE/grafana.json @@ -691,6 +691,42 @@ "new-to-question": "Ńęŵ ŧő Ğřäƒäʼnä?" } }, + "migrate-to-cloud": { + "can-i-move": { + "body": "Øʼnčę yőū čőʼnʼnęčŧ ŧĥįş įʼnşŧäľľäŧįőʼn ŧő ä čľőūđ şŧäčĸ, yőū'ľľ þę äþľę ŧő ūpľőäđ đäŧä şőūřčęş äʼnđ đäşĥþőäřđş.", + "link-title": "Ŀęäřʼn äþőūŧ mįģřäŧįʼnģ őŧĥęř şęŧŧįʼnģş", + "title": "Cäʼn Ĩ mővę ŧĥįş įʼnşŧäľľäŧįőʼn ŧő Ğřäƒäʼnä Cľőūđ?" + }, + "cta": { + "button": "Mįģřäŧę ŧĥįş įʼnşŧäʼnčę ŧő Cľőūđ", + "header": "Ŀęŧ ūş mäʼnäģę yőūř Ğřäƒäʼnä şŧäčĸ" + }, + "is-it-secure": { + "body": "Ğřäƒäʼnä Ŀäþş įş čőmmįŧŧęđ ŧő mäįʼnŧäįʼnįʼnģ ŧĥę ĥįģĥęşŧ şŧäʼnđäřđş őƒ đäŧä přįväčy äʼnđ şęčūřįŧy. ßy įmpľęmęʼnŧįʼnģ įʼnđūşŧřy-şŧäʼnđäřđ şęčūřįŧy ŧęčĥʼnőľőģįęş äʼnđ přőčęđūřęş, ŵę ĥęľp přőŧęčŧ őūř čūşŧőmęřş' đäŧä ƒřőm ūʼnäūŧĥőřįžęđ äččęşş, ūşę, őř đįşčľőşūřę.", + "link-title": "Ğřäƒäʼnä Ŀäþş Ŧřūşŧ Cęʼnŧęř", + "title": "Ĩş įŧ şęčūřę?" + }, + "pdc": { + "body": "Ēχpőşįʼnģ yőūř đäŧä şőūřčęş ŧő ŧĥę įʼnŧęřʼnęŧ čäʼn řäįşę şęčūřįŧy čőʼnčęřʼnş. Přįväŧę đäŧä şőūřčę čőʼnʼnęčŧ (PĐC) äľľőŵş Ğřäƒäʼnä Cľőūđ ŧő äččęşş yőūř ęχįşŧįʼnģ đäŧä şőūřčęş ővęř ä şęčūřę ʼnęŧŵőřĸ ŧūʼnʼnęľ.", + "link-title": "Ŀęäřʼn äþőūŧ PĐC", + "title": "Ńőŧ äľľ my đäŧä şőūřčęş äřę őʼn ŧĥę pūþľįč įʼnŧęřʼnęŧ" + }, + "pricing": { + "body": "Ğřäƒäʼnä Cľőūđ ĥäş ä ģęʼnęřőūş ƒřęę pľäʼn äʼnđ ä 14 đäy ūʼnľįmįŧęđ ūşäģę ŧřįäľ. Ńŧęř yőūř ŧřįäľ ęχpįřęş, yőū'ľľ þę þįľľęđ þäşęđ őʼn ūşäģę ővęř ŧĥę ƒřęę pľäʼn ľįmįŧş.", + "link-title": "Ğřäƒäʼnä Cľőūđ přįčįʼnģ", + "title": "Ħőŵ mūčĥ đőęş įŧ čőşŧ?" + }, + "what-is-cloud": { + "body": "Ğřäƒäʼnä čľőūđ įş ä ƒūľľy mäʼnäģęđ čľőūđ-ĥőşŧęđ őþşęřväþįľįŧy pľäŧƒőřm įđęäľ ƒőř čľőūđ ʼnäŧįvę ęʼnvįřőʼnmęʼnŧş. Ĩŧ'ş ęvęřyŧĥįʼnģ yőū ľővę äþőūŧ Ğřäƒäʼnä ŵįŧĥőūŧ ŧĥę ővęřĥęäđ őƒ mäįʼnŧäįʼnįʼnģ, ūpģřäđįʼnģ, äʼnđ şūppőřŧįʼnģ äʼn įʼnşŧäľľäŧįőʼn.", + "link-title": "Ŀęäřʼn äþőūŧ čľőūđ ƒęäŧūřęş", + "title": "Ŵĥäŧ įş Ğřäƒäʼnä Cľőūđ?" + }, + "why-host": { + "body": "Ĩʼn äđđįŧįőʼn ŧő ŧĥę čőʼnvęʼnįęʼnčę őƒ mäʼnäģęđ ĥőşŧįʼnģ, Ğřäƒäʼnä Cľőūđ įʼnčľūđęş mäʼny čľőūđ-ęχčľūşįvę ƒęäŧūřęş ľįĸę ŜĿØş, įʼnčįđęʼnŧ mäʼnäģęmęʼnŧ, mäčĥįʼnę ľęäřʼnįʼnģ, äʼnđ pőŵęřƒūľ őþşęřväþįľįŧy įʼnŧęģřäŧįőʼnş.", + "link-title": "Mőřę qūęşŧįőʼnş? Ŧäľĸ ŧő äʼn ęχpęřŧ", + "title": "Ŵĥy ĥőşŧ ŵįŧĥ Ğřäƒäʼnä?" + } + }, "nav": { "add-new-connections": { "title": "Åđđ ʼnęŵ čőʼnʼnęčŧįőʼn"