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] Localize ml components ( part 2 - job picker ) #27958

Closed
wants to merge 2 commits into from
Closed
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
@@ -1,14 +1,17 @@
<div style='display: flex;' class="ml-job-select-btn-container">
<div class="ml-job-select-btn-label">Job</div>
<div class="ml-job-select-btn-label"
i18n-id="xpack.ml.jobSelectList.menuButtonLabel"
i18n-default-message="Job"
></div>
<div style="flex:0 0 auto;">
<div popover-placement="bottom"
popover-placement="bottom"
popover-html-unsafe="{{unsafeHtml}}"
popover-append-to-body="false"
popover-trigger="click"
class="ml-job-select-btn"
tooltip="{{description.txt}} selected"
aria-label="Job selection menu"
tooltip="{{ ::'xpack.ml.jobSelectList.menuButtonTooltip' | i18n: { defaultMessage: '{descriptionText} selected', values: {descriptionText: description.txt} } }}"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason descriptionText: description.txt is not binding to the UI (returns empty string).

Copy link
Contributor

@pavel06081991 pavel06081991 Jan 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that is because you use one time binding operator ::. When you pass some variable to values then you must not use one time binding

aria-label="{{ ::'xpack.ml.jobSelectList.menuButtonAriaLabel' | i18n: {defaultMessage: 'Job selection menu'} }}"
ng-click='createMenu()'
kbn-accessible-click>
<span class="ml-job-select-btn-text">{{description.txt}}</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
<div class='ml-job-selector'>
<div class="header">
Job Selection
</div>
<h1
class="header"
i18n-id="xpack.ml.jobSelectListTitle"
i18n-default-message="Job Selection"
></h1>

<ml-loading-indicator
label="Loading jobs"
label="{{ ::'xpack.ml.jobSelectList.loadingLabel' | i18n: {defaultMessage: 'Loading jobs'} }}"
is-loading="noJobsCreated===undefined"
/>
<div class="select-list" ng-show='noJobsCreated!==undefined'>
<div ng-if="groups.length && singleSelection !== true">
<div class="list-section-title">
<h2 class="list-section-title">
<input
ng-if="singleSelection !== true"
type="checkbox"
ng-checked="allGroupsSelected"
aria-label="Select all groups checkbox. Total count {{selected.groups.length}}."
aria-label="{{ ::'xpack.ml.jobSelectList.groups.selectAllAriaLabel' | i18n: {defaultMessage: 'Select all groups checkbox. Total count {groupsCount}.', values: { groupsCount: selected.groups.length} } }}"
ng-click="toggleAllGroupsSelection()" />
Groups
</div>
<span
i18n-id="xpack.ml.jobSelectList.groupsTitle"
i18n-default-message="Groups">
</span>
</h2>
<div class="list-section">
<div class='group' ng-repeat="group in selected.groups">
<div class='group-title job-row'>
<div class="job-row-inner">
<label class="kuiFormLabel">
<div >
<input
aria-label="Group ID {{group.id}}"
aria-label="{{ ::'xpack.ml.jobSelectList.groups.idAriaLabel' | i18n: {defaultMessage: 'Group ID {groupId}', values: { groupId: group.id} } }}"
ng-if="singleSelection !== true && group.selectable === true" type="checkbox"
ng-model="group.selected"
ng-click="toggleGroupSelection()" />
Expand All @@ -39,6 +44,7 @@
class='gant-bar'
ng-class="{'disabled-job': job.disabled, 'gant-bar-running': job.running}"
tooltip='{{group.timeRange.label}}'
aria-label="{{ ::'xpack.ml.jobSelectList.groups.gantBarAriaLabel' | i18n: {defaultMessage: 'time range {timeRangeLabel}', values: { timeRangeLabel: group.timeRange.label} } }}"
tooltip-placement="bottom"
tooltip-append-to-body="true"
ng-attr-style='margin-left:{{group.timeRange.fromPx}}px; width: {{group.timeRange.widthPx}}px;'>
Expand All @@ -51,13 +57,16 @@
</div>
</div>

