From bf96beb3fbea40196d53c2e696cb061c8866c4f2 Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Sat, 28 Sep 2019 17:47:33 +0200
Subject: [PATCH 01/17] [ML] wip job types to react
---
.../data_recognizer/data_recognizer.d.ts | 9 +-
.../ml/public/jobs/new_job_new/index.ts | 2 +
.../new_job_new/pages/job_type/directive.tsx | 65 ++++
.../jobs/new_job_new/pages/job_type/page.tsx | 313 ++++++++++++++++++
.../jobs/new_job_new/pages/job_type/route.ts | 30 ++
5 files changed, 417 insertions(+), 2 deletions(-)
create mode 100644 x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/directive.tsx
create mode 100644 x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
create mode 100644 x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/route.ts
diff --git a/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.d.ts b/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.d.ts
index c8a7bba2d189f..f03d632bcb92f 100644
--- a/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.d.ts
+++ b/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.d.ts
@@ -7,9 +7,14 @@
import { FC } from 'react';
import { IndexPattern } from 'ui/index_patterns';
+import { SavedSearch } from 'src/legacy/core_plugins/kibana/public/discover/types';
declare const DataRecognizer: FC<{
indexPattern: IndexPattern;
- results: any;
- className: string;
+ savedSearch: SavedSearch;
+ results: {
+ count: number;
+ onChange?: Function;
+ };
+ className?: string;
}>;
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/index.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/index.ts
index d3feaf087524c..2366f2c655000 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/index.ts
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/index.ts
@@ -6,3 +6,5 @@
import './pages/new_job/route';
import './pages/new_job/directive';
+import './pages/job_type/route';
+import './pages/job_type/directive';
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/directive.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/directive.tsx
new file mode 100644
index 0000000000000..4ad689a943160
--- /dev/null
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/directive.tsx
@@ -0,0 +1,65 @@
+/*
+ * 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 React from 'react';
+import ReactDOM from 'react-dom';
+
+// @ts-ignore
+import { uiModules } from 'ui/modules';
+const module = uiModules.get('apps/ml', ['react']);
+import { timefilter } from 'ui/timefilter';
+import { IndexPatterns } from 'ui/index_patterns';
+
+import { I18nContext } from 'ui/i18n';
+import { IPrivate } from 'ui/private';
+import { InjectorService } from '../../../../../common/types/angular';
+
+import { SearchItemsProvider } from '../../../new_job/utils/new_job_utils';
+import { Page } from './page';
+
+import { KibanaContext, KibanaConfigTypeFix } from '../../../../contexts/kibana';
+
+module.directive('mlJobTypePage', ($injector: InjectorService) => {
+ return {
+ scope: {},
+ restrict: 'E',
+ link: async (scope: ng.IScope, element: ng.IAugmentedJQuery) => {
+ // remove time picker from top of page
+ timefilter.disableTimeRangeSelector();
+ timefilter.disableAutoRefreshSelector();
+
+ const indexPatterns = $injector.get('indexPatterns');
+ const kbnBaseUrl = $injector.get('kbnBaseUrl');
+ const kibanaConfig = $injector.get('config');
+ const Private = $injector.get('Private');
+
+ const createSearchItems = Private(SearchItemsProvider);
+ const { indexPattern, savedSearch, combinedQuery } = createSearchItems();
+ const kibanaContext = {
+ combinedQuery,
+ currentIndexPattern: indexPattern,
+ currentSavedSearch: savedSearch,
+ indexPatterns,
+ kbnBaseUrl,
+ kibanaConfig,
+ };
+
+ ReactDOM.render(
+
+
+ {React.createElement(Page)}
+
+ ,
+ element[0]
+ );
+
+ element.on('$destroy', () => {
+ ReactDOM.unmountComponentAtNode(element[0]);
+ scope.$destroy();
+ });
+ },
+ };
+});
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
new file mode 100644
index 0000000000000..08057cf35dc16
--- /dev/null
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
@@ -0,0 +1,313 @@
+/*
+ * 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 React, { FC } from 'react';
+import { i18n } from '@kbn/i18n';
+import {
+ EuiPage,
+ EuiPageBody,
+ EuiPageContentBody,
+ EuiTitle,
+ EuiSpacer,
+ EuiCallOut,
+ EuiText,
+ EuiFlexGrid,
+ EuiFlexItem,
+ EuiPanel,
+ EuiFlexGroup,
+ EuiLink,
+ EuiIcon,
+} from '@elastic/eui';
+import { FormattedMessage } from '@kbn/i18n/react';
+import { timeBasedIndexCheck } from 'plugins/ml/util/index_utils';
+import { useKibanaContext } from '../../../../contexts/kibana';
+import { DataRecognizer } from '../../../../components/data_recognizer';
+
+export const Page: FC = () => {
+ const kibanaContext = useKibanaContext();
+
+ const { currentSavedSearch, currentIndexPattern } = kibanaContext;
+
+ const isTimeBasedIndex = timeBasedIndexCheck(currentIndexPattern);
+ const indexWarningTitle =
+ !isTimeBasedIndex && currentSavedSearch.id === undefined
+ ? i18n.translate('xpack.ml.newJob.wizard.jobType.indexPatternNotTimeBasedMessage', {
+ defaultMessage: 'Index pattern {indexPatternTitle} is not time based',
+ values: { indexPatternTitle: currentIndexPattern.title },
+ })
+ : i18n.translate(
+ 'xpack.ml.newJob.wizard.jobType.indexPatternFromSavedSearchNotTimeBasedMessage',
+ {
+ defaultMessage:
+ '{savedSearchTitle} uses index pattern {indexPatternTitle} which is not time based',
+ values: {
+ savedSearchTitle: currentSavedSearch.title,
+ indexPatternTitle: currentIndexPattern.title,
+ },
+ }
+ );
+ const pageTitleLabel =
+ currentSavedSearch.id !== undefined
+ ? i18n.translate('xpack.ml.newJob.wizard.jobType.savedSearchPageTitleLabel', {
+ defaultMessage: 'saved search {savedSearchTitle}',
+ values: { savedSearchTitle: currentSavedSearch.title },
+ })
+ : i18n.translate('xpack.ml.newJob.wizard.jobType.indexPatternPageTitleLabel', {
+ defaultMessage: 'index pattern {indexPatternTitle}',
+ values: { indexPatternTitle: currentIndexPattern.title },
+ });
+
+ const recognizerResults = {
+ count: 0,
+ };
+
+ const getUrl = (basePath: string) => {
+ return currentSavedSearch.id === undefined
+ ? `${basePath}?index=${currentIndexPattern.id}`
+ : `${basePath}?savedSearchId=${currentSavedSearch.id}`;
+ };
+
+ const jobTypes = [
+ {
+ href: getUrl('#jobs/new_job/single_metric'),
+ icon: {
+ type: 'createSingleMetricJob',
+ ariaLabel: i18n.translate('xpack.ml.newJob.wizard.jobType.singleMetricAriaLabel', {
+ defaultMessage: 'Single metric job',
+ }),
+ },
+ header: i18n.translate('xpack.ml.newJob.wizard.jobType.singleMetricTitle', {
+ defaultMessage: 'Single metric',
+ }),
+ text: i18n.translate('xpack.ml.newJob.wizard.jobType.singleMetricDescription', {
+ defaultMessage: 'Detect anomalies in a single time series.',
+ }),
+ id: 'mlJobTypeLinkSingleMetricJob',
+ },
+ {
+ href: getUrl('#jobs/new_job/multi_metric'),
+ icon: {
+ type: 'createMultiMetricJob',
+ ariaLabel: i18n.translate('xpack.ml.newJob.wizard.jobType.multiMetricAriaLabel', {
+ defaultMessage: 'Multi metric job',
+ }),
+ },
+ header: i18n.translate('xpack.ml.newJob.wizard.jobType.multiMetricTitle', {
+ defaultMessage: 'Multi metric',
+ }),
+ text: i18n.translate('xpack.ml.newJob.wizard.jobType.multiMetricDescription', {
+ defaultMessage:
+ 'Detect anomalies in multiple metrics by splitting a time series by a categorical field.',
+ }),
+ id: 'mlJobTypeLinkMultiMetricJob',
+ },
+ {
+ href: getUrl('#jobs/new_job/population'),
+ icon: {
+ type: 'createPopulationJob',
+ ariaLabel: i18n.translate('xpack.ml.newJob.wizard.jobType.populationAriaLabel', {
+ defaultMessage: 'Population job',
+ }),
+ },
+ header: i18n.translate('xpack.ml.newJob.wizard.jobType.populationTitle', {
+ defaultMessage: 'Population',
+ }),
+ text: i18n.translate('xpack.ml.newJob.wizard.jobType.populationDescription', {
+ defaultMessage:
+ 'Detect activity that is unusual compared to the behavior of the population.',
+ }),
+ id: 'mlJobTypeLinkPopulationJob',
+ },
+ {
+ href: getUrl('#jobs/new_job/advanced'),
+ icon: {
+ type: 'createAdvancedJob',
+ ariaLabel: i18n.translate('xpack.ml.newJob.wizard.jobType.advancedAriaLabel', {
+ defaultMessage: 'Advanced job',
+ }),
+ },
+ header: i18n.translate('xpack.ml.newJob.wizard.jobType.advancedTitle', {
+ defaultMessage: 'Advanced',
+ }),
+ text: i18n.translate('xpack.ml.newJob.wizard.jobType.advancedDescription', {
+ defaultMessage:
+ 'Use the full range of options to create a job for more advanced use cases.',
+ }),
+ id: 'mlJobTypeLinkAdvancedJob',
+ },
+ ];
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ {isTimeBasedIndex === false && (
+
+
+
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {jobTypes.map(({ href, icon, header, text, id }) => (
+
+
+
+
+
+
+
+
+
+ {header}
+
+
+ {text}
+
+
+
+
+
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/route.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/route.ts
new file mode 100644
index 0000000000000..6b52fee032e06
--- /dev/null
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/route.ts
@@ -0,0 +1,30 @@
+/*
+ * 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 uiRoutes from 'ui/routes';
+
+// @ts-ignore
+import { getCreateJobBreadcrumbs } from 'plugins/ml/jobs/breadcrumbs';
+// @ts-ignore
+import { checkMlNodesAvailable } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
+// @ts-ignore
+import { checkLicenseExpired } from '../../../../license/check_license';
+import { checkCreateJobsPrivilege } from '../../../../privilege/check_privilege';
+// @ts-ignore
+import { loadCurrentIndexPattern, loadCurrentSavedSearch } from '../../../../util/index_utils';
+// @ts-ignore
+
+uiRoutes.when('/jobs/new_job/step/job_type', {
+ template: '',
+ k7Breadcrumbs: getCreateJobBreadcrumbs,
+ resolve: {
+ CheckLicense: checkLicenseExpired,
+ privileges: checkCreateJobsPrivilege,
+ indexPattern: loadCurrentIndexPattern,
+ savedSearch: loadCurrentSavedSearch,
+ checkMlNodesAvailable,
+ },
+});
From 8f23c19477c969a58b17bd989173cf5ac2487ee9 Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Mon, 30 Sep 2019 10:19:34 +0200
Subject: [PATCH 02/17] [ML] delete angular job_type page
---
.../ml/public/jobs/new_job/wizard/index.js | 1 -
.../job_type/__tests__/job_type_controller.js | 46 ---
.../new_job/wizard/steps/job_type/index.js | 9 -
.../wizard/steps/job_type/job_type.html | 274 ------------------
.../steps/job_type/job_type_controller.js | 103 -------
5 files changed, 433 deletions(-)
delete mode 100644 x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/__tests__/job_type_controller.js
delete mode 100644 x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/index.js
delete mode 100644 x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/job_type.html
delete mode 100644 x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/job_type_controller.js
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/index.js b/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/index.js
index c2fb464630669..61ce488f69014 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/index.js
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/index.js
@@ -9,5 +9,4 @@
// SASS TODO: Import wizard.scss instead
// import 'plugins/kibana/visualize/wizard/wizard.less';
import './steps/index_or_search';
-import './steps/job_type';
import 'plugins/ml/components/data_recognizer';
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/__tests__/job_type_controller.js b/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/__tests__/job_type_controller.js
deleted file mode 100644
index f8fd13b2ae36e..0000000000000
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/__tests__/job_type_controller.js
+++ /dev/null
@@ -1,46 +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 ngMock from 'ng_mock';
-import expect from '@kbn/expect';
-import sinon from 'sinon';
-
-// Import this way to be able to stub/mock functions later on in the tests using sinon.
-import * as indexUtils from 'plugins/ml/util/index_utils';
-
-describe('ML - Job Type Controller', () => {
- beforeEach(() => {
- ngMock.module('kibana');
- });
-
- it('Initialize Job Type Controller', (done) => {
- const stub = sinon.stub(indexUtils, 'timeBasedIndexCheck').callsFake(() => false);
- ngMock.inject(function ($rootScope, $controller, $route) {
- // Set up the $route current props required for the tests.
- $route.current = {
- locals: {
- indexPattern: {
- id: 'test_id',
- title: 'test_pattern'
- },
- savedSearch: {}
- }
- };
-
- const scope = $rootScope.$new();
-
- expect(() => {
- $controller('MlNewJobStepJobType', { $scope: scope });
- }).to.not.throwError();
-
- expect(scope.indexWarningTitle).to.eql('Index pattern test_pattern is not time based');
- stub.restore();
- done();
- });
- });
-});
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/index.js b/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/index.js
deleted file mode 100644
index 9a9fa7e73b9f1..0000000000000
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/index.js
+++ /dev/null
@@ -1,9 +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_type_controller';
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/job_type.html b/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/job_type.html
deleted file mode 100644
index 1dc3aea215d93..0000000000000
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/job_type.html
+++ /dev/null
@@ -1,274 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/job_type_controller.js b/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/job_type_controller.js
deleted file mode 100644
index df7768ee9f0c8..0000000000000
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/steps/job_type/job_type_controller.js
+++ /dev/null
@@ -1,103 +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.
- */
-
-
-
-/*
- * Controller for the second step in the Create Job wizard, allowing
- * the user to select the type of job they wish to create.
- */
-
-import uiRoutes from 'ui/routes';
-import { i18n } from '@kbn/i18n';
-import { checkLicenseExpired } from 'plugins/ml/license/check_license';
-import { checkCreateJobsPrivilege } from 'plugins/ml/privilege/check_privilege';
-import { getCreateJobBreadcrumbs } from 'plugins/ml/jobs/breadcrumbs';
-import { SearchItemsProvider } from 'plugins/ml/jobs/new_job/utils/new_job_utils';
-import { loadCurrentIndexPattern, loadCurrentSavedSearch, timeBasedIndexCheck } from 'plugins/ml/util/index_utils';
-import { addItemToRecentlyAccessed } from 'plugins/ml/util/recently_accessed';
-import { checkMlNodesAvailable } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
-import template from './job_type.html';
-import { timefilter } from 'ui/timefilter';
-
-uiRoutes
- .when('/jobs/new_job/step/job_type', {
- template,
- k7Breadcrumbs: getCreateJobBreadcrumbs,
- resolve: {
- CheckLicense: checkLicenseExpired,
- privileges: checkCreateJobsPrivilege,
- indexPattern: loadCurrentIndexPattern,
- savedSearch: loadCurrentSavedSearch,
- checkMlNodesAvailable,
- }
- });
-
-
-import { uiModules } from 'ui/modules';
-const module = uiModules.get('apps/ml');
-
-module.controller('MlNewJobStepJobType',
- function ($scope, Private) {
-
- timefilter.disableTimeRangeSelector(); // remove time picker from top of page
- timefilter.disableAutoRefreshSelector(); // remove time picker from top of page
-
- const createSearchItems = Private(SearchItemsProvider);
- const {
- indexPattern,
- savedSearch } = createSearchItems();
-
- // check to see that the index pattern is time based.
- // if it isn't, display a warning and disable all links
- $scope.indexWarningTitle = '';
- $scope.isTimeBasedIndex = timeBasedIndexCheck(indexPattern);
- if ($scope.isTimeBasedIndex === false) {
- $scope.indexWarningTitle = (savedSearch.id === undefined) ?
- i18n.translate('xpack.ml.newJob.wizard.jobType.indexPatternNotTimeBasedMessage', {
- defaultMessage: 'Index pattern {indexPatternTitle} is not time based',
- values: { indexPatternTitle: indexPattern.title }
- })
- : i18n.translate('xpack.ml.newJob.wizard.jobType.indexPatternFromSavedSearchNotTimeBasedMessage', {
- defaultMessage: '{savedSearchTitle} uses index pattern {indexPatternTitle} which is not time based',
- values: {
- savedSearchTitle: savedSearch.title,
- indexPatternTitle: indexPattern.title
- }
- });
- }
-
- $scope.indexPattern = indexPattern;
- $scope.savedSearch = savedSearch;
- $scope.recognizerResults = {
- count: 0,
- onChange() {
- $scope.$applyAsync();
- }
- };
-
- $scope.pageTitleLabel = (savedSearch.id !== undefined) ?
- i18n.translate('xpack.ml.newJob.wizard.jobType.savedSearchPageTitleLabel', {
- defaultMessage: 'saved search {savedSearchTitle}',
- values: { savedSearchTitle: savedSearch.title }
- })
- : i18n.translate('xpack.ml.newJob.wizard.jobType.indexPatternPageTitleLabel', {
- defaultMessage: 'index pattern {indexPatternTitle}',
- values: { indexPatternTitle: indexPattern.title }
- });
-
- $scope.getUrl = function (basePath) {
- return (savedSearch.id === undefined) ? `${basePath}?index=${indexPattern.id}` :
- `${basePath}?savedSearchId=${savedSearch.id}`;
- };
-
- $scope.addSelectionToRecentlyAccessed = function () {
- const title = (savedSearch.id === undefined) ? indexPattern.title : savedSearch.title;
- const url = $scope.getUrl('');
- addItemToRecentlyAccessed('jobs/new_job/datavisualizer', title, url);
- };
-
- });
From f5acff26ae4da1475018916501ccc8dbb2698678 Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Mon, 30 Sep 2019 12:09:23 +0200
Subject: [PATCH 03/17] [ML] TS refactoring
---
.../public/{breadcrumbs.js => breadcrumbs.ts} | 16 +--
.../data_recognizer/data_recognizer.d.ts | 2 +-
.../jobs/{breadcrumbs.js => breadcrumbs.ts} | 71 ++++++------
.../jobs/new_job_new/pages/job_type/page.tsx | 62 ++++++----
.../jobs/new_job_new/pages/job_type/route.ts | 5 +-
.../jobs/new_job_new/pages/new_job/route.ts | 2 -
.../plugins/ml/public/util/index_utils.js | 108 ------------------
.../plugins/ml/public/util/index_utils.ts | 108 ++++++++++++++++++
...ently_accessed.js => recently_accessed.ts} | 12 +-
9 files changed, 199 insertions(+), 187 deletions(-)
rename x-pack/legacy/plugins/ml/public/{breadcrumbs.js => breadcrumbs.ts} (76%)
rename x-pack/legacy/plugins/ml/public/jobs/{breadcrumbs.js => breadcrumbs.ts} (55%)
delete mode 100644 x-pack/legacy/plugins/ml/public/util/index_utils.js
create mode 100644 x-pack/legacy/plugins/ml/public/util/index_utils.ts
rename x-pack/legacy/plugins/ml/public/util/{recently_accessed.js => recently_accessed.ts} (80%)
diff --git a/x-pack/legacy/plugins/ml/public/breadcrumbs.js b/x-pack/legacy/plugins/ml/public/breadcrumbs.ts
similarity index 76%
rename from x-pack/legacy/plugins/ml/public/breadcrumbs.js
rename to x-pack/legacy/plugins/ml/public/breadcrumbs.ts
index bdde734be7c1a..ba4703d4818ff 100644
--- a/x-pack/legacy/plugins/ml/public/breadcrumbs.js
+++ b/x-pack/legacy/plugins/ml/public/breadcrumbs.ts
@@ -8,28 +8,28 @@ import { i18n } from '@kbn/i18n';
export const ML_BREADCRUMB = Object.freeze({
text: i18n.translate('xpack.ml.machineLearningBreadcrumbLabel', {
- defaultMessage: 'Machine Learning'
+ defaultMessage: 'Machine Learning',
}),
- href: '#/'
+ href: '#/',
});
export const SETTINGS = Object.freeze({
text: i18n.translate('xpack.ml.settingsBreadcrumbLabel', {
- defaultMessage: 'Settings'
+ defaultMessage: 'Settings',
}),
- href: '#/settings?'
+ href: '#/settings?',
});
export const ANOMALY_DETECTION_BREADCRUMB = Object.freeze({
text: i18n.translate('xpack.ml.anomalyDetectionBreadcrumbLabel', {
- defaultMessage: 'Anomaly Detection'
+ defaultMessage: 'Anomaly Detection',
}),
- href: '#/jobs?'
+ href: '#/jobs?',
});
export const DATA_VISUALIZER_BREADCRUMB = Object.freeze({
text: i18n.translate('xpack.ml.datavisualizerBreadcrumbLabel', {
- defaultMessage: 'Data Visualizer'
+ defaultMessage: 'Data Visualizer',
}),
- href: '#/datavisualizer?'
+ href: '#/datavisualizer?',
});
diff --git a/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.d.ts b/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.d.ts
index f03d632bcb92f..e7d191a31e034 100644
--- a/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.d.ts
+++ b/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.d.ts
@@ -11,7 +11,7 @@ import { SavedSearch } from 'src/legacy/core_plugins/kibana/public/discover/type
declare const DataRecognizer: FC<{
indexPattern: IndexPattern;
- savedSearch: SavedSearch;
+ savedSearch?: SavedSearch;
results: {
count: number;
onChange?: Function;
diff --git a/x-pack/legacy/plugins/ml/public/jobs/breadcrumbs.js b/x-pack/legacy/plugins/ml/public/jobs/breadcrumbs.ts
similarity index 55%
rename from x-pack/legacy/plugins/ml/public/jobs/breadcrumbs.js
rename to x-pack/legacy/plugins/ml/public/jobs/breadcrumbs.ts
index d066a524d70aa..35e9c3326a4cc 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/breadcrumbs.js
+++ b/x-pack/legacy/plugins/ml/public/jobs/breadcrumbs.ts
@@ -4,12 +4,15 @@
* you may not use this file except in compliance with the Elastic License.
*/
-
-import { ML_BREADCRUMB, DATA_VISUALIZER_BREADCRUMB, ANOMALY_DETECTION_BREADCRUMB } from '../breadcrumbs';
import { i18n } from '@kbn/i18n';
+import { Breadcrumb } from 'ui/chrome';
+import {
+ ANOMALY_DETECTION_BREADCRUMB,
+ DATA_VISUALIZER_BREADCRUMB,
+ ML_BREADCRUMB,
+} from '../breadcrumbs';
-
-export function getJobManagementBreadcrumbs() {
+export function getJobManagementBreadcrumbs(): Breadcrumb[] {
// Whilst top level nav menu with tabs remains,
// use root ML breadcrumb.
return [
@@ -17,93 +20,93 @@ export function getJobManagementBreadcrumbs() {
ANOMALY_DETECTION_BREADCRUMB,
{
text: i18n.translate('xpack.ml.anomalyDetection.jobManagementLabel', {
- defaultMessage: 'Job Management'
+ defaultMessage: 'Job Management',
}),
- href: ''
- }
+ href: '',
+ },
];
}
-export function getCreateJobBreadcrumbs() {
+export function getCreateJobBreadcrumbs(): Breadcrumb[] {
return [
ML_BREADCRUMB,
ANOMALY_DETECTION_BREADCRUMB,
{
text: i18n.translate('xpack.ml.jobsBreadcrumbs.createJobLabel', {
- defaultMessage: 'Create job'
+ defaultMessage: 'Create job',
}),
- href: '#/jobs/new_job'
- }
+ href: '#/jobs/new_job',
+ },
];
}
-export function getCreateSingleMetricJobBreadcrumbs() {
+export function getCreateSingleMetricJobBreadcrumbs(): Breadcrumb[] {
return [
...getCreateJobBreadcrumbs(),
{
text: i18n.translate('xpack.ml.jobsBreadcrumbs.singleMetricLabel', {
- defaultMessage: 'Single metric'
+ defaultMessage: 'Single metric',
}),
- href: ''
- }
+ href: '',
+ },
];
}
-export function getCreateMultiMetricJobBreadcrumbs() {
+export function getCreateMultiMetricJobBreadcrumbs(): Breadcrumb[] {
return [
...getCreateJobBreadcrumbs(),
{
text: i18n.translate('xpack.ml.jobsBreadcrumbs.multiMetricLabel', {
- defaultMessage: 'Multi metric'
+ defaultMessage: 'Multi metric',
}),
- href: ''
- }
+ href: '',
+ },
];
}
-export function getCreatePopulationJobBreadcrumbs() {
+export function getCreatePopulationJobBreadcrumbs(): Breadcrumb[] {
return [
...getCreateJobBreadcrumbs(),
{
text: i18n.translate('xpack.ml.jobsBreadcrumbs.populationLabel', {
- defaultMessage: 'Population'
+ defaultMessage: 'Population',
}),
- href: ''
- }
+ href: '',
+ },
];
}
-export function getAdvancedJobConfigurationBreadcrumbs() {
+export function getAdvancedJobConfigurationBreadcrumbs(): Breadcrumb[] {
return [
...getCreateJobBreadcrumbs(),
{
text: i18n.translate('xpack.ml.jobsBreadcrumbs.advancedConfigurationLabel', {
- defaultMessage: 'Advanced configuration'
+ defaultMessage: 'Advanced configuration',
}),
- href: ''
- }
+ href: '',
+ },
];
}
-export function getCreateRecognizerJobBreadcrumbs($routeParams) {
+export function getCreateRecognizerJobBreadcrumbs($routeParams: any): Breadcrumb[] {
return [
...getCreateJobBreadcrumbs(),
{
text: $routeParams.id,
- href: ''
- }
+ href: '',
+ },
];
}
-export function getDataVisualizerIndexOrSearchBreadcrumbs() {
+export function getDataVisualizerIndexOrSearchBreadcrumbs(): Breadcrumb[] {
return [
ML_BREADCRUMB,
DATA_VISUALIZER_BREADCRUMB,
{
text: i18n.translate('xpack.ml.jobsBreadcrumbs.selectIndexOrSearchLabel', {
- defaultMessage: 'Select index or search'
+ defaultMessage: 'Select index or search',
}),
- href: ''
- }
+ href: '',
+ },
];
}
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
index 08057cf35dc16..d1525b1ce3950 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
@@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n';
import {
EuiPage,
EuiPageBody,
- EuiPageContentBody,
+ EuiPageContent,
EuiTitle,
EuiSpacer,
EuiCallOut,
@@ -22,9 +22,10 @@ import {
EuiIcon,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
-import { timeBasedIndexCheck } from 'plugins/ml/util/index_utils';
import { useKibanaContext } from '../../../../contexts/kibana';
import { DataRecognizer } from '../../../../components/data_recognizer';
+import { addItemToRecentlyAccessed } from '../../../../util/recently_accessed';
+import { timeBasedIndexCheck } from '../../../../util/index_utils';
export const Page: FC = () => {
const kibanaContext = useKibanaContext();
@@ -70,6 +71,15 @@ export const Page: FC = () => {
: `${basePath}?savedSearchId=${currentSavedSearch.id}`;
};
+ const addSelectionToRecentlyAccessed = () => {
+ const title =
+ currentSavedSearch.id === undefined ? currentIndexPattern.title : currentSavedSearch.title;
+ const url = getUrl('');
+ addItemToRecentlyAccessed('jobs/new_job/datavisualizer', title, url);
+
+ window.location.href = getUrl('#jobs/new_job/datavisualizer');
+ };
+
const jobTypes = [
{
href: getUrl('#jobs/new_job/single_metric'),
@@ -141,9 +151,9 @@ export const Page: FC = () => {
];
return (
-
+
-
+
{
{isTimeBasedIndex === false && (
-
-
-
-
+ <>
+
+
+
+
+
+
-
+ >
)}
@@ -220,13 +233,16 @@ export const Page: FC = () => {
{jobTypes.map(({ href, icon, header, text, id }) => (
-
-
-
+
+
+
@@ -240,8 +256,8 @@ export const Page: FC = () => {
-
-
+
+
))}
@@ -270,7 +286,7 @@ export const Page: FC = () => {
-
+
@@ -306,7 +322,7 @@ export const Page: FC = () => {
-
+
);
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/route.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/route.ts
index 6b52fee032e06..b61424998705d 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/route.ts
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/route.ts
@@ -6,16 +6,13 @@
import uiRoutes from 'ui/routes';
-// @ts-ignore
-import { getCreateJobBreadcrumbs } from 'plugins/ml/jobs/breadcrumbs';
// @ts-ignore
import { checkMlNodesAvailable } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
// @ts-ignore
import { checkLicenseExpired } from '../../../../license/check_license';
import { checkCreateJobsPrivilege } from '../../../../privilege/check_privilege';
-// @ts-ignore
import { loadCurrentIndexPattern, loadCurrentSavedSearch } from '../../../../util/index_utils';
-// @ts-ignore
+import { getCreateJobBreadcrumbs } from '../../../breadcrumbs';
uiRoutes.when('/jobs/new_job/step/job_type', {
template: '
',
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/new_job/route.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/new_job/route.ts
index cdca3a810fcdd..08f05e6884bb3 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/new_job/route.ts
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/new_job/route.ts
@@ -9,14 +9,12 @@ import uiRoutes from 'ui/routes';
// @ts-ignore
import { checkFullLicense } from '../../../../license/check_license';
import { checkGetJobsPrivilege } from '../../../../privilege/check_privilege';
-// @ts-ignore
import { loadCurrentIndexPattern, loadCurrentSavedSearch } from '../../../../util/index_utils';
import {
getCreateSingleMetricJobBreadcrumbs,
getCreateMultiMetricJobBreadcrumbs,
getCreatePopulationJobBreadcrumbs,
- // @ts-ignore
} from '../../../breadcrumbs';
import { Route } from '../../../../../common/types/kibana';
diff --git a/x-pack/legacy/plugins/ml/public/util/index_utils.js b/x-pack/legacy/plugins/ml/public/util/index_utils.js
deleted file mode 100644
index dfc6a7735616a..0000000000000
--- a/x-pack/legacy/plugins/ml/public/util/index_utils.js
+++ /dev/null
@@ -1,108 +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 { toastNotifications } from 'ui/notify';
-import { SavedObjectsClientProvider } from 'ui/saved_objects';
-import { i18n } from '@kbn/i18n';
-
-let indexPatternCache = [];
-let fullIndexPatterns = [];
-let currentIndexPattern = null;
-let currentSavedSearch = null;
-
-export let refreshIndexPatterns = null;
-
-export function loadIndexPatterns(Private, indexPatterns) {
- fullIndexPatterns = indexPatterns;
- const savedObjectsClient = Private(SavedObjectsClientProvider);
- return savedObjectsClient.find({
- type: 'index-pattern',
- fields: ['id', 'title', 'type', 'fields'],
- perPage: 10000
- }).then((response) => {
- indexPatternCache = response.savedObjects;
-
- if (refreshIndexPatterns === null) {
- refreshIndexPatterns = () => {
- return new Promise((resolve, reject) => {
- loadIndexPatterns(Private, indexPatterns)
- .then((resp) => {
- resolve(resp);
- })
- .catch((error) => {
- reject(error);
- });
- });
- };
- }
-
- return indexPatternCache;
- });
-}
-
-export function getIndexPatterns() {
- return indexPatternCache;
-}
-
-export function getIndexPatternNames() {
- return indexPatternCache.map(i => (i.attributes && i.attributes.title));
-}
-
-export function getIndexPatternIdFromName(name) {
- for (let j = 0; j < indexPatternCache.length; j++) {
- if (indexPatternCache[j].get('title') === name) {
- return indexPatternCache[j].id;
- }
- }
- return name;
-}
-
-export function loadCurrentIndexPattern(indexPatterns, $route) {
- fullIndexPatterns = indexPatterns;
- currentIndexPattern = fullIndexPatterns.get($route.current.params.index);
- return currentIndexPattern;
-}
-
-export function getIndexPatternById(id) {
- return fullIndexPatterns.get(id);
-}
-
-export function loadCurrentSavedSearch(savedSearches, $route) {
- currentSavedSearch = savedSearches.get($route.current.params.savedSearchId);
- return currentSavedSearch;
-}
-
-export function getCurrentIndexPattern() {
- return currentIndexPattern;
-}
-
-export function getCurrentSavedSearch() {
- return currentSavedSearch;
-}
-
-// returns true if the index passed in is time based
-// an optional flag will trigger the display a notification at the top of the page
-// warning that the index is not time based
-export function timeBasedIndexCheck(indexPattern, showNotification = false) {
- if (indexPattern.isTimeBased() === false) {
- if (showNotification) {
- toastNotifications.addWarning({
- title: i18n.translate('xpack.ml.indexPatternNotBasedOnTimeSeriesNotificationTitle', {
- defaultMessage: 'The index pattern {indexPatternTitle} is not based on a time series',
- values: { indexPatternTitle: indexPattern.title }
- }),
- text: i18n.translate('xpack.ml.indexPatternNotBasedOnTimeSeriesNotificationDescription', {
- defaultMessage: 'Anomaly detection only runs over time-based indices'
- }),
- });
- }
- return false;
- } else {
- return true;
- }
-}
diff --git a/x-pack/legacy/plugins/ml/public/util/index_utils.ts b/x-pack/legacy/plugins/ml/public/util/index_utils.ts
new file mode 100644
index 0000000000000..16a651dae766e
--- /dev/null
+++ b/x-pack/legacy/plugins/ml/public/util/index_utils.ts
@@ -0,0 +1,108 @@
+/*
+ * 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 { toastNotifications } from 'ui/notify';
+import { i18n } from '@kbn/i18n';
+import { IndexPattern, IndexPatterns } from 'ui/index_patterns';
+import { SavedObjectAttributes, SimpleSavedObject } from 'kibana/public';
+import chrome from 'ui/chrome';
+import { SavedSearchLoader } from '../../../../../../src/legacy/core_plugins/kibana/public/discover/types';
+import { setup as data } from '../../../../../../src/legacy/core_plugins/data/public/legacy';
+
+let indexPatternCache: Array
> = [];
+let fullIndexPatterns: IndexPatterns | null = null;
+
+export let refreshIndexPatterns: (() => Promise) | null = null;
+
+export function loadIndexPatterns() {
+ fullIndexPatterns = data.indexPatterns.indexPatterns;
+ const savedObjectsClient = chrome.getSavedObjectsClient();
+ return savedObjectsClient
+ .find({
+ type: 'index-pattern',
+ fields: ['id', 'title', 'type', 'fields'],
+ perPage: 10000,
+ })
+ .then(response => {
+ indexPatternCache = response.savedObjects;
+ if (refreshIndexPatterns === null) {
+ refreshIndexPatterns = () => {
+ return new Promise((resolve, reject) => {
+ loadIndexPatterns()
+ .then(resp => {
+ resolve(resp);
+ })
+ .catch(error => {
+ reject(error);
+ });
+ });
+ };
+ }
+
+ return indexPatternCache;
+ });
+}
+
+export function getIndexPatterns() {
+ return indexPatternCache;
+}
+
+export function getIndexPatternNames() {
+ return indexPatternCache.map(i => i.attributes && i.attributes.title);
+}
+
+export function getIndexPatternIdFromName(name: string) {
+ for (let j = 0; j < indexPatternCache.length; j++) {
+ if (indexPatternCache[j].get('title') === name) {
+ return indexPatternCache[j].id;
+ }
+ }
+ return name;
+}
+
+export function loadCurrentIndexPattern(indexPatterns: IndexPatterns, $route: Record) {
+ fullIndexPatterns = indexPatterns;
+ return fullIndexPatterns.get($route.current.params.index);
+}
+
+export function getIndexPatternById(id: string): IndexPattern {
+ if (fullIndexPatterns !== null) {
+ return fullIndexPatterns.get(id);
+ } else {
+ throw new Error('Index patterns are not initialized!');
+ }
+}
+
+export function loadCurrentSavedSearch(
+ savedSearches: SavedSearchLoader,
+ $route: Record
+) {
+ return savedSearches.get($route.current.params.savedSearchId);
+}
+
+/**
+ * Returns true if the index passed in is time based
+ * an optional flag will trigger the display a notification at the top of the page
+ * warning that the index is not time based
+ */
+export function timeBasedIndexCheck(indexPattern: IndexPattern, showNotification = false) {
+ if (!indexPattern.isTimeBased()) {
+ if (showNotification) {
+ toastNotifications.addWarning({
+ title: i18n.translate('xpack.ml.indexPatternNotBasedOnTimeSeriesNotificationTitle', {
+ defaultMessage: 'The index pattern {indexPatternTitle} is not based on a time series',
+ values: { indexPatternTitle: indexPattern.title },
+ }),
+ text: i18n.translate('xpack.ml.indexPatternNotBasedOnTimeSeriesNotificationDescription', {
+ defaultMessage: 'Anomaly detection only runs over time-based indices',
+ }),
+ });
+ }
+ return false;
+ } else {
+ return true;
+ }
+}
diff --git a/x-pack/legacy/plugins/ml/public/util/recently_accessed.js b/x-pack/legacy/plugins/ml/public/util/recently_accessed.ts
similarity index 80%
rename from x-pack/legacy/plugins/ml/public/util/recently_accessed.js
rename to x-pack/legacy/plugins/ml/public/util/recently_accessed.ts
index b642be7d1226a..9a3d3089dff2b 100644
--- a/x-pack/legacy/plugins/ml/public/util/recently_accessed.js
+++ b/x-pack/legacy/plugins/ml/public/util/recently_accessed.ts
@@ -4,38 +4,36 @@
* you may not use this file except in compliance with the Elastic License.
*/
-
-
// utility functions for managing which links get added to kibana's recently accessed list
import { recentlyAccessed } from 'ui/persisted_log';
import { i18n } from '@kbn/i18n';
-export function addItemToRecentlyAccessed(page, itemId, url) {
+export function addItemToRecentlyAccessed(page: string, itemId: string, url: string) {
let pageLabel = '';
let id = `ml-job-${itemId}`;
switch (page) {
case 'explorer':
pageLabel = i18n.translate('xpack.ml.anomalyExplorerPageLabel', {
- defaultMessage: 'Anomaly Explorer'
+ defaultMessage: 'Anomaly Explorer',
});
break;
case 'timeseriesexplorer':
pageLabel = i18n.translate('xpack.ml.singleMetricViewerPageLabel', {
- defaultMessage: 'Single Metric Viewer'
+ defaultMessage: 'Single Metric Viewer',
});
break;
case 'jobs/new_job/datavisualizer':
pageLabel = i18n.translate('xpack.ml.dataVisualizerPageLabel', {
- defaultMessage: 'Data Visualizer'
+ defaultMessage: 'Data Visualizer',
});
id = `ml-datavisualizer-${itemId}`;
break;
default:
+ // eslint-disable-next-line no-console
console.error('addItemToRecentlyAccessed - No page specified');
return;
- break;
}
url = `ml#/${page}/${url}`;
From b047654afc7ad7c4564cb87d53377cb85c40c6d0 Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Mon, 30 Sep 2019 14:11:06 +0200
Subject: [PATCH 04/17] [ML] restrict page width
---
.../ml/public/jobs/new_job_new/pages/job_type/page.tsx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
index d1525b1ce3950..37f0c15025b1f 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
@@ -152,8 +152,8 @@ export const Page: FC = () => {
return (
-
-
+
+
{
- {header}
+ {header}
{text}
From 35cdbc6f0804b605b9423eaf2dd0fb98b9b37667 Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Mon, 30 Sep 2019 16:23:33 +0200
Subject: [PATCH 05/17] [ML] refactor with CreateJobLinkCard
---
.../create_job_link_card.tsx | 57 +++-
.../jobs/new_job_new/pages/job_type/page.tsx | 262 ++++++++----------
2 files changed, 156 insertions(+), 163 deletions(-)
diff --git a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
index 6549df35ba381..b7946bada626a 100644
--- a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
+++ b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
@@ -6,23 +6,56 @@
import React, { FC } from 'react';
-import { EuiCard, EuiIcon, IconType } from '@elastic/eui';
+import {
+ EuiIcon,
+ IconType,
+ EuiText,
+ EuiTitle,
+ EuiFlexItem,
+ EuiFlexGroup,
+ EuiPanel,
+ EuiLink,
+} from '@elastic/eui';
interface Props {
iconType: IconType;
- title: string;
- description: string;
- onClick(): void;
+ title: any;
+ description: any;
+ href?: string;
+ onClick?: () => void;
+ isDisabled?: boolean;
}
// Component for rendering a card which links to the Create Job page, displaying an
// icon, card title, description and link.
-export const CreateJobLinkCard: FC = ({ iconType, title, description, onClick }) => (
- }
- title={title}
- description={description}
- onClick={onClick}
- />
+export const CreateJobLinkCard: FC = ({
+ iconType,
+ title,
+ description,
+ onClick,
+ href,
+ isDisabled,
+}) => (
+
+ {/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
+
+
+
+
+
+
+
+ {title}
+
+
+ {description}
+
+
+
+
+
);
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
index 37f0c15025b1f..9405dd44f8652 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
@@ -9,23 +9,19 @@ import { i18n } from '@kbn/i18n';
import {
EuiPage,
EuiPageBody,
- EuiPageContent,
EuiTitle,
EuiSpacer,
EuiCallOut,
EuiText,
EuiFlexGrid,
EuiFlexItem,
- EuiPanel,
- EuiFlexGroup,
- EuiLink,
- EuiIcon,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { useKibanaContext } from '../../../../contexts/kibana';
import { DataRecognizer } from '../../../../components/data_recognizer';
import { addItemToRecentlyAccessed } from '../../../../util/recently_accessed';
import { timeBasedIndexCheck } from '../../../../util/index_utils';
+import { CreateJobLinkCard } from '../../../../components/create_job_link_card';
export const Page: FC = () => {
const kibanaContext = useKibanaContext();
@@ -89,10 +85,10 @@ export const Page: FC = () => {
defaultMessage: 'Single metric job',
}),
},
- header: i18n.translate('xpack.ml.newJob.wizard.jobType.singleMetricTitle', {
+ title: i18n.translate('xpack.ml.newJob.wizard.jobType.singleMetricTitle', {
defaultMessage: 'Single metric',
}),
- text: i18n.translate('xpack.ml.newJob.wizard.jobType.singleMetricDescription', {
+ description: i18n.translate('xpack.ml.newJob.wizard.jobType.singleMetricDescription', {
defaultMessage: 'Detect anomalies in a single time series.',
}),
id: 'mlJobTypeLinkSingleMetricJob',
@@ -105,10 +101,10 @@ export const Page: FC = () => {
defaultMessage: 'Multi metric job',
}),
},
- header: i18n.translate('xpack.ml.newJob.wizard.jobType.multiMetricTitle', {
+ title: i18n.translate('xpack.ml.newJob.wizard.jobType.multiMetricTitle', {
defaultMessage: 'Multi metric',
}),
- text: i18n.translate('xpack.ml.newJob.wizard.jobType.multiMetricDescription', {
+ description: i18n.translate('xpack.ml.newJob.wizard.jobType.multiMetricDescription', {
defaultMessage:
'Detect anomalies in multiple metrics by splitting a time series by a categorical field.',
}),
@@ -122,10 +118,10 @@ export const Page: FC = () => {
defaultMessage: 'Population job',
}),
},
- header: i18n.translate('xpack.ml.newJob.wizard.jobType.populationTitle', {
+ title: i18n.translate('xpack.ml.newJob.wizard.jobType.populationTitle', {
defaultMessage: 'Population',
}),
- text: i18n.translate('xpack.ml.newJob.wizard.jobType.populationDescription', {
+ description: i18n.translate('xpack.ml.newJob.wizard.jobType.populationDescription', {
defaultMessage:
'Detect activity that is unusual compared to the behavior of the population.',
}),
@@ -139,10 +135,10 @@ export const Page: FC = () => {
defaultMessage: 'Advanced job',
}),
},
- header: i18n.translate('xpack.ml.newJob.wizard.jobType.advancedTitle', {
+ title: i18n.translate('xpack.ml.newJob.wizard.jobType.advancedTitle', {
defaultMessage: 'Advanced',
}),
- text: i18n.translate('xpack.ml.newJob.wizard.jobType.advancedDescription', {
+ description: i18n.translate('xpack.ml.newJob.wizard.jobType.advancedDescription', {
defaultMessage:
'Use the full range of options to create a job for more advanced use cases.',
}),
@@ -153,176 +149,140 @@ export const Page: FC = () => {
return (
-
-
-
-
-
-
-
-
- {isTimeBasedIndex === false && (
- <>
-
-
-
-
-
-
-
- >
- )}
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ {isTimeBasedIndex === false && (
+ <>
+
-
-
-
-
-
+
-
+ >
+ )}
+
-
- {jobTypes.map(({ href, icon, header, text, id }) => (
-
-
-
-
-
-
-
-
-
- {header}
-
-
- {text}
-
-
-
-
-
-
- ))}
-
+
+
-
-
-
-
-
-
-
-
+
+
+
-
-
+
+
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ {jobTypes.map(({ href, icon, title, description, id }) => (
+
+
-
-
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ description={
+
+ }
+ isDisabled={!isTimeBasedIndex}
+ onClick={addSelectionToRecentlyAccessed}
+ />
+
+
);
From dcaf46fe225c0f470d45fc26bc8a1a635d75cbb5 Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Mon, 30 Sep 2019 17:24:58 +0200
Subject: [PATCH 06/17] [ML] data-test-subj for functional tests
---
.../create_job_link_card/create_job_link_card.tsx | 7 ++++++-
.../ml/public/jobs/new_job_new/pages/job_type/page.tsx | 2 ++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
index b7946bada626a..b23be2e506294 100644
--- a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
+++ b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
@@ -19,22 +19,26 @@ import {
interface Props {
iconType: IconType;
+ iconAreaLabel?: string;
title: any;
description: any;
href?: string;
onClick?: () => void;
isDisabled?: boolean;
+ 'data-test-subj'?: string;
}
// Component for rendering a card which links to the Create Job page, displaying an
// icon, card title, description and link.
export const CreateJobLinkCard: FC = ({
iconType,
+ iconAreaLabel,
title,
description,
onClick,
href,
isDisabled,
+ 'data-test-subj': dateTestSubj,
}) => (
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
@@ -42,10 +46,11 @@ export const CreateJobLinkCard: FC = ({
href={href}
onClick={onClick}
style={{ display: 'block', pointerEvents: isDisabled ? 'none' : undefined }}
+ data-test-subj={dateTestSubj}
>
-
+
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
index 9405dd44f8652..b5d53153b05aa 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
@@ -230,8 +230,10 @@ export const Page: FC = () => {
{jobTypes.map(({ href, icon, title, description, id }) => (
Date: Mon, 30 Sep 2019 18:07:17 +0200
Subject: [PATCH 07/17] [ML] fix recognized results
---
.../create_job_link_card.tsx | 2 +-
.../jobs/new_job_new/pages/job_type/page.tsx | 22 +++++++++++++------
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
index b23be2e506294..8ece5d590338e 100644
--- a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
+++ b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
@@ -54,7 +54,7 @@ export const CreateJobLinkCard: FC = ({
- {title}
+ {title}
{description}
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
index b5d53153b05aa..8a0209add8bec 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React, { FC } from 'react';
+import React, { FC, useState } from 'react';
import { i18n } from '@kbn/i18n';
import {
EuiPage,
@@ -25,6 +25,7 @@ import { CreateJobLinkCard } from '../../../../components/create_job_link_card';
export const Page: FC = () => {
const kibanaContext = useKibanaContext();
+ const [recognizerResultsCount, setRecognizerResultsCount] = useState(0);
const { currentSavedSearch, currentIndexPattern } = kibanaContext;
@@ -59,6 +60,9 @@ export const Page: FC = () => {
const recognizerResults = {
count: 0,
+ onChange() {
+ setRecognizerResultsCount(recognizerResults.count);
+ },
};
const getUrl = (basePath: string) => {
@@ -175,7 +179,7 @@ export const Page: FC = () => {
>
)}
-
+
@@ -197,11 +201,15 @@ export const Page: FC = () => {
-
+
+
+
+
+
From 8c30a6b5ead0cd7bfbf8d6cde13d9a3b2348b3b7 Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Mon, 30 Sep 2019 19:18:46 +0200
Subject: [PATCH 08/17] [ML] missing i18n
---
.../jobs/new_job_new/pages/job_type/page.tsx | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
index 8a0209add8bec..ab40c4a7013cb 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
@@ -15,6 +15,7 @@ import {
EuiText,
EuiFlexGrid,
EuiFlexItem,
+ EuiLink,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { useKibanaContext } from '../../../../contexts/kibana';
@@ -173,8 +174,14 @@ export const Page: FC = () => {
defaultMessage="Anomaly detection can only be run over indices which are time based."
/>
+
+
+
+
-
>
)}
@@ -276,6 +283,12 @@ export const Page: FC = () => {
Date: Mon, 30 Sep 2019 21:54:24 +0200
Subject: [PATCH 09/17] [ML] add custom logo support for create job link card,
change data recognizer layout
---
.../create_job_link_card.tsx | 10 ++++--
.../data_recognizer/data_recognizer.js | 5 +--
.../data_recognizer/recognized_result.js | 32 +++++++------------
.../jobs/new_job_new/pages/job_type/page.tsx | 14 +++-----
4 files changed, 26 insertions(+), 35 deletions(-)
diff --git a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
index 8ece5d590338e..8f440ff216888 100644
--- a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
+++ b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React, { FC } from 'react';
+import React, { FC, ReactElement } from 'react';
import {
EuiIcon,
@@ -18,7 +18,7 @@ import {
} from '@elastic/eui';
interface Props {
- iconType: IconType;
+ iconType: IconType | ReactElement;
iconAreaLabel?: string;
title: any;
description: any;
@@ -50,7 +50,11 @@ export const CreateJobLinkCard: FC = ({
>
-
+ {typeof iconType === 'string' ? (
+
+ ) : (
+ iconType
+ )}
diff --git a/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.js b/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.js
index fd754ee519104..e9826b6876fb7 100644
--- a/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.js
+++ b/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.js
@@ -8,6 +8,7 @@
import PropTypes from 'prop-types';
+import { EuiFlexGrid } from '@elastic/eui';
import React, { Component } from 'react';
import { RecognizedResult } from './recognized_result';
@@ -57,9 +58,9 @@ export class DataRecognizer extends Component {
render() {
return (
-
+
{this.state.results}
-
+
);
}
}
diff --git a/x-pack/legacy/plugins/ml/public/components/data_recognizer/recognized_result.js b/x-pack/legacy/plugins/ml/public/components/data_recognizer/recognized_result.js
index 60dc38f2291f8..67594536057e1 100644
--- a/x-pack/legacy/plugins/ml/public/components/data_recognizer/recognized_result.js
+++ b/x-pack/legacy/plugins/ml/public/components/data_recognizer/recognized_result.js
@@ -11,7 +11,9 @@ import PropTypes from 'prop-types';
import {
EuiIcon,
+ EuiFlexItem
} from '@elastic/eui';
+import { CreateJobLinkCard } from '../create_job_link_card';
export const RecognizedResult = ({
config,
@@ -36,27 +38,15 @@ export const RecognizedResult = ({
}
return (
-
+
+
+
);
};
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
index ab40c4a7013cb..861960854ffab 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
@@ -208,15 +208,11 @@ export const Page: FC = () => {
-
-
-
-
-
+
From 98bf7369888508035df613868f85e45e1bf55c9d Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Mon, 30 Sep 2019 21:56:40 +0200
Subject: [PATCH 10/17] [ML] rename iconType prop
---
.../create_job_link_card/create_job_link_card.tsx | 10 +++++-----
.../components/data_recognizer/recognized_result.js | 2 +-
.../components/actions_panel/actions_panel.tsx | 2 +-
.../ml/public/jobs/new_job_new/pages/job_type/page.tsx | 4 ++--
4 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
index 8f440ff216888..a03044bebb953 100644
--- a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
+++ b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
@@ -18,7 +18,7 @@ import {
} from '@elastic/eui';
interface Props {
- iconType: IconType | ReactElement;
+ icon: IconType | ReactElement;
iconAreaLabel?: string;
title: any;
description: any;
@@ -31,7 +31,7 @@ interface Props {
// Component for rendering a card which links to the Create Job page, displaying an
// icon, card title, description and link.
export const CreateJobLinkCard: FC = ({
- iconType,
+ icon,
iconAreaLabel,
title,
description,
@@ -50,10 +50,10 @@ export const CreateJobLinkCard: FC = ({
>
- {typeof iconType === 'string' ? (
-
+ {typeof icon === 'string' ? (
+
) : (
- iconType
+ icon
)}
diff --git a/x-pack/legacy/plugins/ml/public/components/data_recognizer/recognized_result.js b/x-pack/legacy/plugins/ml/public/components/data_recognizer/recognized_result.js
index 67594536057e1..bae9443d49bb3 100644
--- a/x-pack/legacy/plugins/ml/public/components/data_recognizer/recognized_result.js
+++ b/x-pack/legacy/plugins/ml/public/components/data_recognizer/recognized_result.js
@@ -44,7 +44,7 @@ export const RecognizedResult = ({
href={href}
title={config.title}
description={config.description}
- iconType={logo}
+ icon={logo}
/>
);
diff --git a/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/components/actions_panel/actions_panel.tsx b/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/components/actions_panel/actions_panel.tsx
index 9a291cabf558f..c115d2c77007d 100644
--- a/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/components/actions_panel/actions_panel.tsx
+++ b/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/components/actions_panel/actions_panel.tsx
@@ -80,7 +80,7 @@ export const ActionsPanel: FC = ({ indexPattern }) => {
{
{
Date: Tue, 1 Oct 2019 09:28:24 +0200
Subject: [PATCH 11/17] [ML] remove unused styles
---
.../data_recognizer/_data_recognizer.scss | 31 -----------
.../data_recognizer/recognized_result.js | 4 +-
.../public/jobs/new_job/wizard/_wizard.scss | 53 -------------------
3 files changed, 2 insertions(+), 86 deletions(-)
delete mode 100644 x-pack/legacy/plugins/ml/public/components/data_recognizer/_data_recognizer.scss
diff --git a/x-pack/legacy/plugins/ml/public/components/data_recognizer/_data_recognizer.scss b/x-pack/legacy/plugins/ml/public/components/data_recognizer/_data_recognizer.scss
deleted file mode 100644
index b915be2ab8453..0000000000000
--- a/x-pack/legacy/plugins/ml/public/components/data_recognizer/_data_recognizer.scss
+++ /dev/null
@@ -1,31 +0,0 @@
-ml-data-recognizer {
- .ml-data-recognizer-logo {
- width: $euiSizeXL;
- }
-}
-
-// Moved here from /home since it's no longer being used there
-.synopsis {
- display: flex;
- flex-grow: 1;
- cursor: pointer;
-
- &:hover,
- &:focus {
- text-decoration: none;
-
- .synopsisTitle {
- text-decoration: underline;
- }
- }
-}
-
-.synopsisTitle {
- font-size: $euiSize;
- font-weight: normal;
- color: $euiColorPrimary;
-}
-
-.synopsisIcon {
- padding-top: $euiSizeS;
-}
diff --git a/x-pack/legacy/plugins/ml/public/components/data_recognizer/recognized_result.js b/x-pack/legacy/plugins/ml/public/components/data_recognizer/recognized_result.js
index bae9443d49bb3..6f511abf89e31 100644
--- a/x-pack/legacy/plugins/ml/public/components/data_recognizer/recognized_result.js
+++ b/x-pack/legacy/plugins/ml/public/components/data_recognizer/recognized_result.js
@@ -30,9 +30,9 @@ export const RecognizedResult = ({
// if a logo is available, use that, otherwise display the id
// the logo should be a base64 encoded image or an eui icon
if(config.logo && config.logo.icon) {
- logo =
;
+ logo = ;
} else if (config.logo && config.logo.src) {
- logo = ;
+ logo =
;
} else {
logo = {config.id}
;
}
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/_wizard.scss b/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/_wizard.scss
index 7eadb9a8ce77a..def24f6d6a747 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/_wizard.scss
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job/wizard/_wizard.scss
@@ -1,56 +1,3 @@
-.job-type-gallery {
- width: 100%;
- padding-right: $euiSizeS;
- padding-left: $euiSizeS;
- background-color: $euiColorLightestShade;
- flex: 1 0 auto;
-
- .job-types-content {
- max-width: 1200px; // SASSTODO: Proper calc
- margin-right: auto;
- margin-left: auto;
- }
-
- .synopsis {
- display: flex;
- flex-grow: 1;
-
- .synopsisTitle {
- font-size: $euiFontSize;
- font-weight: normal;
- color: $euiColorPrimary;
- }
-
- .synopsisIcon {
- padding-top: $euiSizeS;
- }
- }
-
- .synopsis:hover {
- text-decoration: none;
-
- .synopsisTitle {
- text-decoration: underline;
- }
- }
-
- .euiFlexItem.disabled {
- cursor: not-allowed;
- }
-
- .synopsis.disabled {
- pointer-events: none;
-
- .synopsisTitle {
- color: $euiColorDarkShade;
- }
- }
-
- .index-warning {
- border: $euiBorderThin;
- }
-}
-
.index-or-saved-search-selection {
.kuiBarSection .kuiButtonGroup {
display: none;
From 5504a4776a2d8314f2b2e1918d194c6d57dc6952 Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Tue, 1 Oct 2019 10:13:57 +0200
Subject: [PATCH 12/17] [ML] fix page background
---
x-pack/legacy/plugins/ml/public/_hacks.scss | 13 +------------
.../public/components/data_recognizer/_index.scss | 1 -
x-pack/legacy/plugins/ml/public/index.scss | 1 -
3 files changed, 1 insertion(+), 14 deletions(-)
delete mode 100644 x-pack/legacy/plugins/ml/public/components/data_recognizer/_index.scss
diff --git a/x-pack/legacy/plugins/ml/public/_hacks.scss b/x-pack/legacy/plugins/ml/public/_hacks.scss
index b0a8a43d23096..39740360d8a84 100644
--- a/x-pack/legacy/plugins/ml/public/_hacks.scss
+++ b/x-pack/legacy/plugins/ml/public/_hacks.scss
@@ -1,21 +1,10 @@
.tab-datavisualizer_index_select,
.tab-timeseriesexplorer,
-.tab-explorer,
-.tab-jobs {
+.tab-explorer, {
// Make all page background white until More of the pages use EuiPage to wrap in panel-like components
background-color: $euiColorEmptyShade;
}
-.tab-jobs {
- label {
- display: inline-block;
- }
-
- .validation-error {
- margin-top: $euiSizeXS;
- }
-}
-
// ML specific bootstrap hacks
.button-wrapper {
display: inline;
diff --git a/x-pack/legacy/plugins/ml/public/components/data_recognizer/_index.scss b/x-pack/legacy/plugins/ml/public/components/data_recognizer/_index.scss
deleted file mode 100644
index 67cc4372ea622..0000000000000
--- a/x-pack/legacy/plugins/ml/public/components/data_recognizer/_index.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import 'data_recognizer';
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/ml/public/index.scss b/x-pack/legacy/plugins/ml/public/index.scss
index 4cab633d5fa56..a3fefb7b1fac8 100644
--- a/x-pack/legacy/plugins/ml/public/index.scss
+++ b/x-pack/legacy/plugins/ml/public/index.scss
@@ -36,7 +36,6 @@
@import 'components/chart_tooltip/index';
@import 'components/confirm_modal/index';
@import 'components/controls/index';
- @import 'components/data_recognizer/index';
@import 'components/documentation_help_link/index';
@import 'components/entity_cell/index';
@import 'components/field_title_bar/index';
From a351d66eca6c7487a76a87428e77714ea1e4fe0e Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Tue, 1 Oct 2019 12:11:51 +0200
Subject: [PATCH 13/17] [ML] data recognizer wrappers
---
.../components/data_recognizer/data_recognizer.js | 5 ++---
.../components/actions_panel/actions_panel.tsx | 10 ++++------
.../public/jobs/new_job_new/pages/job_type/page.tsx | 12 +++++++-----
3 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.js b/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.js
index e9826b6876fb7..b303ed9b7f008 100644
--- a/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.js
+++ b/x-pack/legacy/plugins/ml/public/components/data_recognizer/data_recognizer.js
@@ -8,7 +8,6 @@
import PropTypes from 'prop-types';
-import { EuiFlexGrid } from '@elastic/eui';
import React, { Component } from 'react';
import { RecognizedResult } from './recognized_result';
@@ -58,9 +57,9 @@ export class DataRecognizer extends Component {
render() {
return (
-
+ <>
{this.state.results}
-
+ >
);
}
}
diff --git a/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/components/actions_panel/actions_panel.tsx b/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/components/actions_panel/actions_panel.tsx
index c115d2c77007d..c6488135cfb88 100644
--- a/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/components/actions_panel/actions_panel.tsx
+++ b/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/components/actions_panel/actions_panel.tsx
@@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n';
import { IndexPattern } from 'ui/index_patterns';
-import { EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
+import { EuiPanel, EuiSpacer, EuiText, EuiTitle, EuiFlexGroup } from '@elastic/eui';
import { useUiChromeContext } from '../../../../contexts/ui/use_ui_chrome_context';
import { CreateJobLinkCard } from '../../../../components/create_job_link_card';
@@ -63,11 +63,9 @@ export const ActionsPanel: FC = ({ indexPattern }) => {
-
+
+
+
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
index 43d2c7f6622b2..2fd1fa8d6a53a 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
@@ -208,11 +208,13 @@ export const Page: FC = () => {
-
+
+
+
From 0a087e33689c893b13ce608219a2154b2aa77fec Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Tue, 1 Oct 2019 13:24:39 +0200
Subject: [PATCH 14/17] [ML] fix IE issue, IndexPatternSavedObject
---
.../create_job_link_card.tsx | 69 +++++++++++--------
.../jobs/new_job_new/pages/job_type/page.tsx | 2 +-
.../plugins/ml/public/util/index_utils.ts | 6 +-
3 files changed, 45 insertions(+), 32 deletions(-)
diff --git a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
index a03044bebb953..40f7cd7153578 100644
--- a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
+++ b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
@@ -39,32 +39,43 @@ export const CreateJobLinkCard: FC = ({
href,
isDisabled,
'data-test-subj': dateTestSubj,
-}) => (
-
- {/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
-
-
-
- {typeof icon === 'string' ? (
-
- ) : (
- icon
- )}
-
-
-
- {title}
-
-
- {description}
-
-
-
-
-
-);
+}) => {
+ const linkHrefAndOnClickProps = {
+ ...(href ? { href } : {}),
+ ...(onClick ? { onClick } : {}),
+ };
+ return (
+
+
+
+
+ {typeof icon === 'string' ? (
+
+ ) : (
+ icon
+ )}
+
+
+
+ {title}
+
+
+ {description}
+
+
+
+
+
+ );
+};
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
index 2fd1fa8d6a53a..390e43348ce90 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
@@ -174,7 +174,6 @@ export const Page: FC = () => {
defaultMessage="Anomaly detection can only be run over indices which are time based."
/>
-
{
}
isDisabled={!isTimeBasedIndex}
onClick={addSelectionToRecentlyAccessed}
+ href={getUrl('#jobs/new_job/datavisualizer')}
/>
diff --git a/x-pack/legacy/plugins/ml/public/util/index_utils.ts b/x-pack/legacy/plugins/ml/public/util/index_utils.ts
index 16a651dae766e..41dd13555726c 100644
--- a/x-pack/legacy/plugins/ml/public/util/index_utils.ts
+++ b/x-pack/legacy/plugins/ml/public/util/index_utils.ts
@@ -12,10 +12,12 @@ import chrome from 'ui/chrome';
import { SavedSearchLoader } from '../../../../../../src/legacy/core_plugins/kibana/public/discover/types';
import { setup as data } from '../../../../../../src/legacy/core_plugins/data/public/legacy';
-let indexPatternCache: Array> = [];
+type IndexPatternSavedObject = SimpleSavedObject;
+
+let indexPatternCache: IndexPatternSavedObject[] = [];
let fullIndexPatterns: IndexPatterns | null = null;
-export let refreshIndexPatterns: (() => Promise) | null = null;
+export let refreshIndexPatterns: (() => Promise) | null = null;
export function loadIndexPatterns() {
fullIndexPatterns = data.indexPatterns.indexPatterns;
From 6bfbd920b32db2c8a2ee0d28ad4db8e13a38ceef Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Tue, 1 Oct 2019 13:32:54 +0200
Subject: [PATCH 15/17] [ML] fix callout
---
.../jobs/new_job_new/pages/job_type/page.tsx | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
index 390e43348ce90..4991039ffa288 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/page.tsx
@@ -167,13 +167,12 @@ export const Page: FC = () => {
{isTimeBasedIndex === false && (
<>
-
-
-
-
+
+
+
{
defaultMessage="Learn more about the characteristics of your data and identify the fields for analysis with machine learning."
/>
}
- isDisabled={!isTimeBasedIndex}
onClick={addSelectionToRecentlyAccessed}
href={getUrl('#jobs/new_job/datavisualizer')}
/>
From e6848220184c20ab94049ccae2bcb758939d4290 Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Tue, 1 Oct 2019 13:45:49 +0200
Subject: [PATCH 16/17] [ML] job type directive test
---
.../pages/job_type/__test__/directive.ts | 45 +++++++++++++++++++
1 file changed, 45 insertions(+)
create mode 100644 x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/__test__/directive.ts
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/__test__/directive.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/__test__/directive.ts
new file mode 100644
index 0000000000000..d7c1b7ec316a6
--- /dev/null
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/__test__/directive.ts
@@ -0,0 +1,45 @@
+/*
+ * 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 ngMock from 'ng_mock';
+import expect from '@kbn/expect';
+import sinon from 'sinon';
+
+// Import this way to be able to stub/mock functions later on in the tests using sinon.
+import * as indexUtils from 'plugins/ml/util/index_utils';
+
+describe('ML - Job Type Directive', () => {
+ let $scope;
+ let $compile;
+ let $element;
+
+ beforeEach(ngMock.module('kibana'));
+ beforeEach(() => {
+ ngMock.inject(function($injector) {
+ $compile = $injector.get('$compile');
+ const $rootScope = $injector.get('$rootScope');
+ $scope = $rootScope.$new();
+ });
+ });
+
+ afterEach(() => {
+ $scope.$destroy();
+ });
+
+ it('Initialize Job Type Directive', done => {
+ const stub = sinon.stub(indexUtils, 'timeBasedIndexCheck').callsFake(() => false);
+ ngMock.inject(function() {
+ expect(() => {
+ $element = $compile('')($scope);
+ }).to.not.throwError();
+
+ // directive has scope: false
+ const scope = $element.isolateScope();
+ expect(scope).to.eql(undefined);
+ done();
+ });
+ });
+});
From 1c89849fddd8d777c398a10acd2f039ae1c45383 Mon Sep 17 00:00:00 2001
From: Dmitrii Arnautov
Date: Tue, 1 Oct 2019 14:34:31 +0200
Subject: [PATCH 17/17] [ML] fix types
---
.../create_job_link_card/create_job_link_card.tsx | 1 -
.../index_based/components/actions_panel/actions_panel.tsx | 1 +
.../pages/job_type/__test__/{directive.ts => directive.js} | 6 +++---
3 files changed, 4 insertions(+), 4 deletions(-)
rename x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/__test__/{directive.ts => directive.js} (87%)
diff --git a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
index 40f7cd7153578..07a924caae772 100644
--- a/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
+++ b/x-pack/legacy/plugins/ml/public/components/create_job_link_card/create_job_link_card.tsx
@@ -55,7 +55,6 @@ export const CreateJobLinkCard: FC = ({
}}
data-test-subj={dateTestSubj}
color="subdued"
- type="link"
{...linkHrefAndOnClickProps}
>
diff --git a/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/components/actions_panel/actions_panel.tsx b/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/components/actions_panel/actions_panel.tsx
index c6488135cfb88..c8295a1e3d8db 100644
--- a/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/components/actions_panel/actions_panel.tsx
+++ b/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/components/actions_panel/actions_panel.tsx
@@ -87,6 +87,7 @@ export const ActionsPanel: FC = ({ indexPattern }) => {
'Use the full range of options to create a job for more advanced use cases',
})}
onClick={openAdvancedJobWizard}
+ href={`${basePath}/app/ml#/jobs/new_job/advanced?index=${indexPattern}`}
/>
);
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/__test__/directive.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/__test__/directive.js
similarity index 87%
rename from x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/__test__/directive.ts
rename to x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/__test__/directive.js
index d7c1b7ec316a6..5be526f2eb2c0 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/__test__/directive.ts
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/job_type/__test__/directive.js
@@ -18,7 +18,7 @@ describe('ML - Job Type Directive', () => {
beforeEach(ngMock.module('kibana'));
beforeEach(() => {
- ngMock.inject(function($injector) {
+ ngMock.inject(function ($injector) {
$compile = $injector.get('$compile');
const $rootScope = $injector.get('$rootScope');
$scope = $rootScope.$new();
@@ -30,8 +30,8 @@ describe('ML - Job Type Directive', () => {
});
it('Initialize Job Type Directive', done => {
- const stub = sinon.stub(indexUtils, 'timeBasedIndexCheck').callsFake(() => false);
- ngMock.inject(function() {
+ sinon.stub(indexUtils, 'timeBasedIndexCheck').callsFake(() => false);
+ ngMock.inject(function () {
expect(() => {
$element = $compile('')($scope);
}).to.not.throwError();