diff --git a/x-pack/plugins/ml/public/settings/__snapshots__/settings.test.js.snap b/x-pack/plugins/ml/public/settings/__snapshots__/settings.test.js.snap
new file mode 100644
index 000000000000..0d573849d96f
--- /dev/null
+++ b/x-pack/plugins/ml/public/settings/__snapshots__/settings.test.js.snap
@@ -0,0 +1,74 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Settings Renders settings page 1`] = `
+
+
+
+
+
+
+ Job Management
+
+
+
+
+
+
+ Calendar management
+
+
+
+
+ Filter Lists
+
+
+
+
+
+
+`;
diff --git a/x-pack/plugins/ml/public/settings/__tests__/settings_controller.js b/x-pack/plugins/ml/public/settings/__tests__/settings_controller.js
deleted file mode 100644
index 5f7e1aec5da6..000000000000
--- a/x-pack/plugins/ml/public/settings/__tests__/settings_controller.js
+++ /dev/null
@@ -1,29 +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 'expect.js';
-
-describe('ML - Settings Controller', () => {
- beforeEach(() => {
- ngMock.module('kibana');
- });
-
- it('Initialize Settings Controller', (done) => {
- ngMock.inject(function ($rootScope, $controller) {
- const scope = $rootScope.$new();
-
- expect(() => {
- $controller('MlSettings', { $scope: scope });
- }).to.not.throwError();
-
- expect(scope.canCreateFilter).to.eql(false);
- done();
- });
- });
-});
diff --git a/x-pack/plugins/ml/public/settings/_settings.scss b/x-pack/plugins/ml/public/settings/_settings.scss
index 281e1156b79e..8659ea3ec2a0 100644
--- a/x-pack/plugins/ml/public/settings/_settings.scss
+++ b/x-pack/plugins/ml/public/settings/_settings.scss
@@ -1,18 +1,14 @@
-.disabled {
- color: $euiColorMediumShade;
- cursor: pointer;
-}
+.mlSettingsPage {
-ml-settings {
- .mgtPanel {
- .mgtPanel__link {
- font-size: $euiFontSizeM;
- line-height: $euiSizeXL;
- margin-left: $euiSizeXS;
- }
-
- .disabled {
- color: $euiColorMediumShade;
- }
+ .mlSettingsPage__body {
+ background: $euiColorLightestShade;
+ min-height: 100vh;
}
-}
\ No newline at end of file
+
+ .mlSettingsPage__content {
+ width: map-get($euiBreakpoints, 'xl');
+ margin-top: $euiSize;
+ margin-bottom: $euiSize;
+ }
+
+}
diff --git a/x-pack/plugins/ml/public/settings/index.js b/x-pack/plugins/ml/public/settings/index.js
index 5faba118e050..659f135d98c5 100644
--- a/x-pack/plugins/ml/public/settings/index.js
+++ b/x-pack/plugins/ml/public/settings/index.js
@@ -6,6 +6,6 @@
-import './settings_controller';
+import './settings_directive';
import './calendars';
import './filter_lists';
diff --git a/x-pack/plugins/ml/public/settings/settings.html b/x-pack/plugins/ml/public/settings/settings.html
deleted file mode 100644
index b50900a02052..000000000000
--- a/x-pack/plugins/ml/public/settings/settings.html
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
-
-
diff --git a/x-pack/plugins/ml/public/settings/settings.js b/x-pack/plugins/ml/public/settings/settings.js
new file mode 100644
index 000000000000..ac921ddcd028
--- /dev/null
+++ b/x-pack/plugins/ml/public/settings/settings.js
@@ -0,0 +1,75 @@
+/*
+ * 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 { PropTypes } from 'prop-types';
+
+import {
+ EuiButtonEmpty,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiPage,
+ EuiPageContentHeader,
+ EuiPageContent,
+ EuiPageBody,
+ EuiTitle
+} from '@elastic/eui';
+
+import chrome from 'ui/chrome';
+
+
+export function Settings({ canCreateFilter, canCreateCalendar }) {
+ return (
+
+
+
+
+
+ Job Management
+
+
+
+
+
+
+ Calendar management
+
+
+
+
+
+ Filter Lists
+
+
+
+
+
+
+
+ );
+}
+
+Settings.propTypes = {
+ canCreateFilter: PropTypes.bool.isRequired,
+ canCreateCalendar: PropTypes.bool.isRequired,
+};
diff --git a/x-pack/plugins/ml/public/settings/settings.test.js b/x-pack/plugins/ml/public/settings/settings.test.js
new file mode 100644
index 000000000000..85f970b7bf08
--- /dev/null
+++ b/x-pack/plugins/ml/public/settings/settings.test.js
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+
+
+jest.mock('ui/chrome', () => ({
+ getBasePath: jest.fn()
+}));
+
+import { shallow, mount } from 'enzyme';
+import React from 'react';
+
+import { Settings } from './settings';
+
+
+describe('Settings', () => {
+
+ test('Renders settings page', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ test('Filter Lists button disabled if canCreateFilter is false', () => {
+ const wrapper = mount(
+
+ );
+
+ const button = wrapper.find('[data-testid="ml_filter_lists_button"]');
+ const filterButton = button.find('EuiButtonEmpty');
+ expect(filterButton.prop('isDisabled')).toBe(true);
+ });
+
+ test('Calendar management button disabled if canCreateCalendar is false', () => {
+ const wrapper = mount(
+
+ );
+
+ const button = wrapper.find('[data-testid="ml_calendar_mng_button"]');
+ const calendarButton = button.find('EuiButtonEmpty');
+ expect(calendarButton.prop('isDisabled')).toBe(true);
+ });
+
+});
diff --git a/x-pack/plugins/ml/public/settings/settings_controller.js b/x-pack/plugins/ml/public/settings/settings_controller.js
deleted file mode 100644
index b4c0e123ef1e..000000000000
--- a/x-pack/plugins/ml/public/settings/settings_controller.js
+++ /dev/null
@@ -1,39 +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 uiRoutes from 'ui/routes';
-import { checkFullLicense } from 'plugins/ml/license/check_license';
-import { checkGetJobsPrivilege, checkPermission } from 'plugins/ml/privilege/check_privilege';
-import { getMlNodeCount } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
-import { initPromise } from 'plugins/ml/util/promise';
-
-import template from './settings.html';
-
-import { timefilter } from 'ui/timefilter';
-
-uiRoutes
- .when('/settings', {
- template,
- resolve: {
- CheckLicense: checkFullLicense,
- privileges: checkGetJobsPrivilege,
- mlNodeCount: getMlNodeCount,
- initPromise: initPromise(true)
- }
- });
-
-import { uiModules } from 'ui/modules';
-const module = uiModules.get('apps/ml');
-
-module.controller('MlSettings', function ($scope) {
-
- timefilter.disableTimeRangeSelector(); // remove time picker from top of page
- timefilter.disableAutoRefreshSelector(); // remove time picker from top of page
-
- $scope.canCreateFilter = checkPermission('canCreateFilter');
-});
diff --git a/x-pack/plugins/ml/public/settings/settings_directive.js b/x-pack/plugins/ml/public/settings/settings_directive.js
new file mode 100644
index 000000000000..767933c6e2ed
--- /dev/null
+++ b/x-pack/plugins/ml/public/settings/settings_directive.js
@@ -0,0 +1,63 @@
+/*
+ * 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 'ngreact';
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+import { uiModules } from 'ui/modules';
+const module = uiModules.get('apps/ml', ['react']);
+
+import { checkFullLicense } from '../license/check_license';
+import { checkGetJobsPrivilege, checkPermission } from '../privilege/check_privilege';
+import { getMlNodeCount } from '../ml_nodes_check/check_ml_nodes';
+import { initPromise } from '../util/promise';
+
+import uiRoutes from 'ui/routes';
+import { timefilter } from 'ui/timefilter';
+
+const template = `
+
+
+
+
+`;
+
+uiRoutes
+ .when('/settings', {
+ template,
+ resolve: {
+ CheckLicense: checkFullLicense,
+ privileges: checkGetJobsPrivilege,
+ mlNodeCount: getMlNodeCount,
+ initPromise: initPromise(false)
+ }
+ });
+
+
+import { Settings } from './settings.js';
+
+module.directive('mlSettings', function () {
+
+ timefilter.disableTimeRangeSelector(); // remove time picker from top of page
+ timefilter.disableAutoRefreshSelector(); // remove time picker from top of page
+
+ const canCreateFilter = checkPermission('canCreateFilter');
+ const canCreateCalendar = checkPermission('canCreateCalendar');
+
+ return {
+ restrict: 'E',
+ replace: false,
+ scope: {},
+ link: function (scope, element) {
+ ReactDOM.render(
+ React.createElement(Settings, { canCreateFilter, canCreateCalendar }),
+ element[0]
+ );
+ }
+ };
+});