[ML] Fix Single Metric Viewer & Explorer annotation table actions overflow and annotations count not matching (#104955)
* Fix annotations * Fix translations * Fix onclick open * Fix label/aggregations mismatch * Fix title
This commit is contained in:
parent
36bf7f7120
commit
f7b87a5f65
4 changed files with 89 additions and 85 deletions
|
@ -18,13 +18,13 @@ import React, { Component, Fragment, useContext } from 'react';
|
|||
import memoizeOne from 'memoize-one';
|
||||
import {
|
||||
EuiBadge,
|
||||
EuiButtonEmpty,
|
||||
EuiCallOut,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiInMemoryTable,
|
||||
EuiLink,
|
||||
EuiLoadingSpinner,
|
||||
EuiToolTip,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
@ -52,6 +52,19 @@ import { timeFormatter } from '../../../../../common/util/date_utils';
|
|||
import { MlAnnotationUpdatesContext } from '../../../contexts/ml/ml_annotation_updates_context';
|
||||
import { DatafeedChartFlyout } from '../../../jobs/jobs_list/components/datafeed_chart_flyout';
|
||||
|
||||
const editAnnotationsText = (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.annotationsTable.editAnnotationsTooltip"
|
||||
defaultMessage="Edit annotation"
|
||||
/>
|
||||
);
|
||||
const viewDataFeedText = (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.annotationsTable.datafeedChartTooltip"
|
||||
defaultMessage="Datafeed chart"
|
||||
/>
|
||||
);
|
||||
|
||||
const CURRENT_SERIES = 'current_series';
|
||||
/**
|
||||
* Table component for rendering the lists of annotations for an ML job.
|
||||
|
@ -463,82 +476,67 @@ class AnnotationsTableUI extends Component {
|
|||
const actions = [];
|
||||
|
||||
actions.push({
|
||||
render: (annotation) => {
|
||||
// find the original annotation because the table might not show everything
|
||||
name: editAnnotationsText,
|
||||
description: editAnnotationsText,
|
||||
icon: 'pencil',
|
||||
type: 'icon',
|
||||
onClick: (annotation) => {
|
||||
const annotationId = annotation._id;
|
||||
const originalAnnotation = annotations.find((d) => d._id === annotationId);
|
||||
const editAnnotationsText = (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.annotationsTable.editAnnotationsTooltip"
|
||||
defaultMessage="Edit annotation"
|
||||
/>
|
||||
);
|
||||
const editAnnotationsAriaLabelText = i18n.translate(
|
||||
'xpack.ml.annotationsTable.editAnnotationsTooltipAriaLabel',
|
||||
{ defaultMessage: 'Edit annotation' }
|
||||
);
|
||||
return (
|
||||
<EuiButtonEmpty
|
||||
size="xs"
|
||||
aria-label={editAnnotationsAriaLabelText}
|
||||
iconType="pencil"
|
||||
onClick={() => annotationUpdatesService.setValue(originalAnnotation ?? annotation)}
|
||||
>
|
||||
{editAnnotationsText}
|
||||
</EuiButtonEmpty>
|
||||
);
|
||||
|
||||
annotationUpdatesService.setValue(originalAnnotation ?? annotation);
|
||||
},
|
||||
});
|
||||
|
||||
if (this.state.jobId && this.props.jobs[0].analysis_config.bucket_span) {
|
||||
// add datafeed modal action
|
||||
actions.push({
|
||||
render: (annotation) => {
|
||||
const viewDataFeedText = (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.annotationsTable.datafeedChartTooltip"
|
||||
defaultMessage="Datafeed chart"
|
||||
/>
|
||||
);
|
||||
const viewDataFeedTooltipAriaLabelText = i18n.translate(
|
||||
'xpack.ml.annotationsTable.datafeedChartTooltipAriaLabel',
|
||||
{ defaultMessage: 'Datafeed chart' }
|
||||
);
|
||||
return (
|
||||
<EuiButtonEmpty
|
||||
size="xs"
|
||||
aria-label={viewDataFeedTooltipAriaLabelText}
|
||||
iconType="visAreaStacked"
|
||||
onClick={() =>
|
||||
this.setState({
|
||||
datafeedFlyoutVisible: true,
|
||||
datafeedEnd: annotation.end_timestamp,
|
||||
})
|
||||
}
|
||||
>
|
||||
{viewDataFeedText}
|
||||
</EuiButtonEmpty>
|
||||
);
|
||||
name: viewDataFeedText,
|
||||
description: viewDataFeedText,
|
||||
icon: 'visAreaStacked',
|
||||
type: 'icon',
|
||||
onClick: (annotation) => {
|
||||
this.setState({
|
||||
datafeedFlyoutVisible: true,
|
||||
datafeedEnd: annotation.end_timestamp,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (isSingleMetricViewerLinkVisible) {
|
||||
actions.push({
|
||||
render: (annotation) => {
|
||||
name: (annotation) => {
|
||||
const isDrillDownAvailable = isTimeSeriesViewJob(this.getJob(annotation.job_id));
|
||||
const openInSingleMetricViewerTooltipText = isDrillDownAvailable ? (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.annotationsTable.openInSingleMetricViewerTooltip"
|
||||
defaultMessage="Open in Single Metric Viewer"
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.annotationsTable.jobConfigurationNotSupportedInSingleMetricViewerTooltip"
|
||||
defaultMessage="Job configuration not supported in Single Metric Viewer"
|
||||
/>
|
||||
|
||||
if (isDrillDownAvailable) {
|
||||
return (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.annotationsTable.openInSingleMetricViewerTooltip"
|
||||
defaultMessage="Open in Single Metric Viewer"
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<EuiToolTip
|
||||
content={
|
||||
<FormattedMessage
|
||||
id="xpack.ml.annotationsTable.jobConfigurationNotSupportedInSingleMetricViewerTooltip"
|
||||
defaultMessage="Job configuration not supported in Single Metric Viewer"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.annotationsTable.openInSingleMetricViewerTooltip"
|
||||
defaultMessage="Open in Single Metric Viewer"
|
||||
/>
|
||||
</EuiToolTip>
|
||||
);
|
||||
const openInSingleMetricViewerAriaLabelText = isDrillDownAvailable
|
||||
},
|
||||
description: (annotation) => {
|
||||
const isDrillDownAvailable = isTimeSeriesViewJob(this.getJob(annotation.job_id));
|
||||
|
||||
return isDrillDownAvailable
|
||||
? i18n.translate('xpack.ml.annotationsTable.openInSingleMetricViewerAriaLabel', {
|
||||
defaultMessage: 'Open in Single Metric Viewer',
|
||||
})
|
||||
|
@ -546,19 +544,11 @@ class AnnotationsTableUI extends Component {
|
|||
'xpack.ml.annotationsTable.jobConfigurationNotSupportedInSingleMetricViewerAriaLabel',
|
||||
{ defaultMessage: 'Job configuration not supported in Single Metric Viewer' }
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiButtonEmpty
|
||||
size="xs"
|
||||
disabled={!isDrillDownAvailable}
|
||||
aria-label={openInSingleMetricViewerAriaLabelText}
|
||||
iconType="visLine"
|
||||
onClick={() => this.openSingleMetricView(annotation)}
|
||||
>
|
||||
{openInSingleMetricViewerTooltipText}
|
||||
</EuiButtonEmpty>
|
||||
);
|
||||
},
|
||||
enabled: (annotation) => isTimeSeriesViewJob(this.getJob(annotation.job_id)),
|
||||
icon: 'visLine',
|
||||
type: 'icon',
|
||||
onClick: (annotation) => this.openSingleMetricView(annotation),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -261,6 +261,30 @@ export class ExplorerUI extends React.Component {
|
|||
} = this.props.explorerState;
|
||||
const { annotationsData, aggregations, error: annotationsError } = annotations;
|
||||
|
||||
const annotationsCnt = Array.isArray(annotationsData) ? annotationsData.length : 0;
|
||||
const allAnnotationsCnt = Array.isArray(aggregations?.event?.buckets)
|
||||
? aggregations.event.buckets.reduce((acc, v) => acc + v.doc_count, 0)
|
||||
: annotationsCnt;
|
||||
|
||||
const badge =
|
||||
allAnnotationsCnt > annotationsCnt ? (
|
||||
<EuiBadge color={'hollow'}>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.explorer.annotationsOutOfTotalCountTitle"
|
||||
defaultMessage="First {visibleCount} out of a total of {totalCount}"
|
||||
values={{ visibleCount: annotationsCnt, totalCount: allAnnotationsCnt }}
|
||||
/>
|
||||
</EuiBadge>
|
||||
) : (
|
||||
<EuiBadge color={'hollow'}>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.explorer.annotationsTitleTotalCount"
|
||||
defaultMessage="Total: {count}"
|
||||
values={{ count: annotationsCnt }}
|
||||
/>
|
||||
</EuiBadge>
|
||||
);
|
||||
|
||||
const jobSelectorProps = {
|
||||
dateFormatTz: getDateFormatTz(),
|
||||
};
|
||||
|
@ -404,7 +428,7 @@ export class ExplorerUI extends React.Component {
|
|||
{loading === false && tableData.anomalies?.length ? (
|
||||
<AnomaliesMap anomalies={tableData.anomalies} jobIds={selectedJobIds} />
|
||||
) : null}
|
||||
{annotationsData.length > 0 && (
|
||||
{annotationsCnt > 0 && (
|
||||
<>
|
||||
<EuiPanel data-test-subj="mlAnomalyExplorerAnnotationsPanel loaded">
|
||||
<EuiAccordion
|
||||
|
@ -416,15 +440,7 @@ export class ExplorerUI extends React.Component {
|
|||
id="xpack.ml.explorer.annotationsTitle"
|
||||
defaultMessage="Annotations {badge}"
|
||||
values={{
|
||||
badge: (
|
||||
<EuiBadge color={'hollow'}>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.explorer.annotationsTitleTotalCount"
|
||||
defaultMessage="Total: {count}"
|
||||
values={{ count: annotationsData.length }}
|
||||
/>
|
||||
</EuiBadge>
|
||||
),
|
||||
badge,
|
||||
}}
|
||||
/>
|
||||
</h2>
|
||||
|
|
|
@ -13639,7 +13639,6 @@
|
|||
"xpack.ml.annotationsTable.byColumnSMVName": "グループ基準",
|
||||
"xpack.ml.annotationsTable.detectorColumnName": "検知器",
|
||||
"xpack.ml.annotationsTable.editAnnotationsTooltip": "注釈を編集します",
|
||||
"xpack.ml.annotationsTable.editAnnotationsTooltipAriaLabel": "注釈を編集します",
|
||||
"xpack.ml.annotationsTable.eventColumnName": "イベント",
|
||||
"xpack.ml.annotationsTable.fromColumnName": "開始:",
|
||||
"xpack.ml.annotationsTable.howToCreateAnnotationDescription": "注釈を作成するには、{linkToSingleMetricView} を開きます",
|
||||
|
|
|
@ -13818,7 +13818,6 @@
|
|||
"xpack.ml.annotationsTable.byColumnSMVName": "依据",
|
||||
"xpack.ml.annotationsTable.detectorColumnName": "检测工具",
|
||||
"xpack.ml.annotationsTable.editAnnotationsTooltip": "编辑注释",
|
||||
"xpack.ml.annotationsTable.editAnnotationsTooltipAriaLabel": "编辑注释",
|
||||
"xpack.ml.annotationsTable.eventColumnName": "事件",
|
||||
"xpack.ml.annotationsTable.fromColumnName": "自",
|
||||
"xpack.ml.annotationsTable.howToCreateAnnotationDescription": "要创建注释,请打开 {linkToSingleMetricView}",
|
||||
|
|
Loading…
Reference in a new issue