Alerting: Improve heading accessibility (#85723)

* Change from h5 to Text component

* Fix goworksum error

* Add headings for contact points and notification policies

* Alert group h2

* Reset labels and move h2 to group by

---------

Co-authored-by: Gilles De Mey <gilles.de.mey@gmail.com>
This commit is contained in:
Tobias Skarhed
2024-04-12 16:19:47 +02:00
committed by GitHub
parent c8d185502b
commit f1f02207f2
8 changed files with 33 additions and 26 deletions

View File

@@ -1488,9 +1488,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"] [0, 0, 0, "Unexpected any. Specify a different type.", "1"]
], ],
"public/app/features/alerting/unified/AlertGroups.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"]
],
"public/app/features/alerting/unified/AlertWarning.tsx:5381": [ "public/app/features/alerting/unified/AlertWarning.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"] [0, 0, 0, "Styles should be written using objects.", "0"]
], ],

View File

@@ -1,8 +1,6 @@
import { css } from '@emotion/css';
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { Alert, LoadingPlaceholder, Text, Box } from '@grafana/ui';
import { Alert, LoadingPlaceholder, useStyles2 } from '@grafana/ui';
import { useQueryParams } from 'app/core/hooks/useQueryParams'; import { useQueryParams } from 'app/core/hooks/useQueryParams';
import { useDispatch } from 'app/types'; import { useDispatch } from 'app/types';
@@ -29,7 +27,6 @@ const AlertGroups = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const [queryParams] = useQueryParams(); const [queryParams] = useQueryParams();
const { groupBy = [] } = getFiltersFromUrlParams(queryParams); const { groupBy = [] } = getFiltersFromUrlParams(queryParams);
const styles = useStyles2(getStyles);
const { currentData: amConfigStatus } = useGetAlertmanagerChoiceStatusQuery(); const { currentData: amConfigStatus } = useGetAlertmanagerChoiceStatusQuery();
@@ -79,7 +76,11 @@ const AlertGroups = () => {
<React.Fragment key={`${JSON.stringify(group.labels)}-group-${index}`}> <React.Fragment key={`${JSON.stringify(group.labels)}-group-${index}`}>
{((index === 1 && Object.keys(filteredAlertGroups[0].labels).length === 0) || {((index === 1 && Object.keys(filteredAlertGroups[0].labels).length === 0) ||
(index === 0 && Object.keys(group.labels).length > 0)) && ( (index === 0 && Object.keys(group.labels).length > 0)) && (
<p className={styles.groupingBanner}>Grouped by: {Object.keys(group.labels).join(', ')}</p> <Box paddingY={2}>
<Text element="h2" variant="body">
Grouped by: {Object.keys(group.labels).join(', ')}
</Text>
</Box>
)} )}
<AlertGroup alertManagerSourceName={selectedAlertmanager || ''} group={group} /> <AlertGroup alertManagerSourceName={selectedAlertmanager || ''} group={group} />
</React.Fragment> </React.Fragment>
@@ -96,10 +97,4 @@ const AlertGroupsPage = () => (
</AlertmanagerPageWrapper> </AlertmanagerPageWrapper>
); );
const getStyles = (theme: GrafanaTheme2) => ({
groupingBanner: css`
margin: ${theme.spacing(2, 0)};
`,
});
export default AlertGroupsPage; export default AlertGroupsPage;

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Icon } from '@grafana/ui'; import { Icon, Text } from '@grafana/ui';
interface Props { interface Props {
namespace: string; namespace: string;
@@ -9,13 +9,17 @@ interface Props {
const RuleLocation = ({ namespace, group }: Props) => { const RuleLocation = ({ namespace, group }: Props) => {
if (!group) { if (!group) {
return <>{namespace}</>; return (
<Text element="h3" variant="body">
{namespace}
</Text>
);
} }
return ( return (
<> <Text element="h3" variant="body">
{namespace} <Icon name="angle-right" /> {group} {namespace} <Icon name="angle-right" aria-label=">" /> {group}
</> </Text>
); );
}; };

View File

@@ -36,6 +36,7 @@ export const AlertGroup = ({ alertManagerSourceName, group }: Props) => {
{Object.keys(group.labels).length ? ( {Object.keys(group.labels).length ? (
<Stack direction="row" alignItems="center"> <Stack direction="row" alignItems="center">
<AlertLabels labels={group.labels} size="sm" /> <AlertLabels labels={group.labels} size="sm" />
{receiverInGroup && ( {receiverInGroup && (
<MetaText icon="at"> <MetaText icon="at">
Delivered to <Strong>{group.receiver.name}</Strong> Delivered to <Strong>{group.receiver.name}</Strong>

View File

@@ -430,7 +430,7 @@ const ContactPointHeader = (props: ContactPointHeaderProps) => {
<div className={styles.headerWrapper}> <div className={styles.headerWrapper}>
<Stack direction="row" alignItems="center" gap={1}> <Stack direction="row" alignItems="center" gap={1}>
<Stack alignItems="center" gap={1}> <Stack alignItems="center" gap={1}>
<Text variant="body" weight="medium"> <Text element="h2" variant="body" weight="medium">
{name} {name}
</Text> </Text>
</Stack> </Stack>

View File

@@ -641,7 +641,9 @@ function DefaultPolicyIndicator() {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
return ( return (
<> <>
<strong>Default policy</strong> <Text element="h2" variant="body" weight="medium">
Default policy
</Text>
<span className={styles.metadata}> <span className={styles.metadata}>
All alert instances will be handled by the default policy if no other matching policies are found. All alert instances will be handled by the default policy if no other matching policies are found.
</span> </span>
@@ -650,7 +652,11 @@ function DefaultPolicyIndicator() {
} }
function AutogeneratedRootIndicator() { function AutogeneratedRootIndicator() {
return <strong> Auto-generated policies</strong>; return (
<Text element="h3" variant="body" weight="medium">
Auto-generated policies
</Text>
);
} }
const InheritedProperties: FC<{ properties: InheritableProperties }> = ({ properties }) => ( const InheritedProperties: FC<{ properties: InheritableProperties }> = ({ properties }) => (

View File

@@ -4,7 +4,7 @@ import React, { useMemo } from 'react';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { GrafanaTheme2, urlUtil } from '@grafana/data'; import { GrafanaTheme2, urlUtil } from '@grafana/data';
import { LinkButton, LoadingPlaceholder, Pagination, Spinner, useStyles2 } from '@grafana/ui'; import { LinkButton, LoadingPlaceholder, Pagination, Spinner, useStyles2, Text } from '@grafana/ui';
import { CombinedRuleNamespace } from 'app/types/unified-alerting'; import { CombinedRuleNamespace } from 'app/types/unified-alerting';
import { DEFAULT_PER_PAGE_PAGINATION } from '../../../../../core/constants'; import { DEFAULT_PER_PAGE_PAGINATION } from '../../../../../core/constants';
@@ -55,7 +55,9 @@ export const CloudRules = ({ namespaces, expandAll }: Props) => {
<section className={styles.wrapper}> <section className={styles.wrapper}>
<div className={styles.sectionHeader}> <div className={styles.sectionHeader}>
<div className={styles.headerRow}> <div className={styles.headerRow}>
<h5>Mimir / Cortex / Loki</h5> <Text element="h2" variant="h5">
Mimir / Cortex / Loki
</Text>
{dataSourcesLoading.length ? ( {dataSourcesLoading.length ? (
<LoadingPlaceholder <LoadingPlaceholder
className={styles.loader} className={styles.loader}

View File

@@ -3,7 +3,7 @@ import React from 'react';
import { useToggle } from 'react-use'; import { useToggle } from 'react-use';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { Button, LoadingPlaceholder, Pagination, Spinner, useStyles2 } from '@grafana/ui'; import { Button, LoadingPlaceholder, Pagination, Spinner, useStyles2, Text } from '@grafana/ui';
import { useQueryParams } from 'app/core/hooks/useQueryParams'; import { useQueryParams } from 'app/core/hooks/useQueryParams';
import { CombinedRuleNamespace } from 'app/types/unified-alerting'; import { CombinedRuleNamespace } from 'app/types/unified-alerting';
@@ -58,7 +58,9 @@ export const GrafanaRules = ({ namespaces, expandAll }: Props) => {
<section className={styles.wrapper}> <section className={styles.wrapper}>
<div className={styles.sectionHeader}> <div className={styles.sectionHeader}>
<div className={styles.headerRow}> <div className={styles.headerRow}>
<h5>Grafana</h5> <Text element="h2" variant="h5">
Grafana
</Text>
{loading ? <LoadingPlaceholder className={styles.loader} text="Loading..." /> : <div />} {loading ? <LoadingPlaceholder className={styles.loader} text="Loading..." /> : <div />}
{hasGrafanaAlerts && canExportRules && ( {hasGrafanaAlerts && canExportRules && (
<Button <Button