);
}
-}
+});
diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_distribution.test.js b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_distribution.test.js
index 9e2a3fc85122f..ccc479abd54fe 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_distribution.test.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_distribution.test.js
@@ -28,7 +28,7 @@ jest.mock('ui/chrome', () => ({
}),
}));
-import { mount } from 'enzyme';
+import { mountWithIntl } from 'test_utils/enzyme_helpers';
import React from 'react';
import { ExplorerChartDistribution } from './explorer_chart_distribution';
@@ -49,7 +49,7 @@ describe('ExplorerChart', () => {
afterEach(() => (SVGElement.prototype.getBBox = originalGetBBox));
test('Initialize', () => {
- const wrapper = mount(
);
+ const wrapper = mountWithIntl(
);
// without setting any attributes and corresponding data
// the directive just ends up being empty.
@@ -63,7 +63,9 @@ describe('ExplorerChart', () => {
loading: true
};
- const wrapper = mount(
);
+ const wrapper = mountWithIntl(
+
+ );
// test if the loading indicator is shown
expect(wrapper.find('.ml-loading-indicator .loading-spinner')).toHaveLength(1);
@@ -83,9 +85,9 @@ describe('ExplorerChart', () => {
};
// We create the element including a wrapper which sets the width:
- return mount(
+ return mountWithIntl(
-
+
);
}
diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_info_tooltip.js b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_info_tooltip.js
index 8c937767e215f..ad53cb12d3ad7 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_info_tooltip.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_info_tooltip.js
@@ -10,10 +10,19 @@ import React from 'react';
import { CHART_TYPE } from '../explorer_constants';
+import { i18n } from '@kbn/i18n';
+import { injectI18n } from '@kbn/i18n/react';
+
const CHART_DESCRIPTION = {
- [CHART_TYPE.EVENT_DISTRIBUTION]: 'The gray dots depict the distribution of occurences over time for a sample of by_field_values with \
-more frequent event types at the top and rarer ones at the bottom.',
- [CHART_TYPE.POPULATION_DISTRIBUTION]: 'The gray dots depict the distribution of values over time for a sample of over_field_values.'
+ [CHART_TYPE.EVENT_DISTRIBUTION]: i18n.translate('xpack.ml.explorer.charts.infoTooltip.chartEventDistributionDescription', {
+ defaultMessage: 'The gray dots depict the distribution of occurences over time for a sample of {byFieldValuesParam} with' +
+ 'more frequent event types at the top and rarer ones at the bottom.',
+ values: { byFieldValuesParam: 'by_field_values' }
+ }),
+ [CHART_TYPE.POPULATION_DISTRIBUTION]: i18n.translate('xpack.ml.explorer.charts.infoTooltip.chartPopulationDistributionDescription', {
+ defaultMessage: 'The gray dots depict the distribution of values over time for a sample of {overFieldValuesParam}.',
+ values: { overFieldValuesParam: 'over_field_values' }
+ }),
};
import { EuiSpacer } from '@elastic/eui';
@@ -31,26 +40,30 @@ function TooltipDefinitionList({ toolTipData }) {
);
}
-export function ExplorerChartInfoTooltip({
+export const ExplorerChartInfoTooltip = injectI18n(function ExplorerChartInfoTooltip({
jobId,
aggregationInterval,
chartFunction,
chartType,
entityFields = [],
+ intl
}) {
const chartDescription = CHART_DESCRIPTION[chartType];
const toolTipData = [
{
- title: 'job ID',
+ title: intl.formatMessage({ id: 'xpack.ml.explorer.charts.infoTooltip.jobIdTitle', defaultMessage: 'job ID' }),
description: jobId,
},
{
- title: 'aggregation interval',
+ title: intl.formatMessage({
+ id: 'xpack.ml.explorer.charts.infoTooltip.aggregationIntervalTitle',
+ defaultMessage: 'aggregation interval'
+ }),
description: aggregationInterval,
},
{
- title: 'chart function',
+ title: intl.formatMessage({ id: 'xpack.ml.explorer.charts.infoTooltip.chartFunctionTitle', defaultMessage: 'chart function' }),
description: chartFunction,
},
];
@@ -73,8 +86,8 @@ export function ExplorerChartInfoTooltip({
)}
);
-}
-ExplorerChartInfoTooltip.propTypes = {
+});
+ExplorerChartInfoTooltip.WrappedComponent.propTypes = {
jobId: PropTypes.string.isRequired,
aggregationInterval: PropTypes.string,
chartFunction: PropTypes.string,
diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_info_tooltip.test.js b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_info_tooltip.test.js
index 6db4360fa7f20..09ad176ed4a23 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_info_tooltip.test.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_info_tooltip.test.js
@@ -5,7 +5,7 @@
*/
-import { shallow } from 'enzyme';
+import { shallowWithIntl } from 'test_utils/enzyme_helpers';
import React from 'react';
import { ExplorerChartInfoTooltip } from './explorer_chart_info_tooltip';
@@ -22,7 +22,7 @@ describe('ExplorerChartTooltip', () => {
jobId: 'mock-job-id'
};
- const wrapper = shallow(
);
+ const wrapper = shallowWithIntl(
);
expect(wrapper).toMatchSnapshot();
});
});
diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.js b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.js
index 6a72a89e11539..2ced3a79d7b94 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.js
@@ -42,10 +42,12 @@ import { mlEscape } from '../../util/string_utils';
import { mlFieldFormatService } from '../../services/field_format_service';
import { mlChartTooltipService } from '../../components/chart_tooltip/chart_tooltip_service';
+import { injectI18n } from '@kbn/i18n/react';
+
const CONTENT_WRAPPER_HEIGHT = 215;
const CONTENT_WRAPPER_CLASS = 'ml-explorer-chart-content-wrapper';
-export class ExplorerChartSingleMetric extends React.Component {
+export const ExplorerChartSingleMetric = injectI18n(class ExplorerChartSingleMetric extends React.Component {
static propTypes = {
tooManyBuckets: PropTypes.bool,
seriesConfig: PropTypes.object,
@@ -63,7 +65,8 @@ export class ExplorerChartSingleMetric extends React.Component {
renderChart() {
const {
tooManyBuckets,
- mlSelectSeverityService
+ mlSelectSeverityService,
+ intl,
} = this.props;
const element = this.rootNode;
@@ -341,10 +344,19 @@ export class ExplorerChartSingleMetric extends React.Component {
if (_.has(marker, 'anomalyScore')) {
const score = parseInt(marker.anomalyScore);
const displayScore = (score > 0 ? score : '< 1');
- contents += ('anomaly score: ' + displayScore);
+ contents += intl.formatMessage({
+ id: 'xpack.ml.explorer.singleMetricChart.anomalyScoreLabel',
+ defaultMessage: 'anomaly score: {displayScore}'
+ }, { displayScore });
if (showMultiBucketAnomalyTooltip(marker) === true) {
- contents += `
multi-bucket impact: ${getMultiBucketImpactLabel(marker.multiBucketImpact)}`;
+ contents += intl.formatMessage({
+ id: 'xpack.ml.explorer.singleMetricChart.multiBucketImpactLabel',
+ defaultMessage: '{br}multi-bucket impact: {multiBucketImpactLabel}'
+ }, {
+ br: '
',
+ multiBucketImpactLabel: getMultiBucketImpactLabel(marker.multiBucketImpact)
+ });
}
// Show actual/typical when available except for rare detectors.
@@ -353,29 +365,61 @@ export class ExplorerChartSingleMetric extends React.Component {
if (_.has(marker, 'actual') && config.functionDescription !== 'rare') {
// Display the record actual in preference to the chart value, which may be
// different depending on the aggregation interval of the chart.
- contents += (`
actual: ${formatValue(marker.actual, config.functionDescription, fieldFormat)}`);
- contents += (`
typical: ${formatValue(marker.typical, config.functionDescription, fieldFormat)}`);
+ contents += intl.formatMessage({
+ id: 'xpack.ml.explorer.singleMetricChart.actualLabel',
+ defaultMessage: '{br}actual: {actualValue}'
+ }, {
+ br: '
',
+ actualValue: formatValue(marker.actual, config.functionDescription, fieldFormat)
+ });
+ contents += intl.formatMessage({
+ id: 'xpack.ml.explorer.singleMetricChart.typicalLabel',
+ defaultMessage: '{br}typical: {typicalValue}'
+ }, {
+ br: '
',
+ typicalValue: formatValue(marker.typical, config.functionDescription, fieldFormat)
+ });
} else {
- contents += (`
value: ${formatValue(marker.value, config.functionDescription, fieldFormat)}`);
+ contents += intl.formatMessage({
+ id: 'xpack.ml.explorer.singleMetricChart.valueLabel',
+ defaultMessage: '{br}value: {value}'
+ }, {
+ br: '
',
+ value: formatValue(marker.value, config.functionDescription, fieldFormat)
+ });
if (_.has(marker, 'byFieldName') && _.has(marker, 'numberOfCauses')) {
const numberOfCauses = marker.numberOfCauses;
const byFieldName = mlEscape(marker.byFieldName);
- if (numberOfCauses === 1) {
- contents += `
1 unusual ${byFieldName} value`;
- } else if (numberOfCauses < 10) {
- contents += `
${numberOfCauses} unusual ${byFieldName} values`;
- } else {
+ intl.formatMessage({
+ id: 'xpack.ml.explorer.singleMetricChart.unusualByFieldValuesLabel',
+ defaultMessage:
+ '{br} { numberOfCauses, plural, one {# unusual {byFieldName} value} other {#{plusSign} unusual {byFieldName} values}}'
+ }, {
+ br: '
',
+ numberOfCauses,
+ byFieldName,
// Maximum of 10 causes are stored in the record, so '10' may mean more than 10.
- contents += `
${numberOfCauses}+ unusual ${byFieldName} values`;
- }
+ plusSign: numberOfCauses < 10 ? '' : '+',
+ });
}
}
} else {
- contents += `value: ${formatValue(marker.value, config.functionDescription, fieldFormat)}`;
+ contents += intl.formatMessage({
+ id: 'xpack.ml.explorer.singleMetricChart.valueWithoutAnomalyScoreLabel',
+ defaultMessage: 'value: {value}'
+ }, {
+ value: formatValue(marker.value, config.functionDescription, fieldFormat)
+ });
}
if (_.has(marker, 'scheduledEvents')) {
- contents += `
Scheduled events:
${marker.scheduledEvents.map(mlEscape).join('
')}`;
+ contents += '
' + intl.formatMessage({
+ id: 'xpack.ml.explorer.singleMetricChart.scheduledEventsLabel',
+ defaultMessage: 'Scheduled events:{br}{scheduledEventsValue}'
+ }, {
+ br: '
',
+ scheduledEventsValue: marker.scheduledEvents.map(mlEscape).join('
')
+ });
}
mlChartTooltipService.show(contents, circle, {
@@ -418,4 +462,4 @@ export class ExplorerChartSingleMetric extends React.Component {
);
}
-}
+});
diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.test.js b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.test.js
index fd922c9805cb8..ad8a04e1af75d 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.test.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.test.js
@@ -28,7 +28,7 @@ jest.mock('ui/chrome', () => ({
}),
}));
-import { mount } from 'enzyme';
+import { mountWithIntl } from 'test_utils/enzyme_helpers';
import React from 'react';
import { ExplorerChartSingleMetric } from './explorer_chart_single_metric';
@@ -49,7 +49,7 @@ describe('ExplorerChart', () => {
afterEach(() => (SVGElement.prototype.getBBox = originalGetBBox));
test('Initialize', () => {
- const wrapper = mount(
);
// without setting any attributes and corresponding data
// the directive just ends up being empty.
@@ -63,7 +63,9 @@ describe('ExplorerChart', () => {
loading: true
};
- const wrapper = mount(
+ );
// test if the loading indicator is shown
expect(wrapper.find('.ml-loading-indicator .loading-spinner')).toHaveLength(1);
@@ -83,9 +85,9 @@ describe('ExplorerChart', () => {
};
// We create the element including a wrapper which sets the width:
- return mount(
+ return mountWithIntl(
);
}
diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_charts_container.js b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_charts_container.js
index b860a6e4f26a5..a0f87d585a632 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_charts_container.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_charts_container.js
@@ -26,10 +26,16 @@ import { ExplorerChartSingleMetric } from './explorer_chart_single_metric';
import { ExplorerChartLabel } from './components/explorer_chart_label';
import { CHART_TYPE } from '../explorer_constants';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
-const textTooManyBuckets = `This selection contains too many buckets to be displayed.
- The dashboard is best viewed over a shorter time range.`;
-const textViewButton = 'Open in Single Metric Viewer';
+const textTooManyBuckets = i18n.translate('xpack.ml.explorer.charts.tooManyBucketsDescription', {
+ defaultMessage: 'This selection contains too many buckets to be displayed.' +
+ 'The dashboard is best viewed over a shorter time range.'
+});
+const textViewButton = i18n.translate('xpack.ml.explorer.charts.openInSingleMetricViewerButtonLabel', {
+ defaultMessage: 'Open in Single Metric Viewer'
+});
// create a somewhat unique ID
// from charts metadata for React's key attribute
@@ -64,7 +70,15 @@ function ExplorerChartContainer({
if (typeof byField !== 'undefined') {
DetectorLabel = (
);
wrapLabel = true;
@@ -105,7 +119,10 @@ function ExplorerChartContainer({
size="xs"
onClick={() => window.open(getExploreSeriesLink(series), '_blank')}
>
- View
+