From a3c73ae7c46b06705726c63a885974c594fc9ea7 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Fri, 23 Feb 2024 11:18:09 +0000 Subject: [PATCH] E2C: Add initial empty state (#83232) * update subtitle * add empty state * rename to InfoPaneLeft/Right * use ' * add "direction" prop to Box * update subtitle * Revert "add "direction" prop to Box" This reverts commit 99f82a27c732541fe9ca0f1dc87e6db0f6eb72fc. --- pkg/services/navtree/navtreeimpl/admin.go | 2 +- .../app/core/utils/navBarItem-translations.ts | 2 +- .../EmptyState/CallToAction.tsx | 23 +++++++++ .../EmptyState/EmptyState.tsx | 37 +++++++++++++++ .../migrate-to-cloud/EmptyState/InfoItem.tsx | 26 ++++++++++ .../EmptyState/InfoPaneLeft.tsx | 47 +++++++++++++++++++ .../EmptyState/InfoPaneRight.tsx | 45 ++++++++++++++++++ .../admin/migrate-to-cloud/MigrateToCloud.tsx | 10 +--- public/locales/en-US/grafana.json | 38 ++++++++++++++- public/locales/pseudo-LOCALE/grafana.json | 38 ++++++++++++++- 10 files changed, 256 insertions(+), 12 deletions(-) create mode 100644 public/app/features/admin/migrate-to-cloud/EmptyState/CallToAction.tsx create mode 100644 public/app/features/admin/migrate-to-cloud/EmptyState/EmptyState.tsx create mode 100644 public/app/features/admin/migrate-to-cloud/EmptyState/InfoItem.tsx create mode 100644 public/app/features/admin/migrate-to-cloud/EmptyState/InfoPaneLeft.tsx create mode 100644 public/app/features/admin/migrate-to-cloud/EmptyState/InfoPaneRight.tsx 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": {