diff --git a/x-pack/plugins/ml/public/jobs/jobs_list/components/create_watch_flyout/create_watch_flyout.js b/x-pack/plugins/ml/public/jobs/jobs_list/components/create_watch_flyout/create_watch_flyout.js index ac432e8323d05..ab84ee7dbd795 100644 --- a/x-pack/plugins/ml/public/jobs/jobs_list/components/create_watch_flyout/create_watch_flyout.js +++ b/x-pack/plugins/ml/public/jobs/jobs_list/components/create_watch_flyout/create_watch_flyout.js @@ -26,11 +26,16 @@ import { toastNotifications } from 'ui/notify'; import { loadFullJob } from '../utils'; import { mlCreateWatchService } from '../../../../jobs/new_job/simple/components/watcher/create_watch_service'; import { CreateWatch } from '../../../../jobs/new_job/simple/components/watcher/create_watch_view'; +import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; -function getSuccessToast(id, url) { +function getSuccessToast(id, url, intl) { return { - title: `Watch ${id} created successfully`, + title: intl.formatMessage({ + id: 'xpack.ml.jobsList.createWatchFlyout.watchCreatedSuccessfullyNotificationMessage', + defaultMessage: 'Watch {id} created successfully' }, + { id } + ), text: ( @@ -41,7 +46,10 @@ function getSuccessToast(id, url) { target="_blank" iconType="link" > - Edit watch + {intl.formatMessage({ + id: 'xpack.ml.jobsList.createWatchFlyout.editWatchButtonLabel', + defaultMessage: 'Edit watch' } + )} @@ -50,7 +58,7 @@ function getSuccessToast(id, url) { }; } -export class CreateWatchFlyout extends Component { +class CreateWatchFlyoutUI extends Component { constructor(props) { super(props); @@ -95,13 +103,17 @@ export class CreateWatchFlyout extends Component { } save = () => { + const { intl } = this.props; mlCreateWatchService.createNewWatch(this.state.jobId) .then((resp) => { - toastNotifications.addSuccess(getSuccessToast(resp.id, resp.url)); + toastNotifications.addSuccess(getSuccessToast(resp.id, resp.url, intl)); this.closeFlyout(); }) .catch((error) => { - toastNotifications.addDanger(`Could not save watch`); + toastNotifications.addDanger(intl.formatMessage({ + id: 'xpack.ml.jobsList.createWatchFlyout.watchNotSavedErrorNotificationMessage', + defaultMessage: 'Could not save watch' + })); console.error(error); }); } @@ -125,7 +137,11 @@ export class CreateWatchFlyout extends Component {

- Create watch for {jobId} +

@@ -145,7 +161,10 @@ export class CreateWatchFlyout extends Component { onClick={this.closeFlyout} flush="left" > - Close + @@ -153,7 +172,10 @@ export class CreateWatchFlyout extends Component { onClick={this.save} fill > - Save + @@ -169,8 +191,9 @@ export class CreateWatchFlyout extends Component { } } -CreateWatchFlyout.propTypes = { +CreateWatchFlyoutUI.propTypes = { setShowFunction: PropTypes.func.isRequired, unsetShowFunction: PropTypes.func.isRequired, }; +export const CreateWatchFlyout = injectI18n(CreateWatchFlyoutUI); diff --git a/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/extract_job_details.js b/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/extract_job_details.js index 27aebbfa66e37..390939d33f9cc 100644 --- a/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/extract_job_details.js +++ b/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/extract_job_details.js @@ -7,6 +7,7 @@ import { detectorToString } from 'plugins/ml/util/string_utils'; import { formatValues, filterObjects } from './format_values'; +import { i18n } from '@kbn/i18n'; export function extractJobDetails(job) { @@ -15,14 +16,18 @@ export function extractJobDetails(job) { } const general = { - title: 'General', + title: i18n.translate('xpack.ml.jobsList.jobDetails.generalTitle', { + defaultMessage: 'General' + }), position: 'left', items: filterObjects(job, true).map(formatValues) }; const customUrl = { - title: 'Custom URLs', + title: i18n.translate('xpack.ml.jobsList.jobDetails.customUrlsTitle', { + defaultMessage: 'Custom URLs' + }), position: 'right', items: [] }; @@ -31,7 +36,9 @@ export function extractJobDetails(job) { } const node = { - title: 'Node', + title: i18n.translate('xpack.ml.jobsList.jobDetails.nodeTitle', { + defaultMessage: 'Node' + }), position: 'right', items: [] }; @@ -40,7 +47,9 @@ export function extractJobDetails(job) { } const detectors = { - title: 'Detectors', + title: i18n.translate('xpack.ml.jobsList.jobDetails.detectorsTitle', { + defaultMessage: 'Detectors' + }), position: 'left', items: [] }; @@ -55,31 +64,41 @@ export function extractJobDetails(job) { } const influencers = { - title: 'Influencers', + title: i18n.translate('xpack.ml.jobsList.jobDetails.influencersTitle', { + defaultMessage: 'Influencers' + }), position: 'left', items: job.analysis_config.influencers.map(i => ['', i]) }; const analysisConfig = { - title: 'Analysis config', + title: i18n.translate('xpack.ml.jobsList.jobDetails.analysisConfigTitle', { + defaultMessage: 'Analysis config' + }), position: 'left', items: filterObjects(job.analysis_config) }; const analysisLimits = { - title: 'Analysis limits', + title: i18n.translate('xpack.ml.jobsList.jobDetails.analysisLimitsTitle', { + defaultMessage: 'Analysis limits' + }), position: 'left', items: filterObjects(job.analysis_limits) }; const dataDescription = { - title: 'Data description', + title: i18n.translate('xpack.ml.jobsList.jobDetails.dataDescriptionTitle', { + defaultMessage: 'Data description' + }), position: 'right', items: filterObjects(job.data_description) }; const datafeed = { - title: 'Datafeed', + title: i18n.translate('xpack.ml.jobsList.jobDetails.datafeedTitle', { + defaultMessage: 'Datafeed' + }), position: 'left', items: filterObjects(job.datafeed_config, true, true) }; @@ -88,13 +107,17 @@ export function extractJobDetails(job) { } const counts = { - title: 'Counts', + title: i18n.translate('xpack.ml.jobsList.jobDetails.countsTitle', { + defaultMessage: 'Counts' + }), position: 'left', items: filterObjects(job.data_counts).map(formatValues) }; const modelSizeStats = { - title: 'Model size stats', + title: i18n.translate('xpack.ml.jobsList.jobDetails.modelSizeStatsTitle', { + defaultMessage: 'Model size stats' + }), position: 'right', items: filterObjects(job.model_size_stats).map(formatValues) }; diff --git a/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/forecasts_table/forecasts_table.js b/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/forecasts_table/forecasts_table.js index 157bc9ae71981..7d286612e6a3d 100644 --- a/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/forecasts_table/forecasts_table.js +++ b/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/forecasts_table/forecasts_table.js @@ -28,6 +28,7 @@ import chrome from 'ui/chrome'; import { FORECAST_REQUEST_STATE } from 'plugins/ml/../common/constants/states'; import { addItemToRecentlyAccessed } from 'plugins/ml/util/recently_accessed'; import { mlForecastService } from 'plugins/ml/services/forecast_service'; +import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; const MAX_FORECASTS = 500; const TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'; @@ -35,7 +36,7 @@ const TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'; /** * Table component for rendering the lists of forecasts run on an ML job. */ -class ForecastsTable extends Component { +class ForecastsTableUI extends Component { constructor(props) { super(props); this.state = { @@ -63,7 +64,10 @@ class ForecastsTable extends Component { console.log('Error loading list of forecasts for jobs list:', resp); this.setState({ isLoading: false, - errorMessage: 'Error loading the list of forecasts run on this job', + errorMessage: this.props.intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.forecastsTable.loadingErrorMessage', + defaultMessage: 'Error loading the list of forecasts run on this job' + }), forecasts: [] }); }); @@ -150,65 +154,110 @@ class ForecastsTable extends Component { if (forecasts.length === 0) { return ( )} iconType="iInCircle" >

- To run a forecast, - open the this.openSingleMetricView()}>Single Metric Viewer + this.openSingleMetricView()}> + + + ) + }} + />

); } + const { intl } = this.props; + const columns = [ { field: 'forecast_create_timestamp', - name: 'Created', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.forecastsTable.createdLabel', + defaultMessage: 'Created' + }), dataType: 'date', render: (date) => formatDate(date, TIME_FORMAT), sortable: true }, { field: 'forecast_start_timestamp', - name: 'From', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.forecastsTable.fromLabel', + defaultMessage: 'From' + }), dataType: 'date', render: (date) => formatDate(date, TIME_FORMAT), sortable: true }, { field: 'forecast_end_timestamp', - name: 'To', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.forecastsTable.toLabel', + defaultMessage: 'To' + }), dataType: 'date', render: (date) => formatDate(date, TIME_FORMAT), sortable: true }, { field: 'forecast_status', - name: 'Status', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.forecastsTable.statusLabel', + defaultMessage: 'Status' + }), sortable: true }, { field: 'forecast_memory_bytes', - name: 'Memory size', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.forecastsTable.memorySizeLabel', + defaultMessage: 'Memory size' + }), render: (bytes) => formatNumber(bytes, '0b'), sortable: true }, { field: 'processing_time_ms', - name: 'Processing time', - render: (ms) => `${ms} ms`, + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.forecastsTable.processingTimeLabel', + defaultMessage: 'Processing time' + }), + render: (ms) => intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.forecastsTable.msTimeUnitLabel', + defaultMessage: '{ms} ms' }, { + ms + }), sortable: true }, { field: 'forecast_expiry_timestamp', - name: 'Expires', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.forecastsTable.expiresLabel', + defaultMessage: 'Expires' + }), render: (date) => formatDate(date, TIME_FORMAT), sortable: true }, { field: 'forecast_messages', - name: 'Messages', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.forecastsTable.messagesLabel', + defaultMessage: 'Messages' + }), sortable: false, render: (messages) => { return ( @@ -221,7 +270,10 @@ class ForecastsTable extends Component { } }, { - name: 'View', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.forecastsTable.viewLabel', + defaultMessage: 'View' + }), render: (forecast) => ( this.openSingleMetricView(forecast)} @@ -247,8 +299,10 @@ class ForecastsTable extends Component { ); } } -ForecastsTable.propTypes = { +ForecastsTableUI.propTypes = { job: PropTypes.object.isRequired, }; +const ForecastsTable = injectI18n(ForecastsTableUI); + export { ForecastsTable }; diff --git a/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/job_details.js b/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/job_details.js index e51d352b10665..bfdb8fec1a907 100644 --- a/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/job_details.js +++ b/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/job_details.js @@ -21,8 +21,9 @@ import { DatafeedPreviewPane } from './datafeed_preview_tab'; import { ForecastsTable } from './forecasts_table'; import { JobDetailsPane } from './job_details_pane'; import { JobMessagesPane } from './job_messages_pane'; +import { injectI18n } from '@kbn/i18n/react'; -export class JobDetails extends Component { +class JobDetailsUI extends Component { constructor(props) { super(props); @@ -63,38 +64,64 @@ export class JobDetails extends Component { modelSizeStats } = extractJobDetails(job); + const { intl } = this.props; + const tabs = [{ id: 'job-settings', - name: 'Job settings', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.tabs.jobSettingsLabel', + defaultMessage: 'Job settings' + }), content: , time: job.open_time }, { id: 'job-config', - name: 'Job config', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.tabs.jobConfigLabel', + defaultMessage: 'Job config' + }), content: , }, { id: 'datafeed', - name: 'Datafeed', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.tabs.datafeedLabel', + defaultMessage: 'Datafeed' + }), content: , }, { id: 'counts', - name: 'Counts', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.tabs.countsLabel', + defaultMessage: 'Counts' + }), content: , }, { id: 'json', - name: 'JSON', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.tabs.jsonLabel', + defaultMessage: 'JSON' + }), content: , }, { id: 'job-messages', - name: 'Job messages', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.tabs.jobMessagesLabel', + defaultMessage: 'Job messages' + }), content: , }, { id: 'datafeed-preview', - name: 'Datafeed preview', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.tabs.datafeedPreviewLabel', + defaultMessage: 'Datafeed preview' + }), content: , }, { id: 'forecasts', - name: 'Forecasts', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.tabs.forecastsLabel', + defaultMessage: 'Forecasts' + }), content: , } ]; @@ -111,9 +138,11 @@ export class JobDetails extends Component { } } } -JobDetails.propTypes = { +JobDetailsUI.propTypes = { jobId: PropTypes.string.isRequired, job: PropTypes.object, addYourself: PropTypes.func.isRequired, removeYourself: PropTypes.func.isRequired, }; + +export const JobDetails = injectI18n(JobDetailsUI); diff --git a/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/job_messages_pane.js b/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/job_messages_pane.js index 5af8199c37b85..9cb3012242544 100644 --- a/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/job_messages_pane.js +++ b/x-pack/plugins/ml/public/jobs/jobs_list/components/job_details/job_messages_pane.js @@ -18,10 +18,11 @@ import { import { formatDate } from '@elastic/eui/lib/services/format'; import { ml } from 'plugins/ml/services/ml_api_service'; import { JobIcon } from '../job_message_icon'; +import { injectI18n } from '@kbn/i18n/react'; const TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'; -export class JobMessagesPane extends Component { +class JobMessagesPaneUI extends Component { constructor(props) { super(props); @@ -44,18 +45,28 @@ export class JobMessagesPane extends Component { render() { const { messages } = this.state; + const { intl } = this.props; const columns = [{ name: '', render: item => () }, { - name: 'Time', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.messagesPane.timeLabel', + defaultMessage: 'Time' + }), render: item => formatDate(item.timestamp, TIME_FORMAT) }, { field: 'node_name', - name: 'Node', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.messagesPane.nodeLabel', + defaultMessage: 'Node' + }), }, { field: 'message', - name: 'Message', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.messagesPane.messageLabel', + defaultMessage: 'Message' + }), } ]; return ( @@ -71,7 +82,8 @@ export class JobMessagesPane extends Component { ); } } -JobMessagesPane.propTypes = { +JobMessagesPaneUI.propTypes = { job: PropTypes.object.isRequired, }; +export const JobMessagesPane = injectI18n(JobMessagesPaneUI); diff --git a/x-pack/plugins/ml/public/jobs/jobs_list/components/job_filter_bar/job_filter_bar.js b/x-pack/plugins/ml/public/jobs/jobs_list/components/job_filter_bar/job_filter_bar.js index 189af8900df6d..d53bd5d895613 100644 --- a/x-pack/plugins/ml/public/jobs/jobs_list/components/job_filter_bar/job_filter_bar.js +++ b/x-pack/plugins/ml/public/jobs/jobs_list/components/job_filter_bar/job_filter_bar.js @@ -20,6 +20,7 @@ import { EuiFlexGroup, EuiFlexItem, } from '@elastic/eui'; +import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; function loadGroups() { return ml.jobs.groups() @@ -28,7 +29,14 @@ function loadGroups() { value: g.id, view: (
- ({g.jobIds.length} job{(g.jobIds.length === 1) ? '' : 's'}) +   + + +
) })); @@ -39,7 +47,7 @@ function loadGroups() { }); } -export class JobFilterBar extends Component { +class JobFilterBarUI extends Component { constructor(props) { super(props); @@ -69,7 +77,12 @@ export class JobFilterBar extends Component { + )} /> @@ -77,6 +90,7 @@ export class JobFilterBar extends Component { } render() { + const { intl } = this.props; const filters = [ { type: 'field_value_toggle_group', @@ -84,15 +98,24 @@ export class JobFilterBar extends Component { items: [ { value: 'opened', - name: 'Opened' + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobFilterBar.openedLabel', + defaultMessage: 'Opened' + }) }, { value: 'closed', - name: 'Closed' + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobFilterBar.closedLabel', + defaultMessage: 'Closed' + }) }, { value: 'failed', - name: 'Failed' + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobFilterBar.failedLabel', + defaultMessage: 'Failed' + }) } ] }, @@ -102,18 +125,27 @@ export class JobFilterBar extends Component { items: [ { value: 'started', - name: 'Started' + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobFilterBar.startedLabel', + defaultMessage: 'Started' + }) }, { value: 'stopped', - name: 'Stopped' + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobFilterBar.stoppedLabel', + defaultMessage: 'Stopped' + }) } ] }, { type: 'field_value_selection', field: 'groups', - name: 'Group', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobFilterBar.groupLabel', + defaultMessage: 'Group' + }), multiSelect: 'or', cache: 10000, options: () => loadGroups() @@ -138,7 +170,8 @@ export class JobFilterBar extends Component { ); } } -JobFilterBar.propTypes = { +JobFilterBarUI.propTypes = { setFilters: PropTypes.func.isRequired, }; +export const JobFilterBar = injectI18n(JobFilterBarUI); diff --git a/x-pack/plugins/ml/public/jobs/jobs_list/components/utils.js b/x-pack/plugins/ml/public/jobs/jobs_list/components/utils.js index e34683f263261..173daf41c4b00 100644 --- a/x-pack/plugins/ml/public/jobs/jobs_list/components/utils.js +++ b/x-pack/plugins/ml/public/jobs/jobs_list/components/utils.js @@ -11,6 +11,7 @@ import { mlMessageBarService } from 'plugins/ml/components/messagebar/messagebar import { mlJobService } from 'plugins/ml/services/job_service'; import { ml } from 'plugins/ml/services/ml_api_service'; import { JOB_STATE, DATAFEED_STATE } from 'plugins/ml/../common/constants/states'; +import { i18n } from '@kbn/i18n'; export function loadFullJob(jobId) { return new Promise((resolve, reject) => { @@ -49,7 +50,9 @@ export function forceStartDatafeeds(jobs, start, end, finish = () => {}) { }) .catch((error) => { mlMessageBarService.notify.error(error); - toastNotifications.addDanger(`Jobs failed to start`, error); + toastNotifications.addDanger(i18n.translate('xpack.ml.jobsList.startJobErrorMessage', { + defaultMessage: 'Jobs failed to start' + }), error); finish(); }); } @@ -64,7 +67,9 @@ export function stopDatafeeds(jobs, finish = () => {}) { }) .catch((error) => { mlMessageBarService.notify.error(error); - toastNotifications.addDanger(`Jobs failed to stop`, error); + toastNotifications.addDanger(i18n.translate('xpack.ml.jobsList.stopJobErrorMessage', { + defaultMessage: 'Jobs failed to stop' + }), error); finish(); }); } @@ -87,30 +92,54 @@ function showResults(resp, action) { let actionText = ''; let actionTextPT = ''; if (action === DATAFEED_STATE.STARTED) { - actionText = 'start'; - actionTextPT = 'started'; + actionText = i18n.translate('xpack.ml.jobsList.startActionStatusText', { + defaultMessage: 'start' + }); + actionTextPT = i18n.translate('xpack.ml.jobsList.startedActionStatusText', { + defaultMessage: 'started' + }); } else if (action === DATAFEED_STATE.STOPPED) { - actionText = 'stop'; - actionTextPT = 'stopped'; + actionText = i18n.translate('xpack.ml.jobsList.stopActionStatusText', { + defaultMessage: 'stop' + }); + actionTextPT = i18n.translate('xpack.ml.jobsList.stoppedActionStatusText', { + defaultMessage: 'stopped' + }); } else if (action === DATAFEED_STATE.DELETED) { - actionText = 'delete'; - actionTextPT = 'deleted'; + actionText = i18n.translate('xpack.ml.jobsList.deleteActionStatusText', { + defaultMessage: 'delete' + }); + actionTextPT = i18n.translate('xpack.ml.jobsList.deletedActionStatusText', { + defaultMessage: 'deleted' + }); } else if (action === JOB_STATE.CLOSED) { - actionText = 'close'; - actionTextPT = 'closed'; + actionText = i18n.translate('xpack.ml.jobsList.closeActionStatusText', { + defaultMessage: 'close' + }); + actionTextPT = i18n.translate('xpack.ml.jobsList.closedActionStatusText', { + defaultMessage: 'closed' + }); } - - if (successes.length > 1) { - toastNotifications.addSuccess(`${successes.length} jobs ${actionTextPT} successfully`); - } else if (successes.length === 1) { - toastNotifications.addSuccess(`${successes[0]} ${actionTextPT} successfully`); - } + toastNotifications.addSuccess(i18n.translate('xpack.ml.jobsList.actionExecuteSuccessfullyNotificationMessage', { + defaultMessage: '{successesJobsCount, plural, one{{successJob}} other{# jobs}} {actionTextPT} successfully', + values: { + successesJobsCount: successes.length, + successJob: successes[0], + actionTextPT + } + })); if (failures.length > 0) { failures.forEach((f) => { mlMessageBarService.notify.error(f.result.error); - toastNotifications.addDanger(`${f.id} failed to ${actionText}`); + toastNotifications.addDanger(i18n.translate('xpack.ml.jobsList.actionFailedNotificationMessage', { + defaultMessage: '{failureId} failed to {actionText}', + values: { + failureId: f.id, + actionText + } + })); }); } } @@ -123,7 +152,10 @@ export function cloneJob(jobId) { }) .catch((error) => { mlMessageBarService.notify.error(error); - toastNotifications.addDanger(`Could not clone ${jobId}. Job could not be found`); + toastNotifications.addDanger(i18n.translate('xpack.ml.jobsList.cloneJobErrorMessage', { + defaultMessage: 'Could not clone {jobId}. Job could not be found', + values: { jobId } + })); }); } @@ -136,7 +168,9 @@ export function closeJobs(jobs, finish = () => {}) { }) .catch((error) => { mlMessageBarService.notify.error(error); - toastNotifications.addDanger(`Jobs failed to close`, error); + toastNotifications.addDanger(i18n.translate('xpack.ml.jobsList.closeJobErrorMessage', { + defaultMessage: 'Jobs failed to close', + }), error); finish(); }); } @@ -150,7 +184,9 @@ export function deleteJobs(jobs, finish = () => {}) { }) .catch((error) => { mlMessageBarService.notify.error(error); - toastNotifications.addDanger(`Jobs failed to delete`, error); + toastNotifications.addDanger(i18n.translate('xpack.ml.jobsList.deleteJobErrorMessage', { + defaultMessage: 'Jobs failed to delete', + }), error); finish(); }); }