diff --git a/packages/grafana-data/src/types/theme.ts b/packages/grafana-data/src/types/theme.ts index a80cbadce48..248c7dfc343 100644 --- a/packages/grafana-data/src/types/theme.ts +++ b/packages/grafana-data/src/types/theme.ts @@ -12,6 +12,7 @@ export interface GrafanaThemeCommons { md: string; lg: string; xl: string; + xxl: string; }; typography: { fontFamily: { diff --git a/packages/grafana-ui/src/themes/default.ts b/packages/grafana-ui/src/themes/default.ts index e07d5944e33..a43b862ad5f 100644 --- a/packages/grafana-ui/src/themes/default.ts +++ b/packages/grafana-ui/src/themes/default.ts @@ -72,6 +72,7 @@ const theme: GrafanaThemeCommons = { md: '769px', // 1 more than regular ipad in portrait lg: '992px', xl: '1200px', + xxl: '1440px', }, spacing: { insetSquishMd: '4px 8px', diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index e9201c50e0d..f1b315efc3f 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -366,7 +366,7 @@ func addGettingStartedPanelToHomeDashboard(dash *simplejson.Json) { "x": 0, "y": 3, "w": 24, - "h": 4, + "h": 9, }, }) diff --git a/public/app/plugins/panel/gettingstarted/GettingStarted.tsx b/public/app/plugins/panel/gettingstarted/GettingStarted.tsx index 9097b70b462..1dee246cdd6 100644 --- a/public/app/plugins/panel/gettingstarted/GettingStarted.tsx +++ b/public/app/plugins/panel/gettingstarted/GettingStarted.tsx @@ -1,125 +1,69 @@ // Libraries import React, { PureComponent } from 'react'; - import { PanelProps } from '@grafana/data'; -import { Icon, IconName } from '@grafana/ui'; -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { backendSrv } from 'app/core/services/backend_srv'; +import { Button, Spinner, stylesFactory } from '@grafana/ui'; +import { config } from '@grafana/runtime'; +import { css, cx } from 'emotion'; import { contextSrv } from 'app/core/core'; +import { backendSrv } from 'app/core/services/backend_srv'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; - -interface Step { - title: string; - cta?: string; - icon: IconName; - href: string; - target?: string; - note?: string; - check: () => Promise; - done?: boolean; -} +import { Step } from './components/Step'; +import imageDark from './img/Onboarding_Panel_dark.svg'; +import imageLight from './img/Onboarding_Panel_light.svg'; +import { getSteps } from './steps'; +import { Card, SetupStep } from './types'; interface State { checksDone: boolean; + currentStep: number; + steps: SetupStep[]; } export class GettingStarted extends PureComponent { - stepIndex = 0; - readonly steps: Step[]; - - constructor(props: PanelProps) { - super(props); - - this.state = { - checksDone: false, - }; - - this.steps = [ - { - title: 'Install Grafana', - icon: 'check', - href: 'http://docs.grafana.org/', - target: '_blank', - note: 'Review the installation docs', - check: () => Promise.resolve(true), - }, - { - title: 'Create a data source', - cta: 'Add data source', - icon: 'database', - href: 'datasources/new?gettingstarted', - check: () => { - return new Promise(resolve => { - resolve( - getDatasourceSrv() - .getMetricSources() - .filter(item => { - return item.meta.builtIn !== true; - }).length > 0 - ); - }); - }, - }, - { - title: 'Build a dashboard', - cta: 'New dashboard', - icon: 'apps', - href: 'dashboard/new?gettingstarted', - check: () => { - return backendSrv.search({ limit: 1 }).then(result => { - return result.length > 0; - }); - }, - }, - { - title: 'Invite your team', - cta: 'Add Users', - icon: 'users-alt', - href: 'org/users?gettingstarted', - check: () => { - return backendSrv.get('/api/org/users/lookup').then((res: any) => { - /* return res.length > 1; */ - return false; - }); - }, - }, - { - title: 'Install apps & plugins', - cta: 'Explore plugin repository', - icon: 'plug', - href: 'https://grafana.com/plugins?utm_source=grafana_getting_started', - check: () => { - return backendSrv.get('/api/plugins', { embedded: 0, core: 0 }).then((plugins: any[]) => { - return plugins.length > 0; - }); - }, - }, - ]; - } + state = { + checksDone: false, + currentStep: 0, + steps: getSteps(), + }; + + async componentDidMount() { + const { steps } = this.state; - componentDidMount() { - this.stepIndex = -1; - return this.nextStep().then((res: any) => { - this.setState({ checksDone: true }); + const checkedStepsPromises: Array> = steps.map(async (step: SetupStep) => { + const checkedCardsPromises: Array> = step.cards.map((card: Card) => { + return card.check().then(passed => { + return { ...card, done: passed }; + }); + }); + const checkedCards = await Promise.all(checkedCardsPromises); + return { + ...step, + done: checkedCards.every(c => c.done), + cards: checkedCards, + }; }); - } - nextStep(): any { - if (this.stepIndex === this.steps.length - 1) { - return Promise.resolve(); - } - - this.stepIndex += 1; - const currentStep = this.steps[this.stepIndex]; - return currentStep.check().then(passed => { - if (passed) { - currentStep.done = true; - return this.nextStep(); - } - return Promise.resolve(); + const checkedSteps = await Promise.all(checkedStepsPromises); + + this.setState({ + currentStep: !checkedSteps[0].done ? 0 : 1, + steps: checkedSteps, + checksDone: true, }); } + onForwardClick = () => { + this.setState(prevState => ({ + currentStep: prevState.currentStep + 1, + })); + }; + + onPreviousClick = () => { + this.setState(prevState => ({ + currentStep: prevState.currentStep - 1, + })); + }; + dismiss = () => { const { id } = this.props; const dashboard = getDashboardSrv().getCurrent(); @@ -137,34 +81,130 @@ export class GettingStarted extends PureComponent { }; render() { - const { checksDone } = this.state; - if (!checksDone) { - return
checking...
; - } + const { checksDone, currentStep, steps } = this.state; + const styles = getStyles(); + const step = steps[currentStep]; return ( -
- -
- {this.steps.map((step, index) => { - return ( -
- - - - - {step.title} - - - {step.cta} - +
+ {!checksDone ? ( +
+
Checking completed setup steps
+ +
+ ) : ( + <> +
+
Remove this panel
+
+ {currentStep === steps.length - 1 && ( +
+
- ); - })} -
+ )} +
+ +
+ {currentStep < steps.length - 1 && ( +
+
+ )} + + )}
); } } + +const getStyles = stylesFactory(() => { + const { theme } = config; + const backgroundImage = theme.isDark ? imageDark : imageLight; + return { + container: css` + display: flex; + flex-direction: column; + height: 100%; + background: url(${backgroundImage}) no-repeat; + background-size: cover; + padding: ${theme.spacing.xl} ${theme.spacing.md} 0; + `, + content: css` + label: content; + display: flex; + justify-content: center; + + @media only screen and (max-width: ${theme.breakpoints.xxl}) { + margin-left: ${theme.spacing.lg}; + justify-content: flex-start; + } + `, + header: css` + label: header; + margin-bottom: ${theme.spacing.lg}; + display: flex; + flex-direction: column; + + @media only screen and (min-width: ${theme.breakpoints.lg}) { + flex-direction: row; + } + `, + headerLogo: css` + height: 58px; + padding-right: ${theme.spacing.md}; + display: none; + + @media only screen and (min-width: ${theme.breakpoints.md}) { + display: block; + } + `, + heading: css` + label: heading; + margin-right: ${theme.spacing.lg}; + margin-bottom: ${theme.spacing.lg}; + flex-grow: 1; + display: flex; + + @media only screen and (min-width: ${theme.breakpoints.md}) { + margin-bottom: 0; + } + `, + backForwardButtons: css` + position: absolute; + bottom: 50%; + top: 50%; + height: 50px; + `, + previous: css` + left: 10px; + + @media only screen and (max-width: ${theme.breakpoints.md}) { + left: 0; + } + `, + forward: css` + right: 10px; + + @media only screen and (max-width: ${theme.breakpoints.md}) { + right: 0; + } + `, + dismiss: css` + display: flex; + justify-content: flex-end; + cursor: pointer; + text-decoration: underline; + margin-right: ${theme.spacing.md}; + margin-bottom: ${theme.spacing.sm}; + `, + loading: css` + display: flex; + justify-content: center; + align-items: center; + height: 100%; + `, + loadingText: css` + margin-right: ${theme.spacing.sm}; + `, + }; +}); diff --git a/public/app/plugins/panel/gettingstarted/components/DocsCard.tsx b/public/app/plugins/panel/gettingstarted/components/DocsCard.tsx new file mode 100644 index 00000000000..4fa48f5b9c2 --- /dev/null +++ b/public/app/plugins/panel/gettingstarted/components/DocsCard.tsx @@ -0,0 +1,61 @@ +import React, { FC } from 'react'; +import { Card } from '../types'; +import { Icon, stylesFactory, useTheme } from '@grafana/ui'; +import { GrafanaTheme } from '@grafana/data'; +import { css } from 'emotion'; +import { cardContent, cardStyle, iconStyle } from './sharedStyles'; + +interface Props { + card: Card; +} + +export const DocsCard: FC = ({ card }) => { + const theme = useTheme(); + const styles = getStyles(theme, card.done); + + return ( + + ); +}; + +const getStyles = stylesFactory((theme: GrafanaTheme, complete: boolean) => { + return { + card: css` + ${cardStyle(theme, complete)} + + min-width: 230px; + + @media only screen and (max-width: ${theme.breakpoints.md}) { + min-width: 192px; + } + `, + heading: css` + text-transform: uppercase; + color: ${complete ? theme.palette.blue95 : '#FFB357'}; + margin-bottom: ${theme.spacing.md}; + `, + title: css` + margin-bottom: 48px; + `, + url: css` + border-top: 1px solid ${theme.colors.border1}; + position: absolute; + bottom: 0; + padding: 8px 16px; + width: 100%; + `, + }; +}); diff --git a/public/app/plugins/panel/gettingstarted/components/Step.tsx b/public/app/plugins/panel/gettingstarted/components/Step.tsx new file mode 100644 index 00000000000..f95af02dd0a --- /dev/null +++ b/public/app/plugins/panel/gettingstarted/components/Step.tsx @@ -0,0 +1,68 @@ +import React, { FC } from 'react'; +import { css } from 'emotion'; +import { GrafanaTheme } from '@grafana/data'; +import { stylesFactory, useTheme } from '@grafana/ui'; +import { TutorialCard } from './TutorialCard'; +import { Card, SetupStep } from '../types'; +import { DocsCard } from './DocsCard'; + +interface Props { + step: SetupStep; +} + +export const Step: FC = ({ step }) => { + const theme = useTheme(); + const styles = getStyles(theme); + + return ( +
+
+

{step.title}

+

{step.info}

+
+
+ {step.cards.map((card: Card, index: number) => { + const key = `${card.title}-${index}`; + if (card.type === 'tutorial') { + return ; + } + return ; + })} +
+
+ ); +}; + +const getStyles = stylesFactory((theme: GrafanaTheme) => { + return { + setup: css` + display: flex; + width: 95%; + `, + info: css` + width: 172px; + margin-right: 5%; + + @media only screen and (max-width: ${theme.breakpoints.xxl}) { + margin-right: ${theme.spacing.xl}; + } + @media only screen and (max-width: ${theme.breakpoints.sm}) { + display: none; + } + `, + title: css` + color: ${theme.palette.blue95}; + `, + cards: css` + overflow-x: scroll; + overflow-y: hidden; + width: 100%; + display: flex; + justify-content: center; + + @media only screen and (max-width: ${theme.breakpoints.xxl}) { + justify-content: flex-start; + } + `, + }; +}); diff --git a/public/app/plugins/panel/gettingstarted/components/TutorialCard.tsx b/public/app/plugins/panel/gettingstarted/components/TutorialCard.tsx new file mode 100644 index 00000000000..ffb838d9d76 --- /dev/null +++ b/public/app/plugins/panel/gettingstarted/components/TutorialCard.tsx @@ -0,0 +1,72 @@ +import React, { FC, MouseEvent } from 'react'; +import { GrafanaTheme } from '@grafana/data'; +import { Icon, stylesFactory, useTheme } from '@grafana/ui'; +import { css } from 'emotion'; +import store from 'app/core/store'; +import { cardContent, cardStyle, iconStyle } from './sharedStyles'; +import { Card } from '../types'; + +interface Props { + card: Card; +} + +export const TutorialCard: FC = ({ card }) => { + const theme = useTheme(); + const styles = getStyles(theme, card.done); + + return ( + ) => handleTutorialClick(event, card)}> +
+
{card.type}
+
{card.done ? 'complete' : card.heading}
+

