fix: [Platform:Dashboards:DashboardEditMode] Observability embeddables get announced incorrectly (#217674)

Closes: #215689

**Description:**
When user clicks on add panel and then selects any of the observability
embeddable panels (SLO burn rate, SLO Overview, SLO Alerts, SLO Error
budget, Monitors overview, Monitors stats), Kibana announces them as
"you are in a modal dialog. Press escape or tap click outside the
dialog....This doesn't give non-sighted user context about the add panel
action they are trying to execute.

**Changes Made:**
1. Added `aria-labelledby={flyoutTitleId}` for mentioned places
This commit is contained in:
Alexey Antonov 2025-04-22 13:34:29 +03:00 committed by GitHub
parent 9e082dd1ff
commit ff25581c34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 44 additions and 11 deletions

View file

@ -17,6 +17,7 @@ import {
EuiSpacer,
EuiSwitch,
EuiTitle,
useGeneratedHtmlId,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { i18n } from '@kbn/i18n';
@ -44,16 +45,21 @@ export function SloConfiguration({ initialInput, onCreate, onCancel }: SloConfig
const hasGroupBy = selectedSlos?.some((slo) => slo.instanceId !== ALL_VALUE);
const flyoutTitleId = useGeneratedHtmlId({
prefix: 'alertsConfigurationFlyout',
});
return (
<EuiFlyout
onClose={onCancel}
css={css`
min-width: 550px;
`}
aria-labelledby={flyoutTitleId}
>
<EuiFlyoutHeader>
<EuiTitle>
<h2>
<h2 id={flyoutTitleId}>
{i18n.translate('xpack.slo.sloEmbeddable.config.sloSelector.headerTitle', {
defaultMessage: 'Alerts configuration',
})}

View file

@ -19,6 +19,7 @@ import {
EuiIcon,
EuiTitle,
EuiToolTip,
useGeneratedHtmlId,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
@ -40,6 +41,9 @@ export function Configuration({ onCreate, onCancel }: Props) {
const [selectedSlo, setSelectedSlo] = useState<SloConfig>();
const [duration, setDuration] = useState<string>('1h');
const [hasError, setHasError] = useState(false);
const flyoutTitleId = useGeneratedHtmlId({
prefix: 'burnRateConfigurationFlyout',
});
const isDurationValid = duration.match(/^\d+[mhd]$/); // matches 1m, 78m, 1h, 6h, 1d, 24d
@ -56,10 +60,10 @@ export function Configuration({ onCreate, onCancel }: Props) {
};
return (
<EuiFlyout onClose={onCancel} style={{ minWidth: 550 }}>
<EuiFlyout onClose={onCancel} css={{ minWidth: 550 }} aria-labelledby={flyoutTitleId}>
<EuiFlyoutHeader>
<EuiTitle>
<h2>
<h2 id={flyoutTitleId}>
{i18n.translate('xpack.slo.burnRateEmbeddable.configuration.headerTitle', {
defaultMessage: 'Burn rate configuration',
})}

View file

@ -17,6 +17,7 @@ import {
EuiTab,
EuiTabs,
EuiTitle,
useGeneratedHtmlId,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { SLOWithSummaryResponse } from '@kbn/slo-schema';
@ -44,6 +45,10 @@ export function SloOverviewDetails({
uiSettings,
} = useKibana().services;
const flyoutTitleId = useGeneratedHtmlId({
prefix: 'sloOverviewFlyout',
});
const onClose = () => {
setSelectedSlo(null);
};
@ -62,10 +67,10 @@ export function SloOverviewDetails({
}
return (
<EuiFlyout onClose={onClose}>
<EuiFlyout onClose={onClose} aria-labelledby={flyoutTitleId}>
<EuiFlyoutHeader>
<EuiTitle>
<h2>
<h2 id={flyoutTitleId}>
{i18n.translate('xpack.slo.sloOverviewDetails.h2.detailsLabel', {
defaultMessage: '{sloName}',
values: { sloName: slo.name },

View file

@ -16,6 +16,7 @@ import {
EuiButtonEmpty,
EuiFlexGroup,
EuiFlexItem,
useGeneratedHtmlId,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
@ -31,16 +32,21 @@ export function SloConfiguration({ onCreate, onCancel }: SloConfigurationProps)
const [selectedSlo, setSelectedSlo] = useState<EmbeddableSloProps>();
const [hasError, setHasError] = useState(false);
const flyoutTitleId = useGeneratedHtmlId({
prefix: 'configurationFlyout',
});
const onConfirmClick = () =>
onCreate({
sloId: selectedSlo?.sloId,
sloInstanceId: selectedSlo?.sloInstanceId,
});
return (
<EuiFlyout onClose={onCancel} style={{ minWidth: 550 }}>
<EuiFlyout onClose={onCancel} css={{ minWidth: 550 }} aria-labelledby={flyoutTitleId}>
<EuiFlyoutHeader>
<EuiTitle>
<h2>
<h2 id={flyoutTitleId}>
{i18n.translate('xpack.slo.errorBudgetEmbeddable.config.sloSelector.headerTitle', {
defaultMessage: 'Error budget burn down configuration',
})}

View file

@ -18,6 +18,7 @@ import {
EuiFlyoutBody,
EuiFlyoutFooter,
EuiTitle,
useGeneratedHtmlId,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { ALL_VALUE } from '@kbn/slo-schema';
@ -198,14 +199,21 @@ export function SloConfiguration({ initialInput, onCreate, onCancel }: SloConfig
const [overviewMode, setOverviewMode] = useState<OverviewMode>(
initialInput?.overviewMode ?? 'single'
);
const flyoutTitleId = useGeneratedHtmlId({
prefix: 'overviewConfigurationFlyout',
});
return (
<EuiFlyout data-test-subj="sloSingleOverviewConfiguration" onClose={onCancel}>
<EuiFlyout
data-test-subj="sloSingleOverviewConfiguration"
onClose={onCancel}
aria-labelledby={flyoutTitleId}
>
<EuiFlyoutHeader>
<EuiFlexGroup direction="column">
<EuiFlexItem>
<EuiTitle>
<h2>
<h2 id={flyoutTitleId}>
{i18n.translate('xpack.slo.overviewEmbeddable.config.sloSelector.headerTitle', {
defaultMessage: 'Overview configuration',
})}

View file

@ -16,6 +16,7 @@ import {
EuiFlyoutBody,
EuiFlyoutFooter,
EuiTitle,
useGeneratedHtmlId,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { FormProvider, useForm } from 'react-hook-form';
@ -49,6 +50,9 @@ export function MonitorConfiguration({
mode: 'all',
});
const { getValues, formState } = methods;
const flyoutTitleId = useGeneratedHtmlId({
prefix: 'monitorConfigurationFlyout',
});
const onConfirmClick = () => {
const newFilters = getValues();
@ -58,10 +62,10 @@ export function MonitorConfiguration({
};
return (
<EuiFlyout onClose={onCancel}>
<EuiFlyout onClose={onCancel} aria-labelledby={flyoutTitleId}>
<EuiFlyoutHeader>
<EuiTitle>
<h2>{title}</h2>
<h2 id={flyoutTitleId}>{title}</h2>
</EuiTitle>
</EuiFlyoutHeader>
<EuiFlyoutBody>