Delete FilterStateManager and QueryFilter :-D (#59872) (#59990)

* delete filter state manager and query filter :-D

* snapshot

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Liza Katz 2020-03-12 14:09:37 +00:00 committed by GitHub
parent e84ac45171
commit ddfe205e7a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 13 additions and 488 deletions

View file

@ -1,175 +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 sinon from 'sinon';
import { FilterStateManager } from './filter_state_manager';
import { StubState } from './test_helpers/stub_state';
import { getFilter } from './test_helpers/get_stub_filter';
import { FilterManager, esFilters } from '../../../../../../plugins/data/public';
import { coreMock } from '../../../../../../core/public/mocks';
const setupMock = coreMock.createSetup();
setupMock.uiSettings.get.mockImplementation((key: string) => {
return true;
});
describe('filter_state_manager', () => {
let appStateStub: StubState;
let globalStateStub: StubState;
let filterManager: FilterManager;
beforeEach(() => {
appStateStub = new StubState();
globalStateStub = new StubState();
filterManager = new FilterManager(setupMock.uiSettings);
});
describe('app_state_undefined', () => {
beforeEach(() => {
// FilterStateManager is tested indirectly.
// Therefore, we don't need it's instance.
new FilterStateManager(
globalStateStub,
() => {
return undefined;
},
filterManager
);
});
test('should NOT watch state until both app and global state are defined', done => {
const f1 = getFilter(esFilters.FilterStateStore.GLOBAL_STATE, false, false, 'age', 34);
globalStateStub.filters.push(f1);
setTimeout(() => {
expect(filterManager.getGlobalFilters()).toHaveLength(0);
done();
}, 100);
});
test('should NOT update app URL when filter manager filters are set', async () => {
appStateStub.save = sinon.stub();
globalStateStub.save = sinon.stub();
const f1 = getFilter(esFilters.FilterStateStore.APP_STATE, false, false, 'age', 34);
const f2 = getFilter(esFilters.FilterStateStore.GLOBAL_STATE, false, false, 'age', 34);
filterManager.setFilters([f1, f2]);
sinon.assert.notCalled(appStateStub.save);
sinon.assert.calledOnce(globalStateStub.save);
});
});
describe('app_state_defined', () => {
let filterStateManager: FilterStateManager;
beforeEach(() => {
// FilterStateManager is tested indirectly.
// Therefore, we don't need it's instance.
filterStateManager = new FilterStateManager(
globalStateStub,
() => {
return appStateStub;
},
filterManager
);
});
afterEach(() => {
filterStateManager.destroy();
});
test('should update filter manager global filters', done => {
const updateSubscription = filterManager.getUpdates$().subscribe(() => {
expect(filterManager.getGlobalFilters()).toHaveLength(1);
if (updateSubscription) {
updateSubscription.unsubscribe();
}
done();
});
const f1 = getFilter(esFilters.FilterStateStore.GLOBAL_STATE, true, true, 'age', 34);
globalStateStub.filters.push(f1);
});
test('should update filter manager app filter', done => {
const updateSubscription = filterManager.getUpdates$().subscribe(() => {
expect(filterManager.getAppFilters()).toHaveLength(1);
if (updateSubscription) {
updateSubscription.unsubscribe();
}
done();
});
const f1 = getFilter(esFilters.FilterStateStore.APP_STATE, false, false, 'age', 34);
appStateStub.filters.push(f1);
});
test('should update URL when filter manager filters are set', () => {
appStateStub.save = sinon.stub();
globalStateStub.save = sinon.stub();
const f1 = getFilter(esFilters.FilterStateStore.APP_STATE, false, false, 'age', 34);
const f2 = getFilter(esFilters.FilterStateStore.GLOBAL_STATE, false, false, 'age', 34);
filterManager.setFilters([f1, f2]);
sinon.assert.calledOnce(appStateStub.save);
sinon.assert.calledOnce(globalStateStub.save);
});
test('should update URL when filter manager filters are added', () => {
appStateStub.save = sinon.stub();
globalStateStub.save = sinon.stub();
const f1 = getFilter(esFilters.FilterStateStore.APP_STATE, false, false, 'age', 34);
const f2 = getFilter(esFilters.FilterStateStore.GLOBAL_STATE, false, false, 'age', 34);
filterManager.addFilters([f1, f2]);
sinon.assert.calledOnce(appStateStub.save);
sinon.assert.calledOnce(globalStateStub.save);
});
});
describe('bug fixes', () => {
/*
** This test is here to reproduce a bug where a filter manager update
** would cause filter state manager detects those changes
** And triggers *another* filter manager update.
*/
test('should NOT re-trigger filter manager', done => {
const f1 = getFilter(esFilters.FilterStateStore.APP_STATE, false, false, 'age', 34);
filterManager.setFilters([f1]);
const setFiltersSpy = sinon.spy(filterManager, 'setFilters');
f1.meta.negate = true;
filterManager.setFilters([f1]);
setTimeout(() => {
expect(setFiltersSpy.callCount).toEqual(1);
done();
}, 100);
});
});
});

View file

@ -1,109 +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 { Subscription } from 'rxjs';
import { State } from 'ui/state_management/state';
import { FilterManager, esFilters, Filter } from '../../../../../../plugins/data/public';
type GetAppStateFunc = () => { filters?: Filter[]; save?: () => void } | undefined | null;
/**
* FilterStateManager is responsible for watching for filter changes
* and syncing with FilterManager, as well as syncing FilterManager changes
* back to the URL.
**/
export class FilterStateManager {
private filterManagerUpdatesSubscription: Subscription;
filterManager: FilterManager;
globalState: State;
getAppState: GetAppStateFunc;
interval: number | undefined;
constructor(globalState: State, getAppState: GetAppStateFunc, filterManager: FilterManager) {
this.getAppState = getAppState;
this.globalState = globalState;
this.filterManager = filterManager;
this.watchFilterState();
this.filterManagerUpdatesSubscription = this.filterManager.getUpdates$().subscribe(() => {
this.updateAppState();
});
}
destroy() {
if (this.interval) {
clearInterval(this.interval);
}
this.filterManagerUpdatesSubscription.unsubscribe();
}
private watchFilterState() {
// This is a temporary solution to remove rootscope.
// Moving forward, state should provide observable subscriptions.
this.interval = window.setInterval(() => {
const appState = this.getAppState();
const stateUndefined = !appState || !this.globalState;
if (stateUndefined) return;
const globalFilters = this.globalState.filters || [];
const appFilters = (appState && appState.filters) || [];
const globalFilterChanged = !esFilters.compareFilters(
this.filterManager.getGlobalFilters(),
globalFilters,
esFilters.COMPARE_ALL_OPTIONS
);
const appFilterChanged = !esFilters.compareFilters(
this.filterManager.getAppFilters(),
appFilters,
esFilters.COMPARE_ALL_OPTIONS
);
const filterStateChanged = globalFilterChanged || appFilterChanged;
if (!filterStateChanged) return;
const newGlobalFilters = _.cloneDeep(globalFilters);
const newAppFilters = _.cloneDeep(appFilters);
FilterManager.setFiltersStore(newAppFilters, esFilters.FilterStateStore.APP_STATE);
FilterManager.setFiltersStore(newGlobalFilters, esFilters.FilterStateStore.GLOBAL_STATE);
this.filterManager.setFilters(newGlobalFilters.concat(newAppFilters));
}, 10);
}
private saveState() {
const appState = this.getAppState();
if (appState && appState.save) appState.save();
this.globalState.save();
}
private updateAppState() {
// Update Angular state before saving State objects (which save it to URL)
const partitionedFilters = this.filterManager.getPartitionedFilters();
const appState = this.getAppState();
if (appState) {
appState.filters = partitionedFilters.appFilters;
}
this.globalState.filters = partitionedFilters.globalFilters;
this.saveState();
}
}

View file

@ -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 { FilterStateManager } from './filter_state_manager';

View file

@ -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 { Filter } from '../../../../../../../plugins/data/public';
export function getFilter(
store: any, // I don't want to export only for this, as it should move to data plugin
disabled: boolean,
negated: boolean,
queryKey: string,
queryValue: any
): Filter {
return {
$state: {
store,
},
meta: {
index: 'logstash-*',
disabled,
negate: negated,
alias: null,
},
query: {
match: {
[queryKey]: queryValue,
},
},
};
}

View file

@ -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 sinon from 'sinon';
import { State } from 'ui/state_management/state';
import { Filter } from '../../../../../../../plugins/data/public';
export class StubState implements State {
filters: Filter[];
save: sinon.SinonSpy<any[], any>;
constructor() {
this.save = sinon.stub();
this.filters = [];
}
getQueryParamName() {
return '_a';
}
translateHashToRison(stateHashOrRison: string | string[]): string | string[] {
return '';
}
}

View file

@ -28,7 +28,6 @@ export function plugin() {
/** @public types */
export { DataSetup, DataStart } from './plugin';
export { SavedQuery, SavedQueryTimeFilter } from '../../../../plugins/data/public';
export {
// agg_types
AggParam, // only the type is used externally, only in vis editor
@ -46,7 +45,6 @@ export {
/** @public static code */
export * from '../common';
export { FilterStateManager } from './filter/filter_manager';
export {
// agg_types TODO need to group these under a namespace or prefix
AggConfigs,

View file

@ -1,18 +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.
*/

View file

@ -1,22 +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 type QueryFilter = any;
export const FilterBarQueryFilterProvider: () => QueryFilter;

View file

@ -1,44 +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 { FilterStateManager } from 'plugins/data';
import { npStart } from 'ui/new_platform';
export function FilterBarQueryFilterProvider(getAppState, globalState) {
const { filterManager } = npStart.plugins.data.query;
const filterStateManager = new FilterStateManager(globalState, getAppState, filterManager);
const queryFilter = {};
queryFilter.getUpdates$ = filterManager.getUpdates$.bind(filterManager);
queryFilter.getFetches$ = filterManager.getFetches$.bind(filterManager);
queryFilter.getFilters = filterManager.getFilters.bind(filterManager);
queryFilter.getAppFilters = filterManager.getAppFilters.bind(filterManager);
queryFilter.getGlobalFilters = filterManager.getGlobalFilters.bind(filterManager);
queryFilter.removeFilter = filterManager.removeFilter.bind(filterManager);
queryFilter.addFilters = filterManager.addFilters.bind(filterManager);
queryFilter.setFilters = filterManager.setFilters.bind(filterManager);
queryFilter.removeAll = filterManager.removeAll.bind(filterManager);
queryFilter.destroy = () => {
filterManager.destroy();
filterStateManager.destroy();
};
return queryFilter;
}

View file

@ -24,8 +24,7 @@ import { Document } from '../../persistence/saved_object_store';
import { getSavedObjectFormat } from './save';
import { WorkspacePanelWrapper } from './workspace_panel_wrapper';
import { generateId } from '../../id_generator';
import { SavedQuery } from '../../../../../../../src/legacy/core_plugins/data/public';
import { Filter, Query } from '../../../../../../../src/plugins/data/public';
import { Filter, Query, SavedQuery } from '../../../../../../../src/plugins/data/public';
export interface EditorFrameProps {
doc?: Document;

View file

@ -7,12 +7,11 @@
import { Ast } from '@kbn/interpreter/common';
import { IconType } from '@elastic/eui/src/components/icon/icon';
import { CoreSetup } from 'src/core/public';
import { SavedQuery } from 'src/legacy/core_plugins/data/public';
import { KibanaDatatable } from '../../../../../src/plugins/expressions/public';
import { DragContextState } from './drag_drop';
import { Document } from './persistence';
import { DateRange } from '../../../../plugins/lens/common';
import { Query, Filter } from '../../../../../src/plugins/data/public';
import { Query, Filter, SavedQuery } from '../../../../../src/plugins/data/public';
// eslint-disable-next-line
export interface EditorFrameOptions {}

View file

@ -11,8 +11,14 @@ import { Dispatch } from 'redux';
import { Subscription } from 'rxjs';
import styled from 'styled-components';
import deepEqual from 'fast-deep-equal';
import { FilterManager, IIndexPattern, TimeRange, Query, Filter } from 'src/plugins/data/public';
import { SavedQuery } from 'src/legacy/core_plugins/data/public';
import {
FilterManager,
IIndexPattern,
TimeRange,
Query,
Filter,
SavedQuery,
} from 'src/plugins/data/public';
import { OnTimeChangeProps } from '@elastic/eui';

View file

@ -5,9 +5,8 @@
*/
import { createSelector } from 'reselect';
import { SavedQuery } from 'src/legacy/core_plugins/data/public';
import { InputsRange } from '../../store/inputs/model';
import { Query } from '../../../../../../../src/plugins/data/public';
import { Query, SavedQuery } from '../../../../../../../src/plugins/data/public';
export {
endSelector,

View file

@ -6,10 +6,9 @@
import actionCreatorFactory from 'typescript-fsa';
import { SavedQuery } from 'src/legacy/core_plugins/data/public';
import { InspectQuery, Refetch, RefetchKql } from './model';
import { InputsModelId } from './constants';
import { Filter } from '../../../../../../../src/plugins/data/public';
import { Filter, SavedQuery } from '../../../../../../../src/plugins/data/public';
const actionCreator = actionCreatorFactory('x-pack/siem/local/inputs');

View file

@ -5,11 +5,10 @@
*/
import { Dispatch } from 'redux';
import { SavedQuery } from 'src/legacy/core_plugins/data/public';
import { Omit } from '../../../common/utility_types';
import { InputsModelId } from './constants';
import { CONSTANTS } from '../../components/url_state/constants';
import { Query, Filter } from '../../../../../../../src/plugins/data/public';
import { Query, Filter, SavedQuery } from '../../../../../../../src/plugins/data/public';
export interface AbsoluteTimeRange {
kind: 'absolute';