Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ML] Fix Single Metric Viewer & Explorer annotation table actions overflow and annotations count not matching #104955

Merged
merged 5 commits into from
Jul 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -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';
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -457,102 +470,79 @@ 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',
})
: i18n.translate(
'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),
});
}

Expand Down
36 changes: 26 additions & 10 deletions x-pack/plugins/ml/public/application/explorer/explorer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
};
Expand Down Expand Up @@ -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
Expand All @@ -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>
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/translations/translations/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -13642,7 +13642,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} を開きます",
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/translations/translations/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -13821,7 +13821,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}",
Expand Down