From fa9954850352807efae1b3e0bcdb1165e3d6c5db Mon Sep 17 00:00:00 2001 From: Alexandr Ogarkov Date: Mon, 12 Nov 2018 17:12:00 +0300 Subject: [PATCH] Translate ml -> jobs - jobs-list(part_2) --- .i18nrc.json | 1 + .../create_watch_flyout.js | 44 +++++++--- .../job_details/extract_job_details.js | 45 +++++++--- .../forecasts_table/forecasts_table.js | 86 +++++++++++++++---- .../components/job_details/job_details.js | 49 ++++++++--- .../job_details/job_messages_pane.js | 22 +++-- .../job_filter_bar/job_filter_bar.js | 53 +++++++++--- .../public/jobs/jobs_list/components/utils.js | 76 +++++++++++----- .../ml/public/jobs/jobs_list/directive.js | 3 +- 9 files changed, 296 insertions(+), 83 deletions(-) diff --git a/.i18nrc.json b/.i18nrc.json index de532fdb60984..494652ce914e8 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -16,6 +16,7 @@ "xpack.grokDebugger": "x-pack/plugins/grokdebugger", "xpack.idxMgmt": "x-pack/plugins/index_management", "xpack.licenseMgmt": "x-pack/plugins/license_management", + "xpack.ml": "x-pack/plugins/ml", "xpack.rollupJobs": "x-pack/plugins/rollup", "xpack.searchProfiler": "x-pack/plugins/searchprofiler", "xpack.security": "x-pack/plugins/security", 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..165a18400edb1 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,10 @@ 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..97e16ded38584 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.jobDetail.generalTitle', { + defaultMessage: 'General' + }), position: 'left', items: filterObjects(job, true).map(formatValues) }; const customUrl = { - title: 'Custom URLs', + title: i18n.translate('xpack.ml.jobsList.jobDetail.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.jobDetail.nodeTitle', { + defaultMessage: 'Node' + }), position: 'right', items: [] }; @@ -40,7 +47,9 @@ export function extractJobDetails(job) { } const detectors = { - title: 'Detectors', + title: i18n.translate('xpack.ml.jobsList.jobDetail.detectorsTitle', { + defaultMessage: 'Detectors' + }), position: 'left', items: [] }; @@ -55,31 +64,41 @@ export function extractJobDetails(job) { } const influencers = { - title: 'Influencers', + title: i18n.translate('xpack.ml.jobsList.jobDetail.influencersTitle', { + defaultMessage: 'Influencers' + }), position: 'left', items: job.analysis_config.influencers.map(i => ['', i]) }; const analysisConfig = { - title: 'Analysis config', + title: i18n.translate('xpack.ml.jobsList.jobDetail.analysisConfigTitle', { + defaultMessage: 'Analysis config' + }), position: 'left', items: filterObjects(job.analysis_config) }; const analysisLimits = { - title: 'Analysis limits', + title: i18n.translate('xpack.ml.jobsList.jobDetail.analysisLimitsTitle', { + defaultMessage: 'Analysis limits' + }), position: 'left', items: filterObjects(job.analysis_limits) }; const dataDescription = { - title: 'Data description', + title: i18n.translate('xpack.ml.jobsList.jobDetail.dataDescriptionTitle', { + defaultMessage: 'Data description' + }), position: 'right', items: filterObjects(job.data_description) }; const datafeed = { - title: 'Datafeed', + title: i18n.translate('xpack.ml.jobsList.jobDetail.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.jobDetail.countsTitle', { + defaultMessage: 'Counts' + }), position: 'left', items: filterObjects(job.data_counts).map(formatValues) }; const modelSizeStats = { - title: 'Model size stats', + title: i18n.translate('xpack.ml.jobsList.jobDetail.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 ed58e884162cd..95691f8955f78 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 @@ -29,6 +29,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'; @@ -36,7 +37,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 = { @@ -64,7 +65,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: [] }); }); @@ -151,65 +155,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 ( @@ -222,7 +271,10 @@ class ForecastsTable extends Component { } }, { - name: 'View', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.forecastsTable.viewLabel', + defaultMessage: 'View' + }), render: (forecast) => ( this.openSingleMetricView(forecast)} @@ -248,8 +300,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 7d6fcff7e4299..1592cfef74cc3 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 @@ -23,8 +23,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); @@ -65,38 +66,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.jobSettingsLabel', + defaultMessage: 'Job settings' + }), content: , time: job.open_time }, { id: 'job-config', - name: 'Job config', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.jobConfigLabel', + defaultMessage: 'Job config' + }), content: , }, { id: 'datafeed', - name: 'Datafeed', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.datafeedLabel', + defaultMessage: 'Datafeed' + }), content: , }, { id: 'counts', - name: 'Counts', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.countsLabel', + defaultMessage: 'Counts' + }), content: , }, { id: 'json', - name: 'JSON', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.jsonLabel', + defaultMessage: 'JSON' + }), content: , }, { id: 'job-messages', - name: 'Job messages', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.jobMessagesLabel', + defaultMessage: 'Job messages' + }), content: , }, { id: 'datafeed-preview', - name: 'Datafeed preview', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.datafeedPreviewLabel', + defaultMessage: 'Datafeed preview' + }), content: , }, { id: 'forecasts', - name: 'Forecasts', + name: intl.formatMessage({ + id: 'xpack.ml.jobsList.jobDetails.forecastsLabel', + defaultMessage: 'Forecasts' + }), content: , } ]; @@ -113,9 +140,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 e2624df92b368..1dd5ee44cdfa9 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 @@ -22,6 +22,7 @@ import { EuiFlexGroup, EuiFlexItem, } from '@elastic/eui'; +import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; function loadGroups() { return ml.jobs.groups() @@ -30,7 +31,14 @@ function loadGroups() { value: g.id, view: (
- ({g.jobIds.length} job{(g.jobIds.length === 1) ? '' : 's'}) + + + +
) })); @@ -41,7 +49,7 @@ function loadGroups() { }); } -export class JobFilterBar extends Component { +class JobFilterBarUI extends Component { constructor(props) { super(props); @@ -71,7 +79,12 @@ export class JobFilterBar extends Component { + )} /> @@ -79,6 +92,7 @@ export class JobFilterBar extends Component { } render() { + const { intl } = this.props; const filters = [ { type: 'field_value_toggle_group', @@ -86,15 +100,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' + }) } ] }, @@ -104,18 +127,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() @@ -139,7 +171,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..6811981eae00f 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: 'stop' + }); + actionTextPT = i18n.translate('xpack.ml.jobsList.closedActionStatusText', { + defaultMessage: 'stop' + }); } - - 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(); }); } diff --git a/x-pack/plugins/ml/public/jobs/jobs_list/directive.js b/x-pack/plugins/ml/public/jobs/jobs_list/directive.js index 84164c5213e70..030524baff642 100644 --- a/x-pack/plugins/ml/public/jobs/jobs_list/directive.js +++ b/x-pack/plugins/ml/public/jobs/jobs_list/directive.js @@ -34,6 +34,7 @@ uiRoutes }); import { JobsPage } from './jobs'; +import { I18nProvider } from '@kbn/i18n/react'; module.directive('jobsPage', function () { return { @@ -41,7 +42,7 @@ module.directive('jobsPage', function () { restrict: 'E', link: (scope, element) => { ReactDOM.render( - React.createElement(JobsPage), + {React.createElement(JobsPage)}, element[0] ); }