mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 02:09:32 -04:00
* Add screen reader only text for monitoring charts
* Add aria label for completed recoveries
* Ensure we have aria label coverage for monitoring chart tooltips
* Ensure table rows are tabbable and include the number of results at the top
* Use EuiScreenReaderOnly
* Updated copy
* Use EUI
* Remove kui usage
* Use an id instead of aria-label
* Show results in the table footer
* Revert "Show results in the table footer"
This reverts commit d622eb7eb4
.
* Show total row count within the monitoring table
* PR feedback
* PR feedback
* Ensure all charts show an interval in the tooltip
* Fix padding issue with the cluster status
This commit is contained in:
parent
b1b4818085
commit
a635df9496
8 changed files with 74 additions and 44 deletions
|
@ -5,11 +5,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { first, get } from 'lodash';
|
|
||||||
|
|
||||||
export function InfoTooltip({ series }) {
|
export function InfoTooltip({ series, bucketSize }) {
|
||||||
|
|
||||||
const bucketSize = get(first(series), 'bucket_size'); // bucket size will be the same for all metrics in all series
|
|
||||||
const tableRows = series.map((item, index) => {
|
const tableRows = series.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<tr
|
<tr
|
||||||
|
|
|
@ -4,14 +4,15 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React, { Fragment } from 'react';
|
||||||
|
import { get, first } from 'lodash';
|
||||||
import { getTitle } from './get_title';
|
import { getTitle } from './get_title';
|
||||||
import { getUnits } from './get_units';
|
import { getUnits } from './get_units';
|
||||||
import { MonitoringTimeseries } from './monitoring_timeseries';
|
import { MonitoringTimeseries } from './monitoring_timeseries';
|
||||||
import { InfoTooltip } from './info_tooltip';
|
import { InfoTooltip } from './info_tooltip';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EuiIconTip, EuiFlexGroup, EuiFlexItem, EuiTitle
|
EuiIconTip, EuiFlexGroup, EuiFlexItem, EuiTitle, EuiScreenReaderOnly
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
export function MonitoringTimeseriesContainer({ series, onBrush }) {
|
export function MonitoringTimeseriesContainer({ series, onBrush }) {
|
||||||
|
@ -19,27 +20,43 @@ export function MonitoringTimeseriesContainer({ series, onBrush }) {
|
||||||
return null; // still loading
|
return null; // still loading
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const title = getTitle(series);
|
||||||
|
const titleForAriaIds = title.replace(/\s+/, '--');
|
||||||
const units = getUnits(series);
|
const units = getUnits(series);
|
||||||
|
const bucketSize = get(first(series), 'bucket_size'); // bucket size will be the same for all metrics in all series
|
||||||
|
|
||||||
|
const seriesScreenReaderTextList = [`Interval: ${bucketSize}`]
|
||||||
|
.concat(series.map(item => `${item.metric.label}: ${item.metric.description}`));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiFlexGroup direction="column" gutterSize="s">
|
<EuiFlexGroup direction="column" gutterSize="s">
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center" style={{ flexGrow: 0 }}>
|
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center" style={{ flexGrow: 0 }}>
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
<EuiTitle>
|
<EuiTitle tabIndex="0">
|
||||||
<h2>
|
<Fragment>
|
||||||
{ getTitle(series) }{ units ? ` (${units})` : '' }
|
<EuiScreenReaderOnly><span>This chart is not screen reader accessible</span></EuiScreenReaderOnly>
|
||||||
</h2>
|
<h2>
|
||||||
|
{ getTitle(series) }{ units ? ` (${units})` : '' }
|
||||||
|
</h2>
|
||||||
|
</Fragment>
|
||||||
</EuiTitle>
|
</EuiTitle>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem grow={false}>
|
<EuiFlexItem grow={false}>
|
||||||
<EuiIconTip
|
<Fragment>
|
||||||
anchorClassName="eui-textRight eui-alignMiddle monitoring-chart-tooltip__trigger"
|
<EuiIconTip
|
||||||
className="monitoring-chart-tooltip__wrapper"
|
anchorClassName="eui-textRight eui-alignMiddle monitoring-chart-tooltip__trigger"
|
||||||
type="iInCircle"
|
className="monitoring-chart-tooltip__wrapper"
|
||||||
position="right"
|
type="iInCircle"
|
||||||
content={<InfoTooltip series={series}/>}
|
position="right"
|
||||||
/>
|
content={<InfoTooltip series={series} bucketSize={bucketSize}/>}
|
||||||
|
/>
|
||||||
|
<EuiScreenReaderOnly>
|
||||||
|
<span id={`monitoringChart${titleForAriaIds}`}>
|
||||||
|
{seriesScreenReaderTextList.join('. ')}
|
||||||
|
</span>
|
||||||
|
</EuiScreenReaderOnly>
|
||||||
|
</Fragment>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
</EuiFlexGroup>
|
</EuiFlexGroup>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import { ClusterStatus } from '../cluster_status';
|
import { ClusterStatus } from '../cluster_status';
|
||||||
import { ShardActivity } from '../shard_activity';
|
import { ShardActivity } from '../shard_activity';
|
||||||
import { MonitoringTimeseriesContainer } from '../../chart';
|
import { MonitoringTimeseriesContainer } from '../../chart';
|
||||||
|
@ -24,24 +24,24 @@ export function ElasticsearchOverview({
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiPage style={{ backgroundColor: 'white' }}>
|
<Fragment>
|
||||||
<EuiPageBody>
|
<ClusterStatus stats={clusterStatus} />
|
||||||
<ClusterStatus stats={clusterStatus} />
|
<EuiPage style={{ backgroundColor: 'white' }}>
|
||||||
|
<EuiPageBody>
|
||||||
<EuiFlexGrid columns={2} gutterSize="none">
|
<EuiFlexGrid columns={2} gutterSize="none">
|
||||||
{metricsToShow.map((metric, index) => (
|
{metricsToShow.map((metric, index) => (
|
||||||
<EuiFlexItem key={index} style={{ width: '50%' }}>
|
<EuiFlexItem key={index} style={{ width: '50%' }}>
|
||||||
<MonitoringTimeseriesContainer
|
<MonitoringTimeseriesContainer
|
||||||
series={metric}
|
series={metric}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
<EuiSpacer size="m"/>
|
<EuiSpacer size="m"/>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
))}
|
))}
|
||||||
</EuiFlexGrid>
|
</EuiFlexGrid>
|
||||||
|
<ShardActivity data={shardActivity} {...props} />
|
||||||
<ShardActivity data={shardActivity} {...props} />
|
</EuiPageBody>
|
||||||
</EuiPageBody>
|
</EuiPage>
|
||||||
</EuiPage>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ const ToggleCompletedSwitch = ({ toggleHistory, showHistory }) => (
|
||||||
<KuiToolBarSection>
|
<KuiToolBarSection>
|
||||||
<KuiToolBarText>
|
<KuiToolBarText>
|
||||||
<EuiSwitch
|
<EuiSwitch
|
||||||
|
id="monitoring_completed_recoveries"
|
||||||
label="Completed recoveries"
|
label="Completed recoveries"
|
||||||
onChange={toggleHistory}
|
onChange={toggleHistory}
|
||||||
checked={showHistory}
|
checked={showHistory}
|
||||||
|
|
|
@ -256,6 +256,7 @@ export class MonitoringTable extends React.Component {
|
||||||
pageIndexFirstRow={numVisibleRows ? firstRow + 1 : 0}
|
pageIndexFirstRow={numVisibleRows ? firstRow + 1 : 0}
|
||||||
pageIndexLastRow={numVisibleRows ? numVisibleRows + firstRow : 0}
|
pageIndexLastRow={numVisibleRows ? numVisibleRows + firstRow : 0}
|
||||||
rowsFiltered={numAvailableRows}
|
rowsFiltered={numAvailableRows}
|
||||||
|
totalRows={this.state.rows.length}
|
||||||
filterText={this.state.filterText}
|
filterText={this.state.filterText}
|
||||||
paginationControls={this.getPaginationControls(numAvailableRows, this.props.alwaysShowPageControls)}
|
paginationControls={this.getPaginationControls(numAvailableRows, this.props.alwaysShowPageControls)}
|
||||||
onFilterChange={this.onFilterChange}
|
onFilterChange={this.onFilterChange}
|
||||||
|
|
|
@ -37,9 +37,18 @@ export function MonitoringTableToolBar(props) {
|
||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
const totalRows = Boolean(props.showTotalRows)
|
||||||
|
? (
|
||||||
|
<p tabIndex="0" className="monitoringTableToolbarTotalRows">
|
||||||
|
{props.totalRows} in total
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<KuiToolBar>
|
<KuiToolBar>
|
||||||
{ searchBox }
|
{ searchBox }
|
||||||
|
{ totalRows }
|
||||||
{ props.renderToolBarSections(props) }
|
{ props.renderToolBarSections(props) }
|
||||||
{ paginationSection }
|
{ paginationSection }
|
||||||
</KuiToolBar>
|
</KuiToolBar>
|
||||||
|
@ -47,5 +56,6 @@ export function MonitoringTableToolBar(props) {
|
||||||
}
|
}
|
||||||
MonitoringTableToolBar.defaultProps = {
|
MonitoringTableToolBar.defaultProps = {
|
||||||
renderToolBarSections: noop,
|
renderToolBarSections: noop,
|
||||||
showSearchBox: true
|
showSearchBox: true,
|
||||||
|
showTotalRows: true
|
||||||
};
|
};
|
||||||
|
|
|
@ -54,17 +54,17 @@ const alertRowFactory = (scope, kbnUrl) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<KuiTableRow>
|
<KuiTableRow>
|
||||||
<KuiTableRowCell>
|
<KuiTableRowCell tabIndex="0">
|
||||||
<Tooltip text={severityIcon.title} placement="bottom" trigger="hover">
|
<Tooltip text={severityIcon.title} placement="bottom" trigger="hover">
|
||||||
<EuiHealth color={severityIcon.color} data-test-subj="alertIcon" aria-label={severityIcon.title}>
|
<EuiHealth color={severityIcon.color} data-test-subj="alertIcon" aria-label={severityIcon.title}>
|
||||||
{ capitalize(severityIcon.value) }
|
{ capitalize(severityIcon.value) }
|
||||||
</EuiHealth>
|
</EuiHealth>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</KuiTableRowCell>
|
</KuiTableRowCell>
|
||||||
<KuiTableRowCell>
|
<KuiTableRowCell tabIndex="0">
|
||||||
{ resolution.icon } { resolution.text }
|
{ resolution.icon } { resolution.text }
|
||||||
</KuiTableRowCell>
|
</KuiTableRowCell>
|
||||||
<KuiTableRowCell>
|
<KuiTableRowCell tabIndex="0">
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
prefix={props.prefix}
|
prefix={props.prefix}
|
||||||
suffix={props.suffix}
|
suffix={props.suffix}
|
||||||
|
@ -73,13 +73,13 @@ const alertRowFactory = (scope, kbnUrl) => {
|
||||||
changeUrl={changeUrl}
|
changeUrl={changeUrl}
|
||||||
/>
|
/>
|
||||||
</KuiTableRowCell>
|
</KuiTableRowCell>
|
||||||
<KuiTableRowCell>
|
<KuiTableRowCell tabIndex="0">
|
||||||
{ linkToCategories[props.metadata.link] ? linkToCategories[props.metadata.link] : 'General' }
|
{ linkToCategories[props.metadata.link] ? linkToCategories[props.metadata.link] : 'General' }
|
||||||
</KuiTableRowCell>
|
</KuiTableRowCell>
|
||||||
<KuiTableRowCell>
|
<KuiTableRowCell tabIndex="0">
|
||||||
{ formatDateTimeLocal(props.update_timestamp) }
|
{ formatDateTimeLocal(props.update_timestamp) }
|
||||||
</KuiTableRowCell>
|
</KuiTableRowCell>
|
||||||
<KuiTableRowCell>
|
<KuiTableRowCell tabIndex="0">
|
||||||
{ formatTimestampToDuration(props.timestamp, CALCULATE_DURATION_SINCE) } ago
|
{ formatTimestampToDuration(props.timestamp, CALCULATE_DURATION_SINCE) } ago
|
||||||
</KuiTableRowCell>
|
</KuiTableRowCell>
|
||||||
</KuiTableRow>
|
</KuiTableRow>
|
||||||
|
|
|
@ -60,3 +60,7 @@
|
||||||
color: #666977;
|
color: #666977;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.monitoringTableToolbarTotalRows {
|
||||||
|
flex: 2; /* This is to ensure this shows directly next to the search bar in the table toolbar */
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue