From d02bed506f009e77c93d6fe2951972640f7a383e Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 22 Jan 2019 12:54:16 -0700 Subject: [PATCH] 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 f71edb1c5e77bb..27311528f9b00b 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 db8119fa784c88..1aaf1f0956d0a7 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 6039285048e229..b9eed586d9dd17 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 bfad2b891d35a4..733e20e8a2e2ae 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 c827028bbba236..4a82ca1cb17d50 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 02f240ffc352b9..37c38742417e8b 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 6eb5a12883d655..48a15467b479aa 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 00000000000000..4743832c113bed --- /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 00000000000000..5d042028c1ef88 --- /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 00000000000000..8ce57e0d0991bf --- /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 34f953f0525ea6..bb30c7461cbe18 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 f6128b429bd0ff..0d69f058dae0db 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 b0e31b7e2f4705..cff886a1ff1234 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 d3a08630e970cc..2abad91c4b9743 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 cf32464034a9c3..6b63dba9e53fdc 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 {