mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Maps] fix double fetch when filters are modified (#74893)
* [Maps] fix double fetch when filters are modified * add unit tests Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
b07db9dec8
commit
4ac0e81554
5 changed files with 124 additions and 17 deletions
|
@ -11,7 +11,7 @@ jest.mock('./data_request_actions', () => {
|
|||
};
|
||||
});
|
||||
|
||||
import { mapExtentChanged, setMouseCoordinates } from './map_actions';
|
||||
import { mapExtentChanged, setMouseCoordinates, setQuery } from './map_actions';
|
||||
|
||||
const getStoreMock = jest.fn();
|
||||
const dispatchMock = jest.fn();
|
||||
|
@ -226,4 +226,95 @@ describe('map_actions', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('setQuery', () => {
|
||||
const query = {
|
||||
language: 'kuery',
|
||||
query: '',
|
||||
queryLastTriggeredAt: '2020-08-14T15:07:12.276Z',
|
||||
};
|
||||
const timeFilters = { from: 'now-1y', to: 'now' };
|
||||
const filters = [
|
||||
{
|
||||
meta: {
|
||||
index: '90943e30-9a47-11e8-b64d-95841ca0b247',
|
||||
alias: null,
|
||||
negate: false,
|
||||
disabled: false,
|
||||
type: 'phrase',
|
||||
key: 'extension',
|
||||
params: { query: 'png' },
|
||||
},
|
||||
query: { match_phrase: { extension: 'png' } },
|
||||
$state: { store: 'appState' },
|
||||
},
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
//Mocks the "previous" state
|
||||
require('../selectors/map_selectors').getQuery = () => {
|
||||
return query;
|
||||
};
|
||||
require('../selectors/map_selectors').getTimeFilters = () => {
|
||||
return timeFilters;
|
||||
};
|
||||
require('../selectors/map_selectors').getFilters = () => {
|
||||
return filters;
|
||||
};
|
||||
require('../selectors/map_selectors').getMapSettings = () => {
|
||||
return {
|
||||
autoFitToDataBounds: false,
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
it('should dispatch query action and resync when query changes', async () => {
|
||||
const newQuery = {
|
||||
language: 'kuery',
|
||||
query: 'foobar',
|
||||
queryLastTriggeredAt: '2020-08-14T15:07:12.276Z',
|
||||
};
|
||||
const setQueryAction = await setQuery({
|
||||
query: newQuery,
|
||||
filters,
|
||||
});
|
||||
await setQueryAction(dispatchMock, getStoreMock);
|
||||
|
||||
expect(dispatchMock.mock.calls).toEqual([
|
||||
[
|
||||
{
|
||||
timeFilters,
|
||||
query: newQuery,
|
||||
filters,
|
||||
type: 'SET_QUERY',
|
||||
},
|
||||
],
|
||||
[undefined], // dispatch<any>(syncDataForAllLayers());
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not dispatch query action when nothing changes', async () => {
|
||||
const setQueryAction = await setQuery({
|
||||
timeFilters,
|
||||
query,
|
||||
filters,
|
||||
});
|
||||
await setQueryAction(dispatchMock, getStoreMock);
|
||||
|
||||
expect(dispatchMock.mock.calls.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('should dispatch query action when nothing changes and force refresh', async () => {
|
||||
const setQueryAction = await setQuery({
|
||||
timeFilters,
|
||||
query,
|
||||
filters,
|
||||
forceRefresh: true,
|
||||
});
|
||||
await setQueryAction(dispatchMock, getStoreMock);
|
||||
|
||||
// Only checking calls length instead of calls because queryLastTriggeredAt changes on this run
|
||||
expect(dispatchMock.mock.calls.length).toEqual(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import _ from 'lodash';
|
||||
import { Dispatch } from 'redux';
|
||||
import turfBboxPolygon from '@turf/bbox-polygon';
|
||||
import turfBooleanContains from '@turf/boolean-contains';
|
||||
|
@ -204,12 +205,12 @@ export function setQuery({
|
|||
query,
|
||||
timeFilters,
|
||||
filters = [],
|
||||
refresh = false,
|
||||
forceRefresh = false,
|
||||
}: {
|
||||
filters: Filter[];
|
||||
filters?: Filter[];
|
||||
query?: Query;
|
||||
timeFilters?: TimeRange;
|
||||
refresh?: boolean;
|
||||
forceRefresh?: boolean;
|
||||
}) {
|
||||
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
|
||||
const prevQuery = getQuery(getState());
|
||||
|
@ -218,15 +219,30 @@ export function setQuery({
|
|||
? prevQuery.queryLastTriggeredAt
|
||||
: generateQueryTimestamp();
|
||||
|
||||
dispatch({
|
||||
type: SET_QUERY,
|
||||
const nextQueryContext = {
|
||||
timeFilters: timeFilters ? timeFilters : getTimeFilters(getState()),
|
||||
query: {
|
||||
...(query ? query : getQuery(getState())),
|
||||
// ensure query changes to trigger re-fetch when "Refresh" clicked
|
||||
queryLastTriggeredAt: refresh ? generateQueryTimestamp() : prevTriggeredAt,
|
||||
queryLastTriggeredAt: forceRefresh ? generateQueryTimestamp() : prevTriggeredAt,
|
||||
},
|
||||
filters: filters ? filters : getFilters(getState()),
|
||||
};
|
||||
|
||||
const prevQueryContext = {
|
||||
timeFilters: getTimeFilters(getState()),
|
||||
query: getQuery(getState()),
|
||||
filters: getFilters(getState()),
|
||||
};
|
||||
|
||||
if (_.isEqual(nextQueryContext, prevQueryContext)) {
|
||||
// do nothing if query context has not changed
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: SET_QUERY,
|
||||
...nextQueryContext,
|
||||
});
|
||||
|
||||
if (getMapSettings(getState()).autoFitToDataBounds) {
|
||||
|
|
|
@ -129,12 +129,12 @@ export class MapEmbeddable extends Embeddable<MapEmbeddableInput, MapEmbeddableO
|
|||
query,
|
||||
timeRange,
|
||||
filters,
|
||||
refresh,
|
||||
forceRefresh,
|
||||
}: {
|
||||
query?: Query;
|
||||
timeRange?: TimeRange;
|
||||
filters: Filter[];
|
||||
refresh?: boolean;
|
||||
forceRefresh?: boolean;
|
||||
}) {
|
||||
this._prevTimeRange = timeRange;
|
||||
this._prevQuery = query;
|
||||
|
@ -144,7 +144,7 @@ export class MapEmbeddable extends Embeddable<MapEmbeddableInput, MapEmbeddableO
|
|||
filters: filters.filter((filter) => !filter.meta.disabled),
|
||||
query,
|
||||
timeFilters: timeRange,
|
||||
refresh,
|
||||
forceRefresh,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ export class MapEmbeddable extends Embeddable<MapEmbeddableInput, MapEmbeddableO
|
|||
query: this._prevQuery,
|
||||
timeRange: this._prevTimeRange,
|
||||
filters: this._prevFilters ?? [],
|
||||
refresh: true,
|
||||
forceRefresh: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -52,13 +52,13 @@ function mapStateToProps(state = {}) {
|
|||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
dispatchSetQuery: ({ refresh, filters, query, timeFilters }) => {
|
||||
dispatchSetQuery: ({ forceRefresh, filters, query, timeFilters }) => {
|
||||
dispatch(
|
||||
setQuery({
|
||||
filters,
|
||||
query,
|
||||
timeFilters,
|
||||
refresh,
|
||||
forceRefresh,
|
||||
})
|
||||
);
|
||||
},
|
||||
|
|
|
@ -142,7 +142,7 @@ export class MapsAppView extends React.Component {
|
|||
return;
|
||||
}
|
||||
|
||||
this._onQueryChange({ time: globalState.time, refresh: true });
|
||||
this._onQueryChange({ time: globalState.time });
|
||||
};
|
||||
|
||||
async _updateIndexPatterns() {
|
||||
|
@ -160,7 +160,7 @@ export class MapsAppView extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
_onQueryChange = ({ filters, query, time, refresh = false }) => {
|
||||
_onQueryChange = ({ filters, query, time, forceRefresh = false }) => {
|
||||
const { filterManager } = getData().query;
|
||||
|
||||
if (filters) {
|
||||
|
@ -168,7 +168,7 @@ export class MapsAppView extends React.Component {
|
|||
}
|
||||
|
||||
this.props.dispatchSetQuery({
|
||||
refresh,
|
||||
forceRefresh,
|
||||
filters: filterManager.getFilters(),
|
||||
query,
|
||||
timeFilters: time,
|
||||
|
@ -336,7 +336,7 @@ export class MapsAppView extends React.Component {
|
|||
this._onQueryChange({
|
||||
query,
|
||||
time: dateRange,
|
||||
refresh: true,
|
||||
forceRefresh: true,
|
||||
});
|
||||
}}
|
||||
onFiltersUpdated={this._onFiltersChange}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue