Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ export function DocumentsColumn({
<EuiIcon type="visLine" size="m" />
);

const cellAriaLabel = hasData
? i18n.translate('xpack.streams.documentsColumn.cellDocCountLabel', {
defaultMessage: '{docCount} documents in {indexPattern}',
values: { docCount, indexPattern },
})
: i18n.translate('xpack.streams.documentsColumn.cellNoDataLabel', {
defaultMessage: 'No documents found in {indexPattern}',
values: { indexPattern },
});

return (
<EuiFlexGroup
alignItems="center"
Expand All @@ -113,13 +123,16 @@ export function DocumentsColumn({
height: ${euiTheme.size.xl};
white-space: nowrap;
`}
role="group"
aria-label={cellAriaLabel}
>
{histogramQueryFetch.loading ? (
<LoadingPlaceholder />
) : (
<>
<EuiFlexItem
grow={2}
aria-hidden="true"
className={css`
text-align: right;
`}
Expand All @@ -128,6 +141,7 @@ export function DocumentsColumn({
</EuiFlexItem>
<EuiFlexItem
grow={3}
aria-hidden="true"
className={css`
border-bottom: ${hasData ? '1px solid' : 'none'} ${euiTheme.colors.lightShade};
display: flex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
isIlmLifecycle,
} from '@kbn/streams-schema';
import { useKibana } from '../../hooks/use_kibana';
import { INFINITE_RETENTION_LABEL, NO_RETENTION_LABEL, NO_DATA_SHORT_LABEL } from './translations';

export function RetentionColumn({ lifecycle }: { lifecycle: IngestStreamEffectiveLifecycle }) {
const {
Expand All @@ -26,7 +27,19 @@ export function RetentionColumn({ lifecycle }: { lifecycle: IngestStreamEffectiv
const ilmLocator = share.url.locators.get<IlmLocatorParams>(ILM_LOCATOR_ID);

if (isErrorLifecycle(lifecycle)) {
return <EuiBadge color="hollow">{lifecycle.error.message}</EuiBadge>;
return (
<EuiBadge
color="hollow"
aria-label={i18n.translate('xpack.streams.streamsRetentionColumn.errorBadgeAriaLabel', {
defaultMessage: 'Retention policy error: {message}',
values: { message: lifecycle.error.message },
})}
role="status"
aria-live="polite"
>
{lifecycle.error.message}
</EuiBadge>
);
}

if (isIlmLifecycle(lifecycle)) {
Expand All @@ -40,6 +53,10 @@ export function RetentionColumn({ lifecycle }: { lifecycle: IngestStreamEffectiv
policyName: lifecycle.ilm.policy,
})}
target="_blank"
aria-label={i18n.translate('xpack.streams.streamsRetentionColumn.ilmLinkAriaLabel', {
defaultMessage: 'ILM policy: {name}, click to edit the policy in a new tab',
values: { name: lifecycle.ilm.policy },
})}
>
{i18n.translate('xpack.streams.streamsRetentionColumn.ilmBadgeLabel', {
defaultMessage: 'ILM policy: {name}',
Expand All @@ -53,14 +70,35 @@ export function RetentionColumn({ lifecycle }: { lifecycle: IngestStreamEffectiv
}

if (isDslLifecycle(lifecycle)) {
return lifecycle.dsl.data_retention || <EuiIcon type="infinity" size="m" />;
const retentionValue = lifecycle.dsl.data_retention;

if (retentionValue) {
return (
<span
tabIndex={0}
aria-label={i18n.translate('xpack.streams.streamsRetentionColumn.dslRetentionAriaLabel', {
defaultMessage: 'Data retention period: {retention}',
values: { retention: retentionValue },
})}
>
{retentionValue}
</span>
);
}

return (
<span
aria-label={INFINITE_RETENTION_LABEL}
style={{ display: 'inline-flex', alignItems: 'center' }}
>
<EuiIcon type="infinity" size="m" aria-hidden="true" />
</span>
);
}

return (
<EuiText color="subdued">
{i18n.translate('xpack.streams.streamsRetentionColumn.noDataLabel', {
defaultMessage: 'N/A',
})}
<EuiText color="subdued" tabIndex={0} aria-label={NO_RETENTION_LABEL}>
{NO_DATA_SHORT_LABEL}
</EuiText>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { i18n } from '@kbn/i18n';

export const NAME_COLUMN_HEADER = i18n.translate('xpack.streams.streamsTreeTable.nameColumnName', {
defaultMessage: 'Name',
});

export const DOCUMENTS_COLUMN_HEADER = i18n.translate(
'xpack.streams.streamsTreeTable.documentsColumnName',
{ defaultMessage: 'Documents' }
);

export const RETENTION_COLUMN_HEADER = i18n.translate(
'xpack.streams.streamsTreeTable.retentionColumnName',
{ defaultMessage: 'Retention' }
);

export const RETENTION_COLUMN_HEADER_ARIA_LABEL = i18n.translate(
'xpack.streams.streamsTreeTable.retentionColumnHeaderAriaLabel',
{
defaultMessage: 'Retention column - shows data retention policies for each stream',
}
);

export const NO_STREAMS_MESSAGE = i18n.translate(
'xpack.streams.streamsTreeTable.noStreamsMessage',
{
defaultMessage: 'No streams found.',
}
);

export const STREAMS_TABLE_SEARCH_ARIA_LABEL = i18n.translate(
'xpack.streams.streamsTreeTable.searchAriaLabel',
{ defaultMessage: 'Search streams by name' }
);

export const STREAMS_TABLE_CAPTION_ARIA_LABEL = i18n.translate(
'xpack.streams.streamsTreeTable.tableCaptionAriaLabel',
{
defaultMessage:
'Streams data table, listing stream names with links, document counts, and retention policies with links',
}
);

export const NO_DATA_SHORT_LABEL = i18n.translate('xpack.streams.documentsColumn.noDataLabel', {
defaultMessage: 'N/A',
});

export const DOCUMENTS_NO_DATA_ICON_ARIA_LABEL = i18n.translate(
'xpack.streams.documentsColumn.noDataIconAriaLabel',
{ defaultMessage: 'No chart data available' }
);

export const INFINITE_RETENTION_LABEL = i18n.translate(
'xpack.streams.streamsRetentionColumn.infiniteRetentionAriaLabel',
{ defaultMessage: 'Infinite retention - data is kept indefinitely' }
);

export const NO_RETENTION_LABEL = i18n.translate(
'xpack.streams.streamsRetentionColumn.noDataAriaLabel',
{ defaultMessage: 'No retention policy configured' }
);
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ import { StreamsAppSearchBar } from '../streams_app_search_bar';
import { DocumentsColumn } from './documents_column';
import { useStreamsAppRouter } from '../../hooks/use_streams_app_router';
import { RetentionColumn } from './retention_column';
import {
NAME_COLUMN_HEADER,
DOCUMENTS_COLUMN_HEADER,
RETENTION_COLUMN_HEADER,
STREAMS_TABLE_SEARCH_ARIA_LABEL,
STREAMS_TABLE_CAPTION_ARIA_LABEL,
RETENTION_COLUMN_HEADER_ARIA_LABEL,
NO_STREAMS_MESSAGE,
} from './translations';

export function StreamsTreeTable({
loading,
Expand Down Expand Up @@ -82,9 +91,7 @@ export function StreamsTreeTable({
columns={[
{
field: 'nameSortKey',
name: i18n.translate('xpack.streams.streamsTreeTable.nameColumnName', {
defaultMessage: 'Name',
}),
name: NAME_COLUMN_HEADER,
sortable: (row: TableRow) => row.rootNameSortKey,
dataType: 'string',
render: (_: unknown, item: TableRow) => (
Expand All @@ -99,9 +106,20 @@ export function StreamsTreeTable({
{item.children && (
<EuiFlexItem grow={false}>
{isEmpty(item.children) ? (
<EuiIcon type="empty" color="text" size="m" />
<EuiIcon type="empty" color="text" size="m" aria-hidden="true" />
) : (
<EuiIcon type="arrowDown" color="text" size="m" />
<EuiIcon
type="arrowDown"
color="text"
size="m"
aria-label={i18n.translate(
'xpack.streams.streamsTreeTable.expandedNodeAriaLabel',
{
defaultMessage: 'Expanded node with {childCount} children',
values: { childCount: item.children.length },
}
)}
/>
)}
</EuiFlexItem>
)}
Expand All @@ -118,17 +136,7 @@ export function StreamsTreeTable({
},
{
field: 'documentsCount',
name: (
<span
className={css`
margin-right: ${euiTheme.size.l};
`}
>
{i18n.translate('xpack.streams.streamsTreeTable.documentsColumnName', {
defaultMessage: 'Documents',
})}
</span>
),
name: DOCUMENTS_COLUMN_HEADER,
width: '280px',
sortable: false,
dataType: 'number',
Expand All @@ -139,24 +147,28 @@ export function StreamsTreeTable({
},
{
field: 'retentionMs',
name: i18n.translate('xpack.streams.streamsTreeTable.retentionColumnName', {
defaultMessage: 'Retention',
}),
name: (
<span aria-label={RETENTION_COLUMN_HEADER_ARIA_LABEL}>{RETENTION_COLUMN_HEADER}</span>
),
width: '160px',
align: 'left',
sortable: (row: TableRow) => row.rootRetentionMs,
dataType: 'number',
render: (_: unknown, item: TableRow) => (
<RetentionColumn lifecycle={item.effective_lifecycle} />
<RetentionColumn
lifecycle={item.effective_lifecycle}
aria-label={i18n.translate('xpack.streams.streamsTreeTable.retentionCellAriaLabel', {
defaultMessage: 'Retention policy for {name}',
values: { name: item.stream.name },
})}
/>
),
},
]}
itemId="name"
items={items}
sorting={sorting}
noItemsMessage={i18n.translate('xpack.streams.streamsTreeTable.noStreamsMessage', {
defaultMessage: 'No streams found.',
})}
noItemsMessage={NO_STREAMS_MESSAGE}
onTableChange={handleTableChange}
pagination={{
initialPageSize: 25,
Expand All @@ -167,9 +179,11 @@ export function StreamsTreeTable({
onChange: handleQueryChange,
box: {
incremental: true,
'aria-label': STREAMS_TABLE_SEARCH_ARIA_LABEL,
},
toolsRight: <StreamsAppSearchBar showDatePicker />,
}}
tableCaption={STREAMS_TABLE_CAPTION_ARIA_LABEL}
/>
);
}