Skip to content

Commit

Permalink
[ML] Converts full time range selector control to EUI / React (elasti…
Browse files Browse the repository at this point in the history
…c#35074)

* [ML] Converts full time range selector control to EUI / React

* [ML] Remove console log from time range selector service

* [ML] Fix linting errors in full time range selector ts files

* [ML] Switch to using I18nContext in wrapping directive

* [ML] Remove unnecessary return from setFullTimeRange

* [ML] Add setFullTimeRange return back in for clone job settings
  • Loading branch information
peteharverson committed Apr 16, 2019
1 parent dee396e commit 02bde32
Show file tree
Hide file tree
Showing 18 changed files with 200 additions and 97 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,54 @@
*/


import React from 'react';
import ReactDOM from 'react-dom';

import template from './full_time_range_selector.html';
import { uiModules } from 'ui/modules';
const module = uiModules.get('apps/ml', ['react']);

import { FullTimeRangeSelectorServiceProvider } from 'plugins/ml/components/full_time_range_selector/full_time_range_selector_service';
import { I18nContext } from 'ui/i18n';

import { uiModules } from 'ui/modules';
const module = uiModules.get('apps/ml');
import { FullTimeRangeSelector } from './index';

module.directive('mlFullTimeRangeSelector', function (Private) {
// Angular directive wrapper for the 'Use full time range' button.
module.directive('mlFullTimeRangeSelector', function () {
return {
restrict: 'E',
replace: true,
template,
scope: {
indexPattern: '=',
disabled: '=',
query: '='
},
controller: function ($scope) {
const mlFullTimeRangeSelectorService = Private(FullTimeRangeSelectorServiceProvider);
link: (scope, element) => {

function renderComponent() {
const props = {
indexPattern: scope.indexPattern,
query: scope.query,
disabled: scope.disabled
};

ReactDOM.render(
<I18nContext>
{React.createElement(FullTimeRangeSelector, props)}
</I18nContext>,
element[0]
);
}

renderComponent();

// As the directive is only used in the job wizards and the data visualizer,
// it is safe to only watch the disabled property.
scope.$watch('disabled', renderComponent);

element.on('$destroy', () => {
scope.$destroy();
});

$scope.setFullTimeRange = function () {
mlFullTimeRangeSelectorService.setFullTimeRange($scope.indexPattern, $scope.query);
};
}

};
});

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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 moment from 'moment';

import { i18n } from '@kbn/i18n';
import { Query } from 'ui/embeddable';
import { IndexPattern } from 'ui/index_patterns';
import { toastNotifications } from 'ui/notify';
import { timefilter } from 'ui/timefilter';
import { ml } from '../../services/ml_api_service';

export function setFullTimeRange(indexPattern: IndexPattern, query: Query) {
return ml
.getTimeFieldRange({
index: indexPattern.title,
timeFieldName: indexPattern.timeFieldName,
query,
})
.then(resp => {
timefilter.setTime({
from: moment(resp.start.epoch).toISOString(),
to: moment(resp.end.epoch).toISOString(),
});
})
.catch(resp => {
toastNotifications.addDanger(
i18n.translate('xpack.ml.fullTimeRangeSelector.errorSettingTimeRangeNotification', {
defaultMessage: 'An error occurred setting the time range.',
})
);
});
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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 { shallowWithIntl } from 'test_utils/enzyme_helpers';

import { Query } from 'ui/embeddable';
import { QueryLanguageType } from 'ui/embeddable/types';
import { IndexPattern } from 'ui/index_patterns';
import { FullTimeRangeSelector } from './index';

// Create a mock for the setFullTimeRange function in the service.
// The mock is hoisted to the top, so need to prefix the mock function
// with 'mock' so it can be used lazily.
const mockSetFullTimeRange = jest.fn((indexPattern: IndexPattern, query: Query) => true);
jest.mock('./full_time_range_selector_service', () => ({
setFullTimeRange: (indexPattern: IndexPattern, query: Query) =>
mockSetFullTimeRange(indexPattern, query),
}));

describe('FullTimeRangeSelector', () => {
const indexPattern: IndexPattern = {
id: '0844fc70-5ab5-11e9-935e-836737467b0f',
fields: [],
title: 'test-index-pattern',
timeFieldName: '@timestamp',
};

const query: Query = {
language: QueryLanguageType.KUERY,
query: 'region:us-east-1',
};

const requiredProps = {
indexPattern,
query,
};

test('renders the selector', () => {
const props = {
...requiredProps,
disabled: false,
};

const wrapper = shallowWithIntl(<FullTimeRangeSelector {...props} />);
expect(wrapper).toMatchSnapshot();
});

test('calls setFullTimeRange on clicking button', () => {
const props = {
...requiredProps,
disabled: false,
};

const wrapper = shallowWithIntl(<FullTimeRangeSelector {...props} />);
wrapper.find('EuiButton').simulate('click');
expect(mockSetFullTimeRange).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* 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 { FormattedMessage } from '@kbn/i18n/react';
import { Query } from 'ui/embeddable';
import { IndexPattern } from 'ui/index_patterns';
import { EuiButton } from '@elastic/eui';
import { setFullTimeRange } from './full_time_range_selector_service';

interface Props {
indexPattern: IndexPattern;
query: Query;
disabled: boolean;
}

// Component for rendering a button which automatically sets the range of the time filter
// to the time range of data in the index(es) mapped to the supplied Kibana index pattern or query.
export const FullTimeRangeSelector: React.SFC<Props> = ({ indexPattern, query, disabled }) => {
return (
<EuiButton fill isDisabled={disabled} onClick={() => setFullTimeRange(indexPattern, query)}>
<FormattedMessage
id="xpack.ml.fullTimeRangeSelector.useFullDataButtonLabel"
defaultMessage="Use full {indexPatternTitle} data"
values={{
indexPatternTitle: indexPattern.title,
}}
/>
</EuiButton>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<h1>{{indexPattern.title}}</h1>
</div>
<div class="euiFlexItem euiFlexItem--flexGrowZero">
<ml-full-time-range-selector ng-if="showSidebar" index-pattern='indexPattern' query='searchQuery' />
<ml-full-time-range-selector ng-if="showSidebar" index-pattern='indexPattern' query='searchQuery' />
</div>
</div>

Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/ml/public/datavisualizer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ import './datavisualizer_controller';
import 'plugins/ml/components/data_recognizer';
import 'plugins/ml/components/field_data_card';
import 'plugins/ml/services/mapping_service';
import 'plugins/ml/components/full_time_range_selector';
import 'plugins/ml/components/full_time_range_selector/full_time_range_selector_directive';
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { mlJobService } from 'plugins/ml/services/job_service';
import { populateAppStateSettings } from 'plugins/ml/jobs/new_job/simple/components/utils/app_state_settings';
import { WIZARD_TYPE } from 'plugins/ml/jobs/new_job/simple/components/constants/general';
import { setFullTimeRange } from '../../../../../components/full_time_range_selector/full_time_range_selector_service';


export function preLoadJob($scope, appState) {
Expand All @@ -16,7 +17,7 @@ export function preLoadJob($scope, appState) {
if (job !== undefined) {
const mlJobSettings = jobSettingsFromJob(job, $scope.ui.aggTypeOptions);
populateAppStateSettings({ mlJobSettings }, $scope);
$scope.setFullTimeRange()
setFullTimeRange($scope.ui.indexPattern, $scope.formConfig.combinedQuery)
.then(() => $scope.loadVis())
.catch(() => $scope.loadVis());
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import {
import { mlJobService } from 'plugins/ml/services/job_service';
import { preLoadJob } from 'plugins/ml/jobs/new_job/simple/components/utils/prepopulate_job_settings';
import { MultiMetricJobServiceProvider } from './create_job_service';
import { FullTimeRangeSelectorServiceProvider } from 'plugins/ml/components/full_time_range_selector/full_time_range_selector_service';
import { mlMessageBarService } from 'plugins/ml/components/messagebar/messagebar_service';
import { ml } from 'plugins/ml/services/ml_api_service';
import template from './create_job.html';
Expand Down Expand Up @@ -77,7 +76,6 @@ module
const moveToAdvancedJobCreation = Private(moveToAdvancedJobCreationProvider);
const chartDataUtils = Private(ChartDataUtilsProvider);
const mlMultiMetricJobService = Private(MultiMetricJobServiceProvider);
const mlFullTimeRangeSelectorService = Private(FullTimeRangeSelectorServiceProvider);
$scope.addNewJobToRecentlyAccessed = addNewJobToRecentlyAccessed;

const stateDefaults = {
Expand Down Expand Up @@ -755,10 +753,6 @@ module
});
};

$scope.setFullTimeRange = function () {
return mlFullTimeRangeSelectorService.setFullTimeRange($scope.ui.indexPattern, $scope.formConfig.combinedQuery);
};

initAgg();
createFields($scope, indexPattern);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ import 'plugins/ml/jobs/new_job/simple/components/general_job_details';
import 'plugins/ml/jobs/new_job/simple/components/enable_model_plot_checkbox';
import 'plugins/ml/jobs/new_job/simple/components/agg_types_filter';
import 'plugins/ml/components/job_group_select';
import 'plugins/ml/components/full_time_range_selector';
import 'plugins/ml/components/full_time_range_selector/full_time_range_selector_directive';
import 'plugins/ml/components/field_type_icon';
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import {
import { mlJobService } from 'plugins/ml/services/job_service';
import { preLoadJob } from 'plugins/ml/jobs/new_job/simple/components/utils/prepopulate_job_settings';
import { PopulationJobServiceProvider } from './create_job_service';
import { FullTimeRangeSelectorServiceProvider } from 'plugins/ml/components/full_time_range_selector/full_time_range_selector_service';
import { mlMessageBarService } from 'plugins/ml/components/messagebar/messagebar_service';
import template from './create_job.html';
import { timefilter } from 'ui/timefilter';
Expand Down Expand Up @@ -76,7 +75,6 @@ module
const moveToAdvancedJobCreation = Private(moveToAdvancedJobCreationProvider);
const chartDataUtils = Private(ChartDataUtilsProvider);
const mlPopulationJobService = Private(PopulationJobServiceProvider);
const mlFullTimeRangeSelectorService = Private(FullTimeRangeSelectorServiceProvider);
$scope.addNewJobToRecentlyAccessed = addNewJobToRecentlyAccessed;

const stateDefaults = {
Expand Down Expand Up @@ -735,10 +733,6 @@ module
moveToAdvancedJobCreation(job);
};

$scope.setFullTimeRange = function () {
return mlFullTimeRangeSelectorService.setFullTimeRange($scope.ui.indexPattern, $scope.formConfig.combinedQuery);
};

initAgg();
createFields($scope, indexPattern);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ import 'plugins/ml/jobs/new_job/simple/components/general_job_details';
import 'plugins/ml/jobs/new_job/simple/components/enable_model_plot_checkbox';
import 'plugins/ml/jobs/new_job/simple/components/agg_types_filter';
import 'plugins/ml/components/job_group_select';
import 'plugins/ml/components/full_time_range_selector';
import 'plugins/ml/components/full_time_range_selector/full_time_range_selector_directive';
import 'plugins/ml/components/field_type_icon';
import 'plugins/ml/components/chart_tooltip';
Loading

0 comments on commit 02bde32

Please sign in to comment.