import { css, cx } from '@emotion/css';
import React from 'react';
import SVG from 'react-inlinesvg';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { config } from '@grafana/runtime';
import { Icon, useStyles2, useTheme2 } from '@grafana/ui';
import { AlertingPageWrapper } from './components/AlertingPageWrapper';
export default function Home() {
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 policy
Get started
-
Create an alert rule by adding queries and expressions from multiple data sources.
-
Add labels to your alert rules{' '}
to connect them to notification policies
-
Configure contact points to define where to send your notifications to.
-
Configure notification policies to route your alert instances to contact points.
);
}
const getWelcomePageStyles = (theme: GrafanaTheme2) => ({
grid: css`
display: grid;
grid-template-rows: min-content auto auto;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
gap: ${theme.spacing(2)};
`,
ctaContainer: css`
grid-column: 1 / span 5;
`,
flowBlock: css`
grid-column: 1 / span 5;
display: flex;
flex-wrap: wrap;
gap: ${theme.spacing(1)};
& > div {
flex: 2;
min-width: 350px;
}
& > svg {
flex: 3;
min-width: 500px;
}
`,
videoBlock: css`
grid-column: 3 / span 3;
grid-row: 3 / span 1;
// Video required
position: relative;
padding: 56.25% 0 0 0; /* 16:9 */
iframe {
position: absolute;
top: ${theme.spacing(2)};
left: ${theme.spacing(2)};
width: calc(100% - ${theme.spacing(4)});
height: calc(100% - ${theme.spacing(4)});
border: none;
}
`,
gettingStartedBlock: css`
grid-column: 1 / span 2;
justify-content: space-between;
`,
list: css`
margin: ${theme.spacing(0, 2)};
& > li {
margin-bottom: ${theme.spacing(1)};
}
`,
});
function WelcomeHeader({ className }: { className?: string }) {
const styles = useStyles2(getWelcomeHeaderStyles);
return (
);
}
const getWelcomeHeaderStyles = (theme: GrafanaTheme2) => ({
ctaContainer: css`
padding: ${theme.spacing(4, 2)};
display: flex;
gap: ${theme.spacing(4)};
justify-content: space-between;
flex-wrap: wrap;
${theme.breakpoints.down('lg')} {
flex-direction: column;
}
`,
separator: css`
width: 1px;
background-color: ${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 (
);
}
const getWelcomeCTAButtonStyles = (theme: GrafanaTheme2) => ({
container: css`
flex: 1;
min-width: 240px;
display: grid;
gap: ${theme.spacing(1)};
grid-template-columns: min-content 1fr 1fr 1fr;
grid-template-rows: min-content auto min-content;
`,
title: css`
margin-bottom: 0;
grid-column: 2 / span 3;
grid-row: 1;
`,
desc: css`
grid-column: 2 / span 3;
grid-row: 2;
`,
actionRow: css`
grid-column: 2 / span 3;
grid-row: 3;
max-width: 240px;
`,
link: css`
color: ${theme.colors.text.link};
`,
});
function ContentBox({ children, className }: React.PropsWithChildren<{ className?: string }>) {
const styles = useStyles2(getContentBoxStyles);
return {children}
;
}
const getContentBoxStyles = (theme: GrafanaTheme2) => ({
box: css`
padding: ${theme.spacing(2)};
background-color: ${theme.colors.background.secondary};
border-radius: 3px;
outline: 1px solid ${theme.colors.border.strong};
`,
});
function ArrowLink({ href, title }: { href: string; title: string }) {
const styles = useStyles2(getArrowLinkStyles);
return (
{title}
);
}
const getArrowLinkStyles = (theme: GrafanaTheme2) => ({
link: css`
display: block;
color: ${theme.colors.text.link};
`,
});