<div class="list-section-title" ng-if="singleSelection !== true">
<h2 class="list-section-title" ng-if="singleSelection !== true">
<input type="checkbox"
ng-checked="allJobsSelected"
aria-label="Select all jobs checkbox. Total count {{selected.jobs.length}}."
aria-label="{{ ::'xpack.ml.jobSelectList.jobs.selectAllAriaLabel' | i18n: {defaultMessage: 'Select all jobs checkbox. Total count {jobsCount}.', values: { jobsCount: selected.jobs.length} } }}"
ng-click="toggleAllJobsSelection()" />
Jobs
</div>
<span
i18n-id="xpack.ml.jobSelectList.jobsTitle"
i18n-default-message="Jobs">
</span>
</h2>
<div class="list-section" ng-class="{'list-section-single': singleSelection}">
<div class='job-row' ng-repeat="job in selected.jobs">
<div class='job-row-inner'>
Expand All @@ -73,7 +82,11 @@
value="{{job.id}}"
ng-model="$parent.$parent.selectedJobRadio"
ng-disabled='job.disabled' />
<span ng-class="{'disabled-job': job.disabled}" aria-label="Job ID {{job.id}}">{{job.id}}</span>
<span ng-class="{'disabled-job': job.disabled}"
aria-label="{{ ::'xpack.ml.jobSelectList.jobs.idAriaLabel' | i18n: {defaultMessage: 'Job ID {jobId}', values: { jobId: job.id} } }}"
>
{{job.id}}
</span>
</span>
</div>
<div>
Expand All @@ -82,13 +95,12 @@
</div>
<div
class='gant-bar'
aria-label="time range {{job.timeRange.label}}"
aria-label="{{ ::'xpack.ml.jobSelectList.jobs.gantBarAriaLabel' | i18n: {defaultMessage: 'time range {timeRangeLabel}', values: { timeRangeLabel: job.timeRange.label} } }}"
ng-class="{'disabled-job': job.disabled, 'gant-bar-running': job.running}"
tooltip='{{job.timeRange.label}}'
tooltip-placement="bottom"
tooltip-append-to-body="true"
ng-attr-style='margin-left:{{job.timeRange.fromPx}}px; width: {{job.timeRange.widthPx}}px;'>

</div>
</div>
</label>
Expand All @@ -97,24 +109,38 @@
</div>
</div>


<div class='footer'>
<button
ng-click="apply()"
class="kuiButton kuiButton--primary"
aria-label="Apply"
aria-label="{{ ::'xpack.ml.jobSelectList.applyButtonAriaLabel' | i18n: {defaultMessage: 'Apply'} }}"
ng-disabled="selectedCount===0"
>
Apply
<span
i18n-id="xpack.ml.jobSelectList.applyButtonLabel"
i18n-default-message="Apply">
</span>
</button>
<button
ng-click="closePopover()"
class="kuiButton kuiButton--primary"
aria-label="{{ ::'xpack.ml.jobSelectList.cancelButtonAriaLabel' | i18n: {defaultMessage: 'Cancel'} }}"
>
<span
i18n-id="xpack.ml.jobSelectList.cancelButtonLabel"
i18n-default-message="Cancel">
</span>
</button>
<button ng-click="closePopover()" class="kuiButton kuiButton--primary" aria-label="Cancel">Cancel</button>
</div>

<div class='apply-time-range'>
<label class="kuiFormLabel">
<input type="checkbox"
ng-model="applyTimeRange"/>
Also apply time range
<span
i18n-id="xpack.ml.jobSelectList.applyTimeRangeLabel"
i18n-default-message="Also apply time range">
</span>
</label>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { timefilter } from 'ui/timefilter';
import { uiModules } from 'ui/modules';
const module = uiModules.get('apps/ml');

module.directive('mlJobSelectList', function (Private) {
module.directive('mlJobSelectList', function (Private, i18n) {
return {
restrict: 'AE',
replace: true,
Expand Down Expand Up @@ -206,9 +206,20 @@ module.directive('mlJobSelectList', function (Private) {
timeRange.toMoment = moment(timeRange.to);
timeRange.fromMoment = moment(timeRange.from);

const fromString = timeRange.fromMoment.format('MMM Do YYYY, HH:mm');
const toString = timeRange.toMoment.format('MMM Do YYYY, HH:mm');
timeRange.label = `${fromString} to ${toString}`;
const fromStringMomentFormat = i18n('xpack.ml.jobSelectList.groups.timeRange.fromStringMomentFormat', {
defaultMessage: 'MMM Do YYYY, HH:mm',
});
const fromString = timeRange.fromMoment.format(fromStringMomentFormat);

const toStringMomentFormat = i18n('xpack.ml.jobSelectList.groups.timeRange.toStringMomentFormat', {
defaultMessage: 'MMM Do YYYY, HH:mm',
});
const toString = timeRange.toMoment.format(toStringMomentFormat);

timeRange.label = i18n('xpack.ml.jobSelectList.groups.timeRangeLabel', {
defaultMessage: '{fromString} to {toString}',
values: { fromString, toString }
});

group.timeRange = timeRange;
return group;
Expand Down Expand Up @@ -354,9 +365,20 @@ module.directive('mlJobSelectList', function (Private) {
job.timeRange.toMoment = moment(job.timeRange.to);
job.timeRange.fromMoment = moment(job.timeRange.from);

const fromString = job.timeRange.fromMoment.format('MMM Do YYYY, HH:mm');
const toString = job.timeRange.toMoment.format('MMM Do YYYY, HH:mm');
job.timeRange.label = `${fromString} to ${toString}`;
const fromStringMomentFormat = i18n('xpack.ml.jobSelectList.jobs.timeRange.fromStringMomentFormat', {
defaultMessage: 'MMM Do YYYY, HH:mm',
});
const fromString = job.timeRange.fromMoment.format(fromStringMomentFormat);

const toStringMomentFormat = i18n('xpack.ml.jobSelectList.jobs.timeRange.toStringMomentFormat', {
defaultMessage: 'MMM Do YYYY, HH:mm',
});
const toString = job.timeRange.toMoment.format(toStringMomentFormat);

job.timeRange.label = i18n('xpack.ml.jobSelectList.jobs.timeRangeLabel', {
defaultMessage: '{fromString} to {toString}',
values: { fromString, toString }
});
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import { mlJobService } from 'plugins/ml/services/job_service';

let jobSelectService = undefined;

export function JobSelectServiceProvider($rootScope, globalState) {

export function JobSelectServiceProvider($rootScope, globalState, i18n) {
function checkGlobalState() {
if (globalState.ml === undefined) {
globalState.ml = {};
Expand All @@ -42,7 +41,9 @@ export function JobSelectServiceProvider($rootScope, globalState) {

// if there are no valid ids, warn and then select the first job
if (validIds.length === 0) {
const warningText = `No jobs selected, auto selecting first job`;
const warningText = i18n('xpack.ml.jobSelectList.noJobsSelectedToast', {
defaultMessage: 'No jobs selected, auto selecting first job',
});
toastNotifications.addWarning(warningText);

if (mlJobService.jobs.length) {
Expand Down Expand Up @@ -89,8 +90,14 @@ export function JobSelectServiceProvider($rootScope, globalState) {

function warnAboutInvalidJobIds(invalidIds) {
if (invalidIds.length > 0) {
const warningText = (invalidIds.length === 1) ? `Requested job ${invalidIds} does not exist` :
`Requested jobs ${invalidIds} do not exist`;
const warningText = i18n('xpack.ml.jobSelectList.invalidJobIdToast', {
defaultMessage: 'Requested {invalidIdsLength, plural, one {job} other {jobs}} {invalidIds} does not exist',
values: {
invalidIds: invalidIds,
invalidIdsLength: invalidIds.length,
}
});

toastNotifications.addWarning(warningText);
}
}
Expand All @@ -102,7 +109,9 @@ export function JobSelectServiceProvider($rootScope, globalState) {
return sum + ((job.groups === undefined) ? 1 : job.groups.length);
}, 0);
if (jobs.length === count) {
txt = 'All jobs';
txt = i18n('xpack.ml.jobSelectList.menu.description.allJobs', {
defaultMessage: 'All jobs',
});
} else {
// not all jobs have been selected
// add up how many jobs belong to groups and how many don't
Expand Down Expand Up @@ -134,16 +143,31 @@ export function JobSelectServiceProvider($rootScope, globalState) {

// show the whole groups first
if (wholeGroups.length) {
txt = wholeGroups[0];
const wholeGroupsTxt = wholeGroups[0];
txt = wholeGroupsTxt;
if (wholeGroups.length > 1 || groupLessJobs > 0) {
const total = (wholeGroups.length - 1) + groupLessJobs;
txt += ` and ${total} other${(total > 1 ? 's' : '')}`;
txt = i18n('xpack.ml.jobSelectList.menu.description.wholeGroupsWithOthers', {
defaultMessage: '{wholeGroups} and {remainingGroups} {remainingGroups, plural, one {other} other {others}}',
values: {
wholeGroups: wholeGroupsTxt,
remainingGroups: total
}
});
}
} else {
// otherwise just list the job ids
txt = splitJobId(jobs[0]).job;
const jobsListText = splitJobId(jobs[0]).job;
txt = jobsListText;
if (jobs.length > 1) {
txt += ` and ${jobs.length - 1} other${(jobs.length > 2 ? 's' : '')}`;
txt = i18n('xpack.ml.jobSelectList.menu.description.jobsListWithOthers', {
defaultMessage: '{jobsList} and {remainingJobs} { jobsLength, plural, one {other} two {other} other {others} }',
values: {
jobsList: jobsListText,
jobsLength: jobs.length,
remainingJobs: jobs.length - 1,
}
});
}
}
}
Expand Down