Alerting: Landing page v2 (#61600)

This commit is contained in:
Konrad Lalik 2023-01-18 12:40:09 +01:00 committed by GitHub
parent ecafb4dd15
commit 9256ca371d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 519 additions and 309 deletions

View File

@ -1,10 +1,11 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import React from 'react'; import React from 'react';
import SVG from 'react-inlinesvg';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental'; import { Stack } from '@grafana/experimental';
import { config } from '@grafana/runtime'; import { config } from '@grafana/runtime';
import { Icon, LinkButton, useStyles2, useTheme2, Tooltip } from '@grafana/ui'; import { Icon, useStyles2, useTheme2 } from '@grafana/ui';
import { AlertingPageWrapper } from './components/AlertingPageWrapper'; import { AlertingPageWrapper } from './components/AlertingPageWrapper';
@ -17,37 +18,27 @@ export default function Home() {
<div className={styles.grid}> <div className={styles.grid}>
<WelcomeHeader className={styles.ctaContainer} /> <WelcomeHeader className={styles.ctaContainer} />
<ContentBox className={styles.flowBlock}> <ContentBox className={styles.flowBlock}>
<img src={`public/img/alerting/at_a_glance_${theme.name.toLowerCase()}.svg`} alt="Alerting flow chart" /> <div>
<ul className={styles.howItWorks}> <h3>How it works</h3>
<ul className={styles.list}>
<li> <li>
Grafana alerting <strong>periodically queries your data sources and evaluates</strong> the alerting Grafana alerting periodically queries data sources and evaluates the condition defined in the alert rule
condition you define
</li>
<li>
If the condition is breached, the alert rule fires and produces <strong>alert instances</strong>{' '}
<Tooltip content="If a query returns multiple time series an alert instance will be created for each of them">
<Icon name="info-circle" />
</Tooltip>
</li>
<li>
Firing instances are sent to <strong>the Alertmanager</strong>{' '}
<Tooltip content="Alertmanager receives alert instances, deduplicates and groups them and then sends a notification to a contact point according to the matching notification policy">
<Icon name="info-circle" />
</Tooltip>
</li>
<li>
Alertmanager routes firing alert instances to <strong>notification policies</strong> based on whether the
labels match
</li>
<li>
Notifications are sent out to <strong>the contact point</strong> defined in the matching notification
policy
</li> </li>
<li>If the condition is breached, an alert instance fires</li>
<li>Firing instances are routed to notification policies based on matching labels</li>
<li>Notifications are sent out to the contact points specified in the notification policy policy</li>
</ul> </ul>
</div>
<SVG
src={`public/img/alerting/at_a_glance_${theme.name.toLowerCase()}.svg`}
width={undefined}
height={undefined}
/>
</ContentBox> </ContentBox>
<ContentBox title="Get started" className={styles.gettingStartedBlock}> <ContentBox className={styles.gettingStartedBlock}>
<h3>Get started</h3>
<Stack direction="column" alignItems="space-between"> <Stack direction="column" alignItems="space-between">
<ul> <ul className={styles.list}>
<li> <li>
<strong>Create an alert rule</strong> by adding queries and expressions from multiple data sources. <strong>Create an alert rule</strong> by adding queries and expressions from multiple data sources.
</li> </li>
@ -66,7 +57,7 @@ export default function Home() {
<ArrowLink href="https://grafana.com/docs/grafana/latest/alerting/" title="Read more in the Docs" /> <ArrowLink href="https://grafana.com/docs/grafana/latest/alerting/" title="Read more in the Docs" />
<ArrowLink <ArrowLink
href="https://university.grafana.com//lms/index.php?r=coursepath/deeplink&id_path=42&hash=caa235c6321f80e03df017ae9ec6eed5c79da9ec" href="https://university.grafana.com//lms/index.php?r=coursepath/deeplink&id_path=42&hash=caa235c6321f80e03df017ae9ec6eed5c79da9ec"
title="Learn more in the Grafana University course" title="Enroll in the Grafana University Alerting course"
/> />
</div> </div>
</Stack> </Stack>
@ -102,14 +93,19 @@ const getWelcomePageStyles = (theme: GrafanaTheme2) => ({
grid-column: 1 / span 5; grid-column: 1 / span 5;
`, `,
flowBlock: css` flowBlock: css`
width: 100%;
grid-column: 1 / span 5; grid-column: 1 / span 5;
img { display: flex;
display: block; flex-wrap: wrap;
margin: 0 auto; gap: ${theme.spacing(1)};
height: auto;
width: 100%; & > div {
flex: 2;
min-width: 350px;
}
& > svg {
flex: 3;
min-width: 500px;
} }
`, `,
videoBlock: css` videoBlock: css`
@ -132,22 +128,11 @@ const getWelcomePageStyles = (theme: GrafanaTheme2) => ({
gettingStartedBlock: css` gettingStartedBlock: css`
grid-column: 1 / span 2; grid-column: 1 / span 2;
justify-content: space-between; justify-content: space-between;
ul {
margin-left: ${theme.spacing(2)};
}
`, `,
howItWorks: css` list: css`
display: flex; margin: ${theme.spacing(0, 2)};
justify-content: space-between; & > li {
flex-wrap: wrap; margin-bottom: ${theme.spacing(1)};
gap: ${theme.spacing(2)};
list-style: none inside none;
list-style-type: disclosure-closed;
> li {
flex: 1;
min-width: 150px;
} }
`, `,
}); });
@ -156,81 +141,73 @@ function WelcomeHeader({ className }: { className?: string }) {
const styles = useStyles2(getWelcomeHeaderStyles); const styles = useStyles2(getWelcomeHeaderStyles);
return ( return (
<div className={cx(styles.container, className)}> <ContentBox className={cx(styles.ctaContainer, className)}>
<header>
<h2>Welcome to Grafana Alerting</h2>
<div>Grafana Alerting helps you manage your alert rules.</div>
</header>
<div className={styles.ctaContainer}>
<WelcomeCTABox <WelcomeCTABox
title="Alert rules" title="Alert rules"
description="Manage your alert rules. Combine data from multiple data sources" description="Define the condition that must be me before an alert rule fires"
icon="list-ul" href="/alerting/list"
href="/alerting/new" hrefText="Manage alert rules"
hrefText="Create alert rules"
/> />
<div className={styles.separator} />
<WelcomeCTABox <WelcomeCTABox
title="Contact points" title="Contact points"
description="Configure who and how receives notifications" description="Configure who receives notifications and how they are sent"
icon="comment-alt-share"
href="/alerting/notifications" href="/alerting/notifications"
hrefText="Manage contact points" hrefText="Manage contact points"
/> />
<div className={styles.separator} />
<WelcomeCTABox <WelcomeCTABox
title="Notification policies" title="Notification policies"
description="Configure the flow of your alerts and route them to contact points" description="Configure how firing alert instances are routed to contact points"
icon="sitemap"
href="/alerting/routes" href="/alerting/routes"
hrefText="Manage notification policies" hrefText="Manage notification policies"
/> />
</div> </ContentBox>
</div>
); );
} }
const getWelcomeHeaderStyles = (theme: GrafanaTheme2) => ({ const getWelcomeHeaderStyles = (theme: GrafanaTheme2) => ({
container: css`
display: flex;
flex-direction: column;
padding: ${theme.spacing(4)};
background-image: url(public/img/alerting/welcome_cta_bg_${theme.name.toLowerCase()}.svg);
background-size: cover;
background-clip: padding-box;
outline: 1px solid hsla(6deg, 60%, 80%, 0.14);
outline-offset: -1px;
border-radius: 3px;
`,
ctaContainer: css` ctaContainer: css`
padding: ${theme.spacing(4)}; padding: ${theme.spacing(4, 2)};
display: flex; display: flex;
gap: ${theme.spacing(4)}; gap: ${theme.spacing(4)};
justify-content: space-between; justify-content: space-between;
flex-wrap: wrap; 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 { interface WelcomeCTABoxProps {
title: string; title: string;
description: string; description: string;
icon: React.ComponentProps<typeof Icon>['name'];
href: string; href: string;
hrefText: string; hrefText: string;
} }
function WelcomeCTABox({ title, description, icon, href, hrefText }: WelcomeCTABoxProps) { function WelcomeCTABox({ title, description, href, hrefText }: WelcomeCTABoxProps) {
const styles = useStyles2(getWelcomeCTAButtonStyles); const styles = useStyles2(getWelcomeCTAButtonStyles);
return ( return (
<div className={styles.container}> <div className={styles.container}>
<div className={styles.icon}>
<Icon name={icon} size="xxl" />
</div>
<h3 className={styles.title}>{title}</h3> <h3 className={styles.title}>{title}</h3>
<div className={styles.desc}>{description}</div> <div className={styles.desc}>{description}</div>
<LinkButton href={href} className={styles.actionButton}> <div className={styles.actionRow}>
<a href={href} className={styles.link}>
{hrefText} {hrefText}
</LinkButton> </a>
</div>
</div> </div>
); );
} }
@ -246,6 +223,7 @@ const getWelcomeCTAButtonStyles = (theme: GrafanaTheme2) => ({
`, `,
title: css` title: css`
margin-bottom: 0;
grid-column: 2 / span 3; grid-column: 2 / span 3;
grid-row: 1; grid-row: 1;
`, `,
@ -255,29 +233,21 @@ const getWelcomeCTAButtonStyles = (theme: GrafanaTheme2) => ({
grid-row: 2; grid-row: 2;
`, `,
actionButton: css` actionRow: css`
grid-column: 2 / span 3; grid-column: 2 / span 3;
grid-row: 3; grid-row: 3;
max-width: 240px; max-width: 240px;
`, `,
icon: css` link: css`
grid-column: 1; color: ${theme.colors.text.link};
grid-row: 1 / span 2;
margin: auto;
color: #ff8833;
`, `,
}); });
function ContentBox({ children, title, className }: React.PropsWithChildren<{ title?: string; className?: string }>) { function ContentBox({ children, className }: React.PropsWithChildren<{ className?: string }>) {
const styles = useStyles2(getContentBoxStyles); const styles = useStyles2(getContentBoxStyles);
return ( return <div className={cx(styles.box, className)}>{children}</div>;
<div className={cx(styles.box, className)}>
{title && <h3>{title}</h3>}
{children}
</div>
);
} }
const getContentBoxStyles = (theme: GrafanaTheme2) => ({ const getContentBoxStyles = (theme: GrafanaTheme2) => ({

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 118 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 138 KiB