Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add advanced setting to control quick ranges #15975

Merged
merged 4 commits into from
Jan 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/management/advanced-options.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ mentioned use "_default_".
`savedObjects:perPage`:: The number of objects shown on each page of the list of saved objects. The default value is 5.
`timepicker:timeDefaults`:: The default time filter selection.
`timepicker:refreshIntervalDefaults`:: The time filter's default refresh interval.
`timepicker:quickRanges`:: The list of ranges to show in the Quick section of the time picker. This should be an array of objects, with each object containing `from`, `to` (see {ref}/common-options.html#date-math[accepted formats]), `display` (the title to be displayed), and `section` (which column to put the option in).
`dashboard:defaultDarkTheme`:: Set this property to `true` to make new dashboards use the dark theme by default.
`filters:pinnedByDefault`:: Set this property to `true` to make filters have a global state by default.
`filterEditor:suggestValues`:: Set this property to `false` to prevent the filter editor from suggesting values for fields.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ describe('DashboardState', function () {
let savedDashboard;
let SavedDashboard;
let timefilter;
let quickTimeRanges;
let dashboardConfig;
const mockQuickTimeRanges = [{ from: 'now/w', to: 'now/w', display: 'This week', section: 0 }];
const mockIndexPattern = { id: 'index1' };

function initDashboardState() {
Expand All @@ -20,7 +20,6 @@ describe('DashboardState', function () {
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function ($injector) {
timefilter = $injector.get('timefilter');
quickTimeRanges = $injector.get('quickRanges');
AppState = $injector.get('AppState');
SavedDashboard = $injector.get('SavedDashboard');
dashboardConfig = $injector.get('dashboardConfig');
Expand All @@ -38,7 +37,7 @@ describe('DashboardState', function () {
timefilter.time.mode = 'absolute';

initDashboardState();
dashboardState.syncTimefilterWithDashboard(timefilter, quickTimeRanges);
dashboardState.syncTimefilterWithDashboard(timefilter, mockQuickTimeRanges);

expect(timefilter.time.mode).to.equal('quick');
expect(timefilter.time.to).to.equal('now/w');
Expand All @@ -55,7 +54,7 @@ describe('DashboardState', function () {
timefilter.time.mode = 'absolute';

initDashboardState();
dashboardState.syncTimefilterWithDashboard(timefilter, quickTimeRanges);
dashboardState.syncTimefilterWithDashboard(timefilter, mockQuickTimeRanges);

expect(timefilter.time.mode).to.equal('relative');
expect(timefilter.time.to).to.equal('now');
Expand All @@ -72,7 +71,7 @@ describe('DashboardState', function () {
timefilter.time.mode = 'quick';

initDashboardState();
dashboardState.syncTimefilterWithDashboard(timefilter, quickTimeRanges);
dashboardState.syncTimefilterWithDashboard(timefilter, mockQuickTimeRanges);

expect(timefilter.time.mode).to.equal('absolute');
expect(timefilter.time.to).to.equal(savedDashboard.timeTo);
Expand Down
5 changes: 2 additions & 3 deletions src/core_plugins/kibana/public/dashboard/dashboard_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ app.directive('dashboardApp', function ($injector) {
const courier = $injector.get('courier');
const AppState = $injector.get('AppState');
const timefilter = $injector.get('timefilter');
const quickRanges = $injector.get('quickRanges');
const kbnUrl = $injector.get('kbnUrl');
const confirmModal = $injector.get('confirmModal');
const config = $injector.get('config');
Expand Down Expand Up @@ -83,7 +82,7 @@ app.directive('dashboardApp', function ($injector) {
// The 'previouslyStored' check is so we only update the time filter on dashboard open, not during
// normal cross app navigation.
if (dashboardStateManager.getIsTimeSavedWithDashboard() && !getAppState.previouslyStored()) {
dashboardStateManager.syncTimefilterWithDashboard(timefilter, quickRanges);
dashboardStateManager.syncTimefilterWithDashboard(timefilter, config.get('timepicker:quickRanges'));
}

const updateState = () => {
Expand Down Expand Up @@ -247,7 +246,7 @@ app.directive('dashboardApp', function ($injector) {
// it does on 'open' because it's been saved to the url and the getAppState.previouslyStored() check on
// reload will cause it not to sync.
if (dashboardStateManager.getIsTimeSavedWithDashboard()) {
dashboardStateManager.syncTimefilterWithDashboard(timefilter, quickRanges);
dashboardStateManager.syncTimefilterWithDashboard(timefilter, config.get('timepicker:quickRanges'));
}
}

Expand Down
36 changes: 35 additions & 1 deletion src/core_plugins/kibana/ui_setting_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,40 @@ export function getUiSettingDefaults() {
}`,
description: 'The timefilter\'s default refresh interval'
},
'timepicker:quickRanges': {
Copy link
Contributor

@nreese nreese Jan 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to add a verify method to ensure the time ranges are valid? It would be better to get an error message and not update the quickRanges on the advanced setting page, then to let users save invalid time ranges and get a cryptic error when selecting the invalid range via the timepicker.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's any sort of verification currently (beyond verifying that the value actually is JSON). I could probably add a custom directive and handling for this but it might add more complexity than it's worth... Plus, there are other JSON values in the advanced settings that we don't have any sort of verification either. What if I just added some notes to the docs about how to configure the value and linked to it in the description?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type: 'json',
value: JSON.stringify([
{ from: 'now/d', to: 'now/d', display: 'Today', section: 0 },
{ from: 'now/w', to: 'now/w', display: 'This week', section: 0 },
{ from: 'now/M', to: 'now/M', display: 'This month', section: 0 },
{ from: 'now/y', to: 'now/y', display: 'This year', section: 0 },
{ from: 'now/d', to: 'now', display: 'Today so far', section: 0 },
{ from: 'now/w', to: 'now', display: 'Week to date', section: 0 },
{ from: 'now/M', to: 'now', display: 'Month to date', section: 0 },
{ from: 'now/y', to: 'now', display: 'Year to date', section: 0 },

{ from: 'now-15m', to: 'now', display: 'Last 15 minutes', section: 1 },
{ from: 'now-30m', to: 'now', display: 'Last 30 minutes', section: 1 },
{ from: 'now-1h', to: 'now', display: 'Last 1 hour', section: 1 },
{ from: 'now-4h', to: 'now', display: 'Last 4 hours', section: 1 },
{ from: 'now-12h', to: 'now', display: 'Last 12 hours', section: 1 },
{ from: 'now-24h', to: 'now', display: 'Last 24 hours', section: 1 },
{ from: 'now-7d', to: 'now', display: 'Last 7 days', section: 1 },

{ from: 'now-30d', to: 'now', display: 'Last 30 days', section: 2 },
{ from: 'now-60d', to: 'now', display: 'Last 60 days', section: 2 },
{ from: 'now-90d', to: 'now', display: 'Last 90 days', section: 2 },
{ from: 'now-6M', to: 'now', display: 'Last 6 months', section: 2 },
{ from: 'now-1y', to: 'now', display: 'Last 1 year', section: 2 },
{ from: 'now-2y', to: 'now', display: 'Last 2 years', section: 2 },
{ from: 'now-5y', to: 'now', display: 'Last 5 years', section: 2 },

], null, 2),
description: 'The list of ranges to show in the Quick section of the time picker. ' +
'This should be an array of objects, with each object containing "from", "to" (see ' +
'<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math" target="_blank" rel="noopener noreferrer">accepted formats</a>' +
'), "display" (the title to be displayed), and "section" (which column to put the option in).'
},
'dashboard:defaultDarkTheme': {
value: false,
description: 'New dashboards use dark theme by default'
Expand All @@ -287,7 +321,7 @@ export function getUiSettingDefaults() {
},
'filterEditor:suggestValues': {
value: true,
description: 'Set this property to `false` to prevent the filter editor from suggesting values for fields.'
description: 'Set this property to false to prevent the filter editor from suggesting values for fields.'
},
'notifications:banner': {
type: 'markdown',
Expand Down
4 changes: 2 additions & 2 deletions src/ui/public/directives/__tests__/timepicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ describe('timepicker directive', function () {
$scope.$digest();
});

it('should contain 4 lists of options', function () {
expect($elem.find('.kbn-timepicker-section .list-unstyled').length).to.be(4);
it('should contain 3 lists of options', function () {
expect($elem.find('.kbn-timepicker-section .list-unstyled').length).to.be(3);
});

it('should have a $scope.setQuick() that calls handler', function () {
Expand Down
4 changes: 2 additions & 2 deletions src/ui/public/directives/pretty_duration.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import _ from 'lodash';
import dateMath from '@elastic/datemath';
import moment from 'moment';
import 'ui/timepicker/quick_ranges';
import 'ui/timepicker/time_units';
import { uiModules } from 'ui/modules';
const module = uiModules.get('kibana');


module.directive('prettyDuration', function (config, quickRanges, timeUnits) {
module.directive('prettyDuration', function (config, timeUnits) {
return {
restrict: 'E',
scope: {
from: '=',
to: '='
},
link: function ($scope, $elem) {
const quickRanges = config.get('timepicker:quickRanges');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a check here to make sure users don't add a crazy number of sections?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meh, we could, but I don't envision that being a super common problem and it's easily fixed.

const dateFormat = config.get('dateFormat');

const lookupByRange = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { uiModules } from 'ui/modules';

const module = uiModules.get('ui/timepicker');

module.directive('kbnTimepickerQuickPanel', function (quickRanges) {
module.directive('kbnTimepickerQuickPanel', function (config) {
return {
restrict: 'E',
replace: true,
Expand All @@ -13,6 +13,7 @@ module.directive('kbnTimepickerQuickPanel', function (quickRanges) {
},
template,
controller: function ($scope) {
const quickRanges = config.get('timepicker:quickRanges');
$scope.quickLists = _(quickRanges).groupBy('section').values().value();
}
};
Expand Down
38 changes: 0 additions & 38 deletions src/ui/public/timepicker/quick_ranges.js

This file was deleted.

1 change: 0 additions & 1 deletion src/ui/public/timepicker/timepicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { Notifier } from 'ui/notify/notifier';
import 'ui/timepicker/timepicker.less';
import 'ui/directives/input_datetime';
import 'ui/directives/inequality';
import 'ui/timepicker/quick_ranges';
import 'ui/timepicker/refresh_intervals';
import 'ui/timepicker/time_units';
import 'ui/timepicker/kbn_global_timepicker';
Expand Down