import { css, cx } from '@emotion/css';
import * as React from 'react';
import SVG from 'react-inlinesvg';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack, Text, TextLink, useStyles2, useTheme2 } from '@grafana/ui';
export default function GettingStarted() {
const theme = useTheme2();
const styles = useStyles2(getWelcomePageStyles);
return (
How it works
-
Grafana alerting periodically queries data sources and evaluates the condition defined in the alert rule
- If the condition is breached, an alert instance fires
- Firing instances are routed to notification policies based on matching labels
- Notifications are sent out to the contact points specified in the notification policy
Get started
-
Create an alert rule to query a data source and evaluate the condition defined
in the alert rule
-
Route alert notifications either directly to a contact point or through
notification policies for more flexibility
-
Monitor your alert rules using dashboards and visualizations
For a hands-on introduction, refer to our{' '}
tutorial to get started with Grafana Alerting
);
}
const getWelcomePageStyles = (theme: GrafanaTheme2) => ({
grid: css({
display: 'grid',
gridTemplateRows: 'min-content auto auto',
gridTemplateColumns: '1fr',
gap: theme.spacing(2),
width: '100%',
[theme.breakpoints.up('lg')]: {
gridTemplateColumns: '3fr 2fr',
},
}),
ctaContainer: css({
gridColumn: '1 / span 5',
}),
svgContainer: css({
'& svg': {
maxWidth: '900px',
flex: 1,
},
}),
list: css({
margin: theme.spacing(0, 2),
'& > li': {
marginBottom: theme.spacing(1),
},
}),
});
export function WelcomeHeader({ className }: { className?: string }) {
const styles = useStyles2(getWelcomeHeaderStyles);
return (
);
}
const getWelcomeHeaderStyles = (theme: GrafanaTheme2) => ({
ctaContainer: css({
padding: theme.spacing(2),
display: 'flex',
gap: theme.spacing(4),
justifyContent: 'space-between',
flexWrap: 'wrap',
[theme.breakpoints.down('lg')]: {
flexDirection: 'column',
},
}),
separator: css({
width: '1px',
backgroundColor: theme.colors.border.medium,
[theme.breakpoints.down('lg')]: {
display: 'none',
},
}),
});
interface WelcomeCTABoxProps {
title: string;
description: string;
href: string;
hrefText: string;
}
function WelcomeCTABox({ title, description, href, hrefText }: WelcomeCTABoxProps) {
const styles = useStyles2(getWelcomeCTAButtonStyles);
return (
{title}
{description}
{hrefText}
);
}
const getWelcomeCTAButtonStyles = (theme: GrafanaTheme2) => ({
container: css({
color: theme.colors.text.primary,
flex: 1,
minWidth: '240px',
display: 'grid',
rowGap: theme.spacing(1),
gridTemplateColumns: 'min-content 1fr 1fr 1fr',
gridTemplateRows: 'min-content auto min-content',
'& h2': {
marginBottom: 0,
gridColumn: '2 / span 3',
gridRow: 1,
},
}),
desc: css({
gridColumn: '2 / span 3',
gridRow: 2,
}),
actionRow: css({
gridColumn: '2 / span 3',
gridRow: 3,
maxWidth: '240px',
}),
});
function ContentBox({ children, className }: React.PropsWithChildren<{ className?: string }>) {
const styles = useStyles2(getContentBoxStyles);
return {children}
;
}
const getContentBoxStyles = (theme: GrafanaTheme2) => ({
box: css({
padding: theme.spacing(2),
backgroundColor: theme.colors.background.secondary,
borderRadius: theme.shape.radius.default,
}),
});