diff --git a/pkg/services/navtree/navtreeimpl/admin.go b/pkg/services/navtree/navtreeimpl/admin.go
index ce30488a36b..db9871e728c 100644
--- a/pkg/services/navtree/navtreeimpl/admin.go
+++ b/pkg/services/navtree/navtreeimpl/admin.go
@@ -139,7 +139,7 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
migrateToCloud := &navtree.NavLink{
Text: "Migrate to Grafana Cloud",
Id: "migrate-to-cloud",
- SubTitle: "Copy data sources, dashboards, and alerts from this installation to a cloud stack",
+ SubTitle: "Copy configuration from your self-managed installation to a cloud stack",
Url: s.cfg.AppSubURL + "/admin/migrate-to-cloud",
}
configNodes = append(configNodes, migrateToCloud)
diff --git a/public/app/core/utils/navBarItem-translations.ts b/public/app/core/utils/navBarItem-translations.ts
index c1353ed8cbe..61969eb5d03 100644
--- a/public/app/core/utils/navBarItem-translations.ts
+++ b/public/app/core/utils/navBarItem-translations.ts
@@ -253,7 +253,7 @@ export function getNavSubTitle(navId: string | undefined) {
case 'migrate-to-cloud':
return t(
'nav.migrate-to-cloud.subtitle',
- 'Copy data sources, dashboards, and alerts from this installation to a cloud stack'
+ 'Copy configuration from your self-managed installation to a cloud stack'
);
case 'support-bundles':
return t('nav.support-bundles.subtitle', 'Download support bundles');
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..09c01b40099
--- /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 { InfoPaneLeft } from './InfoPaneLeft';
+import { InfoPaneRight } from './InfoPaneRight';
+
+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/InfoPaneLeft.tsx b/public/app/features/admin/migrate-to-cloud/EmptyState/InfoPaneLeft.tsx
new file mode 100644
index 00000000000..91eceb990e7
--- /dev/null
+++ b/public/app/features/admin/migrate-to-cloud/EmptyState/InfoPaneLeft.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 InfoPaneLeft = () => {
+ 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/InfoPaneRight.tsx b/public/app/features/admin/migrate-to-cloud/EmptyState/InfoPaneRight.tsx
new file mode 100644
index 00000000000..48cbb1acd87
--- /dev/null
+++ b/public/app/features/admin/migrate-to-cloud/EmptyState/InfoPaneRight.tsx
@@ -0,0 +1,45 @@
+import React from 'react';
+
+import { Box, Stack } from '@grafana/ui';
+import { t, Trans } from 'app/core/internationalization';
+
+import { InfoItem } from './InfoItem';
+
+export const InfoPaneRight = () => {
+ 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 f3d09ecc0ae..a30d26fd97e 100644
--- a/public/app/features/admin/migrate-to-cloud/MigrateToCloud.tsx
+++ b/public/app/features/admin/migrate-to-cloud/MigrateToCloud.tsx
@@ -1,19 +1,13 @@
import React from 'react';
-import { Stack, Text } from '@grafana/ui';
import { Page } from 'app/core/components/Page/Page';
-import { useGetStatusQuery } from './api';
+import { EmptyState } from './EmptyState/EmptyState';
export default function MigrateToCloud() {
- const { data } = useGetStatusQuery();
-
return (
-
- TODO
- {JSON.stringify(data)}
-
+
);
}
diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json
index 2edc000e590..1e66599fe41 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"
@@ -877,7 +913,7 @@
"subtitle": "Manage folder dashboards and permissions"
},
"migrate-to-cloud": {
- "subtitle": "Copy data sources, dashboards, and alerts from this installation to a cloud stack",
+ "subtitle": "Copy configuration from your self-managed installation to a cloud stack",
"title": "Migrate to Grafana Cloud"
},
"monitoring": {
diff --git a/public/locales/pseudo-LOCALE/grafana.json b/public/locales/pseudo-LOCALE/grafana.json
index 9d894e7f4da..6cd2c16ee40 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"
@@ -877,7 +913,7 @@
"subtitle": "Mäʼnäģę ƒőľđęř đäşĥþőäřđş äʼnđ pęřmįşşįőʼnş"
},
"migrate-to-cloud": {
- "subtitle": "Cőpy đäŧä şőūřčęş, đäşĥþőäřđş, äʼnđ äľęřŧş ƒřőm ŧĥįş įʼnşŧäľľäŧįőʼn ŧő ä čľőūđ şŧäčĸ",
+ "subtitle": "Cőpy čőʼnƒįģūřäŧįőʼn ƒřőm yőūř şęľƒ-mäʼnäģęđ įʼnşŧäľľäŧįőʼn ŧő ä čľőūđ şŧäčĸ",
"title": "Mįģřäŧę ŧő Ğřäƒäʼnä Cľőūđ"
},
"monitoring": {