{card.title}

+
{card.info}
+ +
+
+ ); +}; + +const handleTutorialClick = (event: MouseEvent, card: Card) => { + event.preventDefault(); + const isSet = store.get(card.key); + if (!isSet) { + store.set(card.key, true); + } + window.open(`${card.href}?utm_source=grafana_gettingstarted`, '_blank'); +}; + +const getStyles = stylesFactory((theme: GrafanaTheme, complete: boolean) => { + const textColor = `${complete ? theme.palette.blue95 : '#FFB357'}`; + return { + card: css` + ${cardStyle(theme, complete)} + width: 460px; + min-width: 460px; + + @media only screen and (max-width: ${theme.breakpoints.xl}) { + min-width: 368px; + } + + @media only screen and (max-width: ${theme.breakpoints.lg}) { + min-width: 272px; + } + `, + type: css` + color: ${textColor}; + text-transform: uppercase; + `, + heading: css` + text-transform: uppercase; + color: ${textColor}; + margin-bottom: ${theme.spacing.sm}; + `, + info: css` + margin-bottom: ${theme.spacing.md}; + `, + status: css` + display: flex; + justify-content: flex-end; + `, + }; +}); diff --git a/public/app/plugins/panel/gettingstarted/components/sharedStyles.ts b/public/app/plugins/panel/gettingstarted/components/sharedStyles.ts new file mode 100644 index 00000000000..0781f5d5938 --- /dev/null +++ b/public/app/plugins/panel/gettingstarted/components/sharedStyles.ts @@ -0,0 +1,49 @@ +import { GrafanaTheme } from '@grafana/data'; +import { css } from 'emotion'; +import { stylesFactory } from '@grafana/ui'; + +export const cardStyle = stylesFactory((theme: GrafanaTheme, complete: boolean) => { + const completeGradient = 'linear-gradient(to right, #5182CC 0%, #245BAF 100%)'; + const darkThemeGradients = complete ? completeGradient : 'linear-gradient(to right, #f05a28 0%, #fbca0a 100%)'; + const lightThemeGradients = complete ? completeGradient : 'linear-gradient(to right, #FBCA0A 0%, #F05A28 100%)'; + + const borderGradient = theme.isDark ? darkThemeGradients : lightThemeGradients; + + return ` + background-color: ${theme.colors.bg1}; + margin-right: ${theme.spacing.xl}; + border: 1px solid ${theme.colors.border1}; + border-bottom-left-radius: ${theme.border.radius.md}; + border-bottom-right-radius: ${theme.border.radius.md}; + position: relative; + max-height: 230px; + + @media only screen and (max-width: ${theme.breakpoints.xxl}) { + margin-right: ${theme.spacing.md}; + } + &::before { + display: block; + content: ' '; + position: absolute; + left: 0; + right: 0; + height: 2px; + top: 0; + background-image: ${borderGradient}; + } +`; +}); + +export const iconStyle = stylesFactory( + (theme: GrafanaTheme, complete: boolean) => css` + color: ${complete ? theme.palette.blue95 : theme.colors.textWeak}; + + @media only screen and (max-width: ${theme.breakpoints.sm}) { + display: none; + } + ` +); + +export const cardContent = css` + padding: 24px 16px; +`; diff --git a/public/app/plugins/panel/gettingstarted/img/Onboarding_Panel_dark.svg b/public/app/plugins/panel/gettingstarted/img/Onboarding_Panel_dark.svg new file mode 100644 index 00000000000..9b7072cb1d1 --- /dev/null +++ b/public/app/plugins/panel/gettingstarted/img/Onboarding_Panel_dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/app/plugins/panel/gettingstarted/img/Onboarding_Panel_light.svg b/public/app/plugins/panel/gettingstarted/img/Onboarding_Panel_light.svg new file mode 100644 index 00000000000..e2eb0cefc94 --- /dev/null +++ b/public/app/plugins/panel/gettingstarted/img/Onboarding_Panel_light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/app/plugins/panel/gettingstarted/module.ts b/public/app/plugins/panel/gettingstarted/module.ts index c41ea4ee67a..6ce86a581aa 100644 --- a/public/app/plugins/panel/gettingstarted/module.ts +++ b/public/app/plugins/panel/gettingstarted/module.ts @@ -2,4 +2,4 @@ import { PanelPlugin } from '@grafana/data'; import { GettingStarted } from './GettingStarted'; // Simplest possible panel plugin -export const plugin = new PanelPlugin(GettingStarted); +export const plugin = new PanelPlugin(GettingStarted).setNoPadding(); diff --git a/public/app/plugins/panel/gettingstarted/steps.ts b/public/app/plugins/panel/gettingstarted/steps.ts new file mode 100644 index 00000000000..d8bec321365 --- /dev/null +++ b/public/app/plugins/panel/gettingstarted/steps.ts @@ -0,0 +1,107 @@ +import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; +import { getBackendSrv } from 'app/core/services/backend_srv'; +import store from 'app/core/store'; +import { SetupStep } from './types'; + +const step1TutorialTitle = 'Grafana fundamentals'; +const step2TutorialTitle = 'Create users and teams'; +const keyPrefix = 'getting.started.'; +const step1Key = `${keyPrefix}${step1TutorialTitle + .replace(' ', '-') + .trim() + .toLowerCase()}`; +const step2Key = `${keyPrefix}${step2TutorialTitle + .replace(' ', '-') + .trim() + .toLowerCase()}`; + +export const getSteps = (): SetupStep[] => [ + { + heading: 'Welcome to Grafana', + subheading: 'The steps below will guide you to quickly finish setting up your Grafana installation.', + title: 'Basic', + info: 'The steps below will guide you to quickly finish setting up your Grafana installation.', + done: false, + cards: [ + { + type: 'tutorial', + heading: 'Data source and dashboards', + title: step1TutorialTitle, + info: + 'Set up and understand Grafana if you have no prior experience. This tutorial guides you through the entire process and covers the “Data source” and “Dashboards” steps to the right.', + href: 'https://grafana.com/tutorials/grafana-fundamentals', + icon: 'grafana', + check: () => Promise.resolve(store.get(step1Key)), + key: step1Key, + done: false, + }, + { + type: 'docs', + title: 'Add your first data source', + heading: 'data sources', + icon: 'database', + learnHref: 'https://grafana.com/docs/grafana/latest/features/datasources/add-a-data-source', + href: 'datasources/new', + check: () => { + return new Promise(resolve => { + resolve( + getDatasourceSrv() + .getMetricSources() + .filter(item => { + return item.meta.builtIn !== true; + }).length > 0 + ); + }); + }, + done: false, + }, + { + type: 'docs', + heading: 'dashboards', + title: 'Create your first dashboard', + icon: 'apps', + href: 'dashboard/new', + learnHref: 'https://grafana.com/docs/grafana/latest/guides/getting_started/#create-a-dashboard', + check: async () => { + const result = await getBackendSrv().search({ limit: 1 }); + return result.length > 0; + }, + done: false, + }, + ], + }, + { + heading: 'Setup complete!', + subheading: + 'All necessary steps to use Grafana are done. Now tackle advanced steps or make the best use of this home dashboard – it is, after all, a fully customizable dashboard – and remove this panel.', + title: 'Advanced', + info: ' Manage your users and teams and add plugins. These steps are optional', + done: false, + cards: [ + { + type: 'tutorial', + heading: 'Users', + title: 'Create users and teams', + info: 'Learn to organize your users in teams and manage resource access and roles.', + href: 'https://grafana.com/tutorials/create-users-and-teams', + icon: 'users-alt', + key: step2Key, + check: () => Promise.resolve(store.get(step2Key)), + done: false, + }, + { + type: 'docs', + heading: 'plugins', + title: 'Find and install plugins', + learnHref: 'https://grafana.com/docs/grafana/latest/plugins/installation', + href: 'plugins', + icon: 'plug', + check: async () => { + const plugins = await getBackendSrv().get('/api/plugins', { embedded: 0, core: 0 }); + return Promise.resolve(plugins.length > 0); + }, + done: false, + }, + ], + }, +]; diff --git a/public/app/plugins/panel/gettingstarted/types.ts b/public/app/plugins/panel/gettingstarted/types.ts new file mode 100644 index 00000000000..d45273f5f4d --- /dev/null +++ b/public/app/plugins/panel/gettingstarted/types.ts @@ -0,0 +1,26 @@ +import { IconName } from '@grafana/ui'; + +export type CardType = 'tutorial' | 'docs' | 'other'; + +export interface Card { + title: string; + type: CardType; + icon: IconName; + href: string; + check: () => Promise; + done: boolean; + heading: string; + info?: string; + // For local storage + key?: string; + learnHref?: string; +} + +export interface SetupStep { + heading: string; + subheading: string; + title: string; + info: string; + cards: Card[]; + done: boolean; +} diff --git a/public/app/plugins/panel/welcome/Welcome.tsx b/public/app/plugins/panel/welcome/Welcome.tsx index a64218bcf66..b182ee06def 100644 --- a/public/app/plugins/panel/welcome/Welcome.tsx +++ b/public/app/plugins/panel/welcome/Welcome.tsx @@ -1,13 +1,14 @@ import React, { FC } from 'react'; import { css } from 'emotion'; import { GrafanaTheme } from '@grafana/data'; -import { ButtonSelect, stylesFactory, useTheme } from '@grafana/ui'; +import { stylesFactory, useTheme } from '@grafana/ui'; +import lightBackground from './img/background_light.svg'; const helpOptions = [ - { value: 0, label: 'Documentation', href: 'https://grafana.com/docs/grafana/latest/' }, - { value: 1, label: 'Tutorials', href: 'https://grafana.com/tutorials/' }, - { value: 2, label: 'Community', href: 'https://community.grafana.com/' }, - { value: 3, label: 'Public Slack', href: '' }, + { value: 0, label: 'Documentation', href: 'https://grafana.com/docs/grafana/latest' }, + { value: 1, label: 'Tutorials', href: 'https://grafana.com/tutorials' }, + { value: 2, label: 'Community', href: 'https://community.grafana.com' }, + { value: 3, label: 'Public Slack', href: 'http://slack.grafana.com' }, ]; export const WelcomeBanner: FC = () => { @@ -18,19 +19,14 @@ export const WelcomeBanner: FC = () => {

Welcome to Grafana

Need help?

-
- -
{helpOptions.map((option, index) => { return ( - + {option.label} ); @@ -41,14 +37,8 @@ export const WelcomeBanner: FC = () => { ); }; -const onHelpLinkClick = (option: { label: string; href: string }) => { - window.open(option.href, '_blank'); -}; - const getStyles = stylesFactory((theme: GrafanaTheme) => { - const backgroundImage = theme.isDark - ? 'public/img/login_background_dark.svg' - : 'public/img/login_background_light.svg'; + const backgroundImage = theme.isDark ? 'public/img/login_background_dark.svg' : lightBackground; return { container: css` @@ -59,31 +49,28 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => { align-items: center; padding: 0 16px; justify-content: space-between; - - @media only screen and (max-width: ${theme.breakpoints.xl}) { - padding: 0 30px 0 100px; - } + padding: 0 ${theme.spacing.lg}; @media only screen and (max-width: ${theme.breakpoints.lg}) { - padding: 0 24px 0 44px; background-position: 0px; flex-direction: column; align-items: flex-start; justify-content: center; } + @media only screen and (max-width: ${theme.breakpoints.sm}) { - flex-direction: column; - justify-content: flex-start; - align-items: flex-start; - padding: ${theme.spacing.md} ${theme.spacing.md} ${theme.spacing.md} 48px; + padding: 0 ${theme.spacing.sm}; } `, title: css` margin-bottom: 0; + @media only screen and (max-width: ${theme.breakpoints.lg}) { + margin-bottom: ${theme.spacing.sm}; + } + @media only screen and (max-width: ${theme.breakpoints.md}) { font-size: ${theme.typography.heading.h2}; - margin-bottom: ${theme.spacing.sm}; } @media only screen and (max-width: ${theme.breakpoints.sm}) { font-size: ${theme.typography.heading.h3}; @@ -105,14 +92,18 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => { display: none; } `, - helpLinks: css``, + helpLinks: css` + display: flex; + flex-wrap: wrap; + `, helpLink: css` - margin-right: 8px; + margin-right: ${theme.spacing.md}; text-decoration: underline; text-wrap: no-wrap; - `, - smallScreenHelp: css` - display: none; + + @media only screen and (max-width: ${theme.breakpoints.sm}) { + margin-right: 8px; + } `, }; }); diff --git a/public/app/plugins/panel/welcome/img/background_light.svg b/public/app/plugins/panel/welcome/img/background_light.svg new file mode 100644 index 00000000000..0a997d7fdc5 --- /dev/null +++ b/public/app/plugins/panel/welcome/img/background_light.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/dashboards/home.json b/public/dashboards/home.json index 01aed960a00..187a393b662 100644 --- a/public/dashboards/home.json +++ b/public/dashboards/home.json @@ -11,7 +11,7 @@ }, "id": 1, "title": "", - "transparent": true, + "transparent": false, "type": "welcome" }, { diff --git a/public/img/onboarding_art_dark.svg b/public/img/onboarding_art_dark.svg deleted file mode 100644 index 9d3a430d702..00000000000 --- a/public/img/onboarding_art_dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/img/onboarding_art_light.svg b/public/img/onboarding_art_light.svg deleted file mode 100644 index ae9fdb7b01f..00000000000 --- a/public/img/onboarding_art_light.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file