From ecb2593dd2f173e74b976c824a9909326669ca1a Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 27 Dec 2018 14:54:50 -0700 Subject: [PATCH 01/34] replace kbnTimepicker directive with EuiSuperDatePicker --- .../kibana/ui_setting_defaults.js | 35 ++------ src/ui/public/react_components.js | 13 +++ .../timepicker/kbn_global_timepicker.html | 85 ++----------------- .../timepicker/kbn_global_timepicker.js | 17 +--- 4 files changed, 34 insertions(+), 116 deletions(-) diff --git a/src/legacy/core_plugins/kibana/ui_setting_defaults.js b/src/legacy/core_plugins/kibana/ui_setting_defaults.js index 39b9b0dc5148c..4ffc6b74d29c9 100644 --- a/src/legacy/core_plugins/kibana/ui_setting_defaults.js +++ b/src/legacy/core_plugins/kibana/ui_setting_defaults.js @@ -117,7 +117,7 @@ export function getUiSettingDefaults() { name: i18n.translate('kbn.advancedSettings.dateFormatTitle', { defaultMessage: 'Date format', }), - value: 'MMMM Do YYYY, HH:mm:ss.SSS', + value: 'MMM D, YYYY @ HH:mm:ss.SSS', description: i18n.translate('kbn.advancedSettings.dateFormatText', { defaultMessage: 'When displaying a pretty formatted date, use this {formatLink}', description: 'Part of composite text: kbn.advancedSettings.dateFormatText + ' + @@ -777,31 +777,14 @@ export function getUiSettingDefaults() { defaultMessage: 'Time picker quick ranges', }), 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 }, - + { from: 'now/d', to: 'now/d', display: 'Today', }, + { from: 'now/w', to: 'now/w', display: 'This week', }, + { from: 'now/M', to: 'now/M', display: 'This month', }, + { from: 'now/y', to: 'now/y', display: 'This year', }, + { from: 'now/d', to: 'now', display: 'Today so far', }, + { from: 'now/w', to: 'now', display: 'Week to date', }, + { from: 'now/M', to: 'now', display: 'Month to date', }, + { from: 'now/y', to: 'now', display: 'Year to date', }, ], null, 2), type: 'json', description: i18n.translate('kbn.advancedSettings.timepicker.quickRangesText', { diff --git a/src/ui/public/react_components.js b/src/ui/public/react_components.js index 3475eefba926e..1fe69c8542d31 100644 --- a/src/ui/public/react_components.js +++ b/src/ui/public/react_components.js @@ -29,6 +29,7 @@ import { EuiColorPicker, EuiIconTip, EuiCallOut, + EuiSuperDatePicker, } from '@elastic/eui'; import { uiModules } from './modules'; @@ -46,3 +47,15 @@ app.directive('colorPicker', reactDirective => reactDirective(EuiColorPicker)); app.directive('iconTip', reactDirective => reactDirective(EuiIconTip, ['content', 'type', 'position', 'title', 'color'])); app.directive('callOut', reactDirective => reactDirective(EuiCallOut, ['title', 'color', 'size', 'iconType', 'children'])); + +app.directive('superDatePicker', reactDirective => reactDirective(EuiSuperDatePicker, [ + 'start', + 'end', + 'isPaused', + 'refreshInterval', + 'commonlyUsedRanges', + 'dateFormat', + 'recentlyUsedRanges', + 'onTimeChange', + 'onRefreshChange' +])); diff --git a/src/ui/public/timepicker/kbn_global_timepicker.html b/src/ui/public/timepicker/kbn_global_timepicker.html index 0c867d906982f..4eed00440f72e 100644 --- a/src/ui/public/timepicker/kbn_global_timepicker.html +++ b/src/ui/public/timepicker/kbn_global_timepicker.html @@ -5,81 +5,12 @@ class="kuiLocalMenu" data-test-subj="globalTimepicker" > - - - - - - - - - + diff --git a/src/ui/public/timepicker/kbn_global_timepicker.js b/src/ui/public/timepicker/kbn_global_timepicker.js index 8d4dcbae0be16..aeef39285aad1 100644 --- a/src/ui/public/timepicker/kbn_global_timepicker.js +++ b/src/ui/public/timepicker/kbn_global_timepicker.js @@ -20,7 +20,6 @@ import { uiModules } from '../modules'; import toggleHtml from './kbn_global_timepicker.html'; -import { timeNavigation } from './time_navigation'; import { timefilter } from 'ui/timefilter'; import { prettyDuration } from './pretty_duration'; import { prettyInterval } from './pretty_interval'; @@ -70,21 +69,13 @@ uiModules timefilter.toggleRefresh(); }; - $scope.forward = function () { - timefilter.setTime(timeNavigation.stepForward(timefilter.getBounds())); - }; - - $scope.back = function () { - timefilter.setTime(timeNavigation.stepBackward(timefilter.getBounds())); - }; - - $scope.updateFilter = function (from, to, mode) { - timefilter.setTime({ from, to, mode }); + $scope.updateFilter = function ({ start, end }) { + timefilter.setTime({ from: start, to: end }); kbnTopNav.close('filter'); }; - $scope.updateInterval = function (interval) { - timefilter.setRefreshInterval(interval); + $scope.updateInterval = function ({ isPaused, refreshInterval }) { + timefilter.setRefreshInterval({ pause: isPaused, value: refreshInterval }); kbnTopNav.close('interval'); }; From 8a2c1edea475438d41d7224cc76b829f0603e2a4 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 27 Dec 2018 15:18:04 -0700 Subject: [PATCH 02/34] remove kbnTimepicker directive --- src/ui/public/chrome/config/filter.html | 9 - src/ui/public/chrome/config/interval.html | 9 - .../public/directives/__tests__/timepicker.js | 454 ------------------ .../kbn_top_nav/kbn_top_nav_controller.js | 7 +- src/ui/public/timefilter/time_history.js | 2 - .../__tests__/parse_relative_parts.js | 124 ----- .../timepicker/__tests__/time_navigation.js | 61 --- .../public/timepicker/absolute_panel/index.js | 20 - .../kbn_timepicker_absolute_panel.html | 82 ---- .../kbn_timepicker_absolute_panel.js | 41 -- src/ui/public/timepicker/index.js | 2 +- .../timepicker/kbn_global_timepicker.js | 6 - src/ui/public/timepicker/modes.js | 25 - .../public/timepicker/parse_relative_parts.js | 73 --- src/ui/public/timepicker/pretty_duration.js | 74 --- .../public/timepicker/pretty_duration.test.js | 70 --- src/ui/public/timepicker/pretty_interval.js | 45 -- .../public/timepicker/pretty_interval.test.js | 45 -- src/ui/public/timepicker/quick_panel/index.js | 20 - .../kbn_timepicker_quick_panel.html | 14 - .../quick_panel/kbn_timepicker_quick_panel.js | 39 -- .../public/timepicker/recent_panel/index.js | 20 - .../kbn_timepicker_recent_panel.html | 21 - .../kbn_timepicker_recent_panel.js | 43 -- src/ui/public/timepicker/refresh_intervals.js | 41 -- .../public/timepicker/relative_panel/index.js | 20 - .../kbn_timepicker_relative_panel.html | 156 ------ .../kbn_timepicker_relative_panel.js | 42 -- src/ui/public/timepicker/time_navigation.js | 62 --- src/ui/public/timepicker/time_units.js | 29 -- src/ui/public/timepicker/timepicker.html | 132 ----- src/ui/public/timepicker/timepicker.js | 257 ---------- src/ui/public/timepicker/timepicker.less | 100 ---- 33 files changed, 2 insertions(+), 2143 deletions(-) delete mode 100644 src/ui/public/chrome/config/filter.html delete mode 100644 src/ui/public/chrome/config/interval.html delete mode 100644 src/ui/public/directives/__tests__/timepicker.js delete mode 100644 src/ui/public/timepicker/__tests__/parse_relative_parts.js delete mode 100644 src/ui/public/timepicker/__tests__/time_navigation.js delete mode 100644 src/ui/public/timepicker/absolute_panel/index.js delete mode 100644 src/ui/public/timepicker/absolute_panel/kbn_timepicker_absolute_panel.html delete mode 100644 src/ui/public/timepicker/absolute_panel/kbn_timepicker_absolute_panel.js delete mode 100644 src/ui/public/timepicker/modes.js delete mode 100644 src/ui/public/timepicker/parse_relative_parts.js delete mode 100644 src/ui/public/timepicker/pretty_duration.js delete mode 100644 src/ui/public/timepicker/pretty_duration.test.js delete mode 100644 src/ui/public/timepicker/pretty_interval.js delete mode 100644 src/ui/public/timepicker/pretty_interval.test.js delete mode 100644 src/ui/public/timepicker/quick_panel/index.js delete mode 100644 src/ui/public/timepicker/quick_panel/kbn_timepicker_quick_panel.html delete mode 100644 src/ui/public/timepicker/quick_panel/kbn_timepicker_quick_panel.js delete mode 100644 src/ui/public/timepicker/recent_panel/index.js delete mode 100644 src/ui/public/timepicker/recent_panel/kbn_timepicker_recent_panel.html delete mode 100644 src/ui/public/timepicker/recent_panel/kbn_timepicker_recent_panel.js delete mode 100644 src/ui/public/timepicker/refresh_intervals.js delete mode 100644 src/ui/public/timepicker/relative_panel/index.js delete mode 100644 src/ui/public/timepicker/relative_panel/kbn_timepicker_relative_panel.html delete mode 100644 src/ui/public/timepicker/relative_panel/kbn_timepicker_relative_panel.js delete mode 100644 src/ui/public/timepicker/time_navigation.js delete mode 100644 src/ui/public/timepicker/time_units.js delete mode 100644 src/ui/public/timepicker/timepicker.html delete mode 100644 src/ui/public/timepicker/timepicker.js delete mode 100644 src/ui/public/timepicker/timepicker.less diff --git a/src/ui/public/chrome/config/filter.html b/src/ui/public/chrome/config/filter.html deleted file mode 100644 index 91953acb23175..0000000000000 --- a/src/ui/public/chrome/config/filter.html +++ /dev/null @@ -1,9 +0,0 @@ - - diff --git a/src/ui/public/chrome/config/interval.html b/src/ui/public/chrome/config/interval.html deleted file mode 100644 index 9055429800c1a..0000000000000 --- a/src/ui/public/chrome/config/interval.html +++ /dev/null @@ -1,9 +0,0 @@ - - diff --git a/src/ui/public/directives/__tests__/timepicker.js b/src/ui/public/directives/__tests__/timepicker.js deleted file mode 100644 index 7eb9180a453a9..0000000000000 --- a/src/ui/public/directives/__tests__/timepicker.js +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import angular from 'angular'; -import moment from 'moment'; -import expect from 'expect.js'; -import _ from 'lodash'; -import sinon from 'sinon'; -import ngMock from 'ng_mock'; -import 'plugins/kibana/visualize/index'; -import 'plugins/kibana/dashboard/index'; -import 'plugins/kibana/discover/index'; - - -// TODO: This should not be needed, timefilter is only included here, it should move - -let $parentScope; - -let $scope; - -let $elem; -const anchor = '2014-01-01T06:06:06.666Z'; - -const init = function () { - // Load the application - ngMock.module('kibana'); - - // Create the scope - ngMock.inject(function ($rootScope, $compile) { - - // Give us a scope - $parentScope = $rootScope; - - // Add some parameters to it - const timefilter = { - time: { - from: moment().subtract(15, 'minutes'), - to: moment(), - mode: undefined - }, - refreshInterval: { - value: 0, - display: 'Off' - } - }; - $parentScope.timefilter = timefilter; - $parentScope.updateInterval = sinon.spy(); - $parentScope.updateFilter = sinon.spy(); - - // Create the element - $elem = angular.element( - '' + - '' - ); - - // And compile it - $compile($elem)($parentScope); - - // Fire a digest cycle - $elem.scope().$digest(); - - // Grab the isolate scope so we can test it - $scope = $elem.isolateScope(); - }); -}; - - -describe('timepicker directive', function () { - const sandbox = sinon.createSandbox(); - - beforeEach(function () { - // Stub out the clock so 'now' doesn't move - sandbox.useFakeTimers(moment(anchor).valueOf()); - - init(); - }); - - afterEach(function () { - sandbox.restore(); - }); - - describe('tabs', function () { - it('should contain two tabs', function () { - expect($elem.find('.tab-pane').length).to.be(2); - }); - }); - - describe('refresh interval', function () { - beforeEach(function () { - ngMock.inject(function ($rootScope) { - $rootScope.$apply(); - }); - }); - - it('should contain a list of options', function () { - expect($elem.find('.kbn-refresh-section').length).to.be.greaterThan(0); - }); - - it('should have a $scope.setRefreshInterval() that calls handler', function () { - $scope.setRefreshInterval({ value: 10000 }); - sinon.assert.calledOnce($parentScope.updateInterval); - expect($parentScope.updateInterval.firstCall.args[0]).to.have.property('value', 10000); - }); - - it('should unpause when setRefreshInterval is called without pause:true', function () { - $scope.setRefreshInterval({ value: 1000, pause: true }); - expect($parentScope.updateInterval.getCall(0).args[0]).to.have.property('pause', true); - - $scope.setRefreshInterval({ value: 1000, pause: false }); - expect($parentScope.updateInterval.getCall(1).args[0]).to.have.property('pause', false); - - $scope.setRefreshInterval({ value: 1000 }); - expect($parentScope.updateInterval.getCall(2).args[0]).to.have.property('pause', false); - }); - - - it('should highlight the current active interval', function () { - $scope.interval = { value: 300000 }; - $elem.scope().$digest(); - expect($elem.find('.refresh-interval-active').length).to.be(1); - expect($elem.find('.refresh-interval-active').text().trim()).to.be('5 minutes'); - }); - }); - - describe('mode setting', function () { - it('should be in quick mode by default', function () { - expect($scope.mode).to.be('quick'); - }); - - it('should highlight the right mode', function () { - expect($elem.find('.kbn-timepicker-modes .euiTab-isSelected').text().trim()).to.be('Quick'); - - // Each of the 3 modes - const modes = ['absolute', 'relative', 'quick']; - _.each(modes, function (mode) { - $scope.setMode(mode); - $scope.$digest(); - expect($elem.find('.kbn-timepicker-modes .euiTab-isSelected').text().trim().toLowerCase()).to.be(mode); - }); - }); - }); - - describe('quick mode', function () { - - beforeEach(function () { - $scope.setMode('quick'); - $scope.$digest(); - }); - - 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 () { - $scope.setQuick('now', 'now'); - sinon.assert.calledOnce($parentScope.updateFilter); - expect($parentScope.updateFilter.firstCall.args[0]).to.be('now'); - expect($parentScope.updateFilter.firstCall.args[1]).to.be('now'); - }); - }); - - describe('relative mode', function () { - - beforeEach(function () { - $scope.setMode('relative'); - $scope.$digest(); - }); - - it('has a preview of the "from" input', function () { - const preview = $elem.find('.kbn-timepicker-section span[ng-show="relative.from.preview"]'); - expect(preview.text().trim()).to.be(moment().subtract(15, 'minutes').format($scope.format)); - }); - - it('has a disabled "to" field that contains "Now"', function () { - expect($elem.find('.kbn-timepicker-section span[ng-show="relative.to.preview"]').text().trim()).to.be('Now'); - }); - - it('has a submit handler', function () { - const form = $elem.find('form[ng-submit="applyRelative()"]'); - expect(form.length).to.be(1); - }); - - it('disables the submit button if the form is invalid', function () { - let button; - button = $elem.find('button[disabled]'); - expect(button.length).to.be(0); - - // Make the form invalid - $scope.relative.from.count = -3; - $scope.formatRelative('from'); - $scope.$digest(); - - button = $elem.find('button[disabled]'); - expect(button.length).to.be(1); - }); - - it('has a dropdown bound to relative.from.unit that contains all of the intervals', function () { - const select = $elem.find('.kbn-timepicker-section select[ng-model="relative.from.unit"]'); - expect(select.length).to.be(1); - expect(select.find('option').length).to.be(14); - - // Check each relative option, make sure it is in the list - _.each($scope.relativeOptions, function (unit, i) { - expect(select.find('option')[i].text).to.be(unit.text); - }); - }); - - it('has a checkbox that is checked when rounding is enabled', function () { - const checkbox = $elem.find('.kbn-timepicker-section input[ng-model="relative.from.round"]'); - expect(checkbox.length).to.be(1); - - // Rounding is disabled by default - expect(checkbox.prop('checked')).to.be(false); - - // Enable rounding - $scope.relative.from.round = true; - $scope.$digest(); - expect(checkbox.prop('checked')).to.be(true); - }); - - it('rounds the preview down to the unit when rounding is enabled', function () { - // Enable rounding - $scope.relative.from.round = true; - $scope.relative.from.count = 0; - - _.each($scope.units, function (longUnit, shortUnit) { - $scope.relative.from.count = 0; - $scope.relative.from.unit = shortUnit; - $scope.formatRelative('from'); - - // The preview should match the start of the unit e.g., the start of the minute - expect($scope.relative.from.preview).to.be(moment().startOf(longUnit).format($scope.format)); - }); - }); - - it('does not round the preview down to the unit when rounding is disable', function () { - // Disable rounding - $scope.relative.from.round = false; - $scope.relative.from.count = 1; - - _.each($scope.units, function (longUnit, shortUnit) { - $scope.relative.from.unit = shortUnit; - $scope.formatRelative('from'); - - const matches = shortUnit.match(/([smhdwMy])(\+)?/); - let unit; - let opp = '-'; - if (matches) { - unit = matches[1]; - opp = matches[2]; - } - - const fn = opp === '+' ? 'add' : 'subtract'; - - // The preview should match the start of the unit e.g., the start of the minute - expect($scope.relative.from.preview).to.be(moment()[fn](1, unit).format($scope.format)); - }); - }); - - it('has a $scope.applyRelative() that sets from and to based on relative.round, relative.count and relative.unit', function () { - // Disable rounding - $scope.relative.from.round = false; - $scope.relative.from.count = 1; - $scope.relative.from.unit = 's'; - $scope.applyRelative(); - sinon.assert.calledOnce($parentScope.updateFilter); - expect($parentScope.updateFilter.getCall(0).args[0]).to.be('now-1s'); - - $scope.relative.from.count = 2; - $scope.relative.from.unit = 'm'; - $scope.applyRelative(); - expect($parentScope.updateFilter.getCall(1).args[0]).to.be('now-2m'); - - $scope.relative.from.count = 3; - $scope.relative.from.unit = 'h'; - $scope.applyRelative(); - expect($parentScope.updateFilter.getCall(2).args[0]).to.be('now-3h'); - - // Enable rounding - $scope.relative.from.round = true; - $scope.relative.from.count = 7; - $scope.relative.from.unit = 'd'; - $scope.applyRelative(); - expect($parentScope.updateFilter.getCall(3).args[0]).to.be('now-7d/d'); - }); - - it('updates the input fields when the scope variables are changed', function () { - const input = $elem.find('.kbn-timepicker-section input[ng-model="relative.from.count"]'); - const select = $elem.find('.kbn-timepicker-section select[ng-model="relative.from.unit"]'); - - $scope.relative.from.count = 5; - $scope.$digest(); - expect(input.val()).to.be('5'); - - - // Should update the selected option - _.each($scope.units, function (longUnit, shortUnit) { - $scope.relative.from.unit = shortUnit; - $scope.$digest(); - - expect(select.val().split(':')[1]).to.be(shortUnit); - }); - }); - }); - - describe('absolute mode', function () { - - let inputs; - - beforeEach(function () { - $scope.setMode('absolute'); - $scope.$digest(); - - inputs = { - fromInput: $elem.find('.kbn-timepicker-section input[ng-model="absolute.from"]'), - toInput: $elem.find('.kbn-timepicker-section input[ng-model="absolute.to"]'), - fromCalendar: $elem.find('.kbn-timepicker-section div[ng-model="pickFromDate"] '), - toCalendar: $elem.find('.kbn-timepicker-section div[ng-model="pickToDate"] '), - }; - }); - - it('should have input boxes for absolute.from and absolute.to', function () { - expect(inputs.fromInput.length).to.be(1); - expect(inputs.toInput.length).to.be(1); - }); - - it('should have tables that contain calendars bound to absolute.from and absolute.to', function () { - expect(inputs.fromCalendar.length).to.be(1); - expect(inputs.toCalendar.length).to.be(1); - }); - - it('should present a timeframe of 15 minutes ago to now if scope.from and scope.to are not set', function () { - delete $scope.from; - delete $scope.to; - $scope.setMode('absolute'); - $scope.$digest(); - - expect($scope.absolute.from.valueOf()).to.be(moment().subtract(15, 'minutes').valueOf()); - expect($scope.absolute.to.valueOf()).to.be(moment().valueOf()); - }); - - it('should update its own variables if timefilter time is updated', function () { - $scope.setMode('absolute'); - $scope.$digest(); - - const startDate = moment('1980-01-01T00:11:02.001Z'); - const endDate = moment('1983-10-11T00:03:32.051Z'); - - $parentScope.timefilter.time.from = startDate; - $parentScope.timefilter.time.to = endDate; - $parentScope.$digest(); - - expect($scope.absolute.from.valueOf()).to.be(startDate.valueOf()); - expect($scope.absolute.to.valueOf()).to.be(endDate.valueOf()); - }); - - it('should disable the "Go" button if from > to', function () { - $scope.absolute.from = moment('2012-02-01'); - $scope.absolute.to = moment('2012-02-11'); - $scope.$digest(); - expect($elem.find('[data-test-subj="timepickerGoButton"]').attr('disabled')).to.be(undefined); - - $scope.absolute.from = moment('2012-02-12'); - $scope.absolute.to = moment('2012-02-11'); - $scope.$digest(); - expect($elem.find('[data-test-subj="timepickerGoButton"]').attr('disabled')).to.be('disabled'); - }); - - it('should only copy its input to scope.from and scope.to when scope.applyAbsolute() is called', function () { - $scope.from = 'now-30m'; - $scope.to = 'now'; - - $scope.absolute.from = moment('2012-02-01'); - $scope.absolute.to = moment('2012-02-11'); - expect($scope.from).to.be('now-30m'); - expect($scope.to).to.be('now'); - - $scope.applyAbsolute(); - expect($parentScope.updateFilter.firstCall.args[0]).to.eql(moment('2012-02-01')); - expect($parentScope.updateFilter.firstCall.args[1]).to.eql(moment('2012-02-11')); - - $scope.$digest(); - }); - - it('should set from/to to start/end of day if set from datepicker', function () { - $scope.pickFromDate(new Date('2012-02-01 12:00')); - $scope.pickToDate(new Date('2012-02-11 12:00')); - $scope.applyAbsolute(); - - expect($parentScope.updateFilter.firstCall.args[0].valueOf()).to.be(moment('2012-02-01 00:00:00.000').valueOf()); - expect($parentScope.updateFilter.firstCall.args[1].valueOf()).to.be(moment('2012-02-11 23:59:59.999').valueOf()); - }); - - it('should allow setting hour/minute/second after setting from datepicker', function () { - $scope.pickFromDate(new Date('2012-02-01 12:00')); - $scope.pickToDate(new Date('2012-02-11 12:00')); - $scope.applyAbsolute(); - - expect($parentScope.updateFilter.firstCall.args[0].valueOf()).to.be(moment('2012-02-01 00:00:00.000').valueOf()); - expect($parentScope.updateFilter.firstCall.args[1].valueOf()).to.be(moment('2012-02-11 23:59:59.999').valueOf()); - - $scope.absolute.from = moment('2012-02-01 01:23:45'); - $scope.absolute.to = moment('2012-02-11 12:34:56'); - $scope.applyAbsolute(); - - expect($parentScope.updateFilter.secondCall.args[0].valueOf()).to.be(moment('2012-02-01 01:23:45').valueOf()); - expect($parentScope.updateFilter.secondCall.args[1].valueOf()).to.be(moment('2012-02-11 12:34:56').valueOf()); - }); - - describe('datepicker timezone issue', function () { - it('should ignore the timezone from the datepicker because it does not respect dateFormat:tz advanced setting', function () { - moment.tz.setDefault('UTC'); - - $scope.pickFromDate(new Date('2012-02-01 12:00-05:00')); - $scope.pickToDate(new Date('2012-02-11 12:00-05:00')); - $scope.$digest(); - - const formattedFrom = inputs.fromInput.val(); - const formattedTo = inputs.toInput.val(); - - expect(formattedFrom).to.be('2012-02-01 00:00:00.000'); - expect(formattedTo).to.be('2012-02-11 23:59:59.999'); - }); - - after(function () { - moment.tz.setDefault('Browser'); - }); - }); - - }); -}); diff --git a/src/ui/public/kbn_top_nav/kbn_top_nav_controller.js b/src/ui/public/kbn_top_nav/kbn_top_nav_controller.js index d3df4bb6f704f..00400b93f994c 100644 --- a/src/ui/public/kbn_top_nav/kbn_top_nav_controller.js +++ b/src/ui/public/kbn_top_nav/kbn_top_nav_controller.js @@ -20,8 +20,6 @@ import { capitalize, isArray, isFunction, get } from 'lodash'; import chrome from '../chrome'; -import filterTemplate from '../chrome/config/filter.html'; -import intervalTemplate from '../chrome/config/interval.html'; import { i18n } from '@kbn/i18n'; export function KbnTopNavControllerProvider($compile) { @@ -34,10 +32,7 @@ export function KbnTopNavControllerProvider($compile) { this.opts = []; this.menuItems = []; this.currentKey = null; - this.templates = { - interval: intervalTemplate, - filter: filterTemplate, - }; + this.templates = {}; this.locals = new Map(); this.addItems(opts); diff --git a/src/ui/public/timefilter/time_history.js b/src/ui/public/timefilter/time_history.js index 50d6d0d3917e0..ad2f07957d92f 100644 --- a/src/ui/public/timefilter/time_history.js +++ b/src/ui/public/timefilter/time_history.js @@ -19,7 +19,6 @@ import moment from 'moment'; import { PersistedLog } from '../persisted_log'; -import { TIME_MODES } from '../timepicker/modes'; class TimeHistory { constructor() { @@ -38,7 +37,6 @@ class TimeHistory { // time from/to can be strings or moment objects - convert to strings so always dealing with same types const justStringsTime = { from: moment.isMoment(time.from) ? time.from.toISOString() : time.from, - mode: TIME_MODES.RECENT, to: moment.isMoment(time.to) ? time.to.toISOString() : time.to }; this.history.add(justStringsTime); diff --git a/src/ui/public/timepicker/__tests__/parse_relative_parts.js b/src/ui/public/timepicker/__tests__/parse_relative_parts.js deleted file mode 100644 index 52e4dc41262e7..0000000000000 --- a/src/ui/public/timepicker/__tests__/parse_relative_parts.js +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { parseRelativeString, parseRelativeParts } from '../parse_relative_parts'; -import expect from 'expect.js'; -import moment from 'moment'; - -describe('parseRelativeParts(from, to, relativeOptions)', () => { - - it('should parse relative string', () => { - const results = parseRelativeString('now-2h'); - expect(results).to.have.property('count', 2); - expect(results).to.have.property('unit', 'h'); - expect(results).to.have.property('round', false); - }); - - it('should parse now', () => { - const results = parseRelativeString('now'); - expect(results).to.have.property('count', 0); - expect(results).to.have.property('unit', 's'); - expect(results).to.have.property('round', false); - }); - - it('should parse set round options', () => { - const results = parseRelativeString('now-2h/h'); - expect(results).to.have.property('round', true); - }); - - it('should parse now-2h to now-10m/m', () => { - expect(parseRelativeParts('now-2h', 'now-10m/m')).to.eql({ - from: { - count: 2, - unit: 'h', - round: false - }, - to: { - count: 10, - unit: 'm', - round: true - } - }); - }); - - it('should parse now-2h to now+10m/m', () => { - expect(parseRelativeParts('now-2h', 'now+10m/m')).to.eql({ - from: { - count: 2, - unit: 'h', - round: false - }, - to: { - count: 10, - unit: 'm+', - round: true - } - }); - }); - - it('should parse 3 months ago to now', () => { - expect(parseRelativeParts(moment().subtract(3, 'M'), moment())).to.eql({ - from: { - count: 3, - unit: 'M', - round: false - }, - to: { - count: 0, - unit: 's', - round: false - } - }); - }); - - it('should parse 3 months ago to 15 minutes ago', () => { - const from = moment().subtract(3, 'M'); - const to = moment().subtract(15, 'm'); - expect(parseRelativeParts(from, to)).to.eql({ - from: { - count: 3, - unit: 'M', - round: false - }, - to: { - count: 15, - unit: 'm', - round: false - } - }); - }); - - it('should parse 3 months ago to 2 hours from now', () => { - const from = moment().subtract(3, 'M'); - const to = moment().add(2, 'h'); - expect(parseRelativeParts(from, to)).to.eql({ - from: { - count: 3, - unit: 'M', - round: false - }, - to: { - count: 2, - unit: 'h+', - round: false - } - }); - }); - -}); diff --git a/src/ui/public/timepicker/__tests__/time_navigation.js b/src/ui/public/timepicker/__tests__/time_navigation.js deleted file mode 100644 index ab5e9cef1b053..0000000000000 --- a/src/ui/public/timepicker/__tests__/time_navigation.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from 'expect.js'; -import moment from 'moment'; -import { timeNavigation } from '../time_navigation'; - -describe('timeNavigation', () => { - let bounds; - - beforeEach(() => { - bounds = { - min: moment('2016-01-01T00:00:00.000Z'), - max: moment('2016-01-01T00:15:00.000Z') - }; - }); - - it('should step forward by the amount of the duration', () => { - const { from, to, mode } = timeNavigation.stepForward(bounds); - expect(from).to.be('2016-01-01T00:15:00.001Z'); - expect(to).to.be('2016-01-01T00:30:00.001Z'); - expect(mode).to.be('absolute'); - }); - - it('should step backward by the amount of the duration', () => { - const { from, to, mode } = timeNavigation.stepBackward(bounds); - expect(from).to.be('2015-12-31T23:44:59.999Z'); - expect(to).to.be('2015-12-31T23:59:59.999Z'); - expect(mode).to.be('absolute'); - }); - - it('should zoom out to be double the original duration', () => { - const { from, to, mode } = timeNavigation.zoomOut(bounds); - expect(from).to.be('2015-12-31T23:52:30.000Z'); - expect(to).to.be('2016-01-01T00:22:30.000Z'); - expect(mode).to.be('absolute'); - }); - - it('should zoom in to be half the original duration', () => { - const { from, to, mode } = timeNavigation.zoomIn(bounds); - expect(from).to.be('2016-01-01T00:03:45.000Z'); - expect(to).to.be('2016-01-01T00:11:15.000Z'); - expect(mode).to.be('absolute'); - }); -}); diff --git a/src/ui/public/timepicker/absolute_panel/index.js b/src/ui/public/timepicker/absolute_panel/index.js deleted file mode 100644 index 0433e8fe86a6f..0000000000000 --- a/src/ui/public/timepicker/absolute_panel/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import './kbn_timepicker_absolute_panel'; diff --git a/src/ui/public/timepicker/absolute_panel/kbn_timepicker_absolute_panel.html b/src/ui/public/timepicker/absolute_panel/kbn_timepicker_absolute_panel.html deleted file mode 100644 index e72b13feae718..0000000000000 --- a/src/ui/public/timepicker/absolute_panel/kbn_timepicker_absolute_panel.html +++ /dev/null @@ -1,82 +0,0 @@ -
-
-
-
- - - -
- - -
Invalid Date
- -
- -
-
- -
-
- - - -
- - Invalid Date - - -
- -
-
-
- -
- - From must occur before To - - -
-
diff --git a/src/ui/public/timepicker/absolute_panel/kbn_timepicker_absolute_panel.js b/src/ui/public/timepicker/absolute_panel/kbn_timepicker_absolute_panel.js deleted file mode 100644 index 37504cec058c4..0000000000000 --- a/src/ui/public/timepicker/absolute_panel/kbn_timepicker_absolute_panel.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import template from './kbn_timepicker_absolute_panel.html'; -import { uiModules } from '../../modules'; - -const module = uiModules.get('ui/timepicker'); - -module.directive('kbnTimepickerAbsolutePanel', function () { - return { - restrict: 'E', - replace: true, - scope: { - absolute: '=', - applyAbsolute: '&', - format: '=', - pickFromDate: '=', - pickToDate: '=', - setToNow: '&' - }, - template, - controller: function () { - } - }; -}); diff --git a/src/ui/public/timepicker/index.js b/src/ui/public/timepicker/index.js index 2cea4af1a5430..5e68b5bc41103 100644 --- a/src/ui/public/timepicker/index.js +++ b/src/ui/public/timepicker/index.js @@ -17,4 +17,4 @@ * under the License. */ -import './timepicker'; +import './kbn_global_timepicker'; diff --git a/src/ui/public/timepicker/kbn_global_timepicker.js b/src/ui/public/timepicker/kbn_global_timepicker.js index aeef39285aad1..47537174302fa 100644 --- a/src/ui/public/timepicker/kbn_global_timepicker.js +++ b/src/ui/public/timepicker/kbn_global_timepicker.js @@ -21,8 +21,6 @@ import { uiModules } from '../modules'; import toggleHtml from './kbn_global_timepicker.html'; import { timefilter } from 'ui/timefilter'; -import { prettyDuration } from './pretty_duration'; -import { prettyInterval } from './pretty_interval'; uiModules .get('kibana') @@ -47,10 +45,6 @@ uiModules $scope.timefilterValues = { refreshInterval: refreshInterval, time: time, - display: { - time: prettyDuration(time.from, time.to, getConfig), - refreshInterval: prettyInterval(refreshInterval.value), - }, isAutoRefreshSelectorEnabled: timefilter.isAutoRefreshSelectorEnabled, isTimeRangeSelectorEnabled: timefilter.isTimeRangeSelectorEnabled, }; diff --git a/src/ui/public/timepicker/modes.js b/src/ui/public/timepicker/modes.js deleted file mode 100644 index 150c1c6d59a4e..0000000000000 --- a/src/ui/public/timepicker/modes.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export const TIME_MODES = { - ABSOLUTE: 'absolute', - QUICK: 'quick', - RECENT: 'recent', - RELATIVE: 'relative', -}; diff --git a/src/ui/public/timepicker/parse_relative_parts.js b/src/ui/public/timepicker/parse_relative_parts.js deleted file mode 100644 index 1c4ffbf69f567..0000000000000 --- a/src/ui/public/timepicker/parse_relative_parts.js +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import dateMath from '@elastic/datemath'; -import moment from 'moment'; -import _ from 'lodash'; -import { relativeOptions } from './relative_options'; - -export function parseRelativeString(part) { - let results = {}; - const matches = _.isString(part) && part.match(/now(([\-\+])([0-9]+)([smhdwMy])(\/[smhdwMy])?)?/); - - const isNow = matches && !matches[1]; - const operator = matches && matches[2]; - const count = matches && matches[3]; - const unit = matches && matches[4]; - const roundBy = matches && matches[5]; - - if (isNow) { - return { count: 0, unit: 's', round: false }; - } - - if (count && unit) { - results.count = parseInt(count, 10); - results.unit = unit; - if (operator === '+') results.unit += '+'; - results.round = roundBy ? true : false; - return results; - - } else { - results = { count: 0, unit: 's', round: false }; - const duration = moment.duration(moment().diff(dateMath.parse(part))); - const units = _.pluck(_.clone(relativeOptions).reverse(), 'value') - .filter(s => /^[smhdwMy]$/.test(s)); - let unitOp = ''; - for (let i = 0; i < units.length; i++) { - const as = duration.as(units[i]); - if (as < 0) unitOp = '+'; - if (Math.abs(as) > 1) { - results.count = Math.round(Math.abs(as)); - results.unit = units[i] + unitOp; - results.round = false; - break; - } - } - return results; - } - - -} - -export function parseRelativeParts(from, to) { - const results = {}; - results.from = parseRelativeString(from); - results.to = parseRelativeString(to); - if (results.from && results.to) return results; -} diff --git a/src/ui/public/timepicker/pretty_duration.js b/src/ui/public/timepicker/pretty_duration.js deleted file mode 100644 index f2279cdea721a..0000000000000 --- a/src/ui/public/timepicker/pretty_duration.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import dateMath from '@elastic/datemath'; -import moment from 'moment'; -import { timeUnits } from './time_units'; - -function cantLookup(timeFrom, timeTo, dateFormat) { - const displayFrom = formatTimeString(timeFrom, dateFormat); - const displayTo = formatTimeString(timeTo, dateFormat, true); - return `${displayFrom} to ${displayTo}`; -} - -function formatTimeString(timeString, dateFormat, roundUp = false) { - if (moment(timeString).isValid()) { - return moment(timeString).format(dateFormat); - } else { - if (timeString === 'now') { - return 'now'; - } else { - const tryParse = dateMath.parse(timeString, { roundUp: roundUp }); - return moment.isMoment(tryParse) ? '~ ' + tryParse.fromNow() : timeString; - } - } -} - -export function prettyDuration(timeFrom, timeTo, getConfig) { - const quickRanges = getConfig('timepicker:quickRanges'); - const dateFormat = getConfig('dateFormat'); - - const lookupByRange = {}; - quickRanges.forEach((frame) => { - lookupByRange[frame.from + ' to ' + frame.to] = frame; - }); - - // If both parts are date math, try to look up a reasonable string - if (timeFrom && timeTo && !moment.isMoment(timeFrom) && !moment.isMoment(timeTo)) { - const tryLookup = lookupByRange[timeFrom.toString() + ' to ' + timeTo.toString()]; - if (tryLookup) { - return tryLookup.display; - } else { - const fromParts = timeFrom.toString().split('-'); - if (timeTo.toString() === 'now' && fromParts[0] === 'now' && fromParts[1]) { - const rounded = fromParts[1].split('/'); - let text = 'Last ' + rounded[0]; - if (rounded[1]) { - text = text + ' rounded to the ' + timeUnits[rounded[1]]; - } - return text; - } else { - return cantLookup(timeFrom, timeTo, dateFormat); - } - } - } - - // If at least one part is a moment, try to make pretty strings by parsing date math - return cantLookup(timeFrom, timeTo, dateFormat); -} diff --git a/src/ui/public/timepicker/pretty_duration.test.js b/src/ui/public/timepicker/pretty_duration.test.js deleted file mode 100644 index 3a49c7c939634..0000000000000 --- a/src/ui/public/timepicker/pretty_duration.test.js +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from 'expect.js'; -import moment from 'moment-timezone'; -import { prettyDuration } from './pretty_duration'; - -const config = {}; -moment.tz.setDefault('UTC'); -config.dateFormat = 'MMMM Do YYYY, HH:mm:ss.SSS'; -config['timepicker:quickRanges'] = [ - { - from: 'now-15m', - to: 'now', - display: 'quick range 15 minutes custom display', - } -]; -const getConfig = (key) => config[key]; - -test('quick range', () => { - const timeFrom = 'now-15m'; - const timeTo = 'now'; - expect(prettyDuration(timeFrom, timeTo, getConfig)).to.be('quick range 15 minutes custom display'); -}); - -describe('relative range', () => { - test('from = now', () => { - const timeFrom = 'now-1M'; - const timeTo = 'now'; - expect(prettyDuration(timeFrom, timeTo, getConfig)).to.be('Last 1M'); - }); - - test('from is in past', () => { - const timeFrom = 'now-17m'; - const timeTo = 'now-15m'; - expect(prettyDuration(timeFrom, timeTo, getConfig)).to.be('~ 17 minutes ago to ~ 15 minutes ago'); - }); -}); - -describe('absolute range', () => { - test('dates in string format)', () => { - const timeFrom = '2018-01-17T18:57:57.149Z'; - const timeTo = '2018-01-17T20:00:00.000Z'; - expect(prettyDuration(timeFrom, timeTo, getConfig)).to.be('January 17th 2018, 18:57:57.149 to January 17th 2018, 20:00:00.000'); - }); - - test('dates as moment objects', () => { - const timeFrom = moment('2018-01-17T18:57:57.149Z'); - const timeTo = moment('2018-01-17T20:00:00.000Z'); - expect(prettyDuration(timeFrom, timeTo, getConfig)).to.be('January 17th 2018, 18:57:57.149 to January 17th 2018, 20:00:00.000'); - }); -}); - - diff --git a/src/ui/public/timepicker/pretty_interval.js b/src/ui/public/timepicker/pretty_interval.js deleted file mode 100644 index 0d2465ee77d8e..0000000000000 --- a/src/ui/public/timepicker/pretty_interval.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -const MS_IN_SECOND = 1000; -const MS_IN_MINUTE = 60 * MS_IN_SECOND; -const MS_IN_HOUR = 60 * MS_IN_MINUTE; -const MS_IN_DAY = 24 * MS_IN_HOUR; - -export function prettyInterval(intervalInMs) { - if (intervalInMs === 0) { - return 'Off'; - } else if (intervalInMs < MS_IN_MINUTE) { - const intervalInSeconds = Math.round(intervalInMs / MS_IN_SECOND); - const units = intervalInSeconds > 1 ? 'seconds' : 'second'; - return `${intervalInSeconds} ${units}`; - } else if (intervalInMs < MS_IN_HOUR) { - const intervalInMinutes = Math.round(intervalInMs / MS_IN_MINUTE); - const units = intervalInMinutes > 1 ? 'minutes' : 'minute'; - return `${intervalInMinutes} ${units}`; - } else if (intervalInMs < MS_IN_DAY) { - const intervalInHours = Math.round(intervalInMs / MS_IN_HOUR); - const units = intervalInHours > 1 ? 'hours' : 'hour'; - return `${intervalInHours} ${units}`; - } - - const intervalInDays = Math.round(intervalInMs / MS_IN_DAY); - const units = intervalInDays > 1 ? 'days' : 'day'; - return `${intervalInDays} ${units}`; -} diff --git a/src/ui/public/timepicker/pretty_interval.test.js b/src/ui/public/timepicker/pretty_interval.test.js deleted file mode 100644 index 72b99d0c43908..0000000000000 --- a/src/ui/public/timepicker/pretty_interval.test.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from 'expect.js'; -import { prettyInterval } from './pretty_interval'; - -test('Off', () => { - expect(prettyInterval(0)).to.be('Off'); -}); - -test('seconds', () => { - expect(prettyInterval(1000)).to.be('1 second'); - expect(prettyInterval(15000)).to.be('15 seconds'); -}); - -test('minutes', () => { - expect(prettyInterval(60000)).to.be('1 minute'); - expect(prettyInterval(1800000)).to.be('30 minutes'); -}); - -test('hours', () => { - expect(prettyInterval(3600000)).to.be('1 hour'); - expect(prettyInterval(43200000)).to.be('12 hours'); -}); - -test('days', () => { - expect(prettyInterval(86400000)).to.be('1 day'); - expect(prettyInterval(86400000 * 2)).to.be('2 days'); -}); diff --git a/src/ui/public/timepicker/quick_panel/index.js b/src/ui/public/timepicker/quick_panel/index.js deleted file mode 100644 index 4bdadf9358644..0000000000000 --- a/src/ui/public/timepicker/quick_panel/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import './kbn_timepicker_quick_panel'; diff --git a/src/ui/public/timepicker/quick_panel/kbn_timepicker_quick_panel.html b/src/ui/public/timepicker/quick_panel/kbn_timepicker_quick_panel.html deleted file mode 100644 index 7855e5aae8f41..0000000000000 --- a/src/ui/public/timepicker/quick_panel/kbn_timepicker_quick_panel.html +++ /dev/null @@ -1,14 +0,0 @@ -
-
-
    -
  • - -
  • -
-
-
diff --git a/src/ui/public/timepicker/quick_panel/kbn_timepicker_quick_panel.js b/src/ui/public/timepicker/quick_panel/kbn_timepicker_quick_panel.js deleted file mode 100644 index 46ef2d7cb84d6..0000000000000 --- a/src/ui/public/timepicker/quick_panel/kbn_timepicker_quick_panel.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import _ from 'lodash'; -import template from './kbn_timepicker_quick_panel.html'; -import { uiModules } from '../../modules'; - -const module = uiModules.get('ui/timepicker'); - -module.directive('kbnTimepickerQuickPanel', function (config) { - return { - restrict: 'E', - replace: true, - scope: { - setQuick: '&' - }, - template, - controller: function ($scope) { - const quickRanges = config.get('timepicker:quickRanges'); - $scope.quickLists = _(quickRanges).groupBy('section').values().value(); - } - }; -}); diff --git a/src/ui/public/timepicker/recent_panel/index.js b/src/ui/public/timepicker/recent_panel/index.js deleted file mode 100644 index ac90ee48fc69b..0000000000000 --- a/src/ui/public/timepicker/recent_panel/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import './kbn_timepicker_recent_panel'; diff --git a/src/ui/public/timepicker/recent_panel/kbn_timepicker_recent_panel.html b/src/ui/public/timepicker/recent_panel/kbn_timepicker_recent_panel.html deleted file mode 100644 index 2be79b1383af6..0000000000000 --- a/src/ui/public/timepicker/recent_panel/kbn_timepicker_recent_panel.html +++ /dev/null @@ -1,21 +0,0 @@ -
- -
-

- No time history. Your most recent time ranges show up here, so you can easily view them later. -

-
- -
-
    -
  • - -
  • -
-
-
diff --git a/src/ui/public/timepicker/recent_panel/kbn_timepicker_recent_panel.js b/src/ui/public/timepicker/recent_panel/kbn_timepicker_recent_panel.js deleted file mode 100644 index 597cc5b1ed22a..0000000000000 --- a/src/ui/public/timepicker/recent_panel/kbn_timepicker_recent_panel.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import template from './kbn_timepicker_recent_panel.html'; -import { uiModules } from '../../modules'; -import { timeHistory } from '../../timefilter/time_history'; -import { prettyDuration } from '../pretty_duration'; - -const module = uiModules.get('ui/timepicker'); - -module.directive('kbnTimepickerRecentPanel', function () { - return { - restrict: 'E', - replace: true, - scope: { - setQuick: '&' - }, - template, - controller: function ($scope, config) { - const getConfig = (...args) => config.get(...args); - $scope.recent = timeHistory.get().map(time => { - time.display = prettyDuration(time.from, time.to, getConfig); - return time; - }); - } - }; -}); diff --git a/src/ui/public/timepicker/refresh_intervals.js b/src/ui/public/timepicker/refresh_intervals.js deleted file mode 100644 index 4dd66a16e028d..0000000000000 --- a/src/ui/public/timepicker/refresh_intervals.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { uiModules } from '../modules'; -const module = uiModules.get('kibana'); - -module.constant('refreshIntervals', [ - { value: 0, section: 0 }, - - { value: 5000, section: 1 }, - { value: 10000, section: 1 }, - { value: 30000, section: 1 }, - { value: 45000, section: 1 }, - - { value: 60000, section: 2 }, - { value: 300000, section: 2 }, - { value: 900000, section: 2 }, - { value: 1800000, section: 2 }, - - { value: 3600000, section: 3 }, - { value: 7200000, section: 3 }, - { value: 43200000, section: 3 }, - { value: 86400000, section: 3 } -]); - diff --git a/src/ui/public/timepicker/relative_panel/index.js b/src/ui/public/timepicker/relative_panel/index.js deleted file mode 100644 index 7262dbb26899a..0000000000000 --- a/src/ui/public/timepicker/relative_panel/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import './kbn_timepicker_relative_panel'; diff --git a/src/ui/public/timepicker/relative_panel/kbn_timepicker_relative_panel.html b/src/ui/public/timepicker/relative_panel/kbn_timepicker_relative_panel.html deleted file mode 100644 index acf2a2ebebdb4..0000000000000 --- a/src/ui/public/timepicker/relative_panel/kbn_timepicker_relative_panel.html +++ /dev/null @@ -1,156 +0,0 @@ -
-
-
-
- - - -
- -
- - {{relative.from.preview}} - - - Invalid Expression - -
- -
-
- -
- -
- -
-
- -
- -
-
- -
-
- - - -
- -
- - {{relative.to.preview}} - - - Invalid Expression - -
- -
-
- -
- -
- -
-
- -
- -
-
-
- -
- - From must occur before To - - -
-
diff --git a/src/ui/public/timepicker/relative_panel/kbn_timepicker_relative_panel.js b/src/ui/public/timepicker/relative_panel/kbn_timepicker_relative_panel.js deleted file mode 100644 index 78bd136b2bb3e..0000000000000 --- a/src/ui/public/timepicker/relative_panel/kbn_timepicker_relative_panel.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import template from './kbn_timepicker_relative_panel.html'; -import { uiModules } from '../../modules'; - -const module = uiModules.get('ui/timepicker'); - -module.directive('kbnTimepickerRelativePanel', function () { - return { - restrict: 'E', - replace: true, - scope: { - applyRelative: '&', - checkRelative: '&', - formatRelative: '&', - relative: '=', - relativeOptions: '=', - setRelativeToNow: '&', - units: '=' - }, - template, - controller: function () { - } - }; -}); diff --git a/src/ui/public/timepicker/time_navigation.js b/src/ui/public/timepicker/time_navigation.js deleted file mode 100644 index 54b0f9fb9fd6b..0000000000000 --- a/src/ui/public/timepicker/time_navigation.js +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import moment from 'moment'; - -export const timeNavigation = { - // travel forward in time based on the interval between from and to - stepForward({ min, max }) { - const diff = max.diff(min); - return { - from: moment(max).add(1, 'ms').toISOString(), - to: moment(max).add(diff + 1, 'ms').toISOString(), - mode: 'absolute' - }; - }, - - // travel backwards in time based on the interval between from and to - stepBackward({ min, max }) { - const diff = max.diff(min); - return { - from: moment(min).subtract(diff + 1, 'ms').toISOString(), - to: moment(min).subtract(1, 'ms').toISOString(), - mode: 'absolute' - }; - }, - - // zoom out, doubling the difference between start and end, keeping the same time range center - zoomOut({ min, max }) { - const diff = max.diff(min); - return { - from: moment(min).subtract(diff / 2, 'ms').toISOString(), - to: moment(max).add(diff / 2, 'ms').toISOString(), - mode: 'absolute' - }; - }, - - // zoom in, halving the difference between start and end, keeping the same time range center - zoomIn({ min, max }) { - const diff = max.diff(min); - return { - from: moment(min).add(diff / 4, 'ms').toISOString(), - to: moment(max).subtract(diff / 4, 'ms').toISOString(), - mode: 'absolute' - }; - } -}; diff --git a/src/ui/public/timepicker/time_units.js b/src/ui/public/timepicker/time_units.js deleted file mode 100644 index 627202264de7a..0000000000000 --- a/src/ui/public/timepicker/time_units.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export const timeUnits = { - s: 'second', - m: 'minute', - h: 'hour', - d: 'day', - w: 'week', - M: 'month', - y: 'year' -}; - diff --git a/src/ui/public/timepicker/timepicker.html b/src/ui/public/timepicker/timepicker.html deleted file mode 100644 index 5f98c14a3f2e7..0000000000000 --- a/src/ui/public/timepicker/timepicker.html +++ /dev/null @@ -1,132 +0,0 @@ -
- -
- -
-
-

- Time Range -

-
- -
-
- - - - - - - -
-
- -
- - - - - - - -
-
- - -
-

- Refresh Interval -

- - -
-
-
diff --git a/src/ui/public/timepicker/timepicker.js b/src/ui/public/timepicker/timepicker.js deleted file mode 100644 index 87d92022d4d65..0000000000000 --- a/src/ui/public/timepicker/timepicker.js +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import html from './timepicker.html'; -import './quick_panel'; -import './recent_panel'; -import './relative_panel'; -import './absolute_panel'; -import _ from 'lodash'; -import { relativeOptions } from './relative_options'; -import { parseRelativeParts } from './parse_relative_parts'; -import dateMath from '@elastic/datemath'; -import moment from 'moment'; -import './timepicker.less'; -import '../directives/input_datetime'; -import '../directives/inequality'; -import './refresh_intervals'; -import './kbn_global_timepicker'; -import { uiModules } from '../modules'; -import { TIME_MODES } from './modes'; -import { timeUnits } from './time_units'; -import { prettyInterval } from './pretty_interval'; -const module = uiModules.get('ui/timepicker'); - -module.directive('kbnTimepicker', function (refreshIntervals) { - return { - restrict: 'E', - scope: { - from: '=', - to: '=', - mode: '=', - interval: '=', - activeTab: '=', - onFilterSelect: '&', - onIntervalSelect: '&' - }, - template: html, - controller: function ($scope) { - $scope.format = 'MMMM Do YYYY, HH:mm:ss.SSS'; - $scope.modes = Object.values(TIME_MODES); - $scope.activeTab = $scope.activeTab || 'filter'; - - if (_.isUndefined($scope.mode)) $scope.mode = TIME_MODES.QUICK; - - $scope.refreshLists = _(refreshIntervals).groupBy('section').values().value(); - - $scope.relative = { - from: { - count: 1, - unit: 'm', - preview: undefined, - round: false - }, - to: { - count: 0, - unit: 's', - preview: undefined, - round: false - } - }; - - $scope.absolute = { - from: moment(), - to: moment() - }; - - $scope.units = timeUnits; - - $scope.relativeOptions = relativeOptions; - - $scope.$watch('from', function (date) { - if (moment.isMoment(date) && $scope.mode === TIME_MODES.ABSOLUTE) { - $scope.absolute.from = date; - } - }); - - $scope.$watch('to', function (date) { - if (moment.isMoment(date) && $scope.mode === TIME_MODES.ABSOLUTE) { - $scope.absolute.to = date; - } - }); - - // If we always return a new object from the getters below (pickFromDate and pickToDate) we'll create an - // infinite digest loop, so we maintain these copies to return instead. - $scope.$watch('absolute.from', function (newDate) { - if (!newDate) { - return; - } - - _.set($scope, 'browserAbsolute.from', new Date(newDate.year(), newDate.month(), newDate.date())); - }); - - $scope.$watch('absolute.to', function (newDate) { - if (!newDate) { - return; - } - - _.set($scope, 'browserAbsolute.to', new Date(newDate.year(), newDate.month(), newDate.date())); - }); - - // The datepicker directive uses native JavaScript Dates, ignoring moment's default timezone. This causes - // the datepicker and the text input above it to get out of sync if the user changed the `dateFormat:tz` config - // in advanced settings. The text input will show the date in the user selected timezone, the datepicker will - // show the date in the local browser timezone. Since we really just want a day, month, year from the datepicker - // instead of a moment in time, we grab those individual values from the native date. - $scope.pickFromDate = function (date) { - if (!date) return _.get($scope, 'browserAbsolute.from'); - - const defaultTimeZoneDate = moment({ - year: date.getFullYear(), - month: date.getMonth(), - day: date.getDate(), - hour: 0, - minute: 0, - second: 0, - millisecond: 0, - }); - return $scope.absolute.from = defaultTimeZoneDate; - }; - - $scope.pickToDate = function (date) { - if (!date) return _.get($scope, 'browserAbsolute.to'); - - const defaultTimeZoneDate = moment({ - year: date.getFullYear(), - month: date.getMonth(), - day: date.getDate(), - hour: 23, - minute: 59, - second: 59, - millisecond: 999, - }); - return $scope.absolute.to = defaultTimeZoneDate; - }; - - $scope.setMode = function (thisMode) { - switch (thisMode) { - case TIME_MODES.QUICK: - break; - case TIME_MODES.RECENT: - break; - case TIME_MODES.RELATIVE: - $scope.relative = parseRelativeParts($scope.from, $scope.to); - $scope.formatRelative('from'); - $scope.formatRelative('to'); - break; - case TIME_MODES.ABSOLUTE: - $scope.absolute.from = dateMath.parse($scope.from || moment().subtract(15, 'minutes')); - $scope.absolute.to = dateMath.parse($scope.to || moment(), { roundUp: true }); - break; - } - - $scope.mode = thisMode; - }; - - $scope.setQuick = function (from, to) { - $scope.onFilterSelect({ from, to, mode: TIME_MODES.QUICK }); - }; - - $scope.setToNow = function (key) { - $scope.absolute[key] = moment(); - }; - - $scope.setRelativeToNow = function (key) { - $scope.relative[key].count = 0; - $scope.relative[key].round = false; - $scope.formatRelative(key); - }; - - $scope.checkRelative = function () { - if ($scope.relative.from.count != null && $scope.relative.to.count != null) { - const from = dateMath.parse(getRelativeString('from')); - const to = dateMath.parse(getRelativeString('to'), { roundUp: true }); - if (to && from) return to.isBefore(from); - return true; - } - }; - - $scope.formatRelative = function (key) { - const relativeString = getRelativeString(key); - const parsed = dateMath.parse(relativeString, { roundUp: key === 'to' }); - let preview; - if (relativeString === 'now') { - preview = 'Now'; - } else { - preview = parsed ? parsed.format($scope.format) : undefined; - } - _.set($scope, `relative.${key}.preview`, preview); - return parsed; - }; - - $scope.applyRelative = function () { - $scope.onFilterSelect({ - from: getRelativeString('from'), - to: getRelativeString('to'), - mode: TIME_MODES.RELATIVE, - }); - }; - - function getRelativeString(key) { - const count = _.get($scope, `relative.${key}.count`, 0); - const round = _.get($scope, `relative.${key}.round`, false); - const matches = _.get($scope, `relative.${key}.unit`, 's').match(/([smhdwMy])(\+)?/); - let unit; - let operator = '-'; - if (matches && matches[1]) unit = matches[1]; - if (matches && matches[2]) operator = matches[2]; - if (count === 0 && !round) return 'now'; - let result = `now${operator}${count}${unit}`; - result += (round ? '/' + unit : ''); - return result; - } - - $scope.applyAbsolute = function () { - $scope.onFilterSelect({ - from: moment($scope.absolute.from), - to: moment($scope.absolute.to), - mode: TIME_MODES.ABSOLUTE, - }); - }; - - $scope.prettyInterval = function (interval) { - return prettyInterval(interval.value); - }; - - $scope.setRefreshInterval = function (interval) { - interval = _.clone(interval || {}); - interval.pause = (interval.pause == null || interval.pause === false) ? false : true; - - $scope.onIntervalSelect({ - interval: { - value: interval.value, - pause: interval.pause, - } - }); - }; - - $scope.setMode($scope.mode); - } - }; -}); diff --git a/src/ui/public/timepicker/timepicker.less b/src/ui/public/timepicker/timepicker.less deleted file mode 100644 index 6d10a119d6e6b..0000000000000 --- a/src/ui/public/timepicker/timepicker.less +++ /dev/null @@ -1,100 +0,0 @@ -@import (reference) '../styles/bootstrap/_custom_variables.less'; - -.kbn-timepicker { - display: flex; - justify-content: flex-end; - - .kbn-timepicker-content { - width: 100%; - max-width: 600px; - } - - [kbn-time-input] { - text-align: center; - } - .kbn-timepicker-modes { - text-transform: capitalize; - } - .kbn-timepicker-section { - float: left; - - & + .kbn-timepicker-section { - padding-left: 15px; - } - } - .kbn-timepicker-quick-section { - width: 25%; - } - .kbn-timepicker-body { - display: flex; - align-items: top; - justify-content: stretch; - width: 100%; - - @media (max-width: 660px) { - flex-direction: column; - } - } - .kbn-timepicker-body-column { - width: 100%; - } - .kbn-timepicker-form-header { - margin-bottom: 0 !important; - } - .kbn-timepicker-actions { - display: flex; - justify-content: flex-end; - align-items: baseline; - } - .kbn-timepicker-action-item, - .kbn-timepicker-submit-button { - margin-left: 10px; - } - .kbn-timepicker-submit-button { - min-width: 100px; - } - .kbn-refresh-section { - float: left; - padding: 0px 15px; - } - .kbn-timepicket-alert { - width: 100px; - } - .kbn-timepicker-error { - color: @brand-danger; - } - .kbn-timepicker-title { - display: flex; - justify-content: space-between; - } - /** - * 1. Override kuiLocalNav styles. - */ - .kbn-timepicker-title__text { - margin-bottom: 0 !important; /* 1 */ - } - .kbn-timepicker-title__section { - display: flex; - align-items: center; - } - /** - * Avoid last nav overlapping collapse button - */ - .nav:last-child { - margin-right: 24px; - } - - .refresh-interval { - padding: 0.2em 0.4em; - border-radius: @border-radius-small; - } - - .refresh-interval-active { - background-color: @brand-info; - color: @white; - } -} - -.navbar-timepicker-time-desc > .fa-clock-o { - padding-right: 5px; -} From 090f2d00133e130e330afb1f13996b35e641b49b Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 27 Dec 2018 15:23:44 -0700 Subject: [PATCH 03/34] remove bootstrap datepicker --- .../datepicker/datepicker.html | 5 - .../datepicker/datepicker.js | 617 ------------------ .../angular-bootstrap/datepicker/day.html | 81 --- .../angular-bootstrap/datepicker/month.html | 68 -- .../angular-bootstrap/datepicker/popup.html | 10 - .../angular-bootstrap/datepicker/year.html | 68 -- src/ui/public/angular-bootstrap/index.js | 37 -- src/ui/public/styles/bootstrap/bootstrap.less | 2 +- 8 files changed, 1 insertion(+), 887 deletions(-) delete mode 100755 src/ui/public/angular-bootstrap/datepicker/datepicker.html delete mode 100755 src/ui/public/angular-bootstrap/datepicker/datepicker.js delete mode 100755 src/ui/public/angular-bootstrap/datepicker/day.html delete mode 100755 src/ui/public/angular-bootstrap/datepicker/month.html delete mode 100755 src/ui/public/angular-bootstrap/datepicker/popup.html delete mode 100755 src/ui/public/angular-bootstrap/datepicker/year.html diff --git a/src/ui/public/angular-bootstrap/datepicker/datepicker.html b/src/ui/public/angular-bootstrap/datepicker/datepicker.html deleted file mode 100755 index 807ef80a936a5..0000000000000 --- a/src/ui/public/angular-bootstrap/datepicker/datepicker.html +++ /dev/null @@ -1,5 +0,0 @@ -
- - - -
diff --git a/src/ui/public/angular-bootstrap/datepicker/datepicker.js b/src/ui/public/angular-bootstrap/datepicker/datepicker.js deleted file mode 100755 index bcdf3a6570928..0000000000000 --- a/src/ui/public/angular-bootstrap/datepicker/datepicker.js +++ /dev/null @@ -1,617 +0,0 @@ -angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootstrap.position']) - -.constant('datepickerConfig', { - formatDay: 'dd', - formatMonth: 'MMMM', - formatYear: 'yyyy', - formatDayHeader: 'EEE', - formatDayTitle: 'MMMM yyyy', - formatMonthTitle: 'yyyy', - datepickerMode: 'day', - minMode: 'day', - maxMode: 'year', - showWeeks: true, - startingDay: 0, - yearRange: 20, - minDate: null, - maxDate: null -}) - -.controller('DatepickerController', ['$scope', '$attrs', '$parse', '$interpolate', '$timeout', '$log', 'dateFilter', 'datepickerConfig', function($scope, $attrs, $parse, $interpolate, $timeout, $log, dateFilter, datepickerConfig) { - var self = this, - ngModelCtrl = { $setViewValue: angular.noop }; // nullModelCtrl; - - // Modes chain - this.modes = ['day', 'month', 'year']; - - // Configuration attributes - angular.forEach(['formatDay', 'formatMonth', 'formatYear', 'formatDayHeader', 'formatDayTitle', 'formatMonthTitle', - 'minMode', 'maxMode', 'showWeeks', 'startingDay', 'yearRange'], function( key, index ) { - self[key] = angular.isDefined($attrs[key]) ? (index < 8 ? $interpolate($attrs[key])($scope.$parent) : $scope.$parent.$eval($attrs[key])) : datepickerConfig[key]; - }); - - // Watchable date attributes - angular.forEach(['minDate', 'maxDate'], function( key ) { - if ( $attrs[key] ) { - $scope.$parent.$watch($parse($attrs[key]), function(value) { - self[key] = value ? new Date(value) : null; - self.refreshView(); - }); - } else { - self[key] = datepickerConfig[key] ? new Date(datepickerConfig[key]) : null; - } - }); - - $scope.datepickerMode = $scope.datepickerMode || datepickerConfig.datepickerMode; - $scope.uniqueId = 'datepicker-' + $scope.$id + '-' + Math.floor(Math.random() * 10000); - this.activeDate = angular.isDefined($attrs.initDate) ? $scope.$parent.$eval($attrs.initDate) : new Date(); - - $scope.isActive = function(dateObject) { - if (self.compare(dateObject.date, self.activeDate) === 0) { - $scope.activeDateId = dateObject.uid; - return true; - } - return false; - }; - - this.init = function( ngModelCtrl_ ) { - ngModelCtrl = ngModelCtrl_; - - ngModelCtrl.$render = function() { - self.render(); - }; - }; - - this.render = function() { - if ( ngModelCtrl.$modelValue ) { - var date = new Date( ngModelCtrl.$modelValue ), - isValid = !isNaN(date); - - if ( isValid ) { - this.activeDate = date; - } else { - $log.error('Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.'); - } - ngModelCtrl.$setValidity('date', isValid); - } - this.refreshView(); - }; - - this.refreshView = function() { - if ( this.element ) { - this._refreshView(); - - var date = ngModelCtrl.$modelValue ? new Date(ngModelCtrl.$modelValue) : null; - ngModelCtrl.$setValidity('date-disabled', !date || (this.element && !this.isDisabled(date))); - } - }; - - this.createDateObject = function(date, format) { - var model = ngModelCtrl.$modelValue ? new Date(ngModelCtrl.$modelValue) : null; - return { - date: date, - label: dateFilter(date, format), - selected: model && this.compare(date, model) === 0, - disabled: this.isDisabled(date), - current: this.compare(date, new Date()) === 0 - }; - }; - - this.isDisabled = function( date ) { - return ((this.minDate && this.compare(date, this.minDate) < 0) || (this.maxDate && this.compare(date, this.maxDate) > 0) || ($attrs.dateDisabled && $scope.dateDisabled({date: date, mode: $scope.datepickerMode}))); - }; - - // Split array into smaller arrays - this.split = function(arr, size) { - var arrays = []; - while (arr.length > 0) { - arrays.push(arr.splice(0, size)); - } - return arrays; - }; - - $scope.select = function( date ) { - if ( $scope.datepickerMode === self.minMode ) { - var dt = ngModelCtrl.$modelValue ? new Date( ngModelCtrl.$modelValue ) : new Date(0, 0, 0, 0, 0, 0, 0); - dt.setFullYear( date.getFullYear(), date.getMonth(), date.getDate() ); - ngModelCtrl.$setViewValue( dt ); - ngModelCtrl.$render(); - } else { - self.activeDate = date; - $scope.datepickerMode = self.modes[ self.modes.indexOf( $scope.datepickerMode ) - 1 ]; - focusElement(); - } - }; - - $scope.move = function( direction ) { - var year = self.activeDate.getFullYear() + direction * (self.step.years || 0), - month = self.activeDate.getMonth() + direction * (self.step.months || 0); - self.activeDate.setFullYear(year, month, 1); - self.refreshView(); - }; - - $scope.toggleMode = function( direction ) { - direction = direction || 1; - - if (($scope.datepickerMode === self.maxMode && direction === 1) || ($scope.datepickerMode === self.minMode && direction === -1)) { - return; - } - - $scope.datepickerMode = self.modes[ self.modes.indexOf( $scope.datepickerMode ) + direction ]; - focusElement(); - }; - - // Key event mapper - $scope.keys = { 13:'enter', 32:'space', 33:'pageup', 34:'pagedown', 35:'end', 36:'home', 37:'left', 38:'up', 39:'right', 40:'down' }; - - var focusElement = function() { - $timeout(function() { - self.element[0].focus(); - }, 0 , false); - }; - - // Listen for focus requests from popup directive - $scope.$on('datepicker.focus', focusElement); -}]) - -.directive( 'datepicker', function () { - return { - restrict: 'EA', - replace: true, - templateUrl: 'template/datepicker/datepicker.html', - scope: { - datepickerMode: '=?', - dateDisabled: '&' - }, - require: ['datepicker', '?^ngModel'], - controller: 'DatepickerController', - link: function(scope, element, attrs, ctrls) { - var datepickerCtrl = ctrls[0], ngModelCtrl = ctrls[1]; - - if ( ngModelCtrl ) { - datepickerCtrl.init( ngModelCtrl ); - } - } - }; -}) - -.directive('daypicker', ['dateFilter', function (dateFilter) { - return { - restrict: 'EA', - replace: true, - templateUrl: 'template/datepicker/day.html', - require: '^datepicker', - link: function(scope, element, attrs, ctrl) { - scope.showWeeks = ctrl.showWeeks; - - ctrl.step = { months: 1 }; - ctrl.element = element; - - var DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - function getDaysInMonth( year, month ) { - return ((month === 1) && (year % 4 === 0) && ((year % 100 !== 0) || (year % 400 === 0))) ? 29 : DAYS_IN_MONTH[month]; - } - - function getDates(startDate, n) { - var dates = new Array(n), current = new Date(startDate), i = 0; - current.setHours(12); // Prevent repeated dates because of timezone bug - while ( i < n ) { - dates[i++] = new Date(current); - current.setDate( current.getDate() + 1 ); - } - return dates; - } - - ctrl._refreshView = function() { - var year = ctrl.activeDate.getFullYear(), - month = ctrl.activeDate.getMonth(), - firstDayOfMonth = new Date(year, month, 1), - difference = ctrl.startingDay - firstDayOfMonth.getDay(), - numDisplayedFromPreviousMonth = (difference > 0) ? 7 - difference : - difference, - firstDate = new Date(firstDayOfMonth); - - if ( numDisplayedFromPreviousMonth > 0 ) { - firstDate.setDate( - numDisplayedFromPreviousMonth + 1 ); - } - - // 42 is the number of days on a six-month calendar - var days = getDates(firstDate, 42); - for (var i = 0; i < 42; i ++) { - days[i] = angular.extend(ctrl.createDateObject(days[i], ctrl.formatDay), { - secondary: days[i].getMonth() !== month, - uid: scope.uniqueId + '-' + i - }); - } - - scope.labels = new Array(7); - for (var j = 0; j < 7; j++) { - scope.labels[j] = { - abbr: dateFilter(days[j].date, ctrl.formatDayHeader), - full: dateFilter(days[j].date, 'EEEE') - }; - } - - scope.title = dateFilter(ctrl.activeDate, ctrl.formatDayTitle); - scope.rows = ctrl.split(days, 7); - - if ( scope.showWeeks ) { - scope.weekNumbers = []; - var weekNumber = getISO8601WeekNumber( scope.rows[0][0].date ), - numWeeks = scope.rows.length; - while( scope.weekNumbers.push(weekNumber++) < numWeeks ) {} - } - }; - - ctrl.compare = function(date1, date2) { - return (new Date( date1.getFullYear(), date1.getMonth(), date1.getDate() ) - new Date( date2.getFullYear(), date2.getMonth(), date2.getDate() ) ); - }; - - function getISO8601WeekNumber(date) { - var checkDate = new Date(date); - checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); // Thursday - var time = checkDate.getTime(); - checkDate.setMonth(0); // Compare with Jan 1 - checkDate.setDate(1); - return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; - } - - ctrl.handleKeyDown = function( key, evt ) { - var date = ctrl.activeDate.getDate(); - - if (key === 'left') { - date = date - 1; // up - } else if (key === 'up') { - date = date - 7; // down - } else if (key === 'right') { - date = date + 1; // down - } else if (key === 'down') { - date = date + 7; - } else if (key === 'pageup' || key === 'pagedown') { - var month = ctrl.activeDate.getMonth() + (key === 'pageup' ? - 1 : 1); - ctrl.activeDate.setMonth(month, 1); - date = Math.min(getDaysInMonth(ctrl.activeDate.getFullYear(), ctrl.activeDate.getMonth()), date); - } else if (key === 'home') { - date = 1; - } else if (key === 'end') { - date = getDaysInMonth(ctrl.activeDate.getFullYear(), ctrl.activeDate.getMonth()); - } - ctrl.activeDate.setDate(date); - }; - - ctrl.refreshView(); - } - }; -}]) - -.directive('monthpicker', ['dateFilter', function (dateFilter) { - return { - restrict: 'EA', - replace: true, - templateUrl: 'template/datepicker/month.html', - require: '^datepicker', - link: function(scope, element, attrs, ctrl) { - ctrl.step = { years: 1 }; - ctrl.element = element; - - ctrl._refreshView = function() { - var months = new Array(12), - year = ctrl.activeDate.getFullYear(); - - for ( var i = 0; i < 12; i++ ) { - months[i] = angular.extend(ctrl.createDateObject(new Date(year, i, 1), ctrl.formatMonth), { - uid: scope.uniqueId + '-' + i - }); - } - - scope.title = dateFilter(ctrl.activeDate, ctrl.formatMonthTitle); - scope.rows = ctrl.split(months, 3); - }; - - ctrl.compare = function(date1, date2) { - return new Date( date1.getFullYear(), date1.getMonth() ) - new Date( date2.getFullYear(), date2.getMonth() ); - }; - - ctrl.handleKeyDown = function( key, evt ) { - var date = ctrl.activeDate.getMonth(); - - if (key === 'left') { - date = date - 1; // up - } else if (key === 'up') { - date = date - 3; // down - } else if (key === 'right') { - date = date + 1; // down - } else if (key === 'down') { - date = date + 3; - } else if (key === 'pageup' || key === 'pagedown') { - var year = ctrl.activeDate.getFullYear() + (key === 'pageup' ? - 1 : 1); - ctrl.activeDate.setFullYear(year); - } else if (key === 'home') { - date = 0; - } else if (key === 'end') { - date = 11; - } - ctrl.activeDate.setMonth(date); - }; - - ctrl.refreshView(); - } - }; -}]) - -.directive('yearpicker', ['dateFilter', function (dateFilter) { - return { - restrict: 'EA', - replace: true, - templateUrl: 'template/datepicker/year.html', - require: '^datepicker', - link: function(scope, element, attrs, ctrl) { - var range = ctrl.yearRange; - - ctrl.step = { years: range }; - ctrl.element = element; - - function getStartingYear( year ) { - return parseInt((year - 1) / range, 10) * range + 1; - } - - ctrl._refreshView = function() { - var years = new Array(range); - - for ( var i = 0, start = getStartingYear(ctrl.activeDate.getFullYear()); i < range; i++ ) { - years[i] = angular.extend(ctrl.createDateObject(new Date(start + i, 0, 1), ctrl.formatYear), { - uid: scope.uniqueId + '-' + i - }); - } - - scope.title = [years[0].label, years[range - 1].label].join(' - '); - scope.rows = ctrl.split(years, 5); - scope.yearRange = ctrl.yearRange; - }; - - ctrl.compare = function(date1, date2) { - return date1.getFullYear() - date2.getFullYear(); - }; - - ctrl.handleKeyDown = function( key, evt ) { - var date = ctrl.activeDate.getFullYear(); - - if (key === 'left') { - date = date - 1; // up - } else if (key === 'up') { - date = date - 5; // down - } else if (key === 'right') { - date = date + 1; // down - } else if (key === 'down') { - date = date + 5; - } else if (key === 'pageup' || key === 'pagedown') { - date += (key === 'pageup' ? - 1 : 1) * ctrl.step.years; - } else if (key === 'home') { - date = getStartingYear( ctrl.activeDate.getFullYear() ); - } else if (key === 'end') { - date = getStartingYear( ctrl.activeDate.getFullYear() ) + range - 1; - } - ctrl.activeDate.setFullYear(date); - }; - - ctrl.refreshView(); - } - }; -}]) - -.constant('datepickerPopupConfig', { - datepickerPopup: 'yyyy-MM-dd', - currentText: 'Today', - clearText: 'Clear', - closeText: 'Done', - closeOnDateSelection: true, - appendToBody: false, - showButtonBar: true -}) - -.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', 'dateParser', 'datepickerPopupConfig', -function ($compile, $parse, $document, $position, dateFilter, dateParser, datepickerPopupConfig) { - return { - restrict: 'EA', - require: 'ngModel', - scope: { - isOpen: '=?', - currentText: '@', - clearText: '@', - closeText: '@', - dateDisabled: '&' - }, - link: function(scope, element, attrs, ngModel) { - var dateFormat, - closeOnDateSelection = angular.isDefined(attrs.closeOnDateSelection) ? scope.$parent.$eval(attrs.closeOnDateSelection) : datepickerPopupConfig.closeOnDateSelection, - appendToBody = angular.isDefined(attrs.datepickerAppendToBody) ? scope.$parent.$eval(attrs.datepickerAppendToBody) : datepickerPopupConfig.appendToBody; - - scope.showButtonBar = angular.isDefined(attrs.showButtonBar) ? scope.$parent.$eval(attrs.showButtonBar) : datepickerPopupConfig.showButtonBar; - - scope.getText = function( key ) { - return scope[key + 'Text'] || datepickerPopupConfig[key + 'Text']; - }; - - attrs.$observe('datepickerPopup', function(value) { - dateFormat = value || datepickerPopupConfig.datepickerPopup; - ngModel.$render(); - }); - - // popup element used to display calendar - var popupEl = angular.element('
'); - popupEl.attr({ - 'ng-model': 'date', - 'ng-change': 'dateSelection()' - }); - - function cameltoDash( string ){ - return string.replace(/([A-Z])/g, function($1) { return '-' + $1.toLowerCase(); }); - } - - // datepicker element - var datepickerEl = angular.element(popupEl.children()[0]); - if ( attrs.datepickerOptions ) { - angular.forEach(scope.$parent.$eval(attrs.datepickerOptions), function( value, option ) { - datepickerEl.attr( cameltoDash(option), value ); - }); - } - - scope.watchData = {}; - angular.forEach(['minDate', 'maxDate', 'datepickerMode'], function( key ) { - if ( attrs[key] ) { - var getAttribute = $parse(attrs[key]); - scope.$parent.$watch(getAttribute, function(value){ - scope.watchData[key] = value; - }); - datepickerEl.attr(cameltoDash(key), 'watchData.' + key); - - // Propagate changes from datepicker to outside - if ( key === 'datepickerMode' ) { - var setAttribute = getAttribute.assign; - scope.$watch('watchData.' + key, function(value, oldvalue) { - if ( value !== oldvalue ) { - setAttribute(scope.$parent, value); - } - }); - } - } - }); - if (attrs.dateDisabled) { - datepickerEl.attr('date-disabled', 'dateDisabled({ date: date, mode: mode })'); - } - - function parseDate(viewValue) { - if (!viewValue) { - ngModel.$setValidity('date', true); - return null; - } else if (angular.isDate(viewValue) && !isNaN(viewValue)) { - ngModel.$setValidity('date', true); - return viewValue; - } else if (angular.isString(viewValue)) { - var date = dateParser.parse(viewValue, dateFormat) || new Date(viewValue); - if (isNaN(date)) { - ngModel.$setValidity('date', false); - return undefined; - } else { - ngModel.$setValidity('date', true); - return date; - } - } else { - ngModel.$setValidity('date', false); - return undefined; - } - } - ngModel.$parsers.unshift(parseDate); - - // Inner change - scope.dateSelection = function(dt) { - if (angular.isDefined(dt)) { - scope.date = dt; - } - ngModel.$setViewValue(scope.date); - ngModel.$render(); - - if ( closeOnDateSelection ) { - scope.isOpen = false; - element[0].focus(); - } - }; - - element.bind('input change keyup', function() { - scope.$apply(function() { - scope.date = ngModel.$modelValue; - }); - }); - - // Outer change - ngModel.$render = function() { - var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : ''; - element.val(date); - scope.date = parseDate( ngModel.$modelValue ); - }; - - var documentClickBind = function(event) { - if (scope.isOpen && event.target !== element[0]) { - scope.$apply(function() { - scope.isOpen = false; - }); - } - }; - - var keydown = function(evt, noApply) { - scope.keydown(evt); - }; - element.bind('keydown', keydown); - - scope.keydown = function(evt) { - if (evt.which === 27) { - evt.preventDefault(); - evt.stopPropagation(); - scope.close(); - } else if (evt.which === 40 && !scope.isOpen) { - scope.isOpen = true; - } - }; - - scope.$watch('isOpen', function(value) { - if (value) { - scope.$broadcast('datepicker.focus'); - scope.position = appendToBody ? $position.offset(element) : $position.position(element); - scope.position.top = scope.position.top + element.prop('offsetHeight'); - - $document.bind('click', documentClickBind); - } else { - $document.unbind('click', documentClickBind); - } - }); - - scope.select = function( date ) { - if (date === 'today') { - var today = new Date(); - if (angular.isDate(ngModel.$modelValue)) { - date = new Date(ngModel.$modelValue); - date.setFullYear(today.getFullYear(), today.getMonth(), today.getDate()); - } else { - date = new Date(today.setHours(0, 0, 0, 0)); - } - } - scope.dateSelection( date ); - }; - - scope.close = function() { - scope.isOpen = false; - element[0].focus(); - }; - - var $popup = $compile(popupEl)(scope); - // Prevent jQuery cache memory leak (template is now redundant after linking) - popupEl.remove(); - - if ( appendToBody ) { - $document.find('body').append($popup); - } else { - element.after($popup); - } - - scope.$on('$destroy', function() { - $popup.remove(); - element.unbind('keydown', keydown); - $document.unbind('click', documentClickBind); - }); - } - }; -}]) - -.directive('datepickerPopupWrap', function() { - return { - restrict:'EA', - replace: true, - transclude: true, - templateUrl: 'template/datepicker/popup.html', - link:function (scope, element, attrs) { - element.bind('click', function(event) { - event.preventDefault(); - event.stopPropagation(); - }); - } - }; -}); diff --git a/src/ui/public/angular-bootstrap/datepicker/day.html b/src/ui/public/angular-bootstrap/datepicker/day.html deleted file mode 100755 index 026fb49551d93..0000000000000 --- a/src/ui/public/angular-bootstrap/datepicker/day.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - -
-
- - - - - -
-
- {{label.abbr}} -
- {{ weekNumbers[$index] }} - - -
diff --git a/src/ui/public/angular-bootstrap/datepicker/month.html b/src/ui/public/angular-bootstrap/datepicker/month.html deleted file mode 100755 index 8907215e6e8d2..0000000000000 --- a/src/ui/public/angular-bootstrap/datepicker/month.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - -
-
- - - - - -
-
- -
diff --git a/src/ui/public/angular-bootstrap/datepicker/popup.html b/src/ui/public/angular-bootstrap/datepicker/popup.html deleted file mode 100755 index 11c4a6ba25e7e..0000000000000 --- a/src/ui/public/angular-bootstrap/datepicker/popup.html +++ /dev/null @@ -1,10 +0,0 @@ - diff --git a/src/ui/public/angular-bootstrap/datepicker/year.html b/src/ui/public/angular-bootstrap/datepicker/year.html deleted file mode 100755 index 7c1ad3be43253..0000000000000 --- a/src/ui/public/angular-bootstrap/datepicker/year.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - -
-
- - - - - -
-
- -
diff --git a/src/ui/public/angular-bootstrap/index.js b/src/ui/public/angular-bootstrap/index.js index c01f7f4a21064..b519abcaf5dee 100644 --- a/src/ui/public/angular-bootstrap/index.js +++ b/src/ui/public/angular-bootstrap/index.js @@ -21,7 +21,6 @@ angular.module('ui.bootstrap', [ 'ui.bootstrap.buttons', 'ui.bootstrap.dateparser', 'ui.bootstrap.position', - 'ui.bootstrap.datepicker', 'ui.bootstrap.dropdown', 'ui.bootstrap.modal', 'ui.bootstrap.pagination', @@ -36,11 +35,6 @@ angular.module('ui.bootstrap', [ angular.module('ui.bootstrap.tpls', [ 'template/alert/alert.html', - 'template/datepicker/datepicker.html', - 'template/datepicker/day.html', - 'template/datepicker/month.html', - 'template/datepicker/popup.html', - 'template/datepicker/year.html', 'template/modal/backdrop.html', 'template/modal/window.html', 'template/pagination/pager.html', @@ -65,7 +59,6 @@ import './bindHtml/bindHtml'; import './buttons/buttons'; import './collapse/collapse'; import './dateparser/dateparser'; -import './datepicker/datepicker'; import './dropdown/dropdown'; import './modal/modal'; import './pagination/pagination'; @@ -85,36 +78,6 @@ angular.module('template/alert/alert.html', []).run(['$templateCache', function( $templateCache.put('template/alert/alert.html', alert); }]); -import datepicker from './datepicker/datepicker.html'; - -angular.module('template/datepicker/datepicker.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/datepicker/datepicker.html', datepicker); -}]); - -import day from './datepicker/day.html'; - -angular.module('template/datepicker/day.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/datepicker/day.html', day); -}]); - -import month from './datepicker/month.html'; - -angular.module('template/datepicker/month.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/datepicker/month.html', month); -}]); - -import popup from './datepicker/popup.html'; - -angular.module('template/datepicker/popup.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/datepicker/popup.html', popup); -}]); - -import year from './datepicker/year.html'; - -angular.module('template/datepicker/year.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/datepicker/year.html', year); -}]); - import backdrop from './modal/backdrop.html'; angular.module('template/modal/backdrop.html', []).run(['$templateCache', function($templateCache) { diff --git a/src/ui/public/styles/bootstrap/bootstrap.less b/src/ui/public/styles/bootstrap/bootstrap.less index 5f06887d02e8c..be0964ce8d757 100644 --- a/src/ui/public/styles/bootstrap/bootstrap.less +++ b/src/ui/public/styles/bootstrap/bootstrap.less @@ -59,7 +59,7 @@ @import "responsive-utilities.less"; // Minimal usage // Decent usage in multiple areas -@import "dropdowns.less"; // Used in console, datepicker, watcher +@import "dropdowns.less"; // Used in console, watcher @import "input-groups.less"; // Used in ML, typeahead, reporting, graph @import "pagination.less"; @import "pager.less"; From 781e8018b4058ab13c90c96b9e4017fc6c6cd366 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 22 Jan 2019 12:54:16 -0700 Subject: [PATCH 04/34] Embed timepicker in query bar (#29130) * replace kbnTimepicker directive with EuiSuperDatePicker * remove kbnTimepicker directive * remove bootstrap datepicker * embed timepicker in query bar * flesh out date picker in query bar for maps app * wire up refresh config --- .../kibana/public/dashboard/dashboard_app.js | 2 +- .../public/discover/controllers/discover.js | 2 +- .../kibana/public/visualize/editor/editor.js | 2 +- src/ui/public/kbn_top_nav/kbn_top_nav.html | 4 +- src/ui/public/kbn_top_nav/kbn_top_nav.js | 8 +- .../public/query_bar/components/query_bar.tsx | 138 +++++++++++++++--- .../gis/public/actions/store_actions.js | 57 ++------ .../gis/public/angular/get_initial_query.js | 30 ++++ .../angular/get_initial_refresh_config.js | 28 ++++ .../angular/get_initial_time_filters.js | 24 +++ x-pack/plugins/gis/public/angular/map.html | 6 + .../gis/public/angular/map_controller.js | 103 ++++++++----- .../gis/public/components/gis_map/index.js | 12 +- .../gis/public/components/gis_map/view.js | 30 ++-- x-pack/plugins/gis/public/store/map.js | 15 +- 15 files changed, 326 insertions(+), 135 deletions(-) create mode 100644 x-pack/plugins/gis/public/angular/get_initial_query.js create mode 100644 x-pack/plugins/gis/public/angular/get_initial_refresh_config.js create mode 100644 x-pack/plugins/gis/public/angular/get_initial_time_filters.js diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js index f71edb1c5e77b..27311528f9b00 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js @@ -216,7 +216,7 @@ app.directive('dashboardApp', function ($injector) { dashboardStateManager.getPanels().find((panel) => panel.panelIndex === panelIndex); }; - $scope.updateQueryAndFetch = function (query) { + $scope.updateQueryAndFetch = function ({ query }) { const oldQuery = $scope.model.query; if (_.isEqual(oldQuery, query)) { // The user can still request a reload in the query bar, even if the diff --git a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js index db8119fa784c8..1aaf1f0956d0a 100644 --- a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js @@ -643,7 +643,7 @@ function discoverController( .catch(notify.error); }; - $scope.updateQueryAndFetch = function (query) { + $scope.updateQueryAndFetch = function ({ query }) { $state.query = migrateLegacyQuery(query); $scope.fetch(); }; diff --git a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js index 6039285048e22..b9eed586d9dd1 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js @@ -378,7 +378,7 @@ function VisEditor( } } - $scope.updateQueryAndFetch = function (query) { + $scope.updateQueryAndFetch = function ({ query }) { $state.query = migrateLegacyQuery(query); $scope.fetch(); }; diff --git a/src/ui/public/kbn_top_nav/kbn_top_nav.html b/src/ui/public/kbn_top_nav/kbn_top_nav.html index bfad2b891d35a..733e20e8a2e2a 100644 --- a/src/ui/public/kbn_top_nav/kbn_top_nav.html +++ b/src/ui/public/kbn_top_nav/kbn_top_nav.html @@ -32,7 +32,9 @@ > - + + + diff --git a/src/ui/public/kbn_top_nav/kbn_top_nav.js b/src/ui/public/kbn_top_nav/kbn_top_nav.js index c827028bbba23..4a82ca1cb17d5 100644 --- a/src/ui/public/kbn_top_nav/kbn_top_nav.js +++ b/src/ui/public/kbn_top_nav/kbn_top_nav.js @@ -38,10 +38,10 @@ /** * kbnTopNav directive * - * The top section that shows the timepicker, load, share and save dialogues. + * The top section that optionally shows the timepicker and menu items. * * ``` - * + * * ``` * * Menu items/templates are passed to the kbnTopNav via the config attribute @@ -151,6 +151,10 @@ module.directive('kbnTopNav', function (Private) { initTopNav(topNavConfig, null); + if (!_.has($scope, 'showTimepickerInTopNav')) { + $scope.showTimepickerInTopNav = true; + } + return $scope.kbnTopNav; }, diff --git a/src/ui/public/query_bar/components/query_bar.tsx b/src/ui/public/query_bar/components/query_bar.tsx index 02f240ffc352b..37c38742417e8 100644 --- a/src/ui/public/query_bar/components/query_bar.tsx +++ b/src/ui/public/query_bar/components/query_bar.tsx @@ -19,12 +19,14 @@ import { IndexPattern } from 'ui/index_patterns'; -import { compact, debounce, isEqual } from 'lodash'; +import { compact, debounce, get, isEqual } from 'lodash'; import React, { Component } from 'react'; import { getFromLegacyIndexPattern } from 'ui/index_patterns/static_utils'; import { kfetch } from 'ui/kfetch'; import { PersistedLog } from 'ui/persisted_log'; import { Storage } from 'ui/storage'; +// @ts-ignore +import { timeHistory } from 'ui/timefilter/time_history'; import { AutocompleteSuggestion, AutocompleteSuggestionType, @@ -42,6 +44,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiOutsideClickDetector, + EuiSuperDatePicker, } from '@elastic/eui'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; @@ -66,14 +69,25 @@ interface Query { language: string; } +interface DateRange { + from: string; + to: string; +} + interface Props { query: Query; - onSubmit: (query: { query: string | object; language: string }) => void; + onSubmit: ({ dateRange, query }: { dateRange: DateRange; query: Query }) => void; disableAutoFocus?: boolean; appName: string; indexPatterns: IndexPattern[]; store: Storage; intl: InjectedIntl; + showDatePicker: boolean; + from: string; + to: string; + isPaused: boolean; + refreshInterval: number; + onRefreshChange?: (isPaused: boolean, refreshInterval: number) => void; } interface State { @@ -84,6 +98,8 @@ interface State { suggestions: AutocompleteSuggestion[]; suggestionLimit: number; currentProps?: Props; + from: string; + to: string; } export class QueryBarUI extends Component { @@ -92,26 +108,47 @@ export class QueryBarUI extends Component { return null; } + let nextQuery = null; if (nextProps.query.query !== prevState.query.query) { - return { - query: { - query: toUser(nextProps.query.query), - language: nextProps.query.language, - }, - currentProps: nextProps, + nextQuery = { + query: toUser(nextProps.query.query), + language: nextProps.query.language, }; } else if (nextProps.query.language !== prevState.query.language) { - return { - query: { - query: '', - language: nextProps.query.language, - }, - currentProps: nextProps, + nextQuery = { + query: '', + language: nextProps.query.language, }; } - return null; + let nextDateRange = null; + if ( + nextProps.from !== get(prevState, 'currentProps.from') || + nextProps.to !== get(prevState, 'currentProps.to') + ) { + nextDateRange = { + from: nextProps.from, + to: nextProps.to, + }; + } + + const nextState = { + currentProps: nextProps, + }; + if (nextQuery) { + nextState.query = nextQuery; + } + if (nextDateRange) { + nextState.from = nextDateRange.from; + nextState.to = nextDateRange.to; + } + return nextState; } + private static defaultProps = { + showDatePicker: false, + from: 'now-15m', + to: 'now', + }; /* Keep the "draft" value in local state until the user actually submits the query. There are a couple advantages: @@ -135,6 +172,8 @@ export class QueryBarUI extends Component { index: null, suggestions: [], suggestionLimit: 50, + from: this.props.from, + to: this.props.to, }; public updateSuggestions = debounce(async () => { @@ -150,7 +189,11 @@ export class QueryBarUI extends Component { private persistedLog: PersistedLog | null = null; public isDirty = () => { - return this.state.query.query !== this.props.query.query; + return ( + this.state.query.query !== this.props.query.query || + this.state.from !== this.props.from || + this.state.to !== this.props.to + ); }; public increaseLimit = () => { @@ -321,6 +364,13 @@ export class QueryBarUI extends Component { this.onInputChange(event.target.value); }; + public onTimeChange = ({ start, end }: { start: string; end: string }) => { + this.setState({ + from: start, + to: end, + }); + }; + public onKeyUp = (event: React.KeyboardEvent) => { if ([KEY_CODES.LEFT, KEY_CODES.RIGHT, KEY_CODES.HOME, KEY_CODES.END].includes(event.keyCode)) { this.setState({ isSuggestionsVisible: true }); @@ -407,9 +457,20 @@ export class QueryBarUI extends Component { this.persistedLog.add(this.state.query.query); } + timeHistory.add({ + from: this.state.from, + to: this.state.to, + }); + this.props.onSubmit({ - query: fromUser(this.state.query.query), - language: this.state.query.language, + query: { + query: fromUser(this.state.query.query), + language: this.state.query.language, + }, + dateRange: { + from: this.state.from, + to: this.state.to, + }, }); this.setState({ isSuggestionsVisible: false }); }; @@ -426,8 +487,14 @@ export class QueryBarUI extends Component { this.props.store.set('kibana.userQueryLanguage', language); this.props.onSubmit({ - query: '', - language, + query: { + query: '', + language, + }, + dateRange: { + from: this.props.from, + to: this.props.to, + }, }); }; @@ -532,6 +599,7 @@ export class QueryBarUI extends Component { + {this.renderDatePicker()} { ); } + + private renderDatePicker() { + if (!this.props.showDatePicker) { + return null; + } + + const recentlyUsedRanges = timeHistory + .get() + .map(({ from, to }: { from: string; to: string }) => { + return { + start: from, + end: to, + }; + }); + + return ( + + + + ); + } } export const QueryBar = injectI18n(QueryBarUI); diff --git a/x-pack/plugins/gis/public/actions/store_actions.js b/x-pack/plugins/gis/public/actions/store_actions.js index 6eb5a12883d65..48a15467b479a 100644 --- a/x-pack/plugins/gis/public/actions/store_actions.js +++ b/x-pack/plugins/gis/public/actions/store_actions.js @@ -16,7 +16,6 @@ import { getMapReady, getWaitingForMapReadyLayerListRaw, } from '../selectors/map_selectors'; -import { timeService } from '../kibana_services'; export const SET_SELECTED_LAYER = 'SET_SELECTED_LAYER'; export const UPDATE_LAYER_ORDER = 'UPDATE_LAYER_ORDER'; @@ -34,7 +33,6 @@ export const LAYER_DATA_LOAD_STARTED = 'LAYER_DATA_LOAD_STARTED'; export const LAYER_DATA_LOAD_ENDED = 'LAYER_DATA_LOAD_ENDED'; export const LAYER_DATA_LOAD_ERROR = 'LAYER_DATA_LOAD_ERROR'; export const SET_JOINS = 'SET_JOINS'; -export const SET_TIME_FILTERS = 'SET_TIME_FILTERS'; export const SET_QUERY = 'SET_QUERY'; export const TRIGGER_REFRESH_TIMER = 'TRIGGER_REFRESH_TIMER'; export const UPDATE_LAYER_PROP = 'UPDATE_LAYER_PROP'; @@ -385,43 +383,17 @@ export function removeLayer(id) { } export function setMeta(metaJson) { - return async dispatch => { - dispatch({ - type: SET_META, - meta: metaJson - }); - }; -} - -export function setTimeFiltersToKbnGlobalTime() { - return (dispatch) => { - dispatch(setTimeFilters(timeService.getTime())); - }; -} - -export function setTimeFilters({ from, to }) { - return async (dispatch, getState) => { - dispatch({ - type: SET_TIME_FILTERS, - from, - to, - }); - - // Update Kibana global time - const kbnTime = timeService.getTime(); - if ((to && to !== kbnTime.to) || (from && from !== kbnTime.from)) { - timeService.setTime({ from, to }); - } - - const dataFilters = getDataFilters(getState()); - await syncDataForAllLayers(getState, dispatch, dataFilters); + return { + type: SET_META, + meta: metaJson }; } -export function setQuery({ query }) { +export function setQuery({ query, timeFilters }) { return async (dispatch, getState) => { dispatch({ type: SET_QUERY, + timeFilters, query: { ...query, // ensure query changes to trigger re-fetch even when query is the same because "Refresh" clicked @@ -435,21 +407,10 @@ export function setQuery({ query }) { } export function setRefreshConfig({ isPaused, interval }) { - return async (dispatch) => { - dispatch({ - type: SET_REFRESH_CONFIG, - isPaused, - interval, - }); - - // Update Kibana global refresh - const kbnRefresh = timeService.getRefreshInterval(); - if (isPaused !== kbnRefresh.pause || interval !== kbnRefresh.value) { - timeService.setRefreshInterval({ - pause: isPaused, - value: interval, - }); - } + return { + type: SET_REFRESH_CONFIG, + isPaused, + interval, }; } diff --git a/x-pack/plugins/gis/public/angular/get_initial_query.js b/x-pack/plugins/gis/public/angular/get_initial_query.js new file mode 100644 index 0000000000000..4743832c113be --- /dev/null +++ b/x-pack/plugins/gis/public/angular/get_initial_query.js @@ -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. + */ + +const DEFAULT_QUERY_LANGUAGE = 'kuery'; + +export function getInitialQuery({ + mapStateJSON, + appState = {}, + userQueryLanguage, +}) { + + if (appState.query) { + return appState.query; + } + + if (mapStateJSON) { + const mapState = JSON.parse(mapStateJSON); + if (mapState.query) { + return mapState.query; + } + } + + return { + query: '', + language: userQueryLanguage || DEFAULT_QUERY_LANGUAGE + }; +} diff --git a/x-pack/plugins/gis/public/angular/get_initial_refresh_config.js b/x-pack/plugins/gis/public/angular/get_initial_refresh_config.js new file mode 100644 index 0000000000000..5d042028c1ef8 --- /dev/null +++ b/x-pack/plugins/gis/public/angular/get_initial_refresh_config.js @@ -0,0 +1,28 @@ +/* + * 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 chrome from 'ui/chrome'; + +const uiSettings = chrome.getUiSettingsClient(); + +export function getInitialRefreshConfig({ + mapStateJSON, + globalState = {}, +}) { + + if (mapStateJSON) { + const mapState = JSON.parse(mapStateJSON); + if (mapState.refreshConfig) { + return mapState.refreshConfig; + } + } + + const defaultRefreshConfig = uiSettings.get('timepicker:refreshIntervalDefaults'); + const refreshInterval = { ...defaultRefreshConfig, ...globalState.refreshInterval }; + return { + isPaused: refreshInterval.pause, + interval: refreshInterval.value, + }; +} diff --git a/x-pack/plugins/gis/public/angular/get_initial_time_filters.js b/x-pack/plugins/gis/public/angular/get_initial_time_filters.js new file mode 100644 index 0000000000000..8ce57e0d0991b --- /dev/null +++ b/x-pack/plugins/gis/public/angular/get_initial_time_filters.js @@ -0,0 +1,24 @@ +/* + * 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 chrome from 'ui/chrome'; + +const uiSettings = chrome.getUiSettingsClient(); + +export function getInitialTimeFilters({ + mapStateJSON, + globalState = {}, +}) { + + if (mapStateJSON) { + const mapState = JSON.parse(mapStateJSON); + if (mapState.timeFilters) { + return mapState.timeFilters; + } + } + + const defaultTime = uiSettings.get('timepicker:timeDefaults'); + return { ...defaultTime, ...globalState.time }; +} diff --git a/x-pack/plugins/gis/public/angular/map.html b/x-pack/plugins/gis/public/angular/map.html index 34f953f0525ea..bb30c7461cbe1 100644 --- a/x-pack/plugins/gis/public/angular/map.html +++ b/x-pack/plugins/gis/public/angular/map.html @@ -27,6 +27,12 @@ app-name="'maps'" on-submit="updateQueryAndDispatch" index-patterns="indexPatterns" + show-date-picker="showDatePicker" + from="time.from" + to="time.to" + is-paused="refreshConfig.isPaused" + refresh-interval="refreshConfig.interval" + on-refresh-change="onRefreshChange" > diff --git a/x-pack/plugins/gis/public/angular/map_controller.js b/x-pack/plugins/gis/public/angular/map_controller.js index f6128b429bd0f..0d69f058dae0d 100644 --- a/x-pack/plugins/gis/public/angular/map_controller.js +++ b/x-pack/plugins/gis/public/angular/map_controller.js @@ -9,13 +9,11 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { uiModules } from 'ui/modules'; import { applyTheme } from 'ui/theme'; -import { timefilter } from 'ui/timefilter'; import { Provider } from 'react-redux'; import { getStore } from '../store/store'; import { GisMap } from '../components/gis_map'; import { setSelectedLayer, - setTimeFilters, setRefreshConfig, setGoto, replaceLayerList, @@ -30,13 +28,16 @@ import { showSaveModal } from 'ui/saved_objects/show_saved_object_save_modal'; import { showOptionsPopover } from '../components/top_nav/show_options_popover'; import { toastNotifications } from 'ui/notify'; import { getInitialLayers } from './get_initial_layers'; +import { getInitialQuery } from './get_initial_query'; +import { getInitialTimeFilters } from './get_initial_time_filters'; +import { getInitialRefreshConfig } from './get_initial_refresh_config'; const REACT_ANCHOR_DOM_ELEMENT_ID = 'react-gis-root'; -const DEFAULT_QUERY_LANGUAGE = 'kuery'; + const app = uiModules.get('app/gis', []); -app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage, AppState) => { +app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage, AppState, globalState) => { const savedMap = $scope.map = $route.current.locals.map; let isDarkTheme; @@ -44,27 +45,79 @@ app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage inspectorAdapters.requests.reset(); + $scope.$listen(globalState, 'fetch_with_changes', (diff) => { + if (diff.includes('time')) { + $scope.updateQueryAndDispatch({ query: $scope.query, dateRange: globalState.time }); + } + if (diff.includes('refreshInterval')) { + $scope.onRefreshChange({ isPaused: globalState.pause, refreshInterval: globalState.value }); + } + }); + const $state = new AppState(); $scope.$listen($state, 'fetch_with_changes', function (diff) { if (diff.includes('query')) { - $scope.updateQueryAndDispatch($state.query); + $scope.updateQueryAndDispatch({ query: $state.query }); } }); - $scope.query = {}; + + function syncAppAndGlobalState() { + $scope.$evalAsync(() => { + $state.query = $scope.query; + $state.save(); + globalState.time = $scope.time; + globalState.refreshInterval = { + pause: $scope.refreshConfig.isPaused, + value: $scope.refreshConfig.interval, + }; + globalState.save(); + }); + } + + $scope.query = getInitialQuery({ + mapStateJSON: savedMap.mapStateJSON, + appState: $state, + userQueryLanguage: localStorage.get('kibana.userQueryLanguage') + }); + $scope.time = getInitialTimeFilters({ + mapStateJSON: savedMap.mapStateJSON, + globalState: globalState, + }); + $scope.refreshConfig = getInitialRefreshConfig({ + mapStateJSON: savedMap.mapStateJSON, + globalState: globalState, + }); + syncAppAndGlobalState(); + $scope.indexPatterns = []; - $scope.updateQueryAndDispatch = function (newQuery) { - $scope.query = newQuery; + $scope.updateQueryAndDispatch = function ({ dateRange, query }) { + $scope.query = query; + $scope.time = dateRange; getStore().then(store => { // ignore outdated query - if ($scope.query !== newQuery) { + if ($scope.query !== query && $scope.time !== dateRange) { return; } - store.dispatch(setQuery({ query: $scope.query })); + store.dispatch(setQuery({ query: $scope.query, timeFilters: $scope.time })); - // update appState - $state.query = $scope.query; - $state.save(); + syncAppAndGlobalState(); + }); + }; + $scope.onRefreshChange = function ({ isPaused, refreshInterval }) { + $scope.refreshConfig = { + isPaused, + interval: refreshInterval ? refreshInterval : $scope.refreshConfig.interval + }; + getStore().then(store => { + // ignore outdated + if ($scope.refreshConfig.isPaused !== isPaused && $scope.refreshConfig.interval !== refreshInterval) { + return; + } + + store.dispatch(setRefreshConfig($scope.refreshConfig)); + + syncAppAndGlobalState(); }); }; @@ -79,36 +132,20 @@ app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage }); // sync store with savedMap mapState - let queryFromSavedObject; if (savedMap.mapStateJSON) { const mapState = JSON.parse(savedMap.mapStateJSON); - queryFromSavedObject = mapState.query; - const timeFilters = mapState.timeFilters ? mapState.timeFilters : timefilter.getTime(); - store.dispatch(setTimeFilters(timeFilters)); store.dispatch(setGoto({ lat: mapState.center.lat, lon: mapState.center.lon, zoom: mapState.zoom, })); - if (mapState.refreshConfig) { - store.dispatch(setRefreshConfig(mapState.refreshConfig)); - } } const layerList = getInitialLayers(savedMap.layerListJSON, getDataSources(store.getState())); store.dispatch(replaceLayerList(layerList)); - // Initialize query, syncing appState and store - if ($state.query) { - $scope.updateQueryAndDispatch($state.query); - } else if (queryFromSavedObject) { - $scope.updateQueryAndDispatch(queryFromSavedObject); - } else { - $scope.updateQueryAndDispatch({ - query: '', - language: localStorage.get('kibana.userQueryLanguage') || DEFAULT_QUERY_LANGUAGE - }); - } + store.dispatch(setRefreshConfig($scope.refreshConfig)); + store.dispatch(setQuery({ query: $scope.query, timeFilters: $scope.time })); const root = document.getElementById(REACT_ANCHOR_DOM_ELEMENT_ID); render( @@ -206,6 +243,8 @@ app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage return { id }; } + $scope.showTimepickerInTopNav = false; // used by kbn-top-nav directive to disable timepicker in top nav + $scope.showDatePicker = true; // used by query-bar directive to enable timepikcer in query bar $scope.topNavMenu = [{ key: 'inspect', description: 'Open Inspector', @@ -254,8 +293,6 @@ app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage showSaveModal(saveModal); } }]; - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); function updateTheme() { $scope.$evalAsync(() => { diff --git a/x-pack/plugins/gis/public/components/gis_map/index.js b/x-pack/plugins/gis/public/components/gis_map/index.js index b0e31b7e2f470..cff886a1ff123 100644 --- a/x-pack/plugins/gis/public/components/gis_map/index.js +++ b/x-pack/plugins/gis/public/components/gis_map/index.js @@ -7,26 +7,22 @@ import { connect } from 'react-redux'; import { GisMap } from './view'; import { getFlyoutDisplay, FLYOUT_STATE } from '../../store/ui'; -import { - setTimeFiltersToKbnGlobalTime, - triggerRefreshTimer, - setRefreshConfig -} from '../../actions/store_actions'; +import { triggerRefreshTimer } from '../../actions/store_actions'; +import { getRefreshConfig } from '../../selectors/map_selectors'; function mapStateToProps(state = {}) { const flyoutDisplay = getFlyoutDisplay(state); return { layerDetailsVisible: flyoutDisplay === FLYOUT_STATE.LAYER_PANEL, addLayerVisible: flyoutDisplay === FLYOUT_STATE.ADD_LAYER_WIZARD, - noFlyoutVisible: flyoutDisplay === FLYOUT_STATE.NONE + noFlyoutVisible: flyoutDisplay === FLYOUT_STATE.NONE, + refreshConfig: getRefreshConfig(state), }; } function mapDispatchToProps(dispatch) { return { - setTimeFiltersToKbnGlobalTime: () => dispatch(setTimeFiltersToKbnGlobalTime()), triggerRefreshTimer: () => dispatch(triggerRefreshTimer()), - setRefreshConfig: (({ isPaused, interval }) => dispatch(setRefreshConfig({ isPaused, interval }))), }; } diff --git a/x-pack/plugins/gis/public/components/gis_map/view.js b/x-pack/plugins/gis/public/components/gis_map/view.js index d3a08630e970c..2abad91c4b974 100644 --- a/x-pack/plugins/gis/public/components/gis_map/view.js +++ b/x-pack/plugins/gis/public/components/gis_map/view.js @@ -12,39 +12,41 @@ import { AddLayerPanel } from '../layer_addpanel/index'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { Toasts } from '../toasts'; -import { timeService } from '../../kibana_services'; - export class GisMap extends Component { componentDidMount() { - timeService.on('timeUpdate', this.props.setTimeFiltersToKbnGlobalTime); - timeService.on('refreshIntervalUpdate', this.setRefreshTimer); + this.setRefreshTimer(); + } + + componentDidUpdate() { this.setRefreshTimer(); } componentWillUnmount() { - timeService.off('timeUpdate', this.props.setTimeFiltersToKbnGlobalTime); - timeService.off('refreshIntervalUpdate', this.setRefreshTimer); this.clearRefreshTimer(); } setRefreshTimer = () => { + const { isPaused, interval } = this.props.refreshConfig; + + if (this.isPaused === isPaused && this.interval === interval) { + // refreshConfig is the same, nothing to do + return; + } + + this.isPaused = isPaused; + this.interval = interval; + this.clearRefreshTimer(); - const { value, pause } = timeService.getRefreshInterval(); - if (!pause && value > 0) { + if (!isPaused && interval > 0) { this.refreshTimerId = setInterval( () => { this.props.triggerRefreshTimer(); }, - value + interval ); } - - this.props.setRefreshConfig({ - isPaused: pause, - interval: value, - }); } clearRefreshTimer = () => { diff --git a/x-pack/plugins/gis/public/store/map.js b/x-pack/plugins/gis/public/store/map.js index cf32464034a9c..6b63dba9e53fd 100644 --- a/x-pack/plugins/gis/public/store/map.js +++ b/x-pack/plugins/gis/public/store/map.js @@ -19,7 +19,6 @@ import { MAP_EXTENT_CHANGED, MAP_READY, MAP_DESTROYED, - SET_TIME_FILTERS, SET_QUERY, UPDATE_LAYER_PROP, UPDATE_LAYER_STYLE_FOR_SELECTED_LAYER, @@ -161,12 +160,16 @@ export function map(state = INITIAL_STATE, action) { buffer: action.mapState.buffer, }; return { ...state, mapState: { ...state.mapState, ...newMapState } }; - case SET_TIME_FILTERS: - const { from, to } = action; - return { ...state, mapState: { ...state.mapState, timeFilters: { from, to } } }; case SET_QUERY: - const { query } = action; - return { ...state, mapState: { ...state.mapState, query } }; + const { query, timeFilters } = action; + return { + ...state, + mapState: { + ...state.mapState, + query, + timeFilters, + } + }; case SET_REFRESH_CONFIG: const { isPaused, interval } = action; return { From c48cabdfd0c2195fbf53f45c1b946436cb82ebe0 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 22 Jan 2019 13:07:23 -0700 Subject: [PATCH 05/34] fix bug with way update function called by watcher --- .../core_plugins/kibana/public/dashboard/dashboard_app.js | 4 +++- .../kibana/public/discover/controllers/discover.js | 4 +++- .../core_plugins/kibana/public/visualize/editor/editor.js | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js index 27311528f9b00..b17576aa85f89 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js @@ -239,7 +239,9 @@ app.directive('dashboardApp', function ($injector) { $scope.indexPatterns = dashboardStateManager.getPanelIndexPatterns(); }; - $scope.$watch('model.query', $scope.updateQueryAndFetch); + $scope.$watch('model.query', (query) => { + $scope.updateQueryAndFetch({ query }); + }); $scope.$listenAndDigestAsync(timefilter, 'fetch', () => { dashboardStateManager.handleTimeChange(timefilter.getTime()); diff --git a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js index 1aaf1f0956d0a..2f5eb1ffd839a 100644 --- a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js @@ -525,7 +525,9 @@ function discoverController( } }); - $scope.$watch('state.query', $scope.updateQueryAndFetch); + $scope.$watch('state.query', (query) => { + $scope.updateQueryAndFetch({ query }); + }); $scope.$watchMulti([ 'rows', diff --git a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js index b9eed586d9dd1..01e004e0cf1c3 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js @@ -304,7 +304,9 @@ function VisEditor( $appStatus.dirty = status.dirty || !savedVis.id; }); - $scope.$watch('state.query', $scope.updateQueryAndFetch); + $scope.$watch('state.query', (query) => { + $scope.updateQueryAndFetch({ query }); + }); $state.replace(); From 11ec6dfea68431f242450e0addd0338cbc0a2efa Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 22 Jan 2019 16:32:03 -0700 Subject: [PATCH 06/34] get maps application functional tests working with new timepicker --- .../public/query_bar/components/query_bar.tsx | 12 ++ test/functional/config.js | 2 + test/functional/page_objects/header_page.js | 32 +---- test/functional/page_objects/index.js | 1 + test/functional/page_objects/time_picker.js | 111 ++++++++++++++++++ .../apps/gis/saved_object_management.js | 13 +- .../apps/monitoring/_get_lifecycle_methods.js | 4 +- .../test/functional/page_objects/gis_page.js | 6 +- 8 files changed, 141 insertions(+), 40 deletions(-) create mode 100644 test/functional/page_objects/time_picker.js diff --git a/src/ui/public/query_bar/components/query_bar.tsx b/src/ui/public/query_bar/components/query_bar.tsx index 37c38742417e8..12fcefa1be66c 100644 --- a/src/ui/public/query_bar/components/query_bar.tsx +++ b/src/ui/public/query_bar/components/query_bar.tsx @@ -639,6 +639,16 @@ export class QueryBarUI extends Component { }; }); + const commonlyUsedRanges = config + .get('timepicker:quickRanges') + .map(({ from, to, display }: { from: string; to: string; display: string }) => { + return { + start: from, + end: to, + label: display, + }; + }); + return ( { onRefreshChange={this.props.onRefreshChange} showUpdateButton={false} recentlyUsedRanges={recentlyUsedRanges} + commonlyUsedRanges={commonlyUsedRanges} + dateFormat={config.get('dateFormat')} /> ); diff --git a/test/functional/config.js b/test/functional/config.js index aabc2c5eaea32..86d38e1782d0a 100644 --- a/test/functional/config.js +++ b/test/functional/config.js @@ -33,6 +33,7 @@ import { VisualBuilderPageProvider, TimelionPageProvider, SharePageProvider, + TimePickerPageProvider, } from './page_objects'; import { @@ -94,6 +95,7 @@ export default async function ({ readConfigFile }) { visualBuilder: VisualBuilderPageProvider, timelion: TimelionPageProvider, share: SharePageProvider, + timePicker: TimePickerPageProvider, }, services: { es: commonConfig.get('services.es'), diff --git a/test/functional/page_objects/header_page.js b/test/functional/page_objects/header_page.js index 47f9dc231fce1..99512197f89bb 100644 --- a/test/functional/page_objects/header_page.js +++ b/test/functional/page_objects/header_page.js @@ -174,36 +174,6 @@ export function HeaderPageProvider({ getService, getPageObjects }) { await find.clickByLinkText(quickTime); } - async getAutoRefreshState() { - return testSubjects.getAttribute('globalTimepickerAutoRefreshButton', 'data-test-subj-state'); - } - - async getRefreshConfig() { - const refreshState = await testSubjects.getAttribute('globalTimepickerAutoRefreshButton', 'data-test-subj-state'); - const refreshConfig = await testSubjects.getVisibleText('globalRefreshButton'); - return `${refreshState} ${refreshConfig}`; - } - - // check if the auto refresh state is active and to pause it - async pauseAutoRefresh() { - let result = false; - if ((await this.getAutoRefreshState()) === 'active') { - await testSubjects.click('globalTimepickerAutoRefreshButton'); - result = true; - } - return result; - } - - // check if the auto refresh state is inactive and to resume it - async resumeAutoRefresh() { - let result = false; - if ((await this.getAutoRefreshState()) === 'inactive') { - await testSubjects.click('globalTimepickerAutoRefreshButton'); - result = true; - } - return result; - } - async getToastMessage(findTimeout = defaultFindTimeout) { const toastMessage = await find.displayedByCssSelector( 'kbn-truncated.kbnToast__message', @@ -249,6 +219,7 @@ export function HeaderPageProvider({ getService, getPageObjects }) { await testSubjects.find('kibanaChrome', defaultFindTimeout * 10); } + // replaced with timePicker.getTimeConfig async getPrettyDuration() { return await testSubjects.getVisibleText('globalTimepickerRange'); } @@ -256,6 +227,7 @@ export function HeaderPageProvider({ getService, getPageObjects }) { async isSharedTimefilterEnabled() { return await find.existsByCssSelector('[shared-timefilter=true]'); } + } return new HeaderPage(); diff --git a/test/functional/page_objects/index.js b/test/functional/page_objects/index.js index 04fc7240480ff..5d561a42e2fa2 100644 --- a/test/functional/page_objects/index.js +++ b/test/functional/page_objects/index.js @@ -32,3 +32,4 @@ export { PointSeriesPageProvider } from './point_series_page'; export { VisualBuilderPageProvider } from './visual_builder_page'; export { TimelionPageProvider } from './timelion_page'; export { SharePageProvider } from './share_page'; +export { TimePickerPageProvider } from './time_picker'; diff --git a/test/functional/page_objects/time_picker.js b/test/functional/page_objects/time_picker.js new file mode 100644 index 0000000000000..4c8f7ba68a504 --- /dev/null +++ b/test/functional/page_objects/time_picker.js @@ -0,0 +1,111 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export function TimePickerPageProvider({ getService }) { + const log = getService('log'); + const retry = getService('retry'); + const testSubjects = getService('testSubjects'); + + class TimePickerPage { + + async isQuickSelectMenuOpen() { + return await testSubjects.exists('superDatePickerQuickMenu'); + } + + async openQuickSelectTimeMenu() { + log.debug('openQuickSelectTimeMenu'); + const isMenuOpen = await this.isQuickSelectMenuOpen(); + if (!isMenuOpen) { + log.debug('opening quick select menu'); + await retry.try(async () => { + await testSubjects.click('superDatePickerToggleQuickMenuButton'); + }); + } + } + + async closeQuickSelectTimeMenu() { + log.debug('closeQuickSelectTimeMenu'); + const isMenuOpen = await this.isQuickSelectMenuOpen(); + if (isMenuOpen) { + log.debug('closing quick select menu'); + await retry.try(async () => { + await testSubjects.click('superDatePickerToggleQuickMenuButton'); + }); + } + } + + async showStartEndTimes() { + const isShowDatesButton = await testSubjects.exists('superDatePickerShowDatesButton'); + if (isShowDatesButton) { + await testSubjects.click('superDatePickerShowDatesButton'); + } + } + + async getRefreshConfig(keepQuickSelectOpen = false) { + await this.openQuickSelectTimeMenu(); + const interval = await testSubjects.getAttribute('superDatePickerRefreshIntervalInput', 'value'); + const units = await testSubjects.getAttribute('superDatePickerRefreshIntervalUnitsSelect', 'value'); + const toggleButtonText = await testSubjects.getVisibleText('superDatePickerToggleRefreshButton'); + if (!keepQuickSelectOpen) { + await this.closeQuickSelectTimeMenu(); + } + + return { + interval, + units, + isPaused: toggleButtonText === 'Start' ? true : false + }; + } + + async getTimeConfig() { + await this.showStartEndTimes(); + const start = await testSubjects.getVisibleText('superDatePickerstartDatePopoverButton'); + const end = await testSubjects.getVisibleText('superDatePickerendDatePopoverButton'); + return { + start, + end + }; + } + + async pauseAutoRefresh() { + log.debug('pauseAutoRefresh'); + const refreshConfig = await this.getRefreshConfig(true); + if (!refreshConfig.isPaused) { + log.debug('pause auto refresh'); + await testSubjects.click('superDatePickerToggleRefreshButton'); + await this.closeQuickSelectTimeMenu(); + } + + await this.closeQuickSelectTimeMenu(); + } + + async resumeAutoRefresh() { + log.debug('resumeAutoRefresh'); + const refreshConfig = await this.getRefreshConfig(true); + if (refreshConfig.isPaused) { + log.debug('resume auto refresh'); + await testSubjects.click('superDatePickerToggleRefreshButton'); + } + + await this.closeQuickSelectTimeMenu(); + } + } + + return new TimePickerPage(); +} diff --git a/x-pack/test/functional/apps/gis/saved_object_management.js b/x-pack/test/functional/apps/gis/saved_object_management.js index bbfb6c7a2dd24..f65a37c8eb365 100644 --- a/x-pack/test/functional/apps/gis/saved_object_management.js +++ b/x-pack/test/functional/apps/gis/saved_object_management.js @@ -8,7 +8,7 @@ import expect from 'expect.js'; export default function ({ getPageObjects, getService }) { - const PageObjects = getPageObjects(['gis', 'header']); + const PageObjects = getPageObjects(['gis', 'header', 'timePicker']); const queryBar = getService('queryBar'); const browser = getService('browser'); const inspector = getService('inspector'); @@ -25,13 +25,16 @@ export default function ({ getPageObjects, getService }) { }); it('should update global Kibana time to value stored with map', async () => { - const kibanaTime = await PageObjects.header.getPrettyDuration(); - expect(kibanaTime).to.equal('Last 17m'); + const timeConfig = await PageObjects.timePicker.getTimeConfig(); + expect(timeConfig.start).to.equal('~ 17 minutes ago'); + expect(timeConfig.end).to.equal('now'); }); it('should update global Kibana refresh config to value stored with map', async () => { - const kibanaRefreshConfig = await PageObjects.header.getRefreshConfig(); - expect(kibanaRefreshConfig).to.equal('inactive 1 second'); + const kibanaRefreshConfig = await PageObjects.timePicker.getRefreshConfig(); + expect(kibanaRefreshConfig.interval).to.equal('0.016666666666666666'); + expect(kibanaRefreshConfig.units).to.equal('minutes'); + expect(kibanaRefreshConfig.isPaused).to.equal(true); }); it('should set map location to value stored with map', async () => { diff --git a/x-pack/test/functional/apps/monitoring/_get_lifecycle_methods.js b/x-pack/test/functional/apps/monitoring/_get_lifecycle_methods.js index 252eb6e34bacf..518162593a121 100644 --- a/x-pack/test/functional/apps/monitoring/_get_lifecycle_methods.js +++ b/x-pack/test/functional/apps/monitoring/_get_lifecycle_methods.js @@ -6,7 +6,7 @@ export const getLifecycleMethods = (getService, getPageObjects) => { const esArchiver = getService('esArchiver'); - const PageObjects = getPageObjects(['monitoring', 'header']); + const PageObjects = getPageObjects(['monitoring', 'header', 'timePicker']); const noData = getService('monitoringNoData'); let _archive; @@ -30,7 +30,7 @@ export const getLifecycleMethods = (getService, getPageObjects) => { // pause autorefresh in the time filter because we don't wait any ticks, // and we don't want ES to log a warning when data gets wiped out - await PageObjects.header.pauseAutoRefresh(); + await PageObjects.timePicker.pauseAutoRefresh(); await PageObjects.header.setAbsoluteRange(from, to); }, diff --git a/x-pack/test/functional/page_objects/gis_page.js b/x-pack/test/functional/page_objects/gis_page.js index 0ee327e984c87..75a5bf22b800b 100644 --- a/x-pack/test/functional/page_objects/gis_page.js +++ b/x-pack/test/functional/page_objects/gis_page.js @@ -5,7 +5,7 @@ */ export function GisPageProvider({ getService, getPageObjects }) { - const PageObjects = getPageObjects(['common', 'header']); + const PageObjects = getPageObjects(['common', 'header', 'timePicker']); const log = getService('log'); const testSubjects = getService('testSubjects'); @@ -204,10 +204,10 @@ export function GisPageProvider({ getService, getPageObjects }) { async triggerSingleRefresh(refreshInterval) { log.debug(`triggerSingleRefresh, refreshInterval: ${refreshInterval}`); - await PageObjects.header.resumeAutoRefresh(); + await PageObjects.timePicker.resumeAutoRefresh(); log.debug('waiting to give time for refresh timer to fire'); await PageObjects.common.sleep(refreshInterval + (refreshInterval / 2)); - await PageObjects.header.pauseAutoRefresh(); + await PageObjects.timePicker.pauseAutoRefresh(); await PageObjects.header.waitUntilLoadingHasFinished(); } } From d320ca1db59e4997ee718662dc8b562735bddaae Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 22 Jan 2019 17:16:56 -0700 Subject: [PATCH 07/34] update setAbsoluteRange for EuiSuperDatePicker --- .../apps/context/_discover_navigation.js | 4 +- .../apps/dashboard/_dashboard_time.js | 8 ++-- .../apps/dashboard/_embeddable_rendering.js | 12 +++--- test/functional/apps/dashboard/_view_edit.js | 12 +++--- test/functional/apps/discover/_discover.js | 15 ++++--- test/functional/apps/discover/_field_data.js | 4 +- test/functional/apps/discover/_inspector.js | 4 +- .../functional/apps/discover/_shared_links.js | 5 +-- test/functional/apps/discover/_sidebar.js | 5 +-- .../apps/discover/_source_filters.js | 5 +-- test/functional/apps/home/_sample_data.js | 8 ++-- .../apps/management/_handle_alias.js | 4 +- .../apps/management/_kibana_settings.js | 6 +-- .../apps/management/_scripted_fields.js | 18 +++------ .../apps/timelion/_expression_typeahead.js | 6 +-- test/functional/apps/visualize/_area_chart.js | 5 +-- test/functional/apps/visualize/_data_table.js | 19 +++++---- .../apps/visualize/_embedding_chart.js | 4 +- .../functional/apps/visualize/_gauge_chart.js | 5 +-- .../apps/visualize/_heatmap_chart.js | 5 +-- .../visualize/_histogram_request_start.js | 5 +-- .../apps/visualize/_input_control_vis.js | 7 ++-- test/functional/apps/visualize/_inspector.js | 5 +-- test/functional/apps/visualize/_line_chart.js | 5 +-- .../apps/visualize/_linked_saved_searches.js | 8 ++-- .../apps/visualize/_metric_chart.js | 5 +-- test/functional/apps/visualize/_pie_chart.js | 19 ++++----- .../apps/visualize/_point_series_options.js | 5 +-- test/functional/apps/visualize/_region_map.js | 5 +-- test/functional/apps/visualize/_tag_cloud.js | 7 ++-- test/functional/apps/visualize/_tile_map.js | 8 ++-- test/functional/apps/visualize/_tsvb_chart.js | 9 ++--- .../apps/visualize/_vertical_bar_chart.js | 7 ++-- .../functional/page_objects/dashboard_page.js | 8 ++-- test/functional/page_objects/header_page.js | 39 ------------------- test/functional/page_objects/time_picker.js | 36 ++++++++++++++++- .../page_objects/visual_builder_page.js | 5 +-- .../functional/page_objects/visualize_page.js | 12 ------ .../apps/monitoring/_get_lifecycle_methods.js | 4 +- .../functional/apps/security/rbac_phase1.js | 6 +-- .../functional/page_objects/reporting_page.js | 6 +-- 41 files changed, 154 insertions(+), 211 deletions(-) diff --git a/test/functional/apps/context/_discover_navigation.js b/test/functional/apps/context/_discover_navigation.js index 6be4400add141..3a6c357c1ad07 100644 --- a/test/functional/apps/context/_discover_navigation.js +++ b/test/functional/apps/context/_discover_navigation.js @@ -28,12 +28,12 @@ export default function ({ getService, getPageObjects }) { const retry = getService('retry'); const docTable = getService('docTable'); const filterBar = getService('filterBar'); - const PageObjects = getPageObjects(['common', 'header', 'discover']); + const PageObjects = getPageObjects(['common', 'discover', 'timePicker']); describe('context link in discover', function contextSize() { before(async function () { await PageObjects.common.navigateToApp('discover'); - await PageObjects.header.setAbsoluteRange(TEST_DISCOVER_START_TIME, TEST_DISCOVER_END_TIME); + await PageObjects.timePicker.setAbsoluteRange(TEST_DISCOVER_START_TIME, TEST_DISCOVER_END_TIME); await Promise.all(TEST_COLUMN_NAMES.map((columnName) => ( PageObjects.discover.clickFieldListItemAdd(columnName) ))); diff --git a/test/functional/apps/dashboard/_dashboard_time.js b/test/functional/apps/dashboard/_dashboard_time.js index e804d8e3f732e..897fbb62b2b01 100644 --- a/test/functional/apps/dashboard/_dashboard_time.js +++ b/test/functional/apps/dashboard/_dashboard_time.js @@ -25,7 +25,7 @@ const fromTime = '2015-09-19 06:31:44.000'; const toTime = '2015-09-23 18:31:44.000'; export default function ({ getPageObjects, getService }) { - const PageObjects = getPageObjects(['dashboard', 'header']); + const PageObjects = getPageObjects(['dashboard', 'header', 'timePicker']); const browser = getService('browser'); describe('dashboard time', () => { @@ -46,7 +46,7 @@ export default function ({ getPageObjects, getService }) { }); it('Does not set the time picker on open', async () => { - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.dashboard.loadSavedDashboard(dashboardName); @@ -65,7 +65,7 @@ export default function ({ getPageObjects, getService }) { }); it('sets quick time on open', async function () { - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.dashboard.loadSavedDashboard(dashboardName); @@ -75,7 +75,7 @@ export default function ({ getPageObjects, getService }) { it('is saved with absolute time', async function () { await PageObjects.dashboard.switchToEditMode(); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.dashboard.saveDashboard(dashboardName, { storeTimeWithDashboard: true }); }); diff --git a/test/functional/apps/dashboard/_embeddable_rendering.js b/test/functional/apps/dashboard/_embeddable_rendering.js index 0073c3a955a2b..5f7cf2fec9f66 100644 --- a/test/functional/apps/dashboard/_embeddable_rendering.js +++ b/test/functional/apps/dashboard/_embeddable_rendering.js @@ -33,7 +33,7 @@ export default function ({ getService, getPageObjects }) { const pieChart = getService('pieChart'); const dashboardExpect = getService('dashboardExpect'); const dashboardAddPanel = getService('dashboardAddPanel'); - const PageObjects = getPageObjects(['common', 'dashboard', 'header', 'visualize', 'discover']); + const PageObjects = getPageObjects(['common', 'dashboard', 'header', 'visualize', 'discover', 'timePicker']); const expectAllDataRenders = async () => { await pieChart.expectPieSliceCount(16); @@ -96,7 +96,7 @@ export default function ({ getService, getPageObjects }) { const fromTime = '2018-01-01 00:00:00.000'; const toTime = '2018-04-13 00:00:00.000'; - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); }); after(async () => { @@ -139,7 +139,7 @@ export default function ({ getService, getPageObjects }) { // Change the time to make sure that it's updated when re-opened from the listing page. const fromTime = '2018-05-10 00:00:00.000'; const toTime = '2018-05-11 00:00:00.000'; - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.dashboard.loadSavedDashboard('embeddable rendering test'); await PageObjects.dashboard.waitForRenderComplete(); await expectAllDataRenders(); @@ -156,8 +156,7 @@ export default function ({ getService, getPageObjects }) { it('panels are updated when time changes outside of data', async () => { const fromTime = '2018-05-11 00:00:00.000'; const toTime = '2018-05-12 00:00:00.000'; - await PageObjects.header.setAbsoluteRange(fromTime, toTime); - await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.dashboard.waitForRenderComplete(); await expectNoDataRenders(); }); @@ -165,8 +164,7 @@ export default function ({ getService, getPageObjects }) { it('panels are updated when time changes inside of data', async () => { const fromTime = '2018-01-01 00:00:00.000'; const toTime = '2018-04-13 00:00:00.000'; - await PageObjects.header.setAbsoluteRange(fromTime, toTime); - await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.dashboard.waitForRenderComplete(); await expectAllDataRenders(); }); diff --git a/test/functional/apps/dashboard/_view_edit.js b/test/functional/apps/dashboard/_view_edit.js index c4cdb97a593af..049fea0e0724f 100644 --- a/test/functional/apps/dashboard/_view_edit.js +++ b/test/functional/apps/dashboard/_view_edit.js @@ -22,7 +22,7 @@ import expect from 'expect.js'; export default function ({ getService, getPageObjects }) { const queryBar = getService('queryBar'); const dashboardAddPanel = getService('dashboardAddPanel'); - const PageObjects = getPageObjects(['dashboard', 'header', 'common', 'visualize']); + const PageObjects = getPageObjects(['dashboard', 'header', 'common', 'visualize', 'timePicker']); const dashboardName = 'dashboard with filter'; const filterBar = getService('filterBar'); @@ -68,7 +68,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.dashboard.saveDashboard(dashboardName, { storeTimeWithDashboard: true }); await PageObjects.dashboard.switchToEditMode(); - await PageObjects.header.setAbsoluteRange('2013-09-19 06:31:44.000', '2013-09-19 06:31:44.000'); + await PageObjects.timePicker.setAbsoluteRange('2013-09-19 06:31:44.000', '2013-09-19 06:31:44.000'); await PageObjects.dashboard.clickCancelOutOfEditMode(); // confirm lose changes @@ -155,10 +155,10 @@ export default function ({ getService, getPageObjects }) { await PageObjects.dashboard.gotoDashboardEditMode(dashboardName); const newFromTime = '2015-09-19 06:31:44.000'; const newToTime = '2015-09-19 06:31:44.000'; - await PageObjects.header.setAbsoluteRange('2013-09-19 06:31:44.000', '2013-09-19 06:31:44.000'); + await PageObjects.timePicker.setAbsoluteRange('2013-09-19 06:31:44.000', '2013-09-19 06:31:44.000'); await PageObjects.dashboard.saveDashboard(dashboardName, true); await PageObjects.dashboard.switchToEditMode(); - await PageObjects.header.setAbsoluteRange(newToTime, newToTime); + await PageObjects.timePicker.setAbsoluteRange(newToTime, newToTime); await PageObjects.dashboard.clickCancelOutOfEditMode(); await PageObjects.common.clickCancelOnModal(); @@ -181,7 +181,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.dashboard.setTimepickerInDataRange(); await PageObjects.dashboard.saveDashboard(dashboardName, true); await PageObjects.dashboard.switchToEditMode(); - await PageObjects.header.setAbsoluteRange('2013-09-19 06:31:44.000', '2013-09-19 06:31:44.000'); + await PageObjects.timePicker.setAbsoluteRange('2013-09-19 06:31:44.000', '2013-09-19 06:31:44.000'); const newFromTime = await PageObjects.header.getFromTime(); const newToTime = await PageObjects.header.getToTime(); @@ -206,7 +206,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.dashboard.gotoDashboardEditMode(dashboardName); await PageObjects.dashboard.saveDashboard(dashboardName, { storeTimeWithDashboard: false }); await PageObjects.dashboard.switchToEditMode(); - await PageObjects.header.setAbsoluteRange('2014-10-19 06:31:44.000', '2014-12-19 06:31:44.000'); + await PageObjects.timePicker.setAbsoluteRange('2014-10-19 06:31:44.000', '2014-12-19 06:31:44.000'); await PageObjects.dashboard.clickCancelOutOfEditMode(); await PageObjects.common.expectConfirmModalOpenState(false); diff --git a/test/functional/apps/discover/_discover.js b/test/functional/apps/discover/_discover.js index 64e2a2fdc952e..52cfb3cfdf484 100644 --- a/test/functional/apps/discover/_discover.js +++ b/test/functional/apps/discover/_discover.js @@ -26,7 +26,7 @@ export default function ({ getService, getPageObjects }) { const browser = getService('browser'); const kibanaServer = getService('kibanaServer'); const filterBar = getService('filterBar'); - const PageObjects = getPageObjects(['common', 'discover', 'header', 'visualize']); + const PageObjects = getPageObjects(['common', 'discover', 'header', 'visualize', 'timePicker']); const defaultSettings = { 'dateFormat:tz': 'UTC', defaultIndex: 'logstash-*', @@ -49,8 +49,7 @@ export default function ({ getService, getPageObjects }) { await esArchiver.loadIfNeeded('logstash_functional'); log.debug('discover'); await PageObjects.common.navigateToApp('discover'); - log.debug('setAbsoluteRange'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); }); describe('query', function () { @@ -140,7 +139,7 @@ export default function ({ getService, getPageObjects }) { }); it('should modify the time range when a bar is clicked', async function () { - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.waitForVisualization(); await PageObjects.discover.clickHistogramBar(0); await PageObjects.visualize.waitForVisualization(); @@ -149,7 +148,7 @@ export default function ({ getService, getPageObjects }) { }); it('should modify the time range when the histogram is brushed', async function () { - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.waitForVisualization(); await PageObjects.discover.brushHistogram(0, 1); await PageObjects.visualize.waitForVisualization(); @@ -158,7 +157,7 @@ export default function ({ getService, getPageObjects }) { }); it('should show correct initial chart interval of Auto', async function () { - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); const actualInterval = await PageObjects.discover.getChartInterval(); const expectedInterval = 'Auto'; @@ -380,7 +379,7 @@ export default function ({ getService, getPageObjects }) { before(() => { log.debug('setAbsoluteRangeForAnotherQuery'); - return PageObjects.header.setAbsoluteRange(fromTime, toTime); + return PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); }); it('should show "no results"', async () => { @@ -442,7 +441,7 @@ export default function ({ getService, getPageObjects }) { it('should show bars in the correct time zone after switching', async function () { await kibanaServer.uiSettings.replace({ 'dateFormat:tz': 'America/Phoenix' }); await browser.refresh(); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); const ticks = await PageObjects.discover.getBarChartXTicks(); expect(ticks).to.eql([ '2015-09-19 17:00', diff --git a/test/functional/apps/discover/_field_data.js b/test/functional/apps/discover/_field_data.js index 578f578c73d28..9023438e47dd6 100644 --- a/test/functional/apps/discover/_field_data.js +++ b/test/functional/apps/discover/_field_data.js @@ -24,7 +24,7 @@ export default function ({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); const queryBar = getService('queryBar'); - const PageObjects = getPageObjects(['common', 'header', 'discover', 'visualize']); + const PageObjects = getPageObjects(['common', 'header', 'discover', 'visualize', 'timePicker']); describe('discover tab', function describeIndexTests() { before(async function () { @@ -40,7 +40,7 @@ export default function ({ getService, getPageObjects }) { }); await PageObjects.common.navigateToApp('discover'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); }); describe('field data', function () { diff --git a/test/functional/apps/discover/_inspector.js b/test/functional/apps/discover/_inspector.js index 960fde388f967..847c1af2aa1fe 100644 --- a/test/functional/apps/discover/_inspector.js +++ b/test/functional/apps/discover/_inspector.js @@ -20,7 +20,7 @@ import expect from 'expect.js'; export default function ({ getService, getPageObjects }) { - const PageObjects = getPageObjects(['common', 'header', 'visualize']); + const PageObjects = getPageObjects(['common', 'visualize', 'timePicker']); const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); const inspector = getService('inspector'); @@ -59,7 +59,7 @@ export default function ({ getService, getPageObjects }) { }); it('should display request stats with results', async () => { - await PageObjects.header.setAbsoluteRange('2015-09-19 06:31:44.000', '2015-09-23 18:31:44.000'); + await PageObjects.timePicker.setAbsoluteRange('2015-09-19 06:31:44.000', '2015-09-23 18:31:44.000'); await inspector.open(); const requestStats = await inspector.getTableData(); diff --git a/test/functional/apps/discover/_shared_links.js b/test/functional/apps/discover/_shared_links.js index cac5954c4db2f..85d8941d19eb9 100644 --- a/test/functional/apps/discover/_shared_links.js +++ b/test/functional/apps/discover/_shared_links.js @@ -24,7 +24,7 @@ export default function ({ getService, getPageObjects }) { const log = getService('log'); const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); - const PageObjects = getPageObjects(['common', 'discover', 'header', 'share']); + const PageObjects = getPageObjects(['common', 'discover', 'share', 'timePicker']); describe('shared links', function describeIndexTests() { let baseUrl; @@ -54,8 +54,7 @@ export default function ({ getService, getPageObjects }) { log.debug('discover'); await PageObjects.common.navigateToApp('discover'); - log.debug('setAbsoluteRange'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); //After hiding the time picker, we need to wait for //the refresh button to hide before clicking the share button diff --git a/test/functional/apps/discover/_sidebar.js b/test/functional/apps/discover/_sidebar.js index 82b9d99bc80b1..6b26b17ac660e 100644 --- a/test/functional/apps/discover/_sidebar.js +++ b/test/functional/apps/discover/_sidebar.js @@ -23,7 +23,7 @@ export default function ({ getService, getPageObjects }) { const log = getService('log'); const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); - const PageObjects = getPageObjects(['common', 'discover', 'header']); + const PageObjects = getPageObjects(['common', 'discover', 'timePicker']); describe('discover sidebar', function describeIndexTests() { before(async function () { @@ -45,8 +45,7 @@ export default function ({ getService, getPageObjects }) { log.debug('discover'); await PageObjects.common.navigateToApp('discover'); - log.debug('setAbsoluteRange'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); }); describe('field filtering', function () { diff --git a/test/functional/apps/discover/_source_filters.js b/test/functional/apps/discover/_source_filters.js index ca274fc7551c3..070041a453142 100644 --- a/test/functional/apps/discover/_source_filters.js +++ b/test/functional/apps/discover/_source_filters.js @@ -23,7 +23,7 @@ export default function ({ getService, getPageObjects }) { const log = getService('log'); const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); - const PageObjects = getPageObjects(['common', 'header', 'discover']); + const PageObjects = getPageObjects(['common', 'timePicker', 'discover']); describe('source filters', function describeIndexTests() { before(async function () { @@ -45,8 +45,7 @@ export default function ({ getService, getPageObjects }) { log.debug('discover'); await PageObjects.common.navigateToApp('discover'); - log.debug('setAbsoluteRange'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); //After hiding the time picker, we need to wait for //the refresh button to hide before clicking the share button diff --git a/test/functional/apps/home/_sample_data.js b/test/functional/apps/home/_sample_data.js index cc1b8f11adc4d..700eea39f4613 100644 --- a/test/functional/apps/home/_sample_data.js +++ b/test/functional/apps/home/_sample_data.js @@ -24,7 +24,7 @@ export default function ({ getService, getPageObjects }) { const find = getService('find'); const pieChart = getService('pieChart'); const dashboardExpect = getService('dashboardExpect'); - const PageObjects = getPageObjects(['common', 'header', 'home', 'dashboard']); + const PageObjects = getPageObjects(['common', 'header', 'home', 'dashboard', 'timePicker']); describe('sample data', function describeIndexTests() { @@ -85,7 +85,7 @@ export default function ({ getService, getPageObjects }) { const todayYearMonthDay = today.toISOString().substring(0, 10); const fromTime = `${todayYearMonthDay} 00:00:00.000`; const toTime = `${todayYearMonthDay} 23:59:59.999`; - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); const panelCount = await PageObjects.dashboard.getPanelCount(); expect(panelCount).to.be(19); }); @@ -123,7 +123,7 @@ export default function ({ getService, getPageObjects }) { const todayYearMonthDay = today.toISOString().substring(0, 10); const fromTime = `${todayYearMonthDay} 00:00:00.000`; const toTime = `${todayYearMonthDay} 23:59:59.999`; - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); const panelCount = await PageObjects.dashboard.getPanelCount(); expect(panelCount).to.be(11); }); @@ -135,7 +135,7 @@ export default function ({ getService, getPageObjects }) { const todayYearMonthDay = today.toISOString().substring(0, 10); const fromTime = `${todayYearMonthDay} 00:00:00.000`; const toTime = `${todayYearMonthDay} 23:59:59.999`; - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); const panelCount = await PageObjects.dashboard.getPanelCount(); expect(panelCount).to.be(12); }); diff --git a/test/functional/apps/management/_handle_alias.js b/test/functional/apps/management/_handle_alias.js index de89aa626112b..7a866a0274bcb 100644 --- a/test/functional/apps/management/_handle_alias.js +++ b/test/functional/apps/management/_handle_alias.js @@ -23,7 +23,7 @@ export default function ({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); const es = getService('es'); const retry = getService('retry'); - const PageObjects = getPageObjects(['common', 'home', 'settings', 'discover', 'header']); + const PageObjects = getPageObjects(['common', 'home', 'settings', 'discover', 'timePicker']); describe('Index patterns on aliases', function () { before(async function () { @@ -77,7 +77,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.common.navigateToApp('discover'); await PageObjects.discover.selectIndexPattern('alias2'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await retry.try(async function () { expect(await PageObjects.discover.getHitCount()).to.be(expectedHitCount); diff --git a/test/functional/apps/management/_kibana_settings.js b/test/functional/apps/management/_kibana_settings.js index 622ea78fa2443..524005a19a4da 100644 --- a/test/functional/apps/management/_kibana_settings.js +++ b/test/functional/apps/management/_kibana_settings.js @@ -22,7 +22,7 @@ import expect from 'expect.js'; export default function ({ getService, getPageObjects }) { const kibanaServer = getService('kibanaServer'); const browser = getService('browser'); - const PageObjects = getPageObjects(['settings', 'common', 'dashboard', 'header']); + const PageObjects = getPageObjects(['settings', 'common', 'dashboard', 'timePicker']); describe('kibana settings', function describeIndexTests() { before(async function () { @@ -57,7 +57,7 @@ export default function ({ getService, getPageObjects }) { it('when false, dashboard state is unhashed', async function () { await PageObjects.common.navigateToApp('dashboard'); await PageObjects.dashboard.clickNewDashboard(); - await PageObjects.header.setAbsoluteRange('2015-09-19 06:31:44.000', '2015-09-23 18:31:44.000'); + await PageObjects.timePicker.setAbsoluteRange('2015-09-19 06:31:44.000', '2015-09-23 18:31:44.000'); const currentUrl = await browser.getCurrentUrl(); const urlPieces = currentUrl.match(/(.*)?_g=(.*)&_a=(.*)/); const globalState = urlPieces[2]; @@ -80,7 +80,7 @@ export default function ({ getService, getPageObjects }) { it('when true, dashboard state is hashed', async function () { await PageObjects.common.navigateToApp('dashboard'); await PageObjects.dashboard.clickNewDashboard(); - await PageObjects.header.setAbsoluteRange('2015-09-19 06:31:44.000', '2015-09-23 18:31:44.000'); + await PageObjects.timePicker.setAbsoluteRange('2015-09-19 06:31:44.000', '2015-09-23 18:31:44.000'); const currentUrl = await browser.getCurrentUrl(); const urlPieces = currentUrl.match(/(.*)?_g=(.*)&_a=(.*)/); const globalState = urlPieces[2]; diff --git a/test/functional/apps/management/_scripted_fields.js b/test/functional/apps/management/_scripted_fields.js index f2da2df7b56b7..de114baa9ef62 100644 --- a/test/functional/apps/management/_scripted_fields.js +++ b/test/functional/apps/management/_scripted_fields.js @@ -38,7 +38,7 @@ export default function ({ getService, getPageObjects }) { const retry = getService('retry'); const inspector = getService('inspector'); const testSubjects = getService('testSubjects'); - const PageObjects = getPageObjects(['common', 'header', 'settings', 'visualize', 'discover']); + const PageObjects = getPageObjects(['common', 'header', 'settings', 'visualize', 'discover', 'timePicker']); describe('scripted fields', () => { @@ -96,9 +96,7 @@ export default function ({ getService, getPageObjects }) { const fromTime = '2015-09-17 06:31:44.000'; const toTime = '2015-09-18 18:31:44.000'; await PageObjects.common.navigateToApp('discover'); - await log.debug('setAbsoluteRange (' + fromTime + ') to (' + toTime + ')'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); - await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.waitForVisualization(); await PageObjects.discover.clickFieldListItem(scriptedPainlessFieldName); await retry.try(async function () { @@ -159,9 +157,7 @@ export default function ({ getService, getPageObjects }) { const fromTime = '2015-09-17 06:31:44.000'; const toTime = '2015-09-18 18:31:44.000'; await PageObjects.common.navigateToApp('discover'); - await log.debug('setAbsoluteRange (' + fromTime + ') to (' + toTime + ')'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); - await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.waitForVisualization(); await PageObjects.discover.clickFieldListItem(scriptedPainlessFieldName2); await retry.try(async function () { @@ -221,9 +217,7 @@ export default function ({ getService, getPageObjects }) { const fromTime = '2015-09-17 06:31:44.000'; const toTime = '2015-09-18 18:31:44.000'; await PageObjects.common.navigateToApp('discover'); - await log.debug('setAbsoluteRange (' + fromTime + ') to (' + toTime + ')'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); - await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.waitForVisualization(); await PageObjects.discover.clickFieldListItem(scriptedPainlessFieldName2); await retry.try(async function () { @@ -284,9 +278,7 @@ export default function ({ getService, getPageObjects }) { const fromTime = '2015-09-17 19:22:00.000'; const toTime = '2015-09-18 07:00:00.000'; await PageObjects.common.navigateToApp('discover'); - await log.debug('setAbsoluteRange (' + fromTime + ') to (' + toTime + ')'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); - await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.waitForVisualization(); await PageObjects.discover.clickFieldListItem(scriptedPainlessFieldName2); await retry.try(async function () { diff --git a/test/functional/apps/timelion/_expression_typeahead.js b/test/functional/apps/timelion/_expression_typeahead.js index 46d72b0b7e446..aca178a906a86 100644 --- a/test/functional/apps/timelion/_expression_typeahead.js +++ b/test/functional/apps/timelion/_expression_typeahead.js @@ -20,7 +20,7 @@ import expect from 'expect.js'; export default function ({ getPageObjects }) { - const PageObjects = getPageObjects(['common', 'timelion', 'header', 'settings']); + const PageObjects = getPageObjects(['common', 'timelion', 'settings', 'timePicker']); describe('expression typeahead', () => { before(async () => { @@ -28,9 +28,7 @@ export default function ({ getPageObjects }) { const toTime = '2015-09-23 18:31:44.000'; await PageObjects.timelion.initTests(); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); - - await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); }); it('should display function suggestions filtered by function name', async () => { diff --git a/test/functional/apps/visualize/_area_chart.js b/test/functional/apps/visualize/_area_chart.js index 5f2e57dccfaeb..1fffbc2759355 100644 --- a/test/functional/apps/visualize/_area_chart.js +++ b/test/functional/apps/visualize/_area_chart.js @@ -24,7 +24,7 @@ export default function ({ getService, getPageObjects }) { const inspector = getService('inspector'); const browser = getService('browser'); const retry = getService('retry'); - const PageObjects = getPageObjects(['common', 'visualize', 'header', 'settings']); + const PageObjects = getPageObjects(['common', 'visualize', 'header', 'settings', 'timePicker']); describe('area charts', function indexPatternCreation() { const vizName1 = 'Visualization AreaChart Name Test'; @@ -39,8 +39,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.clickAreaChart(); log.debug('clickNewSearch'); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('Click X-Axis'); await PageObjects.visualize.clickBucket('X-Axis'); log.debug('Click Date Histogram'); diff --git a/test/functional/apps/visualize/_data_table.js b/test/functional/apps/visualize/_data_table.js index a742b5012348d..762fff49670a4 100644 --- a/test/functional/apps/visualize/_data_table.js +++ b/test/functional/apps/visualize/_data_table.js @@ -25,7 +25,7 @@ export default function ({ getService, getPageObjects }) { const retry = getService('retry'); const filterBar = getService('filterBar'); const renderable = getService('renderable'); - const PageObjects = getPageObjects(['common', 'visualize', 'header']); + const PageObjects = getPageObjects(['common', 'visualize', 'header', 'timePicker']); const fromTime = '2015-09-19 06:31:44.000'; const toTime = '2015-09-23 18:31:44.000'; @@ -40,8 +40,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.clickDataTable(); log.debug('clickNewSearch'); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('Bucket = Split Rows'); await PageObjects.visualize.clickBucket('Split Rows'); log.debug('Aggregation = Histogram'); @@ -103,7 +102,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.clickAddMetric(); await PageObjects.visualize.clickBucket('Metric', 'metric'); await PageObjects.visualize.selectAggregation('Average Bucket', 'metrics'); @@ -119,7 +118,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.clickBucket('Split Rows'); await PageObjects.visualize.selectAggregation('Date Histogram'); await PageObjects.visualize.selectField('@timestamp'); @@ -139,7 +138,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.clickBucket('Split Rows'); await PageObjects.visualize.selectAggregation('Date Histogram'); await PageObjects.visualize.selectField('@timestamp'); @@ -178,7 +177,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.clickMetricEditor(); await PageObjects.visualize.selectAggregation('Top Hit', 'metrics'); await PageObjects.visualize.selectField('agent.raw', 'metrics'); @@ -193,7 +192,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.clickBucket('Split Rows'); await PageObjects.visualize.selectAggregation('Terms'); await PageObjects.visualize.selectField('extension.raw'); @@ -231,7 +230,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.clickBucket('Split Rows'); await PageObjects.visualize.selectAggregation('Terms'); await PageObjects.visualize.selectField('extension.raw'); @@ -309,7 +308,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.clickBucket('Split Table'); await PageObjects.visualize.selectAggregation('Terms'); await PageObjects.visualize.selectField('extension.raw'); diff --git a/test/functional/apps/visualize/_embedding_chart.js b/test/functional/apps/visualize/_embedding_chart.js index 5cffa53dc7e77..b6caa77d32406 100644 --- a/test/functional/apps/visualize/_embedding_chart.js +++ b/test/functional/apps/visualize/_embedding_chart.js @@ -24,7 +24,7 @@ export default function ({ getService, getPageObjects }) { const log = getService('log'); const renderable = getService('renderable'); const embedding = getService('embedding'); - const PageObjects = getPageObjects(['common', 'visualize', 'header']); + const PageObjects = getPageObjects(['common', 'visualize', 'header', 'timePicker']); const fromTime = '2015-09-19 06:31:44.000'; const toTime = '2015-09-23 18:31:44.000'; @@ -36,7 +36,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.clickBucket('Split Rows'); await PageObjects.visualize.selectAggregation('Date Histogram'); await PageObjects.visualize.selectField('@timestamp'); diff --git a/test/functional/apps/visualize/_gauge_chart.js b/test/functional/apps/visualize/_gauge_chart.js index 070a9545b7469..078aedce591c8 100644 --- a/test/functional/apps/visualize/_gauge_chart.js +++ b/test/functional/apps/visualize/_gauge_chart.js @@ -23,7 +23,7 @@ export default function ({ getService, getPageObjects }) { const log = getService('log'); const retry = getService('retry'); const inspector = getService('inspector'); - const PageObjects = getPageObjects(['common', 'visualize', 'header']); + const PageObjects = getPageObjects(['common', 'visualize', 'timePicker']); describe('gauge chart', function indexPatternCreation() { const fromTime = '2015-09-19 06:31:44.000'; @@ -35,8 +35,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickGauge'); await PageObjects.visualize.clickGauge(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); }); diff --git a/test/functional/apps/visualize/_heatmap_chart.js b/test/functional/apps/visualize/_heatmap_chart.js index 708f2fc340ed2..795cfbe0e0763 100644 --- a/test/functional/apps/visualize/_heatmap_chart.js +++ b/test/functional/apps/visualize/_heatmap_chart.js @@ -22,7 +22,7 @@ import expect from 'expect.js'; export default function ({ getService, getPageObjects }) { const log = getService('log'); const inspector = getService('inspector'); - const PageObjects = getPageObjects(['common', 'visualize', 'header']); + const PageObjects = getPageObjects(['common', 'visualize', 'timePicker']); describe('heatmap chart', function indexPatternCreation() { const vizName1 = 'Visualization HeatmapChart'; @@ -35,8 +35,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickHeatmapChart'); await PageObjects.visualize.clickHeatmapChart(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('Bucket = X-Axis'); await PageObjects.visualize.clickBucket('X-Axis'); log.debug('Aggregation = Date Histogram'); diff --git a/test/functional/apps/visualize/_histogram_request_start.js b/test/functional/apps/visualize/_histogram_request_start.js index e7fd05dc018f5..95eda5003e7f5 100644 --- a/test/functional/apps/visualize/_histogram_request_start.js +++ b/test/functional/apps/visualize/_histogram_request_start.js @@ -22,7 +22,7 @@ import expect from 'expect.js'; export default function ({ getService, getPageObjects }) { const log = getService('log'); const retry = getService('retry'); - const PageObjects = getPageObjects(['common', 'visualize', 'header']); + const PageObjects = getPageObjects(['common', 'visualize', 'timePicker']); describe('histogram agg onSearchRequestStart', function () { before(async function () { @@ -34,8 +34,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickDataTable'); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('Bucket = Split Rows'); await PageObjects.visualize.clickBucket('Split Rows'); log.debug('Aggregation = Histogram'); diff --git a/test/functional/apps/visualize/_input_control_vis.js b/test/functional/apps/visualize/_input_control_vis.js index c95991094980b..3c4fe7270fc16 100644 --- a/test/functional/apps/visualize/_input_control_vis.js +++ b/test/functional/apps/visualize/_input_control_vis.js @@ -21,7 +21,7 @@ import expect from 'expect.js'; export default function ({ getService, getPageObjects }) { const filterBar = getService('filterBar'); - const PageObjects = getPageObjects(['common', 'visualize', 'header']); + const PageObjects = getPageObjects(['common', 'visualize', 'header', 'timePicker']); const testSubjects = getService('testSubjects'); const inspector = getService('inspector'); const find = getService('find'); @@ -35,7 +35,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickInputControlVis(); // set time range to time with no documents - input controls do not use time filter be default - await PageObjects.header.setAbsoluteRange('2017-01-01', '2017-01-02'); + await PageObjects.timePicker.setAbsoluteRange('2017-01-01', '2017-01-02'); await PageObjects.visualize.clickVisEditorTab('controls'); await PageObjects.visualize.addInputControl(); await comboBox.set('indexPatternSelect-0', 'logstash- '); @@ -168,8 +168,7 @@ export default function ({ getService, getPageObjects }) { }); it('should re-create control when global time filter is updated', async () => { - await PageObjects.header.setAbsoluteRange('2015-01-01', '2016-01-01'); - await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.timePicker.setAbsoluteRange('2015-01-01', '2016-01-01'); // Expect control to have values for selected time filter const menu = await comboBox.getOptionsList('listControlSelect0'); diff --git a/test/functional/apps/visualize/_inspector.js b/test/functional/apps/visualize/_inspector.js index ea62939a85111..f90a48510c5e5 100644 --- a/test/functional/apps/visualize/_inspector.js +++ b/test/functional/apps/visualize/_inspector.js @@ -22,7 +22,7 @@ export default function ({ getService, getPageObjects }) { const log = getService('log'); const inspector = getService('inspector'); const filterBar = getService('filterBar'); - const PageObjects = getPageObjects(['common', 'visualize', 'header']); + const PageObjects = getPageObjects(['common', 'visualize', 'timePicker']); describe('inspector', function describeIndexTests() { before(async function () { @@ -33,8 +33,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); }); describe('inspector table', function indexPatternCreation() { diff --git a/test/functional/apps/visualize/_line_chart.js b/test/functional/apps/visualize/_line_chart.js index 9f756ffdf3813..350168006227f 100644 --- a/test/functional/apps/visualize/_line_chart.js +++ b/test/functional/apps/visualize/_line_chart.js @@ -23,7 +23,7 @@ export default function ({ getService, getPageObjects }) { const log = getService('log'); const inspector = getService('inspector'); const retry = getService('retry'); - const PageObjects = getPageObjects(['common', 'visualize', 'header']); + const PageObjects = getPageObjects(['common', 'visualize', 'timePicker']); describe('line charts', function () { const vizName1 = 'Visualization LineChart'; @@ -37,8 +37,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickLineChart'); await PageObjects.visualize.clickLineChart(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('Bucket = Split Chart'); await PageObjects.visualize.clickBucket('Split Chart'); log.debug('Aggregation = Terms'); diff --git a/test/functional/apps/visualize/_linked_saved_searches.js b/test/functional/apps/visualize/_linked_saved_searches.js index 52ce657ee720a..9a80126f5447c 100644 --- a/test/functional/apps/visualize/_linked_saved_searches.js +++ b/test/functional/apps/visualize/_linked_saved_searches.js @@ -22,7 +22,7 @@ import expect from 'expect.js'; export default function ({ getService, getPageObjects }) { const filterBar = getService('filterBar'); const retry = getService('retry'); - const PageObjects = getPageObjects(['common', 'discover', 'visualize', 'header']); + const PageObjects = getPageObjects(['common', 'discover', 'visualize', 'header', 'timePicker']); describe('visualize app', function describeIndexTests() { const fromTime = '2015-09-19 06:31:44.000'; @@ -45,8 +45,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickSavedSearch(savedSearchName); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); - await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await retry.waitFor('wait for count to equal 9,109', async () => { const data = await PageObjects.visualize.getTableVisData(); return data.trim() === '9,109'; @@ -54,8 +53,7 @@ export default function ({ getService, getPageObjects }) { }); it('should respect the time filter when linked to a saved search', async () => { - await PageObjects.header.setAbsoluteRange('2015-09-19 06:31:44.000', '2015-09-21 10:00:00.000'); - await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.timePicker.setAbsoluteRange('2015-09-19 06:31:44.000', '2015-09-21 10:00:00.000'); await retry.waitFor('wait for count to equal 3,950', async () => { const data = await PageObjects.visualize.getTableVisData(); return data.trim() === '3,950'; diff --git a/test/functional/apps/visualize/_metric_chart.js b/test/functional/apps/visualize/_metric_chart.js index c2b7fb0c9b763..fbece9f724814 100644 --- a/test/functional/apps/visualize/_metric_chart.js +++ b/test/functional/apps/visualize/_metric_chart.js @@ -23,7 +23,7 @@ export default function ({ getService, getPageObjects }) { const log = getService('log'); const retry = getService('retry'); const inspector = getService('inspector'); - const PageObjects = getPageObjects(['common', 'visualize', 'header']); + const PageObjects = getPageObjects(['common', 'visualize', 'timePicker']); describe('metric chart', function () { const fromTime = '2015-09-19 06:31:44.000'; @@ -35,8 +35,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickMetric'); await PageObjects.visualize.clickMetric(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); }); it('should have inspector enabled', async function () { diff --git a/test/functional/apps/visualize/_pie_chart.js b/test/functional/apps/visualize/_pie_chart.js index dcab846c277a1..0c9476569f7df 100644 --- a/test/functional/apps/visualize/_pie_chart.js +++ b/test/functional/apps/visualize/_pie_chart.js @@ -24,7 +24,7 @@ export default function ({ getService, getPageObjects }) { const filterBar = getService('filterBar'); const pieChart = getService('pieChart'); const inspector = getService('inspector'); - const PageObjects = getPageObjects(['common', 'visualize', 'header', 'settings']); + const PageObjects = getPageObjects(['common', 'visualize', 'header', 'settings', 'timePicker']); const fromTime = '2015-09-19 06:31:44.000'; const toTime = '2015-09-23 18:31:44.000'; @@ -36,8 +36,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('select bucket Split Slices'); await PageObjects.visualize.clickBucket('Split Slices'); log.debug('Click aggregation Histogram'); @@ -86,8 +85,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); - log.debug(`Set absolute time range from "${fromTime}" to "${toTime}"`); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('select bucket Split Slices'); await PageObjects.visualize.clickBucket('Split Slices'); log.debug('Click aggregation Terms'); @@ -191,8 +189,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('select bucket Split Slices'); await PageObjects.visualize.clickBucket('Split Slices'); log.debug('Click aggregation Filters'); @@ -207,7 +204,7 @@ export default function ({ getService, getPageObjects }) { const emptyFromTime = '2016-09-19 06:31:44.000'; const emptyToTime = '2016-09-23 18:31:44.000'; log.debug('Switch to a different time range from \"' + emptyFromTime + '\" to \"' + emptyToTime + '\"'); - await PageObjects.header.setAbsoluteRange(emptyFromTime, emptyToTime); + await PageObjects.timePicker.setAbsoluteRange(emptyFromTime, emptyToTime); await PageObjects.visualize.waitForVisualization(); await PageObjects.visualize.expectError(); }); @@ -218,8 +215,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('select bucket Split Slices'); await PageObjects.visualize.clickBucket('Split Slices'); log.debug('Click aggregation Filters'); @@ -248,8 +244,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('select bucket Split Slices'); await PageObjects.visualize.clickBucket('Split Chart'); await PageObjects.visualize.selectAggregation('Terms'); diff --git a/test/functional/apps/visualize/_point_series_options.js b/test/functional/apps/visualize/_point_series_options.js index 6262963d886ed..63d19d8999573 100644 --- a/test/functional/apps/visualize/_point_series_options.js +++ b/test/functional/apps/visualize/_point_series_options.js @@ -22,7 +22,7 @@ import expect from 'expect.js'; export default function ({ getService, getPageObjects }) { const log = getService('log'); const retry = getService('retry'); - const PageObjects = getPageObjects(['common', 'visualize', 'header', 'pointSeries']); + const PageObjects = getPageObjects(['common', 'visualize', 'header', 'pointSeries', 'timePicker']); const pointSeriesVis = PageObjects.pointSeries; describe('point series', function describeIndexTests() { @@ -35,8 +35,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickLineChart'); await PageObjects.visualize.clickLineChart(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('Bucket = X-Axis'); await PageObjects.visualize.clickBucket('X-Axis'); log.debug('Aggregation = Date Histogram'); diff --git a/test/functional/apps/visualize/_region_map.js b/test/functional/apps/visualize/_region_map.js index 652de69023d5a..f724e0029fd7e 100644 --- a/test/functional/apps/visualize/_region_map.js +++ b/test/functional/apps/visualize/_region_map.js @@ -29,7 +29,7 @@ export default function ({ getService, getPageObjects }) { const inspector = getService('inspector'); const log = getService('log'); const find = getService('find'); - const PageObjects = getPageObjects(['common', 'visualize', 'header', 'settings']); + const PageObjects = getPageObjects(['common', 'visualize', 'timePicker', 'settings']); before(async function () { @@ -38,8 +38,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickRegionMap'); await PageObjects.visualize.clickRegionMap(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('Bucket = shape field'); await PageObjects.visualize.clickBucket('shape field'); log.debug('Aggregation = Terms'); diff --git a/test/functional/apps/visualize/_tag_cloud.js b/test/functional/apps/visualize/_tag_cloud.js index d0f335cc2cb05..2469836fe7f92 100644 --- a/test/functional/apps/visualize/_tag_cloud.js +++ b/test/functional/apps/visualize/_tag_cloud.js @@ -26,7 +26,7 @@ export default function ({ getService, getPageObjects }) { const browser = getService('browser'); const retry = getService('retry'); const find = getService('find'); - const PageObjects = getPageObjects(['common', 'visualize', 'header', 'settings']); + const PageObjects = getPageObjects(['common', 'visualize', 'header', 'settings', 'timePicker']); describe('tag cloud chart', function () { const vizName1 = 'Visualization tagCloud'; @@ -40,8 +40,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickTagCloud'); await PageObjects.visualize.clickTagCloud(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('select Tags'); await PageObjects.visualize.clickBucket('Tags'); log.debug('Click aggregation Terms'); @@ -140,7 +139,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.common.navigateToApp('visualize'); await PageObjects.visualize.loadSavedVisualization(vizName1, { navigateToVisualize: false }); await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.waitForVisualization(); }); diff --git a/test/functional/apps/visualize/_tile_map.js b/test/functional/apps/visualize/_tile_map.js index a66e6c3941742..f172d811974e3 100644 --- a/test/functional/apps/visualize/_tile_map.js +++ b/test/functional/apps/visualize/_tile_map.js @@ -26,7 +26,7 @@ export default function ({ getService, getPageObjects }) { const find = getService('find'); const testSubjects = getService('testSubjects'); const browser = getService('browser'); - const PageObjects = getPageObjects(['common', 'visualize', 'header', 'settings']); + const PageObjects = getPageObjects(['common', 'visualize', 'timePicker', 'settings']); describe('tile map visualize app', function () { @@ -44,8 +44,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickTileMap'); await PageObjects.visualize.clickTileMap(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); //do not configure aggs }); @@ -70,8 +69,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickTileMap'); await PageObjects.visualize.clickTileMap(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('select bucket Geo Coordinates'); await PageObjects.visualize.clickBucket('Geo Coordinates'); log.debug('Click aggregation Geohash'); diff --git a/test/functional/apps/visualize/_tsvb_chart.js b/test/functional/apps/visualize/_tsvb_chart.js index 66e4aa9aa8d89..40b67c8f28438 100644 --- a/test/functional/apps/visualize/_tsvb_chart.js +++ b/test/functional/apps/visualize/_tsvb_chart.js @@ -24,7 +24,7 @@ export default function ({ getService, getPageObjects }) { const log = getService('log'); const inspector = getService('inspector'); const retry = getService('retry'); - const PageObjects = getPageObjects(['common', 'visualize', 'header', 'settings', 'visualBuilder']); + const PageObjects = getPageObjects(['common', 'visualize', 'header', 'settings', 'visualBuilder', 'timePicker']); describe('visual builder', function describeIndexTests() { @@ -147,7 +147,7 @@ export default function ({ getService, getPageObjects }) { before(async () => { await PageObjects.visualBuilder.resetPage(); await PageObjects.visualBuilder.clickMarkdown(); - await PageObjects.header.setAbsoluteRange('2015-09-22 06:00:00.000', '2015-09-22 11:00:00.000'); + await PageObjects.timePicker.setAbsoluteRange('2015-09-22 06:00:00.000', '2015-09-22 11:00:00.000'); }); it('should allow printing raw timestamp of data', async () => { @@ -194,7 +194,7 @@ export default function ({ getService, getPageObjects }) { before(async () => { await PageObjects.visualBuilder.resetPage(); await PageObjects.visualBuilder.clickTable(); - await PageObjects.header.setAbsoluteRange('2015-09-22 06:00:00.000', '2015-09-22 11:00:00.000'); + await PageObjects.timePicker.setAbsoluteRange('2015-09-22 06:00:00.000', '2015-09-22 11:00:00.000'); log.debug('clicked on Table'); }); @@ -231,8 +231,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualBuilder.clickMetricPanelOptions(); const fromTime = '2018-10-22 00:00:00.000'; const toTime = '2018-10-28 23:59:59.999'; - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualBuilder.setIndexPatternValue('kibana_sample_data_flights'); await PageObjects.visualBuilder.selectIndexPatternTimeField('timestamp'); const newValue = await PageObjects.visualBuilder.getMetricValue(); diff --git a/test/functional/apps/visualize/_vertical_bar_chart.js b/test/functional/apps/visualize/_vertical_bar_chart.js index 330f99d53340d..aeee7a2fd6384 100644 --- a/test/functional/apps/visualize/_vertical_bar_chart.js +++ b/test/functional/apps/visualize/_vertical_bar_chart.js @@ -23,7 +23,7 @@ export default function ({ getService, getPageObjects }) { const log = getService('log'); const retry = getService('retry'); const inspector = getService('inspector'); - const PageObjects = getPageObjects(['common', 'visualize', 'header']); + const PageObjects = getPageObjects(['common', 'visualize', 'header', 'timePicker']); describe('vertical bar chart', function () { const fromTime = '2015-09-19 06:31:44.000'; @@ -36,8 +36,7 @@ export default function ({ getService, getPageObjects }) { log.debug('clickVerticalBarChart'); await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch(); - log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('Bucket = X-Axis'); await PageObjects.visualize.clickBucket('X-Axis'); log.debug('Aggregation = Date Histogram'); @@ -112,7 +111,7 @@ export default function ({ getService, getPageObjects }) { const fromTime = '2015-09-20 06:31:44.000'; const toTime = '2015-09-22 18:31:44.000'; - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); let expectedChartValues = [ 82, 218, 341, 440, 480, 517, 522, 446, 403, 321, 258, 172, 95, 55, 38, 24, 3, 4, diff --git a/test/functional/page_objects/dashboard_page.js b/test/functional/page_objects/dashboard_page.js index 570f79c30b915..4d398e1a1dd41 100644 --- a/test/functional/page_objects/dashboard_page.js +++ b/test/functional/page_objects/dashboard_page.js @@ -35,7 +35,7 @@ export function DashboardPageProvider({ getService, getPageObjects }) { const testSubjects = getService('testSubjects'); const dashboardAddPanel = getService('dashboardAddPanel'); const renderable = getService('renderable'); - const PageObjects = getPageObjects(['common', 'header', 'settings', 'visualize']); + const PageObjects = getPageObjects(['common', 'header', 'settings', 'visualize', 'timePicker']); const defaultFindTimeout = config.get('timeouts.find'); @@ -511,19 +511,19 @@ export function DashboardPageProvider({ getService, getPageObjects }) { async setTimepickerInHistoricalDataRange() { const fromTime = '2015-09-19 06:31:44.000'; const toTime = '2015-09-23 18:31:44.000'; - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); } async setTimepickerInDataRange() { const fromTime = '2018-01-01 00:00:00.000'; const toTime = '2018-04-13 00:00:00.000'; - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); } async setTimepickerInLogstashDataRange() { const fromTime = '2018-04-09 00:00:00.000'; const toTime = '2018-04-13 00:00:00.000'; - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); } async setSaveAsNewCheckBox(checked) { diff --git a/test/functional/page_objects/header_page.js b/test/functional/page_objects/header_page.js index 99512197f89bb..30dca650bfac8 100644 --- a/test/functional/page_objects/header_page.js +++ b/test/functional/page_objects/header_page.js @@ -116,32 +116,6 @@ export function HeaderPageProvider({ getService, getPageObjects }) { }); } - async setFromTime(timeString) { - log.debug(`setFromTime: ${timeString}`); - await retry.try(async () => { - await this.ensureTimePickerIsOpen(); - await this.showAbsoluteSection(); - await find.setValue('input[ng-model=\'absolute.from\']', timeString); - }); - } - - async setToTime(timeString) { - log.debug(`setToTime: ${timeString}`); - await retry.try(async () => { - await this.ensureTimePickerIsOpen(); - await this.showAbsoluteSection(); - await find.setValue('input[ng-model=\'absolute.to\']', timeString); - }); - } - - async clickGoButton() { - log.debug('clickGoButton'); - await retry.try(async () => { - await testSubjects.click('timepickerGoButton'); - await this.waitUntilLoadingHasFinished(); - }); - } - async ensureTimePickerIsOpen() { log.debug('ensureTimePickerIsOpen'); const isOpen = await this.isTimepickerOpen(); @@ -154,19 +128,6 @@ export function HeaderPageProvider({ getService, getPageObjects }) { } } - async setAbsoluteRange(fromTime, toTime) { - log.debug(`Setting absolute range to ${fromTime} to ${toTime}`); - await this.ensureTimePickerIsOpen(); - log.debug('--Clicking Absolute button'); - await this.showAbsoluteSection(); - log.debug('--Setting From Time : ' + fromTime); - await this.setFromTime(fromTime); - log.debug('--Setting To Time : ' + toTime); - await this.setToTime(toTime); - await this.clickGoButton(); - await this.awaitGlobalLoadingIndicatorHidden(); - } - async setQuickTime(quickTime) { await this.ensureTimePickerIsOpen(); log.debug('--Clicking Quick button'); diff --git a/test/functional/page_objects/time_picker.js b/test/functional/page_objects/time_picker.js index 4c8f7ba68a504..8968f0a650686 100644 --- a/test/functional/page_objects/time_picker.js +++ b/test/functional/page_objects/time_picker.js @@ -17,13 +17,47 @@ * under the License. */ -export function TimePickerPageProvider({ getService }) { +export function TimePickerPageProvider({ getService, getPageObjects }) { const log = getService('log'); const retry = getService('retry'); const testSubjects = getService('testSubjects'); + const PageObjects = getPageObjects(['header']); class TimePickerPage { + async setAbsoluteRange(fromTime, toTime) { + log.debug(`Setting absolute range to ${fromTime} to ${toTime}`); + await this.showStartEndTimes(); + + // set from time + await testSubjects.click('superDatePickerstartDatePopoverButton'); + await testSubjects.click('superDatePickerAbsoluteTab'); + await testSubjects.setValue('superDatePickerAbsoluteDateInput', fromTime); + + // set to time + await testSubjects.click('superDatePickerendDatePopoverButton'); + await testSubjects.click('superDatePickerAbsoluteTab'); + await testSubjects.setValue('superDatePickerAbsoluteDateInput', toTime); + + const superDatePickerApplyButtonExists = await testSubjects.exists('superDatePickerApplyTimeButton'); + if (superDatePickerApplyButtonExists) { + // Timepicker is in top nav + // Click super date picker apply button to apply time range + await testSubjects.click('superDatePickerApplyTimeButton'); + } else { + // Timepicker is embedded in query bar + // click query bar submit button to apply time range + await testSubjects.click('querySubmitButton'); + } + await testSubjects.click('superDatePickerApplyTimeButton'); + + await PageObjects.header.awaitGlobalLoadingIndicatorHidden(); + } + + async openFromTimePanel() { + await testSubjects.click('superDatePickerstartDatePopoverButton'); + } + async isQuickSelectMenuOpen() { return await testSubjects.exists('superDatePickerQuickMenu'); } diff --git a/test/functional/page_objects/visual_builder_page.js b/test/functional/page_objects/visual_builder_page.js index cfc523cc052ec..24851dee69e3f 100644 --- a/test/functional/page_objects/visual_builder_page.js +++ b/test/functional/page_objects/visual_builder_page.js @@ -24,7 +24,7 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }) { const browser = getService('browser'); const testSubjects = getService('testSubjects'); const comboBox = getService('comboBox'); - const PageObjects = getPageObjects(['common', 'header', 'visualize']); + const PageObjects = getPageObjects(['common', 'header', 'visualize', 'timePicker']); class VisualBuilderPage { @@ -36,8 +36,7 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }) { log.debug('clickVisualBuilderChart'); await PageObjects.visualize.clickVisualBuilder(); log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); - await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); } async clickMetric() { diff --git a/test/functional/page_objects/visualize_page.js b/test/functional/page_objects/visualize_page.js index 7766c683aecf5..380800e77090f 100644 --- a/test/functional/page_objects/visualize_page.js +++ b/test/functional/page_objects/visualize_page.js @@ -231,18 +231,6 @@ export function VisualizePageProvider({ getService, getPageObjects }) { return await find.byCssSelector('div.vgaVis__controls'); } - async setFromTime(timeString) { - const input = await find.byCssSelector('input[ng-model="absolute.from"]', defaultFindTimeout * 2); - await input.clearValue(); - await input.type(timeString); - } - - async setToTime(timeString) { - const input = await find.byCssSelector('input[ng-model="absolute.to"]', defaultFindTimeout * 2); - await input.clearValue(); - await input.type(timeString); - } - async addInputControl() { await testSubjects.click('inputControlEditorAddBtn'); await PageObjects.header.waitUntilLoadingHasFinished(); diff --git a/x-pack/test/functional/apps/monitoring/_get_lifecycle_methods.js b/x-pack/test/functional/apps/monitoring/_get_lifecycle_methods.js index 518162593a121..cba22994f6f2b 100644 --- a/x-pack/test/functional/apps/monitoring/_get_lifecycle_methods.js +++ b/x-pack/test/functional/apps/monitoring/_get_lifecycle_methods.js @@ -6,7 +6,7 @@ export const getLifecycleMethods = (getService, getPageObjects) => { const esArchiver = getService('esArchiver'); - const PageObjects = getPageObjects(['monitoring', 'header', 'timePicker']); + const PageObjects = getPageObjects(['monitoring', 'timePicker']); const noData = getService('monitoringNoData'); let _archive; @@ -32,7 +32,7 @@ export const getLifecycleMethods = (getService, getPageObjects) => { // and we don't want ES to log a warning when data gets wiped out await PageObjects.timePicker.pauseAutoRefresh(); - await PageObjects.header.setAbsoluteRange(from, to); + await PageObjects.timePicker.setAbsoluteRange(from, to); }, tearDown() { diff --git a/x-pack/test/functional/apps/security/rbac_phase1.js b/x-pack/test/functional/apps/security/rbac_phase1.js index bf8fb2efcb067..021a2df495562 100644 --- a/x-pack/test/functional/apps/security/rbac_phase1.js +++ b/x-pack/test/functional/apps/security/rbac_phase1.js @@ -8,7 +8,7 @@ import expect from 'expect.js'; import { indexBy } from 'lodash'; export default function ({ getService, getPageObjects }) { - const PageObjects = getPageObjects(['security', 'settings', 'common', 'visualize', 'header']); + const PageObjects = getPageObjects(['security', 'settings', 'common', 'visualize', 'timePicker']); const log = getService('log'); const esArchiver = getService('esArchiver'); const browser = getService('browser'); @@ -97,7 +97,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch(); log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.waitForVisualization(); await PageObjects.visualize.saveVisualizationExpectSuccess(vizName1); await PageObjects.security.logout(); @@ -116,7 +116,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch(); log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.waitForVisualization(); await PageObjects.visualize.saveVisualizationExpectFail(vizName1); await PageObjects.security.logout(); diff --git a/x-pack/test/functional/page_objects/reporting_page.js b/x-pack/test/functional/page_objects/reporting_page.js index 7cda7331fe717..356d23480ed64 100644 --- a/x-pack/test/functional/page_objects/reporting_page.js +++ b/x-pack/test/functional/page_objects/reporting_page.js @@ -15,7 +15,7 @@ export function ReportingPageProvider({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); const browser = getService('browser'); const kibanaServer = getService('kibanaServer'); - const PageObjects = getPageObjects(['common', 'security', 'header', 'settings', 'share']); + const PageObjects = getPageObjects(['common', 'security', 'settings', 'share', 'timePicker']); class ReportingPage { async initTests() { @@ -164,14 +164,14 @@ export function ReportingPageProvider({ getService, getPageObjects }) { log.debug('Reporting:setTimepickerInDataRange'); const fromTime = '2015-09-19 06:31:44.000'; const toTime = '2015-09-23 18:31:44.000'; - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); } async setTimepickerInNoDataRange() { log.debug('Reporting:setTimepickerInNoDataRange'); const fromTime = '1999-09-19 06:31:44.000'; const toTime = '1999-09-23 18:31:44.000'; - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); } } From bf3324a29330ae10bd7ec1c9e67ba02b14488c92 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 22 Jan 2019 20:01:26 -0700 Subject: [PATCH 08/34] replace setQuickTime with calls to setAbsoluteTime --- .../apps/dashboard/_dashboard_time.js | 49 +++++--------- .../apps/dashboard/_dashboard_time_picker.js | 3 +- test/functional/apps/dashboard/_view_edit.js | 32 ++++----- test/functional/page_objects/header_page.js | 66 ------------------- test/functional/page_objects/time_picker.js | 10 +-- .../dashboard_mode/dashboard_view_mode.js | 2 +- 6 files changed, 37 insertions(+), 125 deletions(-) diff --git a/test/functional/apps/dashboard/_dashboard_time.js b/test/functional/apps/dashboard/_dashboard_time.js index 897fbb62b2b01..b34d061f608a0 100644 --- a/test/functional/apps/dashboard/_dashboard_time.js +++ b/test/functional/apps/dashboard/_dashboard_time.js @@ -50,44 +50,27 @@ export default function ({ getPageObjects, getService }) { await PageObjects.dashboard.loadSavedDashboard(dashboardName); - const fromTimeNext = await PageObjects.header.getFromTime(); - const toTimeNext = await PageObjects.header.getToTime(); - expect(fromTimeNext).to.equal(fromTime); - expect(toTimeNext).to.equal(toTime); + const time = await PageObjects.timePicker.getTimeConfig(); + expect(time.start).to.equal('Sep 19, 2015 @ 06:31:44.000'); + expect(time.end).to.equal('Sep 23, 2015 @ 18:31:44.000'); }); }); describe('dashboard with stored timed', async function () { - it('is saved with quick time', async function () { - await PageObjects.dashboard.switchToEditMode(); - await PageObjects.header.setQuickTime('Today'); - await PageObjects.dashboard.saveDashboard(dashboardName, { storeTimeWithDashboard: true }); - }); - - it('sets quick time on open', async function () { - await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); - - await PageObjects.dashboard.loadSavedDashboard(dashboardName); - - const prettyPrint = await PageObjects.header.getPrettyDuration(); - expect(prettyPrint).to.equal('Today'); - }); - - it('is saved with absolute time', async function () { + it('is saved with time', async function () { await PageObjects.dashboard.switchToEditMode(); await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.dashboard.saveDashboard(dashboardName, { storeTimeWithDashboard: true }); }); - it('sets absolute time on open', async function () { - await PageObjects.header.setQuickTime('Today'); + it('sets time on open', async function () { + await PageObjects.timePicker.setAbsoluteRange('2019-01-01 00:00:00.000', '2019-01-02 00:00:00.000'); await PageObjects.dashboard.loadSavedDashboard(dashboardName); - const fromTimeNext = await PageObjects.header.getFromTime(); - const toTimeNext = await PageObjects.header.getToTime(); - expect(fromTimeNext).to.equal(fromTime); - expect(toTimeNext).to.equal(toTime); + const time = await PageObjects.timePicker.getTimeConfig(); + expect(time.start).to.equal('Sep 19, 2015 @ 06:31:44.000'); + expect(time.end).to.equal('Sep 23, 2015 @ 18:31:44.000'); }); // If time is stored with a dashboard, it's supposed to override the current time settings when opened. @@ -100,10 +83,11 @@ export default function ({ getPageObjects, getService }) { await PageObjects.dashboard.gotoDashboardLandingPage(); - const urlWithGlobalTime = `${kibanaBaseUrl}#/dashboard/${id}?_g=(time:(from:now-1h,mode:quick,to:now))`; + const urlWithGlobalTime = `${kibanaBaseUrl}#/dashboard/${id}?_g=(time:(from:now-1h,to:now))`; await browser.get(urlWithGlobalTime, false); - const prettyPrint = await PageObjects.header.getPrettyDuration(); - expect(prettyPrint).to.equal('Last 1 hour'); + const time = await PageObjects.timePicker.getTimeConfig(); + expect(time.start).to.equal('~ an hour ago'); + expect(time.end).to.equal('now'); }); }); @@ -115,12 +99,13 @@ export default function ({ getPageObjects, getService }) { it('preserved during navigation', async function () { await PageObjects.dashboard.loadSavedDashboard(dashboardName); - await PageObjects.header.setQuickTime('Today'); + await PageObjects.timePicker.setAbsoluteRange('2019-01-01 00:00:00.000', '2019-01-02 00:00:00.000'); await PageObjects.header.clickVisualize(); await PageObjects.header.clickDashboard(); - const prettyPrint = await PageObjects.header.getPrettyDuration(); - expect(prettyPrint).to.equal('Today'); + const time = await PageObjects.timePicker.getTimeConfig(); + expect(time.start).to.equal('Jan 1, 2019 @ 00:00:00.000'); + expect(time.end).to.equal('Jan 2, 2019 @ 00:00:00.000'); }); }); }); diff --git a/test/functional/apps/dashboard/_dashboard_time_picker.js b/test/functional/apps/dashboard/_dashboard_time_picker.js index 1cbb0c44e5c67..91d2f12eacf7d 100644 --- a/test/functional/apps/dashboard/_dashboard_time_picker.js +++ b/test/functional/apps/dashboard/_dashboard_time_picker.js @@ -54,7 +54,8 @@ export default function ({ getService, getPageObjects }) { await dashboardVisualizations.createAndAddSavedSearch({ name: 'saved search', fields: ['bytes', 'agent'] }); await dashboardExpect.docTableFieldCount(150); - await PageObjects.header.setQuickTime('Today'); + // Set to time range with no data + await PageObjects.timePicker.setAbsoluteRange('2000-01-01 00:00:00.000', '2000-01-01 01:00:00.000'); await dashboardExpect.docTableFieldCount(0); }); }); diff --git a/test/functional/apps/dashboard/_view_edit.js b/test/functional/apps/dashboard/_view_edit.js index 049fea0e0724f..7851d5320f2e3 100644 --- a/test/functional/apps/dashboard/_view_edit.js +++ b/test/functional/apps/dashboard/_view_edit.js @@ -62,8 +62,7 @@ export default function ({ getService, getPageObjects }) { it('when time changed is stored with dashboard', async function () { await PageObjects.dashboard.setTimepickerInDataRange(); - const originalFromTime = await PageObjects.header.getFromTime(); - const originalToTime = await PageObjects.header.getToTime(); + const originalTime = await PageObjects.timePicker.getTimeConfig(); await PageObjects.dashboard.saveDashboard(dashboardName, { storeTimeWithDashboard: true }); @@ -74,11 +73,10 @@ export default function ({ getService, getPageObjects }) { // confirm lose changes await PageObjects.common.clickConfirmOnModal(); - const newFromTime = await PageObjects.header.getFromTime(); - const newToTime = await PageObjects.header.getToTime(); + const newTime = await PageObjects.timePicker.getTimeConfig(); - expect(newFromTime).to.equal(originalFromTime); - expect(newToTime).to.equal(originalToTime); + expect(newTime.start).to.equal(originalTime.start); + expect(newTime.end).to.equal(originalTime.end); }); it('when the query is edited and applied', async function () { @@ -153,12 +151,10 @@ export default function ({ getService, getPageObjects }) { describe('and preserves edits on cancel', function () { it('when time changed is stored with dashboard', async function () { await PageObjects.dashboard.gotoDashboardEditMode(dashboardName); - const newFromTime = '2015-09-19 06:31:44.000'; - const newToTime = '2015-09-19 06:31:44.000'; await PageObjects.timePicker.setAbsoluteRange('2013-09-19 06:31:44.000', '2013-09-19 06:31:44.000'); await PageObjects.dashboard.saveDashboard(dashboardName, true); await PageObjects.dashboard.switchToEditMode(); - await PageObjects.timePicker.setAbsoluteRange(newToTime, newToTime); + await PageObjects.timePicker.setAbsoluteRange('2015-09-19 06:31:44.000', '2015-09-19 06:31:44.000'); await PageObjects.dashboard.clickCancelOutOfEditMode(); await PageObjects.common.clickCancelOnModal(); @@ -166,11 +162,10 @@ export default function ({ getService, getPageObjects }) { await PageObjects.dashboard.loadSavedDashboard(dashboardName); - const fromTime = await PageObjects.header.getFromTime(); - const toTime = await PageObjects.header.getToTime(); + const time = await PageObjects.timePicker.getTimeConfig(); - expect(fromTime).to.equal(newFromTime); - expect(toTime).to.equal(newToTime); + expect(time.start).to.equal('Sep 19, 2015 @ 06:31:44.000'); + expect(time.end).to.equal('Sep 19, 2015 @ 06:31:44.000'); }); }); }); @@ -182,9 +177,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.dashboard.saveDashboard(dashboardName, true); await PageObjects.dashboard.switchToEditMode(); await PageObjects.timePicker.setAbsoluteRange('2013-09-19 06:31:44.000', '2013-09-19 06:31:44.000'); - - const newFromTime = await PageObjects.header.getFromTime(); - const newToTime = await PageObjects.header.getToTime(); + const newTime = await PageObjects.timePicker.getTimeConfig(); await PageObjects.dashboard.clickCancelOutOfEditMode(); @@ -193,11 +186,10 @@ export default function ({ getService, getPageObjects }) { await PageObjects.dashboard.loadSavedDashboard(dashboardName); - const fromTime = await PageObjects.header.getFromTime(); - const toTime = await PageObjects.header.getToTime(); + const time = await PageObjects.timePicker.getTimeConfig(); - expect(fromTime).to.equal(newFromTime); - expect(toTime).to.equal(newToTime); + expect(time.start).to.equal(newTime.start); + expect(time.end).to.equal(newTime.end); }); }); diff --git a/test/functional/page_objects/header_page.js b/test/functional/page_objects/header_page.js index 30dca650bfac8..e5616f1ed54ca 100644 --- a/test/functional/page_objects/header_page.js +++ b/test/functional/page_objects/header_page.js @@ -65,76 +65,10 @@ export function HeaderPageProvider({ getService, getPageObjects }) { await this.awaitGlobalLoadingIndicatorHidden(); } - async clickTimepicker() { - await testSubjects.click('globalTimepickerButton'); - } - - async clickQuickButton() { - await retry.try(async () => { - await testSubjects.click('timepicker-quick-button'); - }); - } - async isTimepickerOpen() { return await testSubjects.exists('timePicker'); } - async isAbsoluteSectionShowing() { - log.debug('isAbsoluteSectionShowing'); - return await find.existsByCssSelector('input[ng-model=\'absolute.from\']'); - } - - async showAbsoluteSection() { - log.debug('showAbsoluteSection'); - const isAbsoluteSectionShowing = await this.isAbsoluteSectionShowing(); - if (!isAbsoluteSectionShowing) { - await retry.try(async () => { - await testSubjects.click('timepicker-absolute-button'); - // Check to make sure one of the elements on the absolute section is showing. - await this.getFromTime(); - }); - } - } - - async getFromTime() { - log.debug('getFromTime'); - return await retry.try(async () => { - await this.ensureTimePickerIsOpen(); - await this.showAbsoluteSection(); - const element = await find.byCssSelector('input[ng-model=\'absolute.from\']'); - return await element.getProperty('value'); - }); - } - - async getToTime() { - log.debug('getToTime'); - return await retry.try(async () => { - await this.ensureTimePickerIsOpen(); - await this.showAbsoluteSection(); - const element = await find.byCssSelector('input[ng-model=\'absolute.to\']'); - return await element.getProperty('value'); - }); - } - - async ensureTimePickerIsOpen() { - log.debug('ensureTimePickerIsOpen'); - const isOpen = await this.isTimepickerOpen(); - if (!isOpen) { - await retry.try(async () => { - await this.clickTimepicker(); - const isOpen = await this.isTimepickerOpen(); - if (!isOpen) throw new Error('Time picker still not open, try again.'); - }); - } - } - - async setQuickTime(quickTime) { - await this.ensureTimePickerIsOpen(); - log.debug('--Clicking Quick button'); - await this.clickQuickButton(); - await find.clickByLinkText(quickTime); - } - async getToastMessage(findTimeout = defaultFindTimeout) { const toastMessage = await find.displayedByCssSelector( 'kbn-truncated.kbnToast__message', diff --git a/test/functional/page_objects/time_picker.js b/test/functional/page_objects/time_picker.js index 8968f0a650686..22ed077e2fddc 100644 --- a/test/functional/page_objects/time_picker.js +++ b/test/functional/page_objects/time_picker.js @@ -29,16 +29,16 @@ export function TimePickerPageProvider({ getService, getPageObjects }) { log.debug(`Setting absolute range to ${fromTime} to ${toTime}`); await this.showStartEndTimes(); - // set from time - await testSubjects.click('superDatePickerstartDatePopoverButton'); - await testSubjects.click('superDatePickerAbsoluteTab'); - await testSubjects.setValue('superDatePickerAbsoluteDateInput', fromTime); - // set to time await testSubjects.click('superDatePickerendDatePopoverButton'); await testSubjects.click('superDatePickerAbsoluteTab'); await testSubjects.setValue('superDatePickerAbsoluteDateInput', toTime); + // set from time + await testSubjects.click('superDatePickerstartDatePopoverButton'); + await testSubjects.click('superDatePickerAbsoluteTab'); + await testSubjects.setValue('superDatePickerAbsoluteDateInput', fromTime); + const superDatePickerApplyButtonExists = await testSubjects.exists('superDatePickerApplyTimeButton'); if (superDatePickerApplyButtonExists) { // Timepicker is in top nav diff --git a/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js b/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js index cb701ffb6f32b..01a6129dcd57b 100644 --- a/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js +++ b/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js @@ -173,7 +173,7 @@ export default function ({ getService, getPageObjects }) { }); it('shows the timepicker', async () => { - const timePickerExists = await testSubjects.exists('globalTimepickerButton'); + const timePickerExists = await testSubjects.exists('superDatePickerApplyTimeButton'); expect(timePickerExists).to.be(true); }); From ed5536102356ab5e3455f246d5b1cfbc159518c9 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 22 Jan 2019 20:33:43 -0700 Subject: [PATCH 09/34] remove open time picker button in discover empty results view --- .../__snapshots__/no_results.test.js.snap | 15 ++--- .../public/discover/directives/no_results.js | 26 +------- .../discover/directives/no_results.test.js | 61 +------------------ .../kibana/public/discover/index.html | 2 - test/functional/apps/discover/_discover.js | 11 ---- test/functional/page_objects/discover_page.js | 11 +--- test/functional/page_objects/header_page.js | 4 -- 7 files changed, 10 insertions(+), 120 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/discover/directives/__snapshots__/no_results.test.js.snap b/src/legacy/core_plugins/kibana/public/discover/directives/__snapshots__/no_results.test.js.snap index a6eacbf0ec7fb..ebc27316d4675 100644 --- a/src/legacy/core_plugins/kibana/public/discover/directives/__snapshots__/no_results.test.js.snap +++ b/src/legacy/core_plugins/kibana/public/discover/directives/__snapshots__/no_results.test.js.snap @@ -425,20 +425,13 @@ Array [
-

+

Expand your time range

- One or more of the indices you’re looking at contains a date field. Your query may not match anything in the current time range, or there may not be any data at all in the currently selected time range. You can try - - and changing the time range to one which contains data. + One or more of the indices you’re looking at contains a date field. Your query may not match anything in the current time range, or there may not be any data at all in the currently selected time range. You can try changing the time range to one which contains data.

diff --git a/src/legacy/core_plugins/kibana/public/discover/directives/no_results.js b/src/legacy/core_plugins/kibana/public/discover/directives/no_results.js index 4427658a2792f..9f57c49977f5a 100644 --- a/src/legacy/core_plugins/kibana/public/discover/directives/no_results.js +++ b/src/legacy/core_plugins/kibana/public/discover/directives/no_results.js @@ -33,18 +33,13 @@ import { EuiText, } from '@elastic/eui'; +// eslint-disable-next-line react/prefer-stateless-function export class DiscoverNoResults extends Component { static propTypes = { shardFailures: PropTypes.array, timeFieldName: PropTypes.string, queryLanguage: PropTypes.string, - isTimePickerOpen: PropTypes.bool.isRequired, getDocLink: PropTypes.func.isRequired, - topNavToggle: PropTypes.func.isRequired, - }; - - onClickTimePickerButton = () => { - this.props.topNavToggle('filter'); }; render() { @@ -53,7 +48,6 @@ export class DiscoverNoResults extends Component { timeFieldName, queryLanguage, getDocLink, - isTimePickerOpen, } = this.props; let shardFailuresMessage; @@ -125,7 +119,7 @@ export class DiscoverNoResults extends Component { -

+

- - - ) - }} + the currently selected time range. You can try changing the time range to one which contains data." />

diff --git a/src/legacy/core_plugins/kibana/public/discover/directives/no_results.test.js b/src/legacy/core_plugins/kibana/public/discover/directives/no_results.test.js index 1aeb66ceccc91..afc9ec14f51c0 100644 --- a/src/legacy/core_plugins/kibana/public/discover/directives/no_results.test.js +++ b/src/legacy/core_plugins/kibana/public/discover/directives/no_results.test.js @@ -18,9 +18,7 @@ */ import React from 'react'; -import { renderWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers'; -import sinon from 'sinon'; -import { findTestSubject } from '@elastic/eui/lib/test'; +import { renderWithIntl } from 'test_utils/enzyme_helpers'; import { DiscoverNoResults, @@ -43,8 +41,6 @@ describe('DiscoverNoResults', () => { const component = renderWithIntl( {}} getDocLink={() => ''} /> ); @@ -58,8 +54,6 @@ describe('DiscoverNoResults', () => { const component = renderWithIntl( {}} getDocLink={() => ''} /> ); @@ -68,45 +62,11 @@ describe('DiscoverNoResults', () => { }); }); - describe('isTimePickerOpen', () => { - test('false is reflected in the aria-expanded state of the button', () => { - const component = renderWithIntl( - {}} - getDocLink={() => ''} - /> - ); - - expect( - component.find('[data-test-subj="discoverNoResultsTimefilter"]')[0].attribs['aria-expanded'] - ).toBe('false'); - }); - - test('true is reflected in the aria-expanded state of the button', () => { - const component = renderWithIntl( - {}} - getDocLink={() => ''} - /> - ); - - expect( - component.find('[data-test-subj="discoverNoResultsTimefilter"]')[0].attribs['aria-expanded'] - ).toBe('true'); - }); - }); - describe('timeFieldName', () => { test('renders time range feedback', () => { const component = renderWithIntl( {}} getDocLink={() => ''} /> ); @@ -120,8 +80,6 @@ describe('DiscoverNoResults', () => { const component = renderWithIntl( {}} getDocLink={() => 'documentation-link'} /> ); @@ -129,22 +87,5 @@ describe('DiscoverNoResults', () => { expect(component).toMatchSnapshot(); }); }); - - describe('topNavToggle', () => { - test('is called whe time picker button is clicked', () => { - const topNavToggleSpy = sinon.stub(); - const component = mountWithIntl( - ''} - /> - ); - - findTestSubject(component, 'discoverNoResultsTimefilter').simulate('click'); - sinon.assert.calledOnce(topNavToggleSpy); - }); - }); }); }); diff --git a/src/legacy/core_plugins/kibana/public/discover/index.html b/src/legacy/core_plugins/kibana/public/discover/index.html index 1534ca0e580fe..be6b791085998 100644 --- a/src/legacy/core_plugins/kibana/public/discover/index.html +++ b/src/legacy/core_plugins/kibana/public/discover/index.html @@ -71,8 +71,6 @@

true) - .catch(() => false); + async hasNoResultsTimepicker() { + return await testSubjects.exists('discoverNoResultsTimefilter'); } async clickFieldListItem(field) { diff --git a/test/functional/page_objects/header_page.js b/test/functional/page_objects/header_page.js index e5616f1ed54ca..f264d4a737ee9 100644 --- a/test/functional/page_objects/header_page.js +++ b/test/functional/page_objects/header_page.js @@ -65,10 +65,6 @@ export function HeaderPageProvider({ getService, getPageObjects }) { await this.awaitGlobalLoadingIndicatorHidden(); } - async isTimepickerOpen() { - return await testSubjects.exists('timePicker'); - } - async getToastMessage(findTimeout = defaultFindTimeout) { const toastMessage = await find.displayedByCssSelector( 'kbn-truncated.kbnToast__message', From 57302ae8a1093c1ff8c037c28d9e66a6a7eaf2e9 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 23 Jan 2019 09:34:14 -0700 Subject: [PATCH 10/34] pass config values to super-date-picker directive --- src/ui/public/react_components.js | 6 +++- src/ui/public/timefilter/time_history.js | 5 ++- .../timepicker/kbn_global_timepicker.html | 4 +++ .../timepicker/kbn_global_timepicker.js | 36 +++++++++++++++---- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/ui/public/react_components.js b/src/ui/public/react_components.js index 1fe69c8542d31..542fe19d8a09d 100644 --- a/src/ui/public/react_components.js +++ b/src/ui/public/react_components.js @@ -57,5 +57,9 @@ app.directive('superDatePicker', reactDirective => reactDirective(EuiSuperDatePi 'dateFormat', 'recentlyUsedRanges', 'onTimeChange', - 'onRefreshChange' + 'onRefreshChange', + 'isAutoRefreshOnly', + 'commonlyUsedRanges', + 'dateFormat', + 'recentlyUsedRanges', ])); diff --git a/src/ui/public/timefilter/time_history.js b/src/ui/public/timefilter/time_history.js index ad2f07957d92f..1ae908d174f97 100644 --- a/src/ui/public/timefilter/time_history.js +++ b/src/ui/public/timefilter/time_history.js @@ -24,7 +24,10 @@ class TimeHistory { constructor() { const historyOptions = { maxLength: 10, - filterDuplicates: true + filterDuplicates: true, + isDuplicate: (oldItem, newItem) => { + return oldItem.from === newItem.from && oldItem.to === newItem.to; + } }; this.history = new PersistedLog('kibana.timepicker.timeHistory', historyOptions); } diff --git a/src/ui/public/timepicker/kbn_global_timepicker.html b/src/ui/public/timepicker/kbn_global_timepicker.html index 4eed00440f72e..8edf05a343793 100644 --- a/src/ui/public/timepicker/kbn_global_timepicker.html +++ b/src/ui/public/timepicker/kbn_global_timepicker.html @@ -12,5 +12,9 @@ refresh-interval="timefilterValues.refreshInterval.value" on-time-change="updateFilter" on-refresh-change="updateInterval" + is-auto-refresh-only="!timefilterValues.isTimeRangeSelectorEnabled" + commonly-used-ranges="commonlyUsedRanges" + date-format="dateFormat" + recently-used-ranges="recentlyUsedRanges" /> diff --git a/src/ui/public/timepicker/kbn_global_timepicker.js b/src/ui/public/timepicker/kbn_global_timepicker.js index 47537174302fa..759746849cd07 100644 --- a/src/ui/public/timepicker/kbn_global_timepicker.js +++ b/src/ui/public/timepicker/kbn_global_timepicker.js @@ -21,12 +21,11 @@ import { uiModules } from '../modules'; import toggleHtml from './kbn_global_timepicker.html'; import { timefilter } from 'ui/timefilter'; +import { timeHistory } from 'ui/timefilter/time_history'; uiModules .get('kibana') .directive('kbnGlobalTimepicker', (globalState, config) => { - const getConfig = (...args) => config.get(...args); - const listenForUpdates = ($scope) => { $scope.$listenAndDigestAsync(timefilter, 'refreshIntervalUpdate', () => { setTimefilterValues($scope); @@ -48,29 +47,52 @@ uiModules isAutoRefreshSelectorEnabled: timefilter.isAutoRefreshSelectorEnabled, isTimeRangeSelectorEnabled: timefilter.isTimeRangeSelectorEnabled, }; + $scope.recentlyUsedRanges = timeHistory.get().map(({ from, to }) => { + return { + start: from, + end: to, + }; + }); } return { template: toggleHtml, replace: true, - require: '^kbnTopNav', - link: ($scope, element, attributes, kbnTopNav) => { + link: ($scope) => { listenForUpdates($scope); setTimefilterValues($scope); + config.watch('timepicker:quickRanges', (quickRanges) => { + // quickRanges is null when timepicker:quickRanges is set to default value + const ranges = quickRanges ? quickRanges : config.get('timepicker:quickRanges'); + $scope.commonlyUsedRanges = ranges.map(({ from, to, display }) => { + return { + start: from, + end: to, + label: display, + }; + }); + }); + + config.watch('dateFormat', (dateFormat) => { + // dateFormat is null when dateFormat is set to default value + $scope.dateFormat = dateFormat ? dateFormat : config.get('dateFormat'); + }); + $scope.toggleRefresh = () => { timefilter.toggleRefresh(); }; $scope.updateFilter = function ({ start, end }) { timefilter.setTime({ from: start, to: end }); - kbnTopNav.close('filter'); }; $scope.updateInterval = function ({ isPaused, refreshInterval }) { - timefilter.setRefreshInterval({ pause: isPaused, value: refreshInterval }); - kbnTopNav.close('interval'); + timefilter.setRefreshInterval({ + pause: isPaused, + value: refreshInterval ? refreshInterval : $scope.timefilterValues.refreshInterval.value + }); }; $scope.getSharedTimeFilterFromDate = function () { From 4e295c361ed94de85ddc75ad8a294b0a9080b839 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 23 Jan 2019 11:58:37 -0700 Subject: [PATCH 11/34] remove getPrettyDuration --- test/functional/apps/dashboard/_time_zones.js | 12 ++++--- test/functional/apps/discover/_discover.js | 22 ++++++------ test/functional/page_objects/header_page.js | 9 ----- test/functional/page_objects/time_picker.js | 34 ++++++++++++++++--- 4 files changed, 47 insertions(+), 30 deletions(-) diff --git a/test/functional/apps/dashboard/_time_zones.js b/test/functional/apps/dashboard/_time_zones.js index 73931f225da52..514b0366d19bb 100644 --- a/test/functional/apps/dashboard/_time_zones.js +++ b/test/functional/apps/dashboard/_time_zones.js @@ -22,7 +22,7 @@ import expect from 'expect.js'; export default function ({ getService, getPageObjects }) { const pieChart = getService('pieChart'); - const PageObjects = getPageObjects(['dashboard', 'header', 'settings', 'common']); + const PageObjects = getPageObjects(['dashboard', 'timePicker', 'settings', 'common']); describe('dashboard time zones', () => { before(async () => { @@ -41,8 +41,9 @@ export default function ({ getService, getPageObjects }) { }); it('Exported dashboard adjusts EST time to UTC', async () => { - const timeRange = await PageObjects.header.getPrettyDuration(); - expect(timeRange).to.be('April 10th 2018, 03:00:00.000 to April 10th 2018, 04:00:00.000'); + const time = await PageObjects.timePicker.getTimeConfigAsAbsoluteTimes(); + expect(time.start).to.be('2018-04-10 03:00:00.000'); + expect(time.end).to.be('2018-04-10 04:00:00.000'); await pieChart.expectPieSliceCount(4); }); @@ -52,8 +53,9 @@ export default function ({ getService, getPageObjects }) { await PageObjects.settings.setAdvancedSettingsSelect('dateFormat:tz', 'EST'); await PageObjects.common.navigateToApp('dashboard'); await PageObjects.dashboard.loadSavedDashboard('time zone test'); - const timeRange = await PageObjects.header.getPrettyDuration(); - expect(timeRange).to.be('April 9th 2018, 22:00:00.000 to April 9th 2018, 23:00:00.000'); + const time = await PageObjects.timePicker.getTimeConfigAsAbsoluteTimes(); + expect(time.start).to.be('2018-04-09 22:00:00.000'); + expect(time.end).to.be('2018-04-09 23:00:00.000'); await pieChart.expectPieSliceCount(4); }); }); diff --git a/test/functional/apps/discover/_discover.js b/test/functional/apps/discover/_discover.js index 49250ce560a58..5015932015a60 100644 --- a/test/functional/apps/discover/_discover.js +++ b/test/functional/apps/discover/_discover.js @@ -34,9 +34,7 @@ export default function ({ getService, getPageObjects }) { describe('discover app', function describeIndexTests() { const fromTime = '2015-09-19 06:31:44.000'; - const fromTimeString = 'September 19th 2015, 06:31:44.000'; const toTime = '2015-09-23 18:31:44.000'; - const toTimeString = 'September 23rd 2015, 18:31:44.000'; before(async function () { // delete .kibana index and update configDoc @@ -56,10 +54,9 @@ export default function ({ getService, getPageObjects }) { const queryName1 = 'Query # 1'; it('should show correct time range string by timepicker', async function () { - const actualTimeString = await PageObjects.header.getPrettyDuration(); - - const expectedTimeString = `${fromTimeString} to ${toTimeString}`; - expect(actualTimeString).to.be(expectedTimeString); + const time = await PageObjects.timePicker.getTimeConfig(); + expect(time.start).to.be('Sep 19, 2015 @ 06:31:44.000'); + expect(time.end).to.be('Sep 23, 2015 @ 18:31:44.000'); }); it('save query should show toast message and display query name', async function () { @@ -119,8 +116,7 @@ export default function ({ getService, getPageObjects }) { it('should show correct time range string in chart', async function () { const actualTimeString = await PageObjects.discover.getChartTimespan(); - - const expectedTimeString = `${fromTimeString} - ${toTimeString}`; + const expectedTimeString = `Sep 19, 2015 @ 06:31:44.000 - Sep 23, 2015 @ 18:31:44.000`; expect(actualTimeString).to.be(expectedTimeString); }); @@ -143,8 +139,9 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.waitForVisualization(); await PageObjects.discover.clickHistogramBar(0); await PageObjects.visualize.waitForVisualization(); - const actualTimeString = await PageObjects.header.getPrettyDuration(); - expect(actualTimeString).to.be('September 20th 2015, 00:00:00.000 to September 20th 2015, 03:00:00.000'); + const time = await PageObjects.timePicker.getTimeConfig(); + expect(time.start).to.be('Sep 20, 2015 @ 00:00:00.000'); + expect(time.end).to.be('Sep 20, 2015 @ 03:00:00.000'); }); it('should modify the time range when the histogram is brushed', async function () { @@ -152,8 +149,9 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.waitForVisualization(); await PageObjects.discover.brushHistogram(0, 1); await PageObjects.visualize.waitForVisualization(); - const actualTimeString = await PageObjects.header.getPrettyDuration(); - expect(actualTimeString).to.be('September 19th 2015, 23:59:02.606 to September 20th 2015, 02:56:40.744'); + const time = await PageObjects.timePicker.getTimeConfig(); + expect(time.start).to.be('Sep 19, 2015 @ 23:55:14.810'); + expect(time.end).to.be('Sep 20, 2015 @ 02:56:40.744'); }); it('should show correct initial chart interval of Auto', async function () { diff --git a/test/functional/page_objects/header_page.js b/test/functional/page_objects/header_page.js index f264d4a737ee9..b3dd6f17b45c3 100644 --- a/test/functional/page_objects/header_page.js +++ b/test/functional/page_objects/header_page.js @@ -110,15 +110,6 @@ export function HeaderPageProvider({ getService, getPageObjects }) { await testSubjects.find('kibanaChrome', defaultFindTimeout * 10); } - // replaced with timePicker.getTimeConfig - async getPrettyDuration() { - return await testSubjects.getVisibleText('globalTimepickerRange'); - } - - async isSharedTimefilterEnabled() { - return await find.existsByCssSelector('[shared-timefilter=true]'); - } - } return new HeaderPage(); diff --git a/test/functional/page_objects/time_picker.js b/test/functional/page_objects/time_picker.js index 22ed077e2fddc..359b422b45e51 100644 --- a/test/functional/page_objects/time_picker.js +++ b/test/functional/page_objects/time_picker.js @@ -85,10 +85,17 @@ export function TimePickerPageProvider({ getService, getPageObjects }) { } async showStartEndTimes() { - const isShowDatesButton = await testSubjects.exists('superDatePickerShowDatesButton'); - if (isShowDatesButton) { - await testSubjects.click('superDatePickerShowDatesButton'); - } + await retry.try(async () => { + const isShowDatesButton = await testSubjects.exists('superDatePickerShowDatesButton'); + if (isShowDatesButton) { + await testSubjects.click('superDatePickerShowDatesButton'); + } + + const endButtonExists = await testSubjects.exists('superDatePickerendDatePopoverButton'); + if (!endButtonExists) { + throw new Error('start/end date buttons are not showing'); + } + }); } async getRefreshConfig(keepQuickSelectOpen = false) { @@ -117,6 +124,25 @@ export function TimePickerPageProvider({ getService, getPageObjects }) { }; } + async getTimeConfigAsAbsoluteTimes() { + await this.showStartEndTimes(); + + // get to time + await testSubjects.click('superDatePickerendDatePopoverButton'); + await testSubjects.click('superDatePickerAbsoluteTab'); + const end = await testSubjects.getAttribute('superDatePickerAbsoluteDateInput', 'value'); + + // get from time + await testSubjects.click('superDatePickerstartDatePopoverButton'); + await testSubjects.click('superDatePickerAbsoluteTab'); + const start = await testSubjects.getAttribute('superDatePickerAbsoluteDateInput', 'value'); + + return { + start, + end + }; + } + async pauseAutoRefresh() { log.debug('pauseAutoRefresh'); const refreshConfig = await this.getRefreshConfig(true); From 74cccb18f41ad9b3ee6670eefa2a5fdae16670a0 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 23 Jan 2019 12:54:03 -0700 Subject: [PATCH 12/34] clean up typescript lint problems --- src/ui/public/query_bar/components/query_bar.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ui/public/query_bar/components/query_bar.tsx b/src/ui/public/query_bar/components/query_bar.tsx index 2297a0091130a..a19b9c507cea5 100644 --- a/src/ui/public/query_bar/components/query_bar.tsx +++ b/src/ui/public/query_bar/components/query_bar.tsx @@ -44,9 +44,11 @@ import { EuiFlexGroup, EuiFlexItem, EuiOutsideClickDetector, - EuiSuperDatePicker, } from '@elastic/eui'; +// @ts-ignore +import { EuiSuperDatePicker } from '@elastic/eui'; + import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; const KEY_CODES = { @@ -132,7 +134,7 @@ export class QueryBarUI extends Component { }; } - const nextState = { + const nextState: any = { currentProps: nextProps, }; if (nextQuery) { @@ -144,6 +146,8 @@ export class QueryBarUI extends Component { } return nextState; } + + // @ts-ignore private static defaultProps = { showDatePicker: false, from: 'now-15m', @@ -669,4 +673,5 @@ export class QueryBarUI extends Component { } } +// @ts-ignore export const QueryBar = injectI18n(QueryBarUI); From 8f2f82eeb9f994478af2a755045d15860204379c Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 23 Jan 2019 13:55:11 -0700 Subject: [PATCH 13/34] some functional test fixes --- src/ui/public/query_bar/components/query_bar.tsx | 10 +++++++++- .../apps/dashboard/_dashboard_time_picker.js | 2 +- test/functional/apps/discover/_discover.js | 2 +- test/functional/apps/management/_scripted_fields.js | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ui/public/query_bar/components/query_bar.tsx b/src/ui/public/query_bar/components/query_bar.tsx index a19b9c507cea5..debd90c9f3f51 100644 --- a/src/ui/public/query_bar/components/query_bar.tsx +++ b/src/ui/public/query_bar/components/query_bar.tsx @@ -78,7 +78,15 @@ interface DateRange { interface Props { query: Query; - onSubmit: ({ dateRange, query }: { dateRange: DateRange; query: Query }) => void; + onSubmit: ( + { + dateRange, + query, + }: { + dateRange: DateRange; + query: Query; + } + ) => void; disableAutoFocus?: boolean; appName: string; indexPatterns: IndexPattern[]; diff --git a/test/functional/apps/dashboard/_dashboard_time_picker.js b/test/functional/apps/dashboard/_dashboard_time_picker.js index 91d2f12eacf7d..77e6601f44d58 100644 --- a/test/functional/apps/dashboard/_dashboard_time_picker.js +++ b/test/functional/apps/dashboard/_dashboard_time_picker.js @@ -23,7 +23,7 @@ export default function ({ getService, getPageObjects }) { const dashboardExpect = getService('dashboardExpect'); const pieChart = getService('pieChart'); const dashboardVisualizations = getService('dashboardVisualizations'); - const PageObjects = getPageObjects(['dashboard', 'header', 'visualize']); + const PageObjects = getPageObjects(['dashboard', 'header', 'visualize', 'timePicker']); describe('dashboard time picker', function describeIndexTests() { before(async function () { diff --git a/test/functional/apps/discover/_discover.js b/test/functional/apps/discover/_discover.js index 5015932015a60..8f3e251debd37 100644 --- a/test/functional/apps/discover/_discover.js +++ b/test/functional/apps/discover/_discover.js @@ -150,7 +150,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.discover.brushHistogram(0, 1); await PageObjects.visualize.waitForVisualization(); const time = await PageObjects.timePicker.getTimeConfig(); - expect(time.start).to.be('Sep 19, 2015 @ 23:55:14.810'); + expect(time.start).to.be('Sep 19, 2015 @ 23:59:02.606'); expect(time.end).to.be('Sep 20, 2015 @ 02:56:40.744'); }); diff --git a/test/functional/apps/management/_scripted_fields.js b/test/functional/apps/management/_scripted_fields.js index de114baa9ef62..0ddd02653d270 100644 --- a/test/functional/apps/management/_scripted_fields.js +++ b/test/functional/apps/management/_scripted_fields.js @@ -106,7 +106,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.waitForVisualization(); await retry.try(async function () { const rowData = await PageObjects.discover.getDocTableIndex(1); - expect(rowData).to.be('September 18th 2015, 18:20:57.916\n18'); + expect(rowData).to.be('Sep 18, 2015 @ 18:20:57.916\n18'); }); }); From d9a6aa1141c52748ea55681c538b14cd692d70cc Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 23 Jan 2019 15:03:08 -0700 Subject: [PATCH 14/34] try something else to fix I18n problems --- src/ui/public/query_bar/components/query_bar.tsx | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/ui/public/query_bar/components/query_bar.tsx b/src/ui/public/query_bar/components/query_bar.tsx index debd90c9f3f51..66489901962e5 100644 --- a/src/ui/public/query_bar/components/query_bar.tsx +++ b/src/ui/public/query_bar/components/query_bar.tsx @@ -78,15 +78,7 @@ interface DateRange { interface Props { query: Query; - onSubmit: ( - { - dateRange, - query, - }: { - dateRange: DateRange; - query: Query; - } - ) => void; + onSubmit: (payload: { dateRange: DateRange; query: Query }) => void; disableAutoFocus?: boolean; appName: string; indexPatterns: IndexPattern[]; From 2e3a143c5c906c4ad90d618342ba15409d54230c Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 23 Jan 2019 15:47:31 -0700 Subject: [PATCH 15/34] fix some more functional tests --- test/functional/apps/discover/_field_data.js | 4 ++-- test/functional/apps/management/_scripted_fields.js | 6 +++--- test/functional/apps/visualize/_input_control_vis.js | 4 ++-- test/functional/apps/visualize/_tsvb_chart.js | 1 + 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/test/functional/apps/discover/_field_data.js b/test/functional/apps/discover/_field_data.js index 9023438e47dd6..08610295e0805 100644 --- a/test/functional/apps/discover/_field_data.js +++ b/test/functional/apps/discover/_field_data.js @@ -83,9 +83,9 @@ export default function ({ getService, getPageObjects }) { // Note: Could just check the timestamp, but might as well check that the whole doc is as expected. const ExpectedDoc = - 'September 20th 2015, 00:00:00.000\ntype:apache index:logstash-2015.09.20 @timestamp:September 20th 2015, 00:00:00.000' + 'Sep 20, 2015 @ 00:00:00.000\ntype:apache index:logstash-2015.09.20 @timestamp:Sep 20, 2015 @ 00:00:00.000' + ' ip:143.84.142.7 extension:jpg response:200 geo.coordinates:{ "lat": 38.68407028, "lon": -120.9871642 }' - + ' geo.src:ES geo.dest:US geo.srcdest:ES:US @tags:error, info utc_time:September 20th 2015, 00:00:00.000' + + ' geo.src:ES geo.dest:US geo.srcdest:ES:US @tags:error, info utc_time:Sep 20, 2015 @ 00:00:00.000' + ' referer:http://www.slate.com/success/vladimir-kovalyonok agent:Mozilla/4.0 (compatible; MSIE 6.0;' + ' Windows NT 5.1; SV1; .NET CLR 1.1.4322) clientip:143.84.142.7 bytes:1,623' + ' host:media-for-the-masses.theacademyofperformingartsandscience.org request:/uploads/steven-hawley.jpg' diff --git a/test/functional/apps/management/_scripted_fields.js b/test/functional/apps/management/_scripted_fields.js index 0ddd02653d270..0d10ba1397036 100644 --- a/test/functional/apps/management/_scripted_fields.js +++ b/test/functional/apps/management/_scripted_fields.js @@ -167,7 +167,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.waitForVisualization(); await retry.try(async function () { const rowData = await PageObjects.discover.getDocTableIndex(1); - expect(rowData).to.be('September 18th 2015, 18:20:57.916\ngood'); + expect(rowData).to.be('Sep 18, 2015 @ 18:20:57.916\ngood'); }); }); @@ -227,7 +227,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.waitForVisualization(); await retry.try(async function () { const rowData = await PageObjects.discover.getDocTableIndex(1); - expect(rowData).to.be('September 18th 2015, 18:20:57.916\ntrue'); + expect(rowData).to.be('Sep 18, 2015 @ 18:20:57.916\ntrue'); }); }); @@ -288,7 +288,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.waitForVisualization(); await retry.try(async function () { const rowData = await PageObjects.discover.getDocTableIndex(1); - expect(rowData).to.be('September 18th 2015, 06:52:55.953\n2015-09-18 07:00'); + expect(rowData).to.be('Sep 18, 2015 @ 06:52:55.953\n2015-09-18 07:00'); }); }); diff --git a/test/functional/apps/visualize/_input_control_vis.js b/test/functional/apps/visualize/_input_control_vis.js index 3c4fe7270fc16..45e5a74fc1e48 100644 --- a/test/functional/apps/visualize/_input_control_vis.js +++ b/test/functional/apps/visualize/_input_control_vis.js @@ -35,7 +35,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickInputControlVis(); // set time range to time with no documents - input controls do not use time filter be default - await PageObjects.timePicker.setAbsoluteRange('2017-01-01', '2017-01-02'); + await PageObjects.timePicker.setAbsoluteRange('2017-01-01 00:00:00.000', '2017-01-02 00:00:00.000'); await PageObjects.visualize.clickVisEditorTab('controls'); await PageObjects.visualize.addInputControl(); await comboBox.set('indexPatternSelect-0', 'logstash- '); @@ -168,7 +168,7 @@ export default function ({ getService, getPageObjects }) { }); it('should re-create control when global time filter is updated', async () => { - await PageObjects.timePicker.setAbsoluteRange('2015-01-01', '2016-01-01'); + await PageObjects.timePicker.setAbsoluteRange('2015-01-01 00:00:00.000', '2016-01-01 00:00:00.000'); // Expect control to have values for selected time filter const menu = await comboBox.getOptionsList('listControlSelect0'); diff --git a/test/functional/apps/visualize/_tsvb_chart.js b/test/functional/apps/visualize/_tsvb_chart.js index 40b67c8f28438..993059d8c7a98 100644 --- a/test/functional/apps/visualize/_tsvb_chart.js +++ b/test/functional/apps/visualize/_tsvb_chart.js @@ -34,6 +34,7 @@ export default function ({ getService, getPageObjects }) { }); it('should show the correct count in the legend', async function () { + await PageObjects.header.waitUntilLoadingHasFinished(); const actualCount = await PageObjects.visualBuilder.getRhythmChartLegendValue(); expect(actualCount).to.be('156'); }); From d9969a9ad98b3b3f624c5949206e5b66cbefd256 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 23 Jan 2019 15:56:45 -0700 Subject: [PATCH 16/34] update query_bar jest test --- .../query_bar/components/query_bar.test.tsx | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/ui/public/query_bar/components/query_bar.test.tsx b/src/ui/public/query_bar/components/query_bar.test.tsx index 363464a5ca96e..8df14e4cf3210 100644 --- a/src/ui/public/query_bar/components/query_bar.test.tsx +++ b/src/ui/public/query_bar/components/query_bar.test.tsx @@ -207,8 +207,14 @@ describe('QueryBar', () => { component.find(QueryLanguageSwitcher).simulate('selectLanguage', 'lucene'); expect(mockStorage.set).toHaveBeenCalledWith('kibana.userQueryLanguage', 'lucene'); expect(mockCallback).toHaveBeenCalledWith({ - query: '', - language: 'lucene', + dateRange: { + from: 'now-15m', + to: 'now', + }, + query: { + query: '', + language: 'lucene', + }, }); }); @@ -235,8 +241,14 @@ describe('QueryBar', () => { expect(mockCallback).toHaveBeenCalledTimes(1); expect(mockCallback).toHaveBeenCalledWith({ - query: 'extension:jpg', - language: 'kuery', + dateRange: { + from: 'now-15m', + to: 'now', + }, + query: { + query: 'extension:jpg', + language: 'kuery', + }, }); }); From a2d875afa73073183f8e9722c013a9f05add928e Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 23 Jan 2019 16:58:01 -0700 Subject: [PATCH 17/34] remove unused method in kbn_global_timepicker --- src/ui/public/timepicker/kbn_global_timepicker.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/ui/public/timepicker/kbn_global_timepicker.js b/src/ui/public/timepicker/kbn_global_timepicker.js index 759746849cd07..2ff0e8b1c8f54 100644 --- a/src/ui/public/timepicker/kbn_global_timepicker.js +++ b/src/ui/public/timepicker/kbn_global_timepicker.js @@ -80,10 +80,6 @@ uiModules $scope.dateFormat = dateFormat ? dateFormat : config.get('dateFormat'); }); - $scope.toggleRefresh = () => { - timefilter.toggleRefresh(); - }; - $scope.updateFilter = function ({ start, end }) { timefilter.setTime({ from: start, to: end }); }; From 7f2f50489c10d8afb9ec7fd7c17498c65fb4762f Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 31 Jan 2019 08:03:12 -0700 Subject: [PATCH 18/34] do not import removed timepicker styles --- src/ui/public/styles/bootstrap_dark.less | 1 - src/ui/public/styles/bootstrap_light.less | 1 - 2 files changed, 2 deletions(-) diff --git a/src/ui/public/styles/bootstrap_dark.less b/src/ui/public/styles/bootstrap_dark.less index 51273dcc0e83b..5c745fcc3249a 100644 --- a/src/ui/public/styles/bootstrap_dark.less +++ b/src/ui/public/styles/bootstrap_dark.less @@ -5,4 +5,3 @@ // Components -- waiting on EUI conversion @import "~ui/filter_bar/filter_bar"; -@import "~ui/timepicker/timepicker"; diff --git a/src/ui/public/styles/bootstrap_light.less b/src/ui/public/styles/bootstrap_light.less index 9c15f6c0d5646..b251875489fb5 100644 --- a/src/ui/public/styles/bootstrap_light.less +++ b/src/ui/public/styles/bootstrap_light.less @@ -5,4 +5,3 @@ // Components -- waiting on EUI conversion @import "~ui/filter_bar/filter_bar"; -@import "~ui/timepicker/timepicker"; From c832caaeeaf958d463cecf68321f9f835d745179 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 31 Jan 2019 12:58:26 -0700 Subject: [PATCH 19/34] remove mode from time state --- src/legacy/core_plugins/kibana/ui_setting_defaults.js | 1 - src/ui/public/timefilter/timefilter.js | 2 -- test/functional/apps/discover/_shared_links.js | 4 ++-- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/legacy/core_plugins/kibana/ui_setting_defaults.js b/src/legacy/core_plugins/kibana/ui_setting_defaults.js index 7b55619681388..84016663f5269 100644 --- a/src/legacy/core_plugins/kibana/ui_setting_defaults.js +++ b/src/legacy/core_plugins/kibana/ui_setting_defaults.js @@ -751,7 +751,6 @@ export function getUiSettingDefaults() { `{ "from": "now-15m", "to": "now", - "mode": "quick" }`, type: 'json', description: i18n.translate('kbn.advancedSettings.timepicker.timeDefaultsText', { diff --git a/src/ui/public/timefilter/timefilter.js b/src/ui/public/timefilter/timefilter.js index 8f2bbd799efa4..f2d2f4dea5c6b 100644 --- a/src/ui/public/timefilter/timefilter.js +++ b/src/ui/public/timefilter/timefilter.js @@ -51,7 +51,6 @@ class Timefilter extends SimpleEmitter { * @param {Object} time * @property {string|moment} time.from * @property {string|moment} time.to - * @property {string} time.mode (quick | relative | absolute) */ setTime = (time) => { // Object.assign used for partially composed updates @@ -60,7 +59,6 @@ class Timefilter extends SimpleEmitter { this._time = { from: newTime.from, to: newTime.to, - mode: newTime.mode }; timeHistory.add(this._time); this.emit('timeUpdate'); diff --git a/test/functional/apps/discover/_shared_links.js b/test/functional/apps/discover/_shared_links.js index 85d8941d19eb9..933f11246fae3 100644 --- a/test/functional/apps/discover/_shared_links.js +++ b/test/functional/apps/discover/_shared_links.js @@ -69,7 +69,7 @@ export default function ({ getService, getPageObjects }) { baseUrl + '/app/kibana?_t=1453775307251#' + '/discover?_g=(refreshInterval:(pause:!t,value:0),time' + - ':(from:\'2015-09-19T06:31:44.000Z\',mode:absolute,to:\'2015-09' + + ':(from:\'2015-09-19T06:31:44.000Z\',to:\'2015-09' + '-23T18:31:44.000Z\'))&_a=(columns:!(_source),index:\'logstash-' + '*\',interval:auto,query:(language:lucene,query:\'\')' + ',sort:!(\'@timestamp\',desc))'; @@ -96,7 +96,7 @@ export default function ({ getService, getPageObjects }) { '/discover/ab12e3c0-f231-11e6-9486-733b1ac9221a' + '?_g=(refreshInterval%3A(pause%3A!t%2Cvalue%3A0)' + '%2Ctime%3A(from%3A\'2015-09-19T06%3A31%3A44.000Z\'%2C' + - 'mode%3Aabsolute%2Cto%3A\'2015-09-23T18%3A31%3A44.000Z\'))'; + 'to%3A\'2015-09-23T18%3A31%3A44.000Z\'))'; await PageObjects.discover.loadSavedSearch('A Saved Search'); await PageObjects.share.clickShareTopNavButton(); await PageObjects.share.exportAsSavedObject(); From 7bcf565f3f8dc1076be7a23920ec932806bc5b99 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 31 Jan 2019 12:59:06 -0700 Subject: [PATCH 20/34] remove mode from time_history interface --- src/ui/public/timefilter/time_history.d.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ui/public/timefilter/time_history.d.ts b/src/ui/public/timefilter/time_history.d.ts index 4a7331dbb8c58..bc13fb06d03b1 100644 --- a/src/ui/public/timefilter/time_history.d.ts +++ b/src/ui/public/timefilter/time_history.d.ts @@ -20,7 +20,6 @@ interface TimeRange { from: string; to: string; - mode?: string; } export interface TimeHistory { From 76e8c1cd20650624a0aacf990ef3cc3dfe8fde02 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 31 Jan 2019 13:06:27 -0700 Subject: [PATCH 21/34] fix problem with ui_settings_defaults --- src/legacy/core_plugins/kibana/ui_setting_defaults.js | 2 +- test/functional/apps/visualize/_pie_chart.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/legacy/core_plugins/kibana/ui_setting_defaults.js b/src/legacy/core_plugins/kibana/ui_setting_defaults.js index 84016663f5269..e7d8739e6f032 100644 --- a/src/legacy/core_plugins/kibana/ui_setting_defaults.js +++ b/src/legacy/core_plugins/kibana/ui_setting_defaults.js @@ -750,7 +750,7 @@ export function getUiSettingDefaults() { value: `{ "from": "now-15m", - "to": "now", + "to": "now" }`, type: 'json', description: i18n.translate('kbn.advancedSettings.timepicker.timeDefaultsText', { diff --git a/test/functional/apps/visualize/_pie_chart.js b/test/functional/apps/visualize/_pie_chart.js index a38dbdaa94f7f..853cabef206f4 100644 --- a/test/functional/apps/visualize/_pie_chart.js +++ b/test/functional/apps/visualize/_pie_chart.js @@ -217,7 +217,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); log.debug('select bucket Split Slices'); await PageObjects.visualize.clickBucket('Split Slices'); log.debug('Click aggregation Histogram'); From 5d9976f66e49277a9225f988c359e4b764aa5afe Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 31 Jan 2019 13:40:59 -0700 Subject: [PATCH 22/34] fix failing TSVB functional test --- test/functional/services/combo_box.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/test/functional/services/combo_box.js b/test/functional/services/combo_box.js index a4f7c0e97709c..e3fda8863f014 100644 --- a/test/functional/services/combo_box.js +++ b/test/functional/services/combo_box.js @@ -35,6 +35,7 @@ export function ComboBoxProvider({ getService }) { async setElement(comboBoxElement, value) { log.debug(`comboBox.setElement, value: ${value}`); await this._filterOptionsList(comboBoxElement, value); + await this.openOptionsList(comboBoxElement); await find.clickByCssSelector('.euiComboBoxOption'); await this.closeOptionsList(comboBoxElement); } @@ -49,6 +50,7 @@ export function ComboBoxProvider({ getService }) { async _filterOptionsList(comboBoxElement, filterValue) { const input = await comboBoxElement.findByTagName('input'); await input.clearValue(); + await this._waitForOptionsListLoading(comboBoxElement); await input.type(filterValue); await this._waitForOptionsListLoading(comboBoxElement); } @@ -119,8 +121,16 @@ export function ComboBoxProvider({ getService }) { async closeOptionsList(comboBoxElement) { const isOptionsListOpen = await testSubjects.exists('comboBoxOptionsList'); if (isOptionsListOpen) { - const closeBtn = await comboBoxElement.findByCssSelector('[data-test-subj="comboBoxToggleListButton"]'); - await closeBtn.click(); + const toggleBtn = await comboBoxElement.findByCssSelector('[data-test-subj="comboBoxToggleListButton"]'); + await toggleBtn.click(); + } + } + + async openOptionsList(comboBoxElement) { + const isOptionsListOpen = await testSubjects.exists('comboBoxOptionsList'); + if (!isOptionsListOpen) { + const toggleBtn = await comboBoxElement.findByCssSelector('[data-test-subj="comboBoxToggleListButton"]'); + await toggleBtn.click(); } } From c0210451350123d839ec768f2973eca2a12c5b27 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 31 Jan 2019 15:48:59 -0700 Subject: [PATCH 23/34] another round to test fixes --- .../lib/__tests__/change_time_filter.test.js | 8 +++----- src/ui/public/timefilter/timefilter.test.js | 12 +++++------- src/ui/public/timepicker/kbn_global_timepicker.html | 2 +- src/ui/public/utils/__tests__/brush_event.test.js | 5 ++--- .../test/functional/apps/monitoring/cluster/list.js | 4 ++-- 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/ui/public/filter_bar/lib/__tests__/change_time_filter.test.js b/src/ui/public/filter_bar/lib/__tests__/change_time_filter.test.js index 6f02c06aea5b1..b9916c1f08a06 100644 --- a/src/ui/public/filter_bar/lib/__tests__/change_time_filter.test.js +++ b/src/ui/public/filter_bar/lib/__tests__/change_time_filter.test.js @@ -25,7 +25,7 @@ jest.mock('ui/chrome', get: (key) => { switch(key) { case 'timepicker:timeDefaults': - return { from: 'now-15m', to: 'now', mode: 'quick' }; + return { from: 'now-15m', to: 'now' }; case 'timepicker:refreshIntervalDefaults': return { display: 'Off', pause: false, value: 0 }; default: @@ -47,8 +47,7 @@ describe('changeTimeFilter()', function () { test('should change the timefilter to match the range gt/lt', function () { const filter = { range: { '@timestamp': { gt, lt } } }; changeTimeFilter(filter); - const { mode, to, from } = timefilter.getTime(); - expect(mode).to.be('absolute'); + const { to, from } = timefilter.getTime(); expect(to).to.be(new Date(lt).toISOString()); expect(from).to.be(new Date(gt).toISOString()); }); @@ -56,8 +55,7 @@ describe('changeTimeFilter()', function () { test('should change the timefilter to match the range gte/lte', function () { const filter = { range: { '@timestamp': { gte: gt, lte: lt } } }; changeTimeFilter(filter); - const { mode, to, from } = timefilter.getTime(); - expect(mode).to.be('absolute'); + const { to, from } = timefilter.getTime(); expect(to).to.be(new Date(lt).toISOString()); expect(from).to.be(new Date(gt).toISOString()); }); diff --git a/src/ui/public/timefilter/timefilter.test.js b/src/ui/public/timefilter/timefilter.test.js index f35f5addaa250..eb07711126e48 100644 --- a/src/ui/public/timefilter/timefilter.test.js +++ b/src/ui/public/timefilter/timefilter.test.js @@ -25,7 +25,7 @@ jest.mock('ui/chrome', get: (key) => { switch (key) { case 'timepicker:timeDefaults': - return { from: 'now-15m', to: 'now', mode: 'quick' }; + return { from: 'now-15m', to: 'now' }; case 'timepicker:refreshIntervalDefaults': return { pause: false, value: 0 }; default: @@ -69,15 +69,14 @@ describe('setTime', () => { timefilter.setTime({ from: 0, to: 1, - mode: 'absolute' }); timefilter.on('timeUpdate', update); timefilter.on('fetch', fetch); }); test('should update time', () => { - timefilter.setTime({ from: 5, to: 10, mode: 'absolute' }); - expect(timefilter.getTime()).to.eql({ from: 5, to: 10, mode: 'absolute' }); + timefilter.setTime({ from: 5, to: 10 }); + expect(timefilter.getTime()).to.eql({ from: 5, to: 10 }); }); test('should not add unexpected object keys to time state', () => { @@ -88,7 +87,7 @@ describe('setTime', () => { test('should allow partial updates to time', () => { timefilter.setTime({ from: 5, to: 10 }); - expect(timefilter.getTime()).to.eql({ from: 5, to: 10, mode: 'absolute' }); + expect(timefilter.getTime()).to.eql({ from: 5, to: 10 }); }); test('not emit anything if the time has not changed', () => { @@ -106,11 +105,10 @@ describe('setTime', () => { test('should return strings and not moment objects', () => { const from = moment().subtract(15, 'minutes'); const to = moment(); - timefilter.setTime({ to, from, mode: 'absolute' }); + timefilter.setTime({ to, from }); expect(timefilter.getTime()).to.eql({ from: from.toISOString(), to: to.toISOString(), - mode: 'absolute' }); }); }); diff --git a/src/ui/public/timepicker/kbn_global_timepicker.html b/src/ui/public/timepicker/kbn_global_timepicker.html index 8edf05a343793..8ef4dcfe1c960 100644 --- a/src/ui/public/timepicker/kbn_global_timepicker.html +++ b/src/ui/public/timepicker/kbn_global_timepicker.html @@ -1,5 +1,5 @@
{ switch (key) { case 'timepicker:timeDefaults': - return { from: 'now-15m', to: 'now', mode: 'quick' }; + return { from: 'now-15m', to: 'now' }; case 'timepicker:refreshIntervalDefaults': return { display: 'Off', pause: false, value: 0 }; default: @@ -126,8 +126,7 @@ describe('brushEvent', () => { const event = _.cloneDeep(dateEvent); event.range = [JAN_01_2014, JAN_01_2014 + DAY_IN_MS]; onBrushEvent(event, $state); - const { mode, from, to } = timefilter.getTime(); - expect(mode).to.be('absolute'); + const { from, to } = timefilter.getTime(); // Set to a baseline timezone for comparison. expect(from).to.be(new Date(JAN_01_2014).toISOString()); // Set to a baseline timezone for comparison. diff --git a/x-pack/test/functional/apps/monitoring/cluster/list.js b/x-pack/test/functional/apps/monitoring/cluster/list.js index 0be843c6c86c6..eae7882a2748c 100644 --- a/x-pack/test/functional/apps/monitoring/cluster/list.js +++ b/x-pack/test/functional/apps/monitoring/cluster/list.js @@ -21,8 +21,8 @@ export default function ({ getService, getPageObjects }) { before(async () => { await setup('monitoring/multicluster', { - from: '2017-08-15 21:00:00', - to: '2017-08-16 00:00:00', + from: '2017-08-15 21:00:00.000', + to: '2017-08-16 00:00:00.000', }); await clusterList.assertDefaults(); From c7be764adc51dfa6f19f7d1e232ef274c187280c Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 1 Feb 2019 10:32:59 -0700 Subject: [PATCH 24/34] more functional test changes --- src/ui/public/agg_table/__tests__/_table.js | 12 ++++++------ test/functional/apps/visualize/_tsvb_chart.js | 8 +++++--- .../functional/apps/monitoring/beats/beat_detail.js | 4 ++-- .../test/functional/apps/monitoring/beats/cluster.js | 4 ++-- .../test/functional/apps/monitoring/beats/listing.js | 4 ++-- .../functional/apps/monitoring/beats/overview.js | 4 ++-- .../apps/monitoring/elasticsearch/shards.js | 4 ++-- 7 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/ui/public/agg_table/__tests__/_table.js b/src/ui/public/agg_table/__tests__/_table.js index c89cd090614a0..299da94902143 100644 --- a/src/ui/public/agg_table/__tests__/_table.js +++ b/src/ui/public/agg_table/__tests__/_table.js @@ -194,10 +194,10 @@ describe('AggTable Directive', function () { $scope.table = response.tables[0]; $scope.showTotal = true; $scope.totalFunc = totalFunc; - const $el = $(``); $compile($el)($scope); $scope.$digest(); @@ -224,7 +224,7 @@ describe('AggTable Directive', function () { '', '2014-09-28', '9,283', - 'September 28th 2014, 00:00:00.000', + 'Sep 28, 2014 @ 00:00:00.000', '1', '11' ]); @@ -234,7 +234,7 @@ describe('AggTable Directive', function () { '', '2014-10-03', '220,943', - 'October 3rd 2014, 00:00:00.000', + 'Oct 3, 2014 @ 00:00:00.000', '239', '837' ]); diff --git a/test/functional/apps/visualize/_tsvb_chart.js b/test/functional/apps/visualize/_tsvb_chart.js index 3d82f24c268f4..f1cb0236798d1 100644 --- a/test/functional/apps/visualize/_tsvb_chart.js +++ b/test/functional/apps/visualize/_tsvb_chart.js @@ -36,9 +36,11 @@ export default function ({ getService, getPageObjects }) { }); it('should show the correct count in the legend', async function () { - await PageObjects.header.waitUntilLoadingHasFinished(); - const actualCount = await PageObjects.visualBuilder.getRhythmChartLegendValue(); - expect(actualCount).to.be('156'); + await retry.try(async () => { + await PageObjects.header.waitUntilLoadingHasFinished(); + const actualCount = await PageObjects.visualBuilder.getRhythmChartLegendValue(); + expect(actualCount).to.be('156'); + }); }); it('should show the correct count in the legend with 2h offset', async function () { diff --git a/x-pack/test/functional/apps/monitoring/beats/beat_detail.js b/x-pack/test/functional/apps/monitoring/beats/beat_detail.js index 2eab9f6354836..5ca033549f937 100644 --- a/x-pack/test/functional/apps/monitoring/beats/beat_detail.js +++ b/x-pack/test/functional/apps/monitoring/beats/beat_detail.js @@ -17,8 +17,8 @@ export default function ({ getService, getPageObjects }) { before(async () => { await setup('monitoring/beats', { - from: '2017-12-19 17:14:09', - to: '2017-12-19 18:15:09', + from: '2017-12-19 17:14:09.000', + to: '2017-12-19 18:15:09.000', }); // go to beats detail diff --git a/x-pack/test/functional/apps/monitoring/beats/cluster.js b/x-pack/test/functional/apps/monitoring/beats/cluster.js index 90482b432ca0d..949feef987851 100644 --- a/x-pack/test/functional/apps/monitoring/beats/cluster.js +++ b/x-pack/test/functional/apps/monitoring/beats/cluster.js @@ -15,8 +15,8 @@ export default function ({ getService, getPageObjects }) { before(async () => { await setup('monitoring/beats', { - from: '2017-12-19 17:14:09', - to: '2017-12-19 18:15:09', + from: '2017-12-19 17:14:09.000', + to: '2017-12-19 18:15:09.000', }); }); diff --git a/x-pack/test/functional/apps/monitoring/beats/listing.js b/x-pack/test/functional/apps/monitoring/beats/listing.js index f9f4a20f5ebc0..0a0148aee69c6 100644 --- a/x-pack/test/functional/apps/monitoring/beats/listing.js +++ b/x-pack/test/functional/apps/monitoring/beats/listing.js @@ -17,8 +17,8 @@ export default function ({ getService, getPageObjects }) { before(async () => { await setup('monitoring/beats', { - from: '2017-12-19 17:14:09', - to: '2017-12-19 18:15:09', + from: '2017-12-19 17:14:09.000', + to: '2017-12-19 18:15:09.000', }); // go to beats listing diff --git a/x-pack/test/functional/apps/monitoring/beats/overview.js b/x-pack/test/functional/apps/monitoring/beats/overview.js index f24c9e4270947..049ffc963c4f9 100644 --- a/x-pack/test/functional/apps/monitoring/beats/overview.js +++ b/x-pack/test/functional/apps/monitoring/beats/overview.js @@ -17,8 +17,8 @@ export default function ({ getService, getPageObjects }) { before(async () => { await setup('monitoring/beats', { - from: '2017-12-19 17:14:09', - to: '2017-12-19 18:15:09', + from: '2017-12-19 17:14:09.000', + to: '2017-12-19 18:15:09.000', }); // go to beats overview diff --git a/x-pack/test/functional/apps/monitoring/elasticsearch/shards.js b/x-pack/test/functional/apps/monitoring/elasticsearch/shards.js index 2a5819d10ea99..5a6d6c8aa5478 100644 --- a/x-pack/test/functional/apps/monitoring/elasticsearch/shards.js +++ b/x-pack/test/functional/apps/monitoring/elasticsearch/shards.js @@ -19,8 +19,8 @@ export default function ({ getService, getPageObjects }) { before(async () => { await setup('monitoring/singlecluster-three-nodes-shard-relocation', { - from: '2017-10-05 19:34:48', - to: '2017-10-05 20:35:12', + from: '2017-10-05 19:34:48.000', + to: '2017-10-05 20:35:12.000', }); }); From 5dab392b8499c22cbce436c57fb0fa0e330883aa Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 1 Feb 2019 11:53:02 -0700 Subject: [PATCH 25/34] fixes for failing tests --- src/ui/public/documentation_links/index.d.ts | 20 ---- src/ui/public/filters/__tests__/moment.js | 4 +- src/ui/public/timepicker/__tests__/toggle.js | 101 ------------------ .../apps/monitoring/logstash/pipelines.js | 4 +- 4 files changed, 4 insertions(+), 125 deletions(-) delete mode 100644 src/ui/public/documentation_links/index.d.ts delete mode 100644 src/ui/public/timepicker/__tests__/toggle.js diff --git a/src/ui/public/documentation_links/index.d.ts b/src/ui/public/documentation_links/index.d.ts deleted file mode 100644 index b37021b497de3..0000000000000 --- a/src/ui/public/documentation_links/index.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export function getDocLink(id: string): string; diff --git a/src/ui/public/filters/__tests__/moment.js b/src/ui/public/filters/__tests__/moment.js index ffc404630c4ca..e3550df031ee7 100644 --- a/src/ui/public/filters/__tests__/moment.js +++ b/src/ui/public/filters/__tests__/moment.js @@ -57,11 +57,11 @@ describe('moment formatting filter', function () { // MMMM Do YYYY, HH:mm:ss.SSS it('should format moments', function () { - expect(filter(moment())).to.be('January 1st 2014, 06:06:06.666'); + expect(filter(moment())).to.be('Jan 1, 2014 @ 06:06:06.666'); }); it('should format dates', function () { - expect(filter(new Date())).to.be('January 1st 2014, 06:06:06.666'); + expect(filter(new Date())).to.be('Jan 1, 2014 @ 06:06:06.666'); }); it('should return the original value if passed anything other than a moment or Date', function () { diff --git a/src/ui/public/timepicker/__tests__/toggle.js b/src/ui/public/timepicker/__tests__/toggle.js deleted file mode 100644 index 57684bcc3c8e5..0000000000000 --- a/src/ui/public/timepicker/__tests__/toggle.js +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from 'expect.js'; -import ngMock from 'ng_mock'; -import $ from 'jquery'; -import { timefilter } from 'ui/timefilter'; - -describe('kbnGlobalTimepicker', function () { - let compile; - let scope; - - beforeEach(() => { - ngMock.module('kibana'); - ngMock.inject(($compile, $rootScope) => { - scope = $rootScope.$new(); - compile = () => { - const $el = $(''); - $el.data('$kbnTopNavController', {}); // Mock the kbnTopNav - $compile($el)(scope); - scope.$apply(); - return $el; - }; - }); - }); - - it('injects the timepicker into the DOM', () => { - const $el = compile(); - expect($el.attr('data-test-subj')).to.be('globalTimepicker'); - }); - - it('sets data-shared-timefilter-* using the timefilter when auto-refresh selector is enabled', function () { - const minString = '2000-01-01T00:00:00Z'; - const maxString = '2001-01-01T00:00:00Z'; - - timefilter.enableAutoRefreshSelector(); - timefilter.disableTimeRangeSelector(); - timefilter.setTime({ - from: minString, - to: maxString, - mode: 'absolute' - }); - - const $el = compile(); - - expect($el.attr('data-shared-timefilter-from')).to.eql(minString); - expect($el.attr('data-shared-timefilter-to')).to.eql(maxString); - }); - - it('sets data-shared-timefilter-* using the timefilter when time range selector is enabled', function () { - const minString = '2000-01-01T00:00:00Z'; - const maxString = '2001-01-01T00:00:00Z'; - - timefilter.disableAutoRefreshSelector(); - timefilter.enableTimeRangeSelector(); - timefilter.setTime({ - from: minString, - to: maxString, - mode: 'absolute' - }); - - const $el = compile(); - - expect($el.attr('data-shared-timefilter-from')).to.eql(minString); - expect($el.attr('data-shared-timefilter-to')).to.eql(maxString); - }); - - it(`doesn't set data-shared-timefilter-* when auto-refresh and time range selectors are both disabled`, function () { - const minString = '2000-01-01T00:00:00Z'; - const maxString = '2001-01-01T00:00:00Z'; - - timefilter.disableAutoRefreshSelector(); - timefilter.disableTimeRangeSelector(); - timefilter.setTime({ - from: minString, - to: maxString, - mode: 'absolute' - }); - - const $el = compile(); - - expect($el.attr('data-shared-timefilter-from')).to.eql(''); - expect($el.attr('data-shared-timefilter-to')).to.eql(''); - }); -}); diff --git a/x-pack/test/functional/apps/monitoring/logstash/pipelines.js b/x-pack/test/functional/apps/monitoring/logstash/pipelines.js index 0bca058467fa2..613a3d87efe7c 100644 --- a/x-pack/test/functional/apps/monitoring/logstash/pipelines.js +++ b/x-pack/test/functional/apps/monitoring/logstash/pipelines.js @@ -17,8 +17,8 @@ export default function ({ getService, getPageObjects }) { before(async () => { await setup('monitoring/logstash-pipelines', { - from: '2018-01-22 9:10:00.000', - to: '2018-01-22 9:41:00.000', + from: '2018-01-22 09:10:00.000', + to: '2018-01-22 09:41:00.000', }); // go to pipelines listing From 73e8c7eb861a61e14e73d115b2fb0fb602e0ce11 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 1 Feb 2019 12:46:14 -0700 Subject: [PATCH 26/34] add retry block to flaky tsvb test --- test/functional/apps/visualize/_tsvb_chart.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/functional/apps/visualize/_tsvb_chart.js b/test/functional/apps/visualize/_tsvb_chart.js index f1cb0236798d1..5fade50d54774 100644 --- a/test/functional/apps/visualize/_tsvb_chart.js +++ b/test/functional/apps/visualize/_tsvb_chart.js @@ -156,9 +156,11 @@ export default function ({ getService, getPageObjects }) { }); it('should allow printing raw timestamp of data', async () => { - await PageObjects.visualBuilder.enterMarkdown('{{ count.data.raw.[0].[0] }}'); - const text = await PageObjects.visualBuilder.getMarkdownText(); - expect(text).to.be('1442901600000'); + await retry.try(async () => { + await PageObjects.visualBuilder.enterMarkdown('{{ count.data.raw.[0].[0] }}'); + const text = await PageObjects.visualBuilder.getMarkdownText(); + expect(text).to.be('1442901600000'); + }); }); it('should allow printing raw value of data', async () => { From 6b373f4d1460e999432af8a09c76e96d8868e66a Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 5 Feb 2019 13:52:44 -0700 Subject: [PATCH 27/34] styles/bootstrap_dark.less --- src/ui/public/styles/bootstrap_dark.less | 3 --- x-pack/plugins/maps/public/shared/layers/vector_layer.js | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ui/public/styles/bootstrap_dark.less b/src/ui/public/styles/bootstrap_dark.less index 5c745fcc3249a..a0079df56a4e2 100644 --- a/src/ui/public/styles/bootstrap_dark.less +++ b/src/ui/public/styles/bootstrap_dark.less @@ -2,6 +2,3 @@ // COMPILER FOR BOOTSTRAP @import "~ui/styles/bootstrap/bootstrap_dark"; - -// Components -- waiting on EUI conversion -@import "~ui/filter_bar/filter_bar"; diff --git a/x-pack/plugins/maps/public/shared/layers/vector_layer.js b/x-pack/plugins/maps/public/shared/layers/vector_layer.js index 59ae867b43ced..f8f019956f6a1 100644 --- a/x-pack/plugins/maps/public/shared/layers/vector_layer.js +++ b/x-pack/plugins/maps/public/shared/layers/vector_layer.js @@ -68,7 +68,7 @@ export class VectorLayer extends AbstractLayer { } isJoinable() { - return !this._source.isFilterByMapBounds(); + return true; } getJoins() { From 368cccc71c6c1ada4e9b5eff0b1dc2ca8e1f3d82 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 5 Feb 2019 14:43:22 -0700 Subject: [PATCH 28/34] fix functional tests --- test/functional/apps/discover/_discover.js | 1 + test/functional/apps/visualize/_data_table.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/discover/_discover.js b/test/functional/apps/discover/_discover.js index 83e5ecb937fcf..009914b777e25 100644 --- a/test/functional/apps/discover/_discover.js +++ b/test/functional/apps/discover/_discover.js @@ -170,6 +170,7 @@ export default function ({ getService, getPageObjects }) { }); it('should show correct data for chart interval Hourly', async function () { + await PageObjects.header.awaitGlobalLoadingIndicatorHidden(); await PageObjects.discover.setChartInterval('Hourly'); const expectedBarChartData = [ diff --git a/test/functional/apps/visualize/_data_table.js b/test/functional/apps/visualize/_data_table.js index e1e6dd9473d25..f2f8b06e5a418 100644 --- a/test/functional/apps/visualize/_data_table.js +++ b/test/functional/apps/visualize/_data_table.js @@ -191,7 +191,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.header.setAbsoluteRange(fromTime, toTime); + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualize.clickBucket('Split Rows'); await PageObjects.visualize.selectAggregation('Range'); await PageObjects.visualize.selectField('bytes'); From 1838d74f342d00ba51594530366c21cd08656e5d Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 5 Feb 2019 15:27:38 -0700 Subject: [PATCH 29/34] call fetch event even when times are the same --- src/ui/public/timefilter/timefilter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/public/timefilter/timefilter.js b/src/ui/public/timefilter/timefilter.js index f2d2f4dea5c6b..f211ee66dcabf 100644 --- a/src/ui/public/timefilter/timefilter.js +++ b/src/ui/public/timefilter/timefilter.js @@ -62,8 +62,8 @@ class Timefilter extends SimpleEmitter { }; timeHistory.add(this._time); this.emit('timeUpdate'); - this.emit('fetch'); } + this.emit('fetch'); } getRefreshInterval = () => { From 02c4f620822614777b96eec6164c2a403ed788f2 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 5 Feb 2019 15:33:06 -0700 Subject: [PATCH 30/34] add retry around flaky tsvb test --- test/functional/apps/visualize/_tsvb_chart.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/functional/apps/visualize/_tsvb_chart.js b/test/functional/apps/visualize/_tsvb_chart.js index 5fade50d54774..4ed66b35c776b 100644 --- a/test/functional/apps/visualize/_tsvb_chart.js +++ b/test/functional/apps/visualize/_tsvb_chart.js @@ -137,11 +137,13 @@ export default function ({ getService, getPageObjects }) { }); it('should verify topN label and count display', async function () { - await PageObjects.visualize.waitForVisualization(); - const labelString = await PageObjects.visualBuilder.getTopNLabel(); - expect(labelString).to.be('Count'); - const gaugeCount = await PageObjects.visualBuilder.getTopNCount(); - expect(gaugeCount).to.be('156'); + await retry.try(async () => { + await PageObjects.visualize.waitForVisualization(); + const labelString = await PageObjects.visualBuilder.getTopNLabel(); + expect(labelString).to.be('Count'); + const gaugeCount = await PageObjects.visualBuilder.getTopNCount(); + expect(gaugeCount).to.be('156'); + }); }); }); From e0afeae8dd696c2079ae22ec4250b53a0d81647e Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 5 Feb 2019 16:24:58 -0700 Subject: [PATCH 31/34] fix timefilter jest test, attempt to fix another flaky functional test --- src/ui/public/timefilter/timefilter.test.js | 4 ++-- test/functional/apps/discover/_field_data.js | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/ui/public/timefilter/timefilter.test.js b/src/ui/public/timefilter/timefilter.test.js index eb07711126e48..8f5bd9164e677 100644 --- a/src/ui/public/timefilter/timefilter.test.js +++ b/src/ui/public/timefilter/timefilter.test.js @@ -90,10 +90,10 @@ describe('setTime', () => { expect(timefilter.getTime()).to.eql({ from: 5, to: 10 }); }); - test('not emit anything if the time has not changed', () => { + test('should emit fetch but not update if the time has not changed', () => { timefilter.setTime({ from: 0, to: 1 }); expect(update.called).to.be(false); - expect(fetch.called).to.be(false); + expect(fetch.called).to.be(true); }); test('emit update and fetch if the time has changed', () => { diff --git a/test/functional/apps/discover/_field_data.js b/test/functional/apps/discover/_field_data.js index 62928a96d6ae2..ebfb1d4dcdfbf 100644 --- a/test/functional/apps/discover/_field_data.js +++ b/test/functional/apps/discover/_field_data.js @@ -46,10 +46,9 @@ export default function ({ getService, getPageObjects }) { describe('field data', function () { it('search php should show the correct hit count', async function () { const expectedHitCount = '445'; - await queryBar.setQuery('php'); - await queryBar.submitQuery(); - - await retry.try(async function tryingForTime() { + await retry.try(async function () { + await queryBar.setQuery('php'); + await queryBar.submitQuery(); const hitCount = await PageObjects.discover.getHitCount(); expect(hitCount).to.be(expectedHitCount); }); From 7bd5c5605f9a188404b189bfcb5c6131c3a20aa8 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 5 Feb 2019 18:46:23 -0700 Subject: [PATCH 32/34] revert emitting fetch outside of areTimePickerValsDifferent check --- src/ui/public/timefilter/timefilter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/public/timefilter/timefilter.js b/src/ui/public/timefilter/timefilter.js index f211ee66dcabf..f2d2f4dea5c6b 100644 --- a/src/ui/public/timefilter/timefilter.js +++ b/src/ui/public/timefilter/timefilter.js @@ -62,8 +62,8 @@ class Timefilter extends SimpleEmitter { }; timeHistory.add(this._time); this.emit('timeUpdate'); + this.emit('fetch'); } - this.emit('fetch'); } getRefreshInterval = () => { From 59624301bacfd81f551f51a40415c2ef7cf4d2e8 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 5 Feb 2019 18:51:29 -0700 Subject: [PATCH 33/34] clean up time mode code that is no longer needed in dashboard --- .../kibana/public/dashboard/dashboard_app.js | 4 ++-- .../public/dashboard/dashboard_state.test.js | 13 +++---------- .../dashboard/dashboard_state_manager.js | 18 +----------------- 3 files changed, 6 insertions(+), 29 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js index 2f64e8d96160d..6c0a4f417209c 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js @@ -125,7 +125,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, config.get('timepicker:quickRanges')); + dashboardStateManager.syncTimefilterWithDashboard(timefilter); } const updateState = () => { @@ -307,7 +307,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, config.get('timepicker:quickRanges')); + dashboardStateManager.syncTimefilterWithDashboard(timefilter); } } diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state.test.js b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state.test.js index 57207ef60e341..b3d817361e6d8 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state.test.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state.test.js @@ -33,7 +33,6 @@ describe('DashboardState', function () { time: {}, setTime: function (time) { this.time = time; }, }; - const mockQuickTimeRanges = [{ from: 'now/w', to: 'now/w', display: 'This week', section: 0 }]; const mockIndexPattern = { id: 'index1' }; function initDashboardState() { @@ -52,12 +51,10 @@ describe('DashboardState', function () { mockTimefilter.time.from = '2015-09-19 06:31:44.000'; mockTimefilter.time.to = '2015-09-29 06:31:44.000'; - mockTimefilter.time.mode = 'absolute'; initDashboardState(); - dashboardState.syncTimefilterWithDashboard(mockTimefilter, mockQuickTimeRanges); + dashboardState.syncTimefilterWithDashboard(mockTimefilter); - expect(mockTimefilter.time.mode).toBe('quick'); expect(mockTimefilter.time.to).toBe('now/w'); expect(mockTimefilter.time.from).toBe('now/w'); }); @@ -69,12 +66,10 @@ describe('DashboardState', function () { mockTimefilter.time.from = '2015-09-19 06:31:44.000'; mockTimefilter.time.to = '2015-09-29 06:31:44.000'; - mockTimefilter.time.mode = 'absolute'; initDashboardState(); - dashboardState.syncTimefilterWithDashboard(mockTimefilter, mockQuickTimeRanges); + dashboardState.syncTimefilterWithDashboard(mockTimefilter); - expect(mockTimefilter.time.mode).toBe('relative'); expect(mockTimefilter.time.to).toBe('now'); expect(mockTimefilter.time.from).toBe('now-13d'); }); @@ -86,12 +81,10 @@ describe('DashboardState', function () { mockTimefilter.time.from = 'now/w'; mockTimefilter.time.to = 'now/w'; - mockTimefilter.time.mode = 'quick'; initDashboardState(); - dashboardState.syncTimefilterWithDashboard(mockTimefilter, mockQuickTimeRanges); + dashboardState.syncTimefilterWithDashboard(mockTimefilter); - expect(mockTimefilter.time.mode).toBe('absolute'); expect(mockTimefilter.time.to).toBe(savedDashboard.timeTo); expect(mockTimefilter.time.from).toBe(savedDashboard.timeFrom); }); diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.js b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.js index cff4438ce3a5d..e8480435d9816 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.js @@ -19,7 +19,6 @@ import { i18n } from '@kbn/i18n'; import _ from 'lodash'; -import moment from 'moment'; import { DashboardViewMode } from './dashboard_view_mode'; import { FilterUtils } from './lib/filter_utils'; @@ -144,13 +143,11 @@ export class DashboardStateManager { * or a relative time (now-15m), or a moment object * @param {String|Object} newTimeFilter.from - either a string representing an absolute or a relative time, or a * moment object - * @param {String} newTimeFilter.mode */ handleTimeChange(newTimeFilter) { store.dispatch(updateTimeRange({ from: FilterUtils.convertTimeToUTCString(newTimeFilter.from), to: FilterUtils.convertTimeToUTCString(newTimeFilter.to), - mode: newTimeFilter.mode, })); } @@ -543,30 +540,17 @@ export class DashboardStateManager { * @param {Object} timeFilter * @param {func} timeFilter.setTime * @param {func} timeFilter.setRefreshInterval - * @param quickTimeRanges */ - syncTimefilterWithDashboard(timeFilter, quickTimeRanges) { + syncTimefilterWithDashboard(timeFilter) { if (!this.getIsTimeSavedWithDashboard()) { throw new Error(i18n.translate('kbn.dashboard.stateManager.timeNotSavedWithDashboardErrorMessage', { defaultMessage: 'The time is not saved with this dashboard so should not be synced.', })); } - let mode; - const isMoment = moment(this.savedDashboard.timeTo).isValid(); - if (isMoment) { - mode = 'absolute'; - } else { - const quickTime = _.find( - quickTimeRanges, - (timeRange) => timeRange.from === this.savedDashboard.timeFrom && timeRange.to === this.savedDashboard.timeTo); - - mode = quickTime ? 'quick' : 'relative'; - } timeFilter.setTime({ from: this.savedDashboard.timeFrom, to: this.savedDashboard.timeTo, - mode }); if (this.savedDashboard.refreshInterval) { From d94975a0960b9e00a6a69bedb1ddd71f1249ce08 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 5 Feb 2019 19:45:12 -0700 Subject: [PATCH 34/34] fix timefilter tests changed by timefilter emit revert --- src/ui/public/timefilter/timefilter.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/public/timefilter/timefilter.test.js b/src/ui/public/timefilter/timefilter.test.js index 8f5bd9164e677..eb07711126e48 100644 --- a/src/ui/public/timefilter/timefilter.test.js +++ b/src/ui/public/timefilter/timefilter.test.js @@ -90,10 +90,10 @@ describe('setTime', () => { expect(timefilter.getTime()).to.eql({ from: 5, to: 10 }); }); - test('should emit fetch but not update if the time has not changed', () => { + test('not emit anything if the time has not changed', () => { timefilter.setTime({ from: 0, to: 1 }); expect(update.called).to.be(false); - expect(fetch.called).to.be(true); + expect(fetch.called).to.be(false); }); test('emit update and fetch if the time has changed', () => {