diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html index 1c2980b34318ce..375cd0fe3b2056 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html @@ -16,6 +16,12 @@ filters="model.filters" on-filters-updated="onFiltersUpdated" show-filter-bar="showFilterBar()" + show-date-picker="true" + date-range-from="model.timeRange.from" + date-range-to="model.timeRange.to" + is-refresh-paused="model.refreshInterval.pause" + refresh-interval="model.refreshInterval.value" + on-refresh-change="onRefreshChange" watch-depth="reference" > 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 6c0a4f417209c0..a2f997205a398f 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js @@ -137,6 +137,8 @@ app.directive('dashboardApp', function ($injector) { timeRestore: dashboardStateManager.getTimeRestore(), title: dashboardStateManager.getTitle(), description: dashboardStateManager.getDescription(), + timeRange: timefilter.getTime(), + refreshInterval: timefilter.getRefreshInterval(), }; $scope.panels = dashboardStateManager.getPanels(); @@ -171,8 +173,8 @@ app.directive('dashboardApp', function ($injector) { queryFilter.getFilters() ); - timefilter.enableAutoRefreshSelector(); - timefilter.enableTimeRangeSelector(); + timefilter.disableTimeRangeSelector(); + timefilter.disableAutoRefreshSelector(); updateState(); @@ -229,7 +231,9 @@ app.directive('dashboardApp', function ($injector) { dashboardStateManager.getPanels().find((panel) => panel.panelIndex === panelIndex); }; - $scope.updateQueryAndFetch = function ({ query }) { + $scope.updateQueryAndFetch = function ({ query, dateRange }) { + timefilter.setTime(dateRange); + const oldQuery = $scope.model.query; if (_.isEqual(oldQuery, query)) { // The user can still request a reload in the query bar, even if the @@ -243,6 +247,13 @@ app.directive('dashboardApp', function ($injector) { $scope.refresh(); }; + $scope.onRefreshChange = function ({ isPaused, refreshInterval }) { + timefilter.setRefreshInterval({ + pause: isPaused, + value: refreshInterval ? refreshInterval : $scope.model.refreshInterval.value + }); + }; + $scope.onFiltersUpdated = filters => { // The filters will automatically be set when the queryFilter emits an update event (see below) queryFilter.setFilters(filters); @@ -280,6 +291,8 @@ app.directive('dashboardApp', function ($injector) { // directly passed down time filter. Then we can get rid of this reliance on scope broadcasts. $scope.refresh(); }); + $scope.$listenAndDigestAsync(timefilter, 'refreshIntervalUpdate', updateState); + $scope.$listenAndDigestAsync(timefilter, 'timeUpdate', updateState); function updateViewMode(newMode) { $scope.topNavMenu = getTopNavConfig(newMode, navActions, dashboardConfig.getHideWriteControls()); // eslint-disable-line no-use-before-define 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 20a4ead4aab50f..d6a55d14498c87 100644 --- a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js @@ -183,6 +183,9 @@ function discoverController( requests: new RequestAdapter() }; + timefilter.disableTimeRangeSelector(); + timefilter.disableAutoRefreshSelector(); + $scope.getDocLink = getDocLink; $scope.intervalOptions = intervalOptions; $scope.showInterval = false; @@ -491,6 +494,12 @@ function discoverController( $scope.$listen(timefilter, 'fetch', function () { $scope.fetch(); }); + $scope.$listen(timefilter, 'refreshIntervalUpdate', () => { + $scope.updateRefreshInterval(); + }); + $scope.$listen(timefilter, 'timeUpdate', () => { + $scope.updateTime(); + }); $scope.$watchCollection('state.sort', function (sort) { if (!sort) return; @@ -518,13 +527,8 @@ function discoverController( // fetch data when filters fire fetch event $scope.$listen(queryFilter, 'fetch', $scope.fetch); - timefilter.enableAutoRefreshSelector(); $scope.$watch('opts.timefield', function (timefield) { - if (!!timefield) { - timefilter.enableTimeRangeSelector(); - } else { - timefilter.disableTimeRangeSelector(); - } + $scope.enableTimeRangeSelector = !!timefield; }); $scope.$watch('state.interval', function () { @@ -662,7 +666,8 @@ function discoverController( .catch(notify.error); }; - $scope.updateQueryAndFetch = function ({ query }) { + $scope.updateQueryAndFetch = function ({ query, dateRange }) { + timefilter.setTime(dateRange); $state.query = migrateLegacyQuery(query); $scope.fetch(); }; @@ -856,6 +861,18 @@ function discoverController( from: dateMath.parse(timefilter.getTime().from), to: dateMath.parse(timefilter.getTime().to, { roundUp: true }) }; + $scope.time = timefilter.getTime(); + }; + + $scope.updateRefreshInterval = function () { + $scope.refreshInterval = timefilter.getRefreshInterval(); + }; + + $scope.onRefreshChange = function ({ isPaused, refreshInterval }) { + timefilter.setRefreshInterval({ + pause: isPaused, + value: refreshInterval ? refreshInterval : $scope.refreshInterval.value + }); }; $scope.resetQuery = function () { diff --git a/src/legacy/core_plugins/kibana/public/discover/index.html b/src/legacy/core_plugins/kibana/public/discover/index.html index e109b273a199a0..dcac59395f4040 100644 --- a/src/legacy/core_plugins/kibana/public/discover/index.html +++ b/src/legacy/core_plugins/kibana/public/discover/index.html @@ -38,6 +38,12 @@

diff --git a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.html b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.html index aeab11b0bb66be..c5a24728eb5793 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.html +++ b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.html @@ -35,8 +35,15 @@ index-patterns="[indexPattern]" filters="filters" on-filters-updated="onFiltersUpdated" - show-query-bar="vis.type.requiresSearch && vis.type.options.showQueryBar" + show-query-bar="showQueryBar()" show-filter-bar="vis.type.options.showFilterBar && chrome.getVisible()" + show-date-picker="enableQueryBarTimeRangeSelector" + date-range-from="timeRange.from" + date-range-to="timeRange.to" + is-refresh-paused="refreshInterval.pause" + refresh-interval="refreshInterval.value" + show-auto-refresh-only="showAutoRefreshOnlyInQueryBar" + on-refresh-change="onRefreshChange" watch-depth="reference" > 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 797361b2b7952d..8bcc7756381460 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js @@ -326,6 +326,10 @@ function VisEditor( $scope.isAddToDashMode = () => addToDashMode; + $scope.showQueryBar = () => { + return vis.type.requiresSearch && vis.type.options.showQueryBar; + }; + $scope.timeRange = timefilter.getTime(); $scope.opts = _.pick($scope, 'savedVis', 'isAddToDashMode'); @@ -343,13 +347,27 @@ function VisEditor( $scope.$watchMulti([ 'searchSource.getField("index")', 'vis.type.options.showTimePicker', - ], function ([index, requiresTimePicker]) { + $scope.showQueryBar, + ], function ([index, requiresTimePicker, showQueryBar]) { const showTimeFilter = Boolean((!index || index.timeFieldName) && requiresTimePicker); - if (showTimeFilter) { + if (showQueryBar) { + timefilter.disableTimeRangeSelector(); + timefilter.disableAutoRefreshSelector(); + $scope.enableQueryBarTimeRangeSelector = true; + $scope.showAutoRefreshOnlyInQueryBar = !showTimeFilter; + } + else if (showTimeFilter) { timefilter.enableTimeRangeSelector(); - } else { + timefilter.enableAutoRefreshSelector(); + $scope.enableQueryBarTimeRangeSelector = false; + $scope.showAutoRefreshOnlyInQueryBar = false; + } + else { timefilter.disableTimeRangeSelector(); + timefilter.enableAutoRefreshSelector(); + $scope.enableQueryBarTimeRangeSelector = false; + $scope.showAutoRefreshOnlyInQueryBar = false; } }); @@ -364,8 +382,12 @@ function VisEditor( } }; - timefilter.enableAutoRefreshSelector(); + const updateRefreshInterval = () => { + $scope.refreshInterval = timefilter.getRefreshInterval(); + }; + $scope.$listenAndDigestAsync(timefilter, 'timeUpdate', updateTimeRange); + $scope.$listenAndDigestAsync(timefilter, 'refreshIntervalUpdate', updateRefreshInterval); // update the searchSource when filters update $scope.$listen(queryFilter, 'update', function () { @@ -402,11 +424,19 @@ function VisEditor( } } - $scope.updateQueryAndFetch = function ({ query }) { + $scope.updateQueryAndFetch = function ({ query, dateRange }) { + timefilter.setTime(dateRange); $state.query = migrateLegacyQuery(query); $scope.fetch(); }; + $scope.onRefreshChange = function ({ isPaused, refreshInterval }) { + timefilter.setRefreshInterval({ + pause: isPaused, + value: refreshInterval ? refreshInterval : $scope.refreshInterval.value + }); + }; + /** * Called when the user clicks "Save" button. */ diff --git a/src/ui/public/query_bar/components/query_bar.tsx b/src/ui/public/query_bar/components/query_bar.tsx index 27bde6632f1e2c..35498b78b79112 100644 --- a/src/ui/public/query_bar/components/query_bar.tsx +++ b/src/ui/public/query_bar/components/query_bar.tsx @@ -84,6 +84,7 @@ interface Props { dateRangeTo?: string; isRefreshPaused?: boolean; refreshInterval?: number; + showAutoRefreshOnly?: boolean; onRefreshChange?: (isPaused: boolean, refreshInterval: number) => void; } @@ -679,6 +680,7 @@ export class QueryBarUI extends Component { recentlyUsedRanges={recentlyUsedRanges} commonlyUsedRanges={commonlyUsedRanges} dateFormat={config.get('dateFormat')} + isAutoRefreshOnly={this.props.showAutoRefreshOnly} /> ); diff --git a/src/ui/public/search_bar/components/search_bar.tsx b/src/ui/public/search_bar/components/search_bar.tsx index 3cc8a56f72206d..52e49e6d7b0566 100644 --- a/src/ui/public/search_bar/components/search_bar.tsx +++ b/src/ui/public/search_bar/components/search_bar.tsx @@ -54,6 +54,13 @@ interface Props { showQueryBar: boolean; showFilterBar: boolean; intl: InjectedIntl; + showDatePicker?: boolean; + dateRangeFrom?: string; + dateRangeTo?: string; + isRefreshPaused?: boolean; + refreshInterval?: number; + showAutoRefreshOnly?: boolean; + onRefreshChange?: (isPaused: boolean, refreshInterval: number) => void; } interface State { @@ -151,6 +158,13 @@ class SearchBarUI extends Component { indexPatterns={this.props.indexPatterns} store={this.props.store} prepend={this.props.showFilterBar ? filterTriggerButton : ''} + showDatePicker={this.props.showDatePicker} + dateRangeFrom={this.props.dateRangeFrom} + dateRangeTo={this.props.dateRangeTo} + isRefreshPaused={this.props.isRefreshPaused} + refreshInterval={this.props.refreshInterval} + showAutoRefreshOnly={this.props.showAutoRefreshOnly} + onRefreshChange={this.props.onRefreshChange} /> ) : ( '' diff --git a/test/functional/apps/dashboard/_embeddable_rendering.js b/test/functional/apps/dashboard/_embeddable_rendering.js index 5f7cf2fec9f66b..b3a2d6633c9f61 100644 --- a/test/functional/apps/dashboard/_embeddable_rendering.js +++ b/test/functional/apps/dashboard/_embeddable_rendering.js @@ -90,7 +90,9 @@ export default function ({ getService, getPageObjects }) { await dashboardExpect.vegaTextsDoNotExist(['5,000']); }; - describe('dashboard embeddable rendering', function describeIndexTests() { + + // FLAKY: https://github.com/elastic/kibana/issues/28818 + describe.skip('dashboard embeddable rendering', function describeIndexTests() { before(async () => { await PageObjects.dashboard.clickNewDashboard(); diff --git a/test/functional/page_objects/time_picker.js b/test/functional/page_objects/time_picker.js index 04b097890ea425..212b772000c936 100644 --- a/test/functional/page_objects/time_picker.js +++ b/test/functional/page_objects/time_picker.js @@ -28,6 +28,10 @@ export function TimePickerPageProvider({ getService, getPageObjects }) { class TimePickerPage { + async timePickerExists() { + return await testSubjects.exists('superDatePickerToggleQuickMenuButton'); + } + formatDateToAbsoluteTimeString(date) { // toISOString returns dates in format 'YYYY-MM-DDTHH:mm:ss.sssZ' // Need to replace T with space and remove timezone 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 e06f7bc84979b1..2ce6ad7bde69fc 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 @@ -24,6 +24,7 @@ export default function ({ getService, getPageObjects }) { 'dashboard', 'header', 'settings', + 'timePicker', ]); const dashboardName = 'Dashboard View Mode Test Dashboard'; const savedSearchName = 'Saved search for dashboard'; @@ -174,7 +175,7 @@ export default function ({ getService, getPageObjects }) { }); it('shows the timepicker', async () => { - const timePickerExists = await testSubjects.exists('superDatePickerApplyTimeButton'); + const timePickerExists = await PageObjects.timePicker.timePickerExists(); expect(timePickerExists).to.be(true); });