Skip to content

Commit

Permalink
[ML] Migrates the limit dropdown to use React.
Browse files Browse the repository at this point in the history
  • Loading branch information
walterra committed Sep 22, 2018
1 parent db4b60b commit e00fe01
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 68 deletions.
4 changes: 2 additions & 2 deletions x-pack/plugins/ml/public/explorer/explorer_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ module.controller('MlExplorerController', function (
const searchBounds = getBoundsRoundedToInterval(bounds, $scope.swimlaneBucketInterval, false);
const selectedJobIds = $scope.getSelectedJobIds();
const limit = mlSelectLimitService.state.get('limit');
const swimlaneLimit = (limit === undefined) ? 10 : limit.val;
const swimlaneLimit = (limit === undefined) ? 10 : limit;

// load scores by influencer/jobId value and time.
// Pass the interval in seconds as the swimlane relies on a fixed number of seconds between buckets
Expand Down Expand Up @@ -965,7 +965,7 @@ module.controller('MlExplorerController', function (
function loadViewBySwimlaneForSelectedTime(earliestMs, latestMs) {
const selectedJobIds = $scope.getSelectedJobIds();
const limit = mlSelectLimitService.state.get('limit');
const swimlaneLimit = (limit === undefined) ? 10 : limit.val;
const swimlaneLimit = (limit === undefined) ? 10 : limit;

// Find the top field values for the selected time, and then load the 'view by'
// swimlane over the full time range for those specific field values.
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/ml/public/explorer/select_limit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@



import './select_limit.js';
import './select_limit_directive.js';

This file was deleted.

125 changes: 69 additions & 56 deletions x-pack/plugins/ml/public/explorer/select_limit/select_limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,65 +7,78 @@


/*
* AngularJS directive for rendering a select element with limit levels.
*/
* React component for rendering a select element with various aggregation limits.
*/

import _ from 'lodash';
import React, { Component } from 'react';

import { stateFactoryProvider } from 'plugins/ml/factories/state_factory';
import {
EuiSelect
} from '@elastic/eui';

import template from './select_limit.html';
import 'plugins/ml/components/controls/controls_select';

import { uiModules } from 'ui/modules';
const module = uiModules.get('apps/ml');
const OPTIONS = [
{ text: '5', value: '5' },
{ text: '10', value: '10' },
{ text: '25', value: '25' },
{ text: '50', value: '50' }
];

module
.service('mlSelectLimitService', function (Private) {
const stateFactory = Private(stateFactoryProvider);
this.state = stateFactory('mlSelectLimit', {
limit: { display: '10', val: 10 }
});
})
.directive('mlSelectLimit', function (mlSelectLimitService) {
return {
restrict: 'E',
template,
link: function (scope, element) {
scope.limitOptions = [
{ display: '5', val: 5 },
{ display: '10', val: 10 },
{ display: '25', val: 25 },
{ display: '50', val: 50 }
];

const limitState = mlSelectLimitService.state.get('limit');
const limitValue = _.get(limitState, 'val', 0);
let limitOption = scope.limitOptions.find(d => d.val === limitValue);
if (limitOption === undefined) {
// Attempt to set value in URL which doesn't map to one of the options.
limitOption = scope.limitOptions.find(d => d.val === 10);
}
scope.limit = limitOption;
mlSelectLimitService.state.set('limit', scope.limit);

scope.setLimit = function (limit) {
if (!_.isEqual(scope.limit, limit)) {
scope.limit = limit;
mlSelectLimitService.state.set('limit', scope.limit).changed();
}
};

function setLimit() {
scope.setLimit(mlSelectLimitService.state.get('limit'));
}

mlSelectLimitService.state.watch(setLimit);

element.on('$destroy', () => {
mlSelectLimitService.state.unwatch(setLimit);
scope.$destroy();
});
}
function optionValueToLimit(value) {
// Builds the corresponding limit object with
// the required display and val properties
// from the specified value.
const option = OPTIONS.find(opt => (opt.value === value));

// Default to 10 if supplied value doesn't map to one of the options.
let limit = +OPTIONS[1].value;
if (option !== undefined) {
limit = +option.value;
}

return limit;
}

class SelectLimit extends Component {
constructor(props) {
super(props);

// Restore the limit from the state, or default to 10.
this.mlSelectLimitService = this.props.mlSelectLimitService;
const limitValue = this.mlSelectLimitService.state.get('limit');
const limit = optionValueToLimit(limitValue);
this.mlSelectLimitService.state.set('limit', limit);

this.state = {
value: limit
};
});
}

onChange = (e) => {
this.setState({
value: e.target.value,
});

const limit = optionValueToLimit(e.target.value);
this.mlSelectLimitService.state.set('limit', +limit).changed();
};

render() {
return (
<React.Fragment>
<label htmlFor="selectLimit" className="euiFormLabel">Limit:</label>
<div style={{ width: '170px', display: 'inline-block' }}>
<EuiSelect
id="selectLimit"
options={OPTIONS}
className="ml-select-limit"
value={this.state.value}
onChange={this.onChange}
/>
</div>
</React.Fragment>
);
}
}

export { SelectLimit };
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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 { stateFactoryProvider } from 'plugins/ml/factories/state_factory';

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

import { SelectLimit } from './select_limit';

module.service('mlSelectLimitService', function (Private) {
const stateFactory = Private(stateFactoryProvider);
this.state = stateFactory('mlSelectLimit', {
limit: 25
});
})
.directive('mlSelectLimit', function ($injector) {
const reactDirective = $injector.get('reactDirective');
const mlSelectLimitService = $injector.get('mlSelectLimitService');

return reactDirective(
SelectLimit,
undefined,
{ restrict: 'E' },
{ mlSelectLimitService }
);
});

0 comments on commit e00fe01

Please sign in to comment.