Saved visualization with search string confuse altering of search string (#103396)

* Add possibility to sync query and filter from state

* Fix unit-tests

* Fix name

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Uladzislau Lasitsa 2021-07-29 18:41:02 +03:00 committed by GitHub
parent 75fd626c7a
commit 57042f0770
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 6 deletions

View file

@ -47,6 +47,7 @@ describe('useVisualizeAppState', () => {
const savedVisInstance = ({
vis: {
setState: jest.fn().mockResolvedValue({}),
data: {},
},
savedVis: {},
embeddableHandler: {},
@ -167,7 +168,31 @@ describe('useVisualizeAppState', () => {
const { aggs, ...visState } = stateContainer.getState().vis;
const expectedNewVisState = {
...visState,
data: { aggs: state.vis.aggs },
data: { aggs: state.vis.aggs, searchSource: { query: state.query, filter: state.filters } },
};
expect(savedVisInstance.vis.setState).toHaveBeenCalledWith(expectedNewVisState);
expect(result.current).toEqual({
appState: stateContainer,
hasUnappliedChanges: false,
});
});
it('should successfully updated vis state and set up app state container if query from app state is different', async () => {
stateContainerGetStateMock.mockImplementation(() => ({
...visualizeAppStateStub,
query: { query: 'test', language: 'kuery' },
}));
const { result, waitForNextUpdate } = renderHook(() =>
useVisualizeAppState(mockServices, eventEmitter, savedVisInstance)
);
await waitForNextUpdate();
const { aggs, ...visState } = stateContainer.getState().vis;
const expectedNewVisState = {
...visState,
data: { aggs: state.vis.aggs, searchSource: { query: state.query, filter: state.filters } },
};
expect(savedVisInstance.vis.setState).toHaveBeenCalledWith(expectedNewVisState);

View file

@ -44,6 +44,7 @@ export const useVisualizeAppState = (
kbnUrlStateStorage: services.kbnUrlStateStorage,
byValue,
});
const currentAppState = stateContainer.getState();
const onDirtyStateChange = ({ isDirty }: { isDirty: boolean }) => {
if (!isDirty) {
@ -57,8 +58,8 @@ export const useVisualizeAppState = (
const { filterManager, queryString } = services.data.query;
// sync initial app state from state to managers
filterManager.setAppFilters(cloneDeep(stateContainer.getState().filters));
queryString.setQuery(migrateLegacyQuery(stateContainer.getState().query));
filterManager.setAppFilters(cloneDeep(currentAppState.filters));
queryString.setQuery(migrateLegacyQuery(currentAppState.query));
// setup syncing of app filters between appState and query services
const stopSyncingAppFilters = connectToQueryState(
@ -90,10 +91,20 @@ export const useVisualizeAppState = (
// The savedVis is pulled from elasticsearch, but the appState is pulled from the url, with the
// defaults applied. If the url was from a previous session which included modifications to the
// appState then they won't be equal.
if (!isEqual(stateContainer.getState().vis, stateDefaults.vis)) {
const { aggs, ...visState } = stateContainer.getState().vis;
if (
!isEqual(currentAppState.vis, stateDefaults.vis) ||
!isEqual(currentAppState.query, stateDefaults.query) ||
!isEqual(currentAppState.filters, stateDefaults.filters)
) {
const { aggs, ...visState } = currentAppState.vis;
const query = currentAppState.query;
const filter = currentAppState.filters;
const visSearchSource = instance.vis.data.searchSource?.getFields() || {};
instance.vis
.setState({ ...visState, data: { aggs } })
.setState({
...visState,
data: { aggs, searchSource: { ...visSearchSource, query, filter } },
})
.then(() => {
// setting up the stateContainer after setState is successful will prevent loading the editor with failures
// otherwise the catch will take presedence