diff --git a/NOTICE.txt b/NOTICE.txt
index 23def5d32730..d1903a471341 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -4,32 +4,6 @@ Copyright 2012-2019 Elasticsearch B.V.
---
This product has relied on ASTExplorer that is licensed under MIT.
----
-This product includes code that was extracted from angular-ui-bootstrap@0.13.1
-which is available under an "MIT" license
-
-The MIT License
-
-Copyright (c) 2012-2016 the AngularUI Team, http://angular-ui.github.io/bootstrap/
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
---
This product uses Noto fonts that are licensed under the SIL Open
Font License, Version 1.1.
diff --git a/x-pack/plugins/ml/public/app.js b/x-pack/plugins/ml/public/app.js
index 16d0f877a6a4..f5f36bffbba3 100644
--- a/x-pack/plugins/ml/public/app.js
+++ b/x-pack/plugins/ml/public/app.js
@@ -16,7 +16,6 @@ import 'ui/autoload/all';
import 'ui/kbn_top_nav';
import 'plugins/ml/access_denied';
-import 'plugins/ml/lib/angular_bootstrap_patch';
import 'plugins/ml/jobs';
import 'plugins/ml/services/calendar_service';
import 'plugins/ml/components/messagebar';
diff --git a/x-pack/plugins/ml/public/components/job_select_list/_index.scss b/x-pack/plugins/ml/public/components/job_select_list/_index.scss
deleted file mode 100644
index 800524055a68..000000000000
--- a/x-pack/plugins/ml/public/components/job_select_list/_index.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import 'job_select_list';
\ No newline at end of file
diff --git a/x-pack/plugins/ml/public/components/job_select_list/_job_select_list.scss b/x-pack/plugins/ml/public/components/job_select_list/_job_select_list.scss
deleted file mode 100644
index 5dc70430d4db..000000000000
--- a/x-pack/plugins/ml/public/components/job_select_list/_job_select_list.scss
+++ /dev/null
@@ -1,343 +0,0 @@
-// SASSTODO: This file needs a rewrite. Needs to be variablized and have actual calculations rather than pixels.
-// Lots of custom colors in here need to be replaced.
-
-// SASSTODO: EXTREMELY DANGEROUS OVERWRITE
-// Little worried about touching it now
-navbar {
- padding: 10px;
- background-color: #EFF0F1;
-}
-
-// SASSTODO: EXTREMELY DANGEROUS OVERWRITE
-// Little worried about touching it now
-navbar button[disabled] {
- color: #FFF;
- background-color: #0079a5;
-}
-
-.ml-job-selector {
- margin: -9px -14px;
-
- .header {
- padding: 9px 14px;
- border-bottom: 1px solid #eeeeee;
- }
- .footer {
- text-align: center;
- padding: 9px;
- border-top: 1px solid #eee;
-
- .kuiButton--primary:focus {
- background-color: #0079a5;
- }
- }
-
- .select-all-controls {
- margin-bottom: 0px;
- padding-bottom: 4px;
- border-bottom: 1px solid #eee;
- & > div {
- width: 280px;
- display: inline-block;
- font-weight: bold;
- }
- }
-
- // SASSTODO: Replace with proper selector
- hr {
- margin: 2px 0px;
- }
-
- // SASSTODO: Replace with proper selector
- label {
- margin-bottom: 0px;
- font-weight: normal;
- }
-
- // SASSTODO: Replace with proper selector
- input {
- margin-right: 4px;
- margin-left: 4px;
- }
-
- .apply-time-range {
- margin-top: 16px;
- position: absolute;
- right: 16px;
- bottom: 12px;
-
- // SASSTODO: Replace with proper selector
- input {
- margin-right: 0px;
- }
- }
-
- .select-list {
- max-height: 400px;
- overflow-y: auto;
- overflow-x: hidden;
-
- background-color: #F5F7FA;
-
- .list-section-title {
- margin: 14px;
- margin-bottom: 5px;
- }
-
- .list-section {
- border: 1px solid #e0e0e0;
- background-color: #ffffff;
- margin: 14px;
- margin-top: 5px;
- padding: 10px;
- border-radius: 3px;
- }
- .list-section-single {
- margin: -1px;
- border-radius: 0px;
- border: 0px;
- }
-
- .group-title {
- border-left: none;
- border-right: none;
- .expand-group-button {
- padding-right: 2px;
- width: 20px;
- }
- }
-
- .job-row {
- white-space: nowrap;
- vertical-align: top;
-
- .use-time-range {
- margin-top: 4px;
- }
-
- .job-row-inner {
- display: inline-block;
- font-size: 13px;
- font-weight: normal;
- color: #444444;
- white-space: nowrap;
-
- margin: 0px;
- padding: 0px;
- line-height: 20px;
-
- // SASSTODO: Replace with proper selector
- & > label > div {
- width: 280px;
- display: inline-block;
- vertical-align: top;
- height: 30px;
- padding-top: 6px;
- overflow: hidden;
- text-overflow: ellipsis;
- padding-right: 4px;
-
- .disabled-job {
- color: #cccccc;
- }
- }
-
- // SASSTODO: Replace with proper selector
- & > label > div:nth-child(2) {
- width: 310px;
- border-left: 1px solid #eee;
- border-right: 1px solid #eee;
- padding-left: 4px;
- padding-top: 6px;
- margin-left: -3px;
-
- .disabled-job {
- background-color: #cccccc;
- }
- }
-
- .job-in-group {
- padding-left: 10px;
- }
- }
-
- .button-container {
- display: inline-block;
- vertical-align: top;
- padding-right: 2px;
- }
-
- .gant-bar {
- background-color: #79adda;
- height: 14px;
- border-radius: 2px;
- }
-
- // SASSTODO: This needs to be rebuilt
- .gant-bar-running {
- background-image:-webkit-gradient(linear,
- 0 100%, 100% 0,
- color-stop(0.25, rgba(255, 255, 255, 0.15)),
- color-stop(0.25, transparent),
- color-stop(0.5, transparent),
- color-stop(0.5, rgba(255, 255, 255, 0.15)),
- color-stop(0.75, rgba(255, 255, 255, 0.15)),
- color-stop(0.75, transparent),
- to(transparent));
- background-image:-webkit-linear-gradient(45deg,
- rgba(255, 255, 255, 0.15) 25%,
- transparent 25%, transparent 50%,
- rgba(255, 255, 255, 0.15) 50%,
- rgba(255, 255, 255, 0.15) 75%,
- transparent 75%,
- transparent);
- background-image:-moz-linear-gradient(45deg,
- rgba(255, 255, 255, 0.15) 25%,
- transparent 25%,
- transparent 50%,
- rgba(255, 255, 255, 0.15) 50%,
- rgba(255, 255, 255, 0.15) 75%,
- transparent 75%,
- transparent);
- background-image:-o-linear-gradient(45deg,
- rgba(255, 255, 255, 0.15) 25%,
- transparent 25%,
- transparent 50%,
- rgba(255, 255, 255, 0.15) 50%,
- rgba(255, 255, 255, 0.15) 75%,
- transparent 75%,
- transparent);
- background-image:linear-gradient(45deg,
- rgba(255, 255, 255, 0.15) 25%,
- transparent 25%,
- transparent 50%,
- rgba(255, 255, 255, 0.15) 50%,
- rgba(255, 255, 255, 0.15) 75%,
- transparent 75%,
- transparent);
- -webkit-background-size:40px 40px;
- -moz-background-size:40px 40px;
- -o-background-size:40px 40px;
- background-size:40px 40px;
-
- -webkit-animation:progress-bar-stripes 2s linear infinite;
- -moz-animation:progress-bar-stripes 2s linear infinite;
- -ms-animation:progress-bar-stripes 2s linear infinite;
- -o-animation:progress-bar-stripes 2s linear infinite;
- animation:progress-bar-stripes 2s linear infinite;
- }
-
- .gant-back-edge {
- height: 18px;
- border-left: 1px solid #d6d6d6;
- border-right: 1px solid #d6d6d6;
- margin-bottom: -16px;
- padding-top: 9px;
-
- // SASSTODO: Needs a poper selector
- div {
- height: 1px;
- border-top: 1px dashed #d6d6d6;
- }
- }
- }
- .job-row:hover {
- .job-row-inner {
-
- // SASSTODO: Needs a poper selector
- & > label > div {
- background-color: #f2f2f2;
- }
- }
- }
- }
-}
-
-.ml-select-list-on {
- color: #ffffff;
- background-color: #000099;
-}
-
-.ml-select-list-on {
- color: #ffffff;
- background-color: #000099;
-}
-
-.ml-job-select-btn-container {
- .popover {
- min-width: 640px;
- max-width: 660px !important;
- left: 9px !important;
- .arrow {
- left: 150px !important;
- }
- }
-
- .ml-job-select-btn-label {
- background-color:#9c9c9c;
- color: #ffffff;
- display:inline-block;
- padding:0px 10px;
- border: 0px solid #ecf0f1;
- border-top-style: solid;
- border-right-style: none;
- border-bottom-style: solid;
- border-left-style: solid;
- border-top-left-radius: 4px;
- border-bottom-left-radius: 4px;
- height: 34px;
- line-height:33px;
- font-size: 12px;
- }
-
- .ml-job-select-btn {
- width: 300px;
- height: 34px;
- text-align: left;
- color: #444444;
- background-color: white;
- border: 1px solid #ffffff;
- border-left-width: 0px;
- border-radius: 0px 4px 4px 0px;
- padding: 6px 16px;
- padding-left: 10px;
- transition: border-color ease-in-out .15s;
- font-size: 14px;
- line-height: 20px;
- cursor: pointer;
-
- .ml-job-select-btn-text {
- float: left;
- width: 260px;
- overflow-x: hidden;
- display: inline-flex;
- white-space: nowrap;
-
- span {
- overflow-x: hidden;
- text-overflow: ellipsis;
- padding-right: 5px;
- }
- }
-
- .caret {
- float: right;
- margin-top: 6px;
- display:inline-block;
- }
- }
-
- .ml-job-select-btn:hover, .ml-job-select-btn:focus, .ml-job-select-btn:active {
- color: #444444;
- background-color: #ffffff;
- border-color: #0079a5;
- border-left-width: 1px;
- padding-left: 9px;
- transform: none;
- }
-
- .ml-job-select-btn:focus {
- outline: none;
- box-shadow: none;
- }
-}
diff --git a/x-pack/plugins/ml/public/components/job_select_list/index.js b/x-pack/plugins/ml/public/components/job_select_list/index.js
deleted file mode 100644
index bba2809644d8..000000000000
--- a/x-pack/plugins/ml/public/components/job_select_list/index.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-
-
-
-import './job_select_list_directive';
-import './job_select_button_directive.js';
-import './job_select_service.js';
diff --git a/x-pack/plugins/ml/public/components/job_select_list/job_select_button.html b/x-pack/plugins/ml/public/components/job_select_list/job_select_button.html
deleted file mode 100644
index 6381b2538027..000000000000
--- a/x-pack/plugins/ml/public/components/job_select_list/job_select_button.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
- {{description.txt}}
-
-
-
-
diff --git a/x-pack/plugins/ml/public/components/job_select_list/job_select_button_directive.js b/x-pack/plugins/ml/public/components/job_select_list/job_select_button_directive.js
deleted file mode 100644
index 51511ab544e9..000000000000
--- a/x-pack/plugins/ml/public/components/job_select_list/job_select_button_directive.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-
-
-/*
- * ml-job-select-list directive for rendering a multi-select control for selecting
- * one or more jobs from the list of configured jobs.
- */
-
-import template from './job_select_button.html';
-
-import 'ui/accessibility/kbn_accessible_click';
-import { uiModules } from 'ui/modules';
-const module = uiModules.get('apps/ml');
-
-import { JobSelectServiceProvider } from 'plugins/ml/components/job_select_list/job_select_service';
-
-module.directive('jobSelectButton', function (Private) {
-
- const mlJobSelectService = Private(JobSelectServiceProvider);
-
- function link(scope) {
- scope.selectJobBtnJobIdLabel = '';
- scope.unsafeHtml = '';
- scope.description = scope.singleSelection ? mlJobSelectService.singleJobDescription : mlJobSelectService.description;
-
- scope.createMenu = function () {
- let txt = '';
- scope.unsafeHtml = txt;
- };
- }
-
- return {
- scope: {
- timeseriesonly: '=',
- singleSelection: '='
- },
- link,
- replace: true,
- template
- };
-});
diff --git a/x-pack/plugins/ml/public/components/job_select_list/job_select_list.html b/x-pack/plugins/ml/public/components/job_select_list/job_select_list.html
deleted file mode 100644
index 29b16648c01a..000000000000
--- a/x-pack/plugins/ml/public/components/job_select_list/job_select_list.html
+++ /dev/null
@@ -1,147 +0,0 @@
-
-
-
-
-
-
-
-
- {{ ::'xpack.ml.jobSelectList.groupsTitle' | i18n: { defaultMessage: 'Groups' } }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ ::'xpack.ml.jobSelectList.jobsTitle' | i18n: { defaultMessage: 'Jobs' } }}
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/x-pack/plugins/ml/public/components/job_select_list/job_select_list_directive.js b/x-pack/plugins/ml/public/components/job_select_list/job_select_list_directive.js
deleted file mode 100644
index 7fb3e07ab1aa..000000000000
--- a/x-pack/plugins/ml/public/components/job_select_list/job_select_list_directive.js
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-
-
-/*
- * ml-job-select-list directive for rendering a multi-select control for selecting
- * one or more jobs from the list of configured jobs.
- */
-
-import _ from 'lodash';
-import $ from 'jquery';
-import moment from 'moment';
-import d3 from 'd3';
-
-import template from './job_select_list.html';
-import { isTimeSeriesViewJob } from 'plugins/ml/../common/util/job_utils';
-import { mlJobService } from 'plugins/ml/services/job_service';
-import { JobSelectServiceProvider } from 'plugins/ml/components/job_select_list/job_select_service';
-
-import { timefilter } from 'ui/timefilter';
-import { uiModules } from 'ui/modules';
-const module = uiModules.get('apps/ml');
-
-module.directive('mlJobSelectList', function (Private) {
- return {
- restrict: 'AE',
- replace: true,
- transclude: true,
- template,
- controller: function ($scope, i18n) {
- const mlJobSelectService = Private(JobSelectServiceProvider);
- $scope.jobs = [];
- $scope.groups = [];
- $scope.homelessJobs = [];
- $scope.singleSelection = false;
- $scope.timeSeriesOnly = false;
- $scope.noJobsCreated = undefined;
- $scope.applyTimeRange = mlJobSelectService.jobSelectListState.applyTimeRange;
- $scope.urlSelectedIds = {};
- $scope.selected = {};
- $scope.allGroupsSelected = false;
- $scope.allJobsSelected = false;
- $scope.selectedJobRadio = '';
- $scope.selectedCount = 0;
-
- mlJobService.loadJobs()
- .then((resp) => {
- if (resp.jobs.length > 0) {
- $scope.noJobsCreated = false;
- const jobs = [];
- resp.jobs.forEach(job => {
- if (job.groups && job.groups.length) {
- job.groups.forEach(group => {
- jobs.push(createJob(`${group}.${job.job_id}`, group, job));
- });
- } else {
- jobs.push(createJob(job.job_id, null, job));
- }
- });
- normalizeTimes(jobs);
- $scope.jobs = jobs;
- const { groups, homeless } = createGroups($scope.jobs);
- $scope.groups = groups;
- $scope.homelessJobs = homeless;
- $scope.selected = {
- groups: [],
- jobs: []
- };
-
- // count all jobs, including duplicates in groups.
- // if it's the same as the number of ids passed in, tick all jobs
- const jobCount = resp.jobs.reduce((sum, job) => (sum + ((job.groups === undefined) ? 1 : job.groups.length)), 0);
- const selectAll = (jobCount === $scope.urlSelectedIds.jobs.length);
-
- // create the groups and jobs which are used in the menu
- groups.forEach(group => {
- $scope.selected.groups.push({
- id: group.id,
- selected: group.selected,
- // TODO: is the selectable property of a group still needed?
- selectable: group.selectable,
- timeRange: group.timeRange,
- isGroup: true,
- });
- });
-
- jobs.forEach(job => {
- if ($scope.selected.jobs.find(j => j.id === job.name) === undefined) {
- $scope.selected.jobs.push({
- id: job.name,
- selected: selectAll || job.selected,
- disabled: job.disabled,
- timeRange: job.timeRange,
- running: job.running,
- isGroup: false
- });
- }
- });
-
- $scope.allJobsSelected = areAllJobsSelected();
- $scope.allGroupsSelected = areAllGroupsSelected();
- createSelectedCount();
-
- // if in single selection mode, set the radio button controller ($scope.selectedJobRadio)
- // to the selected job id
- if ($scope.singleSelection === true) {
- $scope.jobs.forEach(j => {
- if (j.selected) {
- $scope.selectedJobRadio = j.name;
- }
- });
- }
- } else {
- $scope.noJobsCreated = true;
- }
- $scope.$applyAsync();
- }).catch((resp) => {
- console.log('mlJobSelectList controller - error getting job info from ES:', resp);
- });
-
- function createJob(jobId, groupId, job) {
- return {
- id: jobId,
- name: job.job_id,
- group: groupId,
- isGroup: false,
- selected: _.includes($scope.urlSelectedIds.jobs, job.job_id),
- disabled: !($scope.timeSeriesOnly === false || isTimeSeriesViewJob(job) === true),
- running: (job.datafeed_config && job.datafeed_config.state === 'started'),
- timeRange: {
- to: job.data_counts.latest_record_timestamp,
- from: job.data_counts.earliest_record_timestamp,
- fromPx: 0,
- toPx: 0,
- widthPx: 0,
- label: ''
- }
- };
- }
-
- function createGroups(jobsIn) {
- const jobGroups = {};
- const homeless = [];
- // first pull all of the groups out of all of the jobs
- // keeping homeless (groupless) jobs in a separate list
- jobsIn.forEach(job => {
- if (job.group !== null) {
- if (jobGroups[job.group] === undefined) {
- jobGroups[job.group] = [job];
- } else {
- jobGroups[job.group].push(job);
- }
- } else {
- homeless.push(job);
- }
- });
-
- const groups = _.map(jobGroups, (jobs, id) => {
- const group = {
- id,
- selected: false,
- selectable: true,
- expanded: false,
- isGroup: true,
- jobs
- };
- // check to see whether all of the groups jobs have been selected,
- // if they have, select the group
- if ($scope.singleSelection === false) {
- group.selected = _.includes($scope.urlSelectedIds.groups, id);
- }
-
- // create an over all time range for the group
- const timeRange = {
- to: null,
- toMoment: null,
- from: null,
- fromMoment: null,
- fromPx: null,
- toPx: null,
- widthPx: null,
- };
-
- jobs.forEach(job => {
- job.group = group;
-
- if (timeRange.to === null || job.timeRange.to > timeRange.to) {
- timeRange.to = job.timeRange.to;
- timeRange.toMoment = job.timeRange.toMoment;
- }
- if (timeRange.from === null || job.timeRange.from < timeRange.from) {
- timeRange.from = job.timeRange.from;
- timeRange.fromMoment = job.timeRange.fromMoment;
- }
- if (timeRange.toPx === null || job.timeRange.toPx > timeRange.toPx) {
- timeRange.toPx = job.timeRange.toPx;
- }
- if (timeRange.fromPx === null || job.timeRange.fromPx < timeRange.fromPx) {
- timeRange.fromPx = job.timeRange.fromPx;
- }
- });
- timeRange.widthPx = timeRange.toPx - timeRange.fromPx;
- 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 = i18n('xpack.ml.jobSelectList.groupTimeRangeLabel', {
- defaultMessage: '{fromString} to {toString}',
- values: {
- fromString,
- toString,
- }
- });
-
- group.timeRange = timeRange;
- return group;
- });
-
- return {
- groups,
- homeless
- };
- }
-
- // apply the selected jobs
- $scope.apply = function () {
- // if in single selection mode, get the job id from $scope.selectedJobRadio
- const selectedJobs = [];
- if ($scope.singleSelection) {
- selectedJobs.push(...$scope.selected.jobs.filter(j => j.id === $scope.selectedJobRadio));
- } else {
- selectedJobs.push(...$scope.selected.jobs.filter(j => j.selected));
- selectedJobs.push(...$scope.selected.groups.filter(g => g.selected));
- }
-
- if (areAllJobsSelected()) {
- // if all jobs have been selected, just store '*' in the url
- mlJobSelectService.setJobIds(['*']);
- } else {
- const jobIds = selectedJobs.map(j => (j.isGroup ? `${j.id}.*` : j.id));
- mlJobSelectService.setJobIds(jobIds);
- }
-
- // if the apply time range checkbox is ticked,
- // find the min and max times for all selected jobs
- // and apply them to the timefilter
- if ($scope.applyTimeRange) {
- const times = [];
- selectedJobs.forEach(job => {
- if (job.timeRange.from !== undefined) {
- times.push(job.timeRange.from);
- }
- if (job.timeRange.to !== undefined) {
- times.push(job.timeRange.to);
- }
- });
- if (times.length) {
- const min = _.min(times);
- const max = _.max(times);
- timefilter.setTime({
- from: moment(min).toISOString(),
- to: moment(max).toISOString()
- });
- }
- }
- mlJobSelectService.jobSelectListState.applyTimeRange = $scope.applyTimeRange;
- $scope.closePopover();
- };
-
- // ticking a job
- $scope.toggleSelection = function () {
- // check to see if all jobs are now selected
- $scope.allJobsSelected = areAllJobsSelected();
- $scope.allGroupsSelected = areAllGroupsSelected();
- createSelectedCount();
- };
-
- // ticking the all jobs checkbox
- $scope.toggleAllJobsSelection = function () {
- const allJobsSelected = areAllJobsSelected();
- $scope.allJobsSelected = !allJobsSelected;
-
- $scope.selected.jobs.forEach(job => {
- job.selected = $scope.allJobsSelected;
- });
-
- createSelectedCount();
- };
-
- // ticking a group
- $scope.toggleGroupSelection = function () {
- $scope.allGroupsSelected = areAllGroupsSelected();
- createSelectedCount();
- };
-
- // ticking the all jobs checkbox
- $scope.toggleAllGroupsSelection = function () {
- const allGroupsSelected = areAllGroupsSelected();
- $scope.allGroupsSelected = !allGroupsSelected;
-
- $scope.selected.groups.forEach(group => {
- group.selected = $scope.allGroupsSelected;
- });
- createSelectedCount();
- };
-
- // check to see whether all jobs in the list have been selected
- function areAllJobsSelected() {
- let allSelected = true;
- $scope.selected.jobs.forEach(job => {
- if (job.selected === false) {
- allSelected = false;
- }
- });
- return allSelected;
- }
-
- // check to see whether all groups in the list have been selected
- function areAllGroupsSelected() {
- let allSelected = true;
- $scope.selected.groups.forEach(group => {
- if (group.selected === false) {
- allSelected = false;
- }
- });
- return allSelected;
- }
-
- function createSelectedCount() {
- $scope.selectedCount = 0;
- $scope.selected.jobs.forEach(job => {
- if (job.selected) {
- $scope.selectedCount++;
- }
- });
- $scope.selected.groups.forEach(group => {
- if (group.selected) {
- $scope.selectedCount++;
- }
- });
- }
-
- // create the data used for the gant charts
- function normalizeTimes(jobs) {
- const min = _.min(jobs, job => +job.timeRange.from);
- const max = _.max(jobs, job => +job.timeRange.to);
-
- const gantScale = d3.scale.linear().domain([min.timeRange.from, max.timeRange.to]).range([1, 299]);
-
- jobs.forEach(job => {
- if (job.timeRange.to !== undefined && job.timeRange.from !== undefined) {
- job.timeRange.fromPx = gantScale(job.timeRange.from);
- job.timeRange.toPx = gantScale(job.timeRange.to);
- job.timeRange.widthPx = job.timeRange.toPx - job.timeRange.fromPx;
-
- 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 = i18n('xpack.ml.jobSelectList.jobTimeRangeLabel', {
- defaultMessage: '{fromString} to {toString}',
- values: {
- fromString,
- toString,
- }
- });
- }
- });
-
- }
-
- $scope.useTimeRange = function (job) {
- timefilter.setTime({
- from: job.timeRange.fromMoment.toISOString(),
- to: job.timeRange.toMoment.toISOString()
- });
- };
- },
- link: function (scope, element, attrs) {
- const mlJobSelectService = Private(JobSelectServiceProvider);
- scope.timeSeriesOnly = false;
- if (attrs.timeseriesonly === 'true') {
- scope.timeSeriesOnly = true;
- }
-
- if (attrs.singleSelection === 'true') {
- scope.singleSelection = true;
- }
-
- // Make a copy of the list of jobs ids
- // '*' is passed to indicate 'All jobs'.
- scope.urlSelectedIds = {
- groups: [...mlJobSelectService.groupIds],
- jobs: [...mlJobSelectService.jobIdsWithGroup],
- };
-
- // Giving the parent div focus fixes checkbox tick UI selection on IE.
- $('.ml-select-list', element).focus();
- }
- };
-});
diff --git a/x-pack/plugins/ml/public/components/job_select_list/job_select_service.js b/x-pack/plugins/ml/public/components/job_select_list/job_select_service.js
deleted file mode 100644
index 435ed4161345..000000000000
--- a/x-pack/plugins/ml/public/components/job_select_list/job_select_service.js
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-
-
-// Service with functions used for broadcasting job picker changes
-
-import _ from 'lodash';
-import { toastNotifications } from 'ui/notify';
-
-import { mlJobService } from 'plugins/ml/services/job_service';
-
-let jobSelectService = undefined;
-
-export function JobSelectServiceProvider($rootScope, globalState, i18n) {
-
- function checkGlobalState() {
- if (globalState.ml === undefined) {
- globalState.ml = {};
- globalState.save();
- }
- }
- checkGlobalState();
-
- function loadJobIdsFromGlobalState() {
- const jobIds = [];
- if (globalState.ml && globalState.ml.jobIds) {
- let tempJobIds = [];
- if (typeof globalState.ml.jobIds === 'string') {
- tempJobIds.push(globalState.ml.jobIds);
- } else {
- tempJobIds = globalState.ml.jobIds;
- }
- tempJobIds = tempJobIds.map(id => String(id));
- const invalidIds = getInvalidJobIds(removeGroupIds(tempJobIds));
- warnAboutInvalidJobIds(invalidIds);
-
- let validIds = _.difference(tempJobIds, invalidIds);
-
- // if there are no valid ids, warn and then select the first job
- if (validIds.length === 0) {
- toastNotifications.addWarning(i18n('xpack.ml.jobSelect.noJobsSelectedWarningMessage', {
- defaultMessage: 'No jobs selected, auto selecting first job',
- }));
-
- if (mlJobService.jobs.length) {
- validIds = [mlJobService.jobs[0].job_id];
- }
- }
- jobIds.push(...validIds);
-
- // replace the job ids in the url with the ones which are valid
- storeJobIdsInGlobalState(jobIds);
- } else {
- checkGlobalState();
-
- // no jobs selected, use the first in the list
- if (mlJobService.jobs.length) {
- jobIds.push(mlJobService.jobs[0].job_id);
- }
- storeJobIdsInGlobalState(jobIds);
- }
-
- return jobIds;
- }
-
- function storeJobIdsInGlobalState(jobIds) {
- globalState.ml.jobIds = jobIds;
- globalState.save();
- }
-
- // check that the ids read from the url exist by comparing them to the
- // jobs loaded via mlJobsService.
- function getInvalidJobIds(ids) {
- return ids.filter(id => {
- const job = _.find(mlJobService.jobs, { 'job_id': id });
- return (job === undefined && id !== '*');
- });
- }
-
- function removeGroupIds(jobIds) {
- return jobIds.map(id => {
- const splitId = id.split('.');
- return (splitId.length > 1) ? splitId[1] : splitId[0];
- });
- }
-
- function warnAboutInvalidJobIds(invalidIds) {
- if (invalidIds.length > 0) {
- toastNotifications.addWarning(i18n('xpack.ml.jobSelect.requestedJobsDoesNotExistWarningMessage', {
- defaultMessage: `Requested
-{invalidIdsLength, plural, one {job {invalidIds} does not exist} other {jobs {invalidIds} do not exist}}`,
- values: {
- invalidIdsLength: invalidIds.length,
- invalidIds,
- }
- }));
- }
- }
-
- function createDescription(jobs) {
- let txt = '';
- // add up the number of jobs including duplicates if they belong to multiple groups
- const jobCount = mlJobService.jobs.length;
-
- // add up how many jobs belong to groups and how many don't
- const selectedGroupJobs = [];
- const groupCounts = {};
- let groupLessJobs = 0;
- const splitJobs = jobs.map(job => {
- const obj = splitJobId(job);
- if (obj.group) {
- // keep track of selected jobs from group selection
- selectedGroupJobs.push(obj.job);
- }
- return obj;
- });
-
- splitJobs.forEach(jobObj => {
- if (jobObj.group) {
- groupCounts[jobObj.group] = (groupCounts[jobObj.group] || 0) + 1;
- } else {
- // if job has already been included via group selection don't add as groupless job
- if (selectedGroupJobs.includes(jobObj.job) === false) {
- groupLessJobs++;
- }
- }
- });
- // All jobs have been selected
- if ((_.uniq(selectedGroupJobs).length + groupLessJobs) === jobCount) {
- txt = i18n('xpack.ml.jobSelect.allJobsDescription', {
- defaultMessage: 'All jobs',
- });
- } else {
- const wholeGroups = [];
- const groups = mlJobService.getJobGroups();
- // work out how many groups have all of their jobs selected
- groups.forEach(group => {
- const groupCount = groupCounts[group.id];
- if (groupCount !== undefined && groupCount === group.jobs.length) {
- // this group has all of it's jobs selected
- wholeGroups.push(group.id);
- } else {
- if (groupCount !== undefined) {
- // this job doesn't so add it to the count of groupless jobs
- groupLessJobs += groupCount;
- }
- }
- });
-
- // show the whole groups first
- if (wholeGroups.length) {
- txt = wholeGroups[0];
- if (wholeGroups.length > 1 || groupLessJobs > 0) {
- const total = (wholeGroups.length - 1) + groupLessJobs;
- txt = i18n('xpack.ml.jobSelect.wholeGroupDescription', {
- defaultMessage: `{wholeGroup} (with {count, plural, zero {# job} one {# job} other {# jobs}}) and
- {total, plural, zero {# other} one {# other} other {# others}}`,
- values: {
- count: groupCounts[wholeGroups[0]],
- wholeGroup: wholeGroups[0],
- total,
- }
- });
- }
- } else {
- // otherwise just list the job ids
- txt = splitJobId(jobs[0]).job;
- if (jobs.length > 1) {
- txt = i18n('xpack.ml.jobSelect.jobDescription', {
- defaultMessage: '{jobId} and {jobsAmount, plural, zero {# other} one {# other} other {# others}}',
- values: {
- jobId: splitJobId(jobs[0]).job,
- jobsAmount: jobs.length - 1,
- }
- });
- }
- }
- }
- return txt;
- }
- // function to split the group from the job and return both or just the job
- function splitJobId(jobId) {
- let obj = {};
- const splitId = jobId.split('.');
- if (splitId.length === 2) {
- obj = { group: splitId[0], job: splitId[1] };
- } else {
- obj = { job: jobId };
- }
- return obj;
- }
- this.splitJobId = splitJobId;
-
- // expands `*` into groupId.jobId list
- // expands `groupId.*` into `groupId.jobId` list
- // returns list of expanded job ids
- function expandGroups(jobIds) {
- const newJobIds = [];
- const groups = mlJobService.getJobGroups();
- jobIds.forEach(jobId => {
- if (jobId === '*') {
- mlJobService.jobs.forEach(job => {
- if (job.groups === undefined) {
- newJobIds.push(job.job_id);
- } else {
- newJobIds.push(...job.groups.map(g => `${g}.${job.job_id}`));
- }
- });
- } else {
- const splitId = splitJobId(jobId);
- if (splitId.group !== undefined && splitId.job === '*') {
- const groupId = splitId.group;
- const group = groups.find(g => g.id === groupId);
- group.jobs.forEach(j => {
- newJobIds.push(`${groupId}.${j.job_id}`);
- });
- }
- else {
- newJobIds.push(jobId);
- }
- }
- });
- return newJobIds;
- }
-
- function getGroupIds(jobIds) {
- const groupIds = [];
- jobIds.forEach(jobId => {
- const splitId = splitJobId(jobId);
- if (splitId.group !== undefined && splitId.job === '*') {
- groupIds.push(splitId.group);
- }
- });
- return groupIds;
- }
-
- // takes an array of ids.
- // this could be a mixture of job ids, group ids or a *.
- // stores an expanded list of job ids (i.e. groupId.jobId) and a list of jobs ids only.
- // creates the description text used on the job picker button.
- function processIds(service, ids) {
- const expandedJobIds = expandGroups(ids);
- service.jobIdsWithGroup.length = 0;
- service.jobIdsWithGroup.push(...expandedJobIds);
- service.groupIds = getGroupIds(ids);
- service.jobIds.length = 0;
- service.jobIds.push(...removeGroupIds(expandedJobIds));
- service.description.txt = createDescription(service.jobIdsWithGroup);
- service.singleJobDescription.txt = ids[0];
- setBrowserTitle(service.description.txt);
- }
-
- // display the job id in the tab title
- function setBrowserTitle(title) {
- document.title = `${title} - Kibana`;
- }
-
- class JobSelectService {
- constructor() {
- this.jobIds = [];
- this.groupIds = [];
- this.description = { txt: '' };
- this.singleJobDescription = { txt: '' };
- this.jobSelectListState = {
- applyTimeRange: true
- };
- this.jobIdsWithGroup = [];
- this.splitJobId = splitJobId;
- }
-
- // Broadcasts that a change has been made to the selected jobs.
- broadcastJobSelectionChange() {
- $rootScope.$broadcast('jobSelectionChange', this.getSelectedJobIds());
- }
-
- // Add a listener for changes to the selected jobs.
- listenJobSelectionChange(scope, callback) {
- const handler = $rootScope.$on('jobSelectionChange', callback);
- scope.$on('$destroy', handler);
- }
-
- // called externally to retrieve the selected jobs ids.
- // passing in `true` will load the jobs ids from the URL first
- getSelectedJobIds(loadFromURL) {
- if (loadFromURL) {
- processIds(this, loadJobIdsFromGlobalState());
- }
- return this.jobIds;
- }
-
- // called externally to set the job ids.
- // job ids are added to the URL and an event is broadcast for anything listening.
- // e.g. the anomaly explorer or time series explorer.
- // currently only called by the jobs selection menu.
- setJobIds(jobIds) {
- processIds(this, jobIds);
- storeJobIdsInGlobalState(jobIds);
- this.broadcastJobSelectionChange();
- }
- }
-
- if (jobSelectService === undefined) {
- jobSelectService = new JobSelectService();
- }
- return jobSelectService;
-}
diff --git a/x-pack/plugins/ml/public/lib/angular_bootstrap_patch.js b/x-pack/plugins/ml/public/lib/angular_bootstrap_patch.js
deleted file mode 100644
index a13b151c2655..000000000000
--- a/x-pack/plugins/ml/public/lib/angular_bootstrap_patch.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/* eslint-disable @kbn/eslint/require-license-header */
-
-/**
- * @notice
- *
- * This product includes code that was extracted from angular-ui-bootstrap@0.13.1
- * which is available under an "MIT" license
- *
- * The MIT License
- *
- * Copyright (c) 2012-2016 the AngularUI Team, http://angular-ui.github.io/bootstrap/
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-// This file contains a section of code taken from angular-ui-bootstrap@0.13.1
-// and adds it to kibana's included version of 0.12.1
-// It adds the ability to allow html to be used as the content of the popover component
-
-import 'ui/angular-bootstrap';
-
-import { uiModules } from 'ui/modules';
-const module = uiModules.get('apps/ml');
-
-module
- .directive('popover', [ '$tooltip', function ($tooltip) {
- return $tooltip('popover', 'popover', 'click');
- }])
- .directive('popoverHtmlUnsafePopup', function ($compile) {
- let template = '';
- template += '
';
- template += '
';
- template += '
';
- template += '
';
- template += '
';
- return {
- restrict: 'EA',
- replace: true,
- scope: {
- title: '@',
- content: '@',
- placement: '@',
- animation: '&',
- isOpen: '&'
- },
- template: template,
- link: function (scope, element) {
- // The content of the popup is added as a string and does not run through angular's templating system.
- // therefore {{stuff}} substitutions don't happen.
- // we have to manually apply the template, compile it with this scope and then set it as the html
- scope.$apply();
- const cont = $compile(scope.content)(scope);
- element.find('.popover-content').html(cont);
-
- // function to force the popover to close
- scope.closePopover = function () {
- scope.$parent.$parent.isOpen = false;
- scope.$parent.$parent.$applyAsync();
- element.remove();
- };
- }
- };
- })
- .directive('popoverHtmlUnsafe', ['$tooltip', function ($tooltip) {
- return $tooltip('popoverHtmlUnsafe', 'popover', 'click');
- }]);
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 893804328717..f7ab1588c8a7 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -6145,30 +6145,9 @@
"xpack.ml.jobsBreadcrumbs.populationLabel": "填充",
"xpack.ml.jobsBreadcrumbs.selectIndexOrSearchLabel": "选择索引或搜索",
"xpack.ml.jobsBreadcrumbs.singleMetricLabel": "单一指标",
- "xpack.ml.jobSelect.allJobsDescription": "所有作业",
- "xpack.ml.jobSelect.jobDescription": "{jobId} 和 {jobsAmount, plural, zero {# 个其他作业} one {# 个其他作业} other {# 个其他作业}}",
"xpack.ml.jobSelect.noJobsSelectedWarningMessage": "未选择作业,将自动选择第一个作业",
"xpack.ml.jobSelect.requestedJobsDoesNotExistWarningMessage": "已请求\n{invalidIdsLength, plural, one { 个作业 {invalidIds} 不存在} other { 个作业 {invalidIds} 不存在}}",
- "xpack.ml.jobSelect.wholeGroupDescription": "{wholeGroup}(具有 {count, plural, zero {# 个作业} one {# 个作业} other {# 个作业}})以及\n {total, plural, zero {# 个其他} one {# 个其他} other {# 个其他}}",
- "xpack.ml.jobSelectButton.jobSelectionMenuButtonAriaLabel": "作业选择菜单",
- "xpack.ml.jobSelectButton.jobSelectionMenuButtonTooltip": "已选择 {description}",
- "xpack.ml.jobSelectButton.jobTitle": "作业",
- "xpack.ml.jobSelectList.applyButtonAriaLabel": "应用",
- "xpack.ml.jobSelectList.applyButtonLabel": "应用",
- "xpack.ml.jobSelectList.applyTimeRangeLabel": "同时应用时间范围",
- "xpack.ml.jobSelectList.cancelButtonAriaLabel": "取消",
- "xpack.ml.jobSelectList.cancelButtonLabel": "取消",
- "xpack.ml.jobSelectList.groupIdAriaLabel": "组 ID {groupId}",
- "xpack.ml.jobSelectList.groupsTitle": "组",
"xpack.ml.jobSelectList.groupTimeRangeLabel": "{fromString} 到 {toString}",
- "xpack.ml.jobSelectList.jobIdAriaLabel": "作业 ID {jobId}",
- "xpack.ml.jobSelectList.jobSelectionTitle": "作业选择",
- "xpack.ml.jobSelectList.jobsTitle": "作业",
- "xpack.ml.jobSelectList.jobTimeRangeLabel": "{fromString} 到 {toString}",
- "xpack.ml.jobSelectList.loadingJobsLabel": "正在加载作业",
- "xpack.ml.jobSelectList.selectAllGroupsCheckboxAriaLabel": "选中所有组复选框。总计数 {selectedGroupsLength}。",
- "xpack.ml.jobSelectList.selectAllJobsCheckboxAriaLabel": "选中所有作业复选框。总计数 {selectedJobsLength}。",
- "xpack.ml.jobSelectList.timeRangeAriaLabel": "时间范围 {jobTimeRangeLabel}",
"xpack.ml.jobSelector.applyFlyoutButton": "应用",
"xpack.ml.jobSelector.applyTimerangeSwitchLabel": "应用时间范围",
"xpack.ml.jobSelector.clearAllFlyoutButton": "全部清除",