mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
* Cleaned up usage of angular dependencies from apply filters \ filter bar * Cleaned up usage of angular dependencies from exact time filter * Removed unused Private from EventsProvider * Deleted unused push_filter * Changed push filters not to be a provider * Renamed mapper functions
This commit is contained in:
parent
f8cfc9e771
commit
650c7d6d8e
38 changed files with 404 additions and 776 deletions
|
@ -20,10 +20,10 @@
|
|||
import sinon from 'sinon';
|
||||
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
|
||||
|
||||
export default function (Private, Promise) {
|
||||
export default function (Private) {
|
||||
const indexPatterns = Private(FixturesStubbedLogstashIndexPatternProvider);
|
||||
const getIndexPatternStub = sinon.stub()
|
||||
.returns(Promise.resolve(indexPatterns));
|
||||
.resolves(indexPatterns);
|
||||
|
||||
return {
|
||||
get: getIndexPatternStub,
|
||||
|
|
|
@ -21,17 +21,16 @@ import 'ngreact';
|
|||
import { uiModules } from '../modules';
|
||||
import template from './directive.html';
|
||||
import { ApplyFiltersPopover } from './apply_filters_popover';
|
||||
import { FilterBarLibMapAndFlattenFiltersProvider } from '../filter_bar/lib/map_and_flatten_filters';
|
||||
import { mapAndFlattenFilters } from '../filter_bar/lib/map_and_flatten_filters';
|
||||
import { wrapInI18nContext } from 'ui/i18n';
|
||||
|
||||
const app = uiModules.get('app/kibana', ['react']);
|
||||
|
||||
app.directive('applyFiltersPopoverComponent', (reactDirective) => {
|
||||
return reactDirective(ApplyFiltersPopover);
|
||||
return reactDirective(wrapInI18nContext(ApplyFiltersPopover));
|
||||
});
|
||||
|
||||
app.directive('applyFiltersPopover', (reactDirective, Private) => {
|
||||
const mapAndFlattenFilters = Private(FilterBarLibMapAndFlattenFiltersProvider);
|
||||
|
||||
app.directive('applyFiltersPopover', (indexPatterns) => {
|
||||
return {
|
||||
template,
|
||||
restrict: 'E',
|
||||
|
@ -47,7 +46,7 @@ app.directive('applyFiltersPopover', (reactDirective, Private) => {
|
|||
// popover, because it has to reset its state whenever the new filters change. Setting a `key`
|
||||
// property on the component accomplishes this due to how React handles the `key` property.
|
||||
$scope.$watch('filters', filters => {
|
||||
mapAndFlattenFilters(filters).then(mappedFilters => {
|
||||
mapAndFlattenFilters(indexPatterns, filters).then(mappedFilters => {
|
||||
$scope.state = {
|
||||
filters: mappedFilters,
|
||||
key: Date.now(),
|
||||
|
|
|
@ -30,7 +30,7 @@ import { createLegacyClass } from './utils/legacy_class';
|
|||
|
||||
const location = 'EventEmitter';
|
||||
|
||||
export function EventsProvider(Private, Promise) {
|
||||
export function EventsProvider(Promise) {
|
||||
createLegacyClass(Events).inherits(SimpleEmitter);
|
||||
function Events() {
|
||||
Events.Super.call(this);
|
||||
|
|
|
@ -25,6 +25,8 @@ import MockState from 'fixtures/mock_state';
|
|||
import { FilterBarQueryFilterProvider } from '../query_filter';
|
||||
|
||||
describe('add filters', function () {
|
||||
require('test_utils/no_digest_promises').activateForSuite();
|
||||
|
||||
let filters;
|
||||
let queryFilter;
|
||||
let $rootScope;
|
||||
|
@ -73,44 +75,33 @@ describe('add filters', function () {
|
|||
});
|
||||
|
||||
describe('adding filters', function () {
|
||||
it('should add filters to appState', function () {
|
||||
$rootScope.$digest();
|
||||
|
||||
queryFilter.addFilters(filters);
|
||||
$rootScope.$digest();
|
||||
|
||||
it('should add filters to appState', async function () {
|
||||
await queryFilter.addFilters(filters);
|
||||
expect(appState.filters.length).to.be(3);
|
||||
expect(globalState.filters.length).to.be(0);
|
||||
});
|
||||
|
||||
it('should add filters to globalState', function () {
|
||||
$rootScope.$digest();
|
||||
|
||||
queryFilter.addFilters(filters, true);
|
||||
$rootScope.$digest();
|
||||
it('should add filters to globalState', async function () {
|
||||
await queryFilter.addFilters(filters, true);
|
||||
|
||||
expect(appState.filters.length).to.be(0);
|
||||
expect(globalState.filters.length).to.be(3);
|
||||
});
|
||||
|
||||
it('should accept a single filter', function () {
|
||||
$rootScope.$digest();
|
||||
|
||||
queryFilter.addFilters(filters[0]);
|
||||
$rootScope.$digest();
|
||||
it('should accept a single filter', async function () {
|
||||
await queryFilter.addFilters(filters[0]);
|
||||
|
||||
expect(appState.filters.length).to.be(1);
|
||||
expect(globalState.filters.length).to.be(0);
|
||||
});
|
||||
|
||||
it('should allow overwriting a positive filter by a negated one', () => {
|
||||
$rootScope.$digest();
|
||||
it('should allow overwriting a positive filter by a negated one', async function () {
|
||||
|
||||
// Add negate: false version of the filter
|
||||
const filter = _.cloneDeep(filters[0]);
|
||||
filter.meta.negate = false;
|
||||
|
||||
queryFilter.addFilters(filter);
|
||||
await queryFilter.addFilters(filter);
|
||||
$rootScope.$digest();
|
||||
expect(appState.filters.length).to.be(1);
|
||||
expect(appState.filters[0]).to.eql(filter);
|
||||
|
@ -119,22 +110,21 @@ describe('add filters', function () {
|
|||
const negatedFilter = _.cloneDeep(filters[0]);
|
||||
negatedFilter.meta.negate = true;
|
||||
|
||||
queryFilter.addFilters(negatedFilter);
|
||||
await queryFilter.addFilters(negatedFilter);
|
||||
$rootScope.$digest();
|
||||
// The negated filter should overwrite the positive one
|
||||
expect(appState.filters.length).to.be(1);
|
||||
expect(appState.filters[0]).to.eql(negatedFilter);
|
||||
});
|
||||
|
||||
it('should allow overwriting a negated filter by a positive one', () => {
|
||||
$rootScope.$digest();
|
||||
|
||||
it('should allow overwriting a negated filter by a positive one', async function () {
|
||||
// Add negate: true version of the same filter
|
||||
const negatedFilter = _.cloneDeep(filters[0]);
|
||||
negatedFilter.meta.negate = true;
|
||||
|
||||
queryFilter.addFilters(negatedFilter);
|
||||
await queryFilter.addFilters(negatedFilter);
|
||||
$rootScope.$digest();
|
||||
|
||||
// The negated filter should overwrite the positive one
|
||||
expect(appState.filters.length).to.be(1);
|
||||
expect(appState.filters[0]).to.eql(negatedFilter);
|
||||
|
@ -143,18 +133,24 @@ describe('add filters', function () {
|
|||
const filter = _.cloneDeep(filters[0]);
|
||||
filter.meta.negate = false;
|
||||
|
||||
queryFilter.addFilters(filter);
|
||||
await queryFilter.addFilters(filter);
|
||||
$rootScope.$digest();
|
||||
expect(appState.filters.length).to.be(1);
|
||||
expect(appState.filters[0]).to.eql(filter);
|
||||
});
|
||||
|
||||
it('should fire the update and fetch events', function () {
|
||||
it('should fire the update and fetch events', async function () {
|
||||
const emitSpy = sinon.spy(queryFilter, 'emit');
|
||||
|
||||
const awaitFetch = new Promise(resolve => {
|
||||
queryFilter.on('fetch', () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
// set up the watchers, add new filters, and crank the digest loop
|
||||
$rootScope.$digest();
|
||||
queryFilter.addFilters(filters);
|
||||
await queryFilter.addFilters(filters);
|
||||
$rootScope.$digest();
|
||||
|
||||
// updates should trigger state saves
|
||||
|
@ -162,44 +158,44 @@ describe('add filters', function () {
|
|||
expect(globalState.save.callCount).to.be(1);
|
||||
|
||||
// this time, events should be emitted
|
||||
await awaitFetch;
|
||||
expect(emitSpy.callCount).to.be(2);
|
||||
expect(emitSpy.firstCall.args[0]).to.be('update');
|
||||
expect(emitSpy.secondCall.args[0]).to.be('fetch');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('filter reconciliation', function () {
|
||||
it('should de-dupe appState filters being added', function () {
|
||||
it('should de-dupe appState filters being added', async function () {
|
||||
const newFilter = _.cloneDeep(filters[1]);
|
||||
appState.filters = filters;
|
||||
$rootScope.$digest();
|
||||
expect(appState.filters.length).to.be(3);
|
||||
|
||||
queryFilter.addFilters(newFilter);
|
||||
await queryFilter.addFilters(newFilter);
|
||||
$rootScope.$digest();
|
||||
expect(appState.filters.length).to.be(3);
|
||||
});
|
||||
|
||||
it('should de-dupe globalState filters being added', function () {
|
||||
it('should de-dupe globalState filters being added', async function () {
|
||||
const newFilter = _.cloneDeep(filters[1]);
|
||||
globalState.filters = filters;
|
||||
$rootScope.$digest();
|
||||
expect(globalState.filters.length).to.be(3);
|
||||
|
||||
queryFilter.addFilters(newFilter, true);
|
||||
await queryFilter.addFilters(newFilter, true);
|
||||
$rootScope.$digest();
|
||||
expect(globalState.filters.length).to.be(3);
|
||||
});
|
||||
|
||||
it('should mutate global filters on appState filter changes', function () {
|
||||
it('should mutate global filters on appState filter changes', async function () {
|
||||
const idx = 1;
|
||||
globalState.filters = filters;
|
||||
$rootScope.$digest();
|
||||
|
||||
const appFilter = _.cloneDeep(filters[idx]);
|
||||
appFilter.meta.negate = true;
|
||||
queryFilter.addFilters(appFilter);
|
||||
await queryFilter.addFilters(appFilter);
|
||||
$rootScope.$digest();
|
||||
|
||||
const res = queryFilter.getFilters();
|
||||
|
|
|
@ -1,87 +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 expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarPushFilterProvider } from '../push_filter';
|
||||
describe('Filter Bar pushFilter()', function () {
|
||||
|
||||
let pushFilterFn;
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
pushFilterFn = Private(FilterBarPushFilterProvider);
|
||||
}));
|
||||
|
||||
it('is a function that returns a function', function () {
|
||||
expect(pushFilterFn).to.be.a(Function);
|
||||
expect(pushFilterFn({})).to.be.a(Function);
|
||||
});
|
||||
|
||||
it('throws an error if passed something besides an object', function () {
|
||||
expect(pushFilterFn).withArgs(true).to.throwError();
|
||||
});
|
||||
|
||||
describe('pushFilter($state)()', function () {
|
||||
let $state;
|
||||
let pushFilter;
|
||||
let filter;
|
||||
|
||||
beforeEach(ngMock.inject(function () {
|
||||
$state = { $newFilters: [] };
|
||||
pushFilter = pushFilterFn($state);
|
||||
filter = { query: { query_string: { query: '' } } };
|
||||
}));
|
||||
|
||||
it('should create the filters property it needed', function () {
|
||||
const altState = {};
|
||||
pushFilterFn(altState)(filter);
|
||||
expect(altState.$newFilters).to.be.an(Array);
|
||||
});
|
||||
|
||||
it('should replace the filters property instead of modifying it', function () {
|
||||
// If we push directly instead of using pushFilter a $watch('filters') does not trigger
|
||||
|
||||
let oldFilters;
|
||||
|
||||
oldFilters = $state.$newFilters;
|
||||
$state.$newFilters.push(filter);
|
||||
expect($state.$newFilters).to.equal(oldFilters); // Same object
|
||||
|
||||
oldFilters = $state.$newFilters;
|
||||
pushFilter(filter);
|
||||
expect($state.$newFilters).to.not.equal(oldFilters); // New object!
|
||||
});
|
||||
|
||||
it('should add meta data to the filter', function () {
|
||||
pushFilter(filter, true, 'myIndex');
|
||||
expect($state.$newFilters[0].meta).to.be.an(Object);
|
||||
|
||||
expect($state.$newFilters[0].meta.negate).to.be(true);
|
||||
expect($state.$newFilters[0].meta.index).to.be('myIndex');
|
||||
|
||||
pushFilter(filter, false, 'myIndex');
|
||||
expect($state.$newFilters[0].meta.negate).to.be(false);
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
|
@ -19,24 +19,20 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarLibExtractTimeFilterProvider } from '../extract_time_filter';
|
||||
import { extractTimeFilter } from '../extract_time_filter';
|
||||
import IndexPatternMock from 'fixtures/mock_index_patterns';
|
||||
|
||||
describe('Filter Bar Directive', function () {
|
||||
describe('extractTimeFilter()', function () {
|
||||
let extractTimeFilter;
|
||||
let $rootScope;
|
||||
let mockIndexPatterns;
|
||||
|
||||
beforeEach(ngMock.module(
|
||||
'kibana',
|
||||
'kibana/courier',
|
||||
function ($provide) {
|
||||
$provide.service('indexPatterns', require('fixtures/mock_index_patterns'));
|
||||
}
|
||||
'kibana/courier'
|
||||
));
|
||||
|
||||
beforeEach(ngMock.inject(function (Private, _$rootScope_) {
|
||||
extractTimeFilter = Private(FilterBarLibExtractTimeFilterProvider);
|
||||
$rootScope = _$rootScope_;
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
mockIndexPatterns = Private(IndexPatternMock);
|
||||
}));
|
||||
|
||||
it('should return the matching filter for the default time field', function (done) {
|
||||
|
@ -44,11 +40,10 @@ describe('Filter Bar Directive', function () {
|
|||
{ meta: { index: 'logstash-*' }, query: { match: { _type: { query: 'apache', type: 'phrase' } } } },
|
||||
{ meta: { index: 'logstash-*' }, range: { 'time': { gt: 1388559600000, lt: 1388646000000 } } }
|
||||
];
|
||||
extractTimeFilter(filters).then(function (filter) {
|
||||
extractTimeFilter(mockIndexPatterns, filters).then(function (filter) {
|
||||
expect(filter).to.eql(filters[1]);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should not return the non-matching filter for the default time field', function (done) {
|
||||
|
@ -56,11 +51,10 @@ describe('Filter Bar Directive', function () {
|
|||
{ meta: { index: 'logstash-*' }, query: { match: { _type: { query: 'apache', type: 'phrase' } } } },
|
||||
{ meta: { index: 'logstash-*' }, range: { '@timestamp': { gt: 1388559600000, lt: 1388646000000 } } }
|
||||
];
|
||||
extractTimeFilter(filters).then(function (filter) {
|
||||
extractTimeFilter(mockIndexPatterns, filters).then(function (filter) {
|
||||
expect(filter).to.be(undefined);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -20,74 +20,57 @@
|
|||
import sinon from 'sinon';
|
||||
import expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarLibGenerateMappingChainProvider } from '../generate_mapping_chain';
|
||||
import { generateMappingChain } from '../generate_mapping_chain';
|
||||
|
||||
describe('Filter Bar Directive', function () {
|
||||
describe('generateMappingChain()', function () {
|
||||
|
||||
let generateMappingChain;
|
||||
|
||||
let $rootScope;
|
||||
let Promise;
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private, _$rootScope_, _Promise_) {
|
||||
$rootScope = _$rootScope_;
|
||||
Promise = _Promise_;
|
||||
generateMappingChain = Private(FilterBarLibGenerateMappingChainProvider);
|
||||
}));
|
||||
|
||||
|
||||
it('should create a chaining function which calls the next function if the promise is rejected', function (done) {
|
||||
const filter = {};
|
||||
const mapping = sinon.stub();
|
||||
mapping.returns(Promise.reject(filter));
|
||||
const mappingChainFn = generateMappingChain(mapping);
|
||||
mapping.rejects(filter);
|
||||
const next = sinon.stub();
|
||||
next.returns(Promise.resolve('good'));
|
||||
const chain = mappingChainFn(next);
|
||||
next.resolves('good');
|
||||
const chain = generateMappingChain(mapping, next);
|
||||
chain(filter).then(function (result) {
|
||||
expect(result).to.be('good');
|
||||
sinon.assert.calledOnce(next);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should create a chaining function which DOES NOT call the next function if the result is resolved', function (done) {
|
||||
const mapping = sinon.stub();
|
||||
mapping.returns(Promise.resolve('good'));
|
||||
const mappingChainFn = generateMappingChain(mapping);
|
||||
mapping.resolves('good');
|
||||
const next = sinon.stub();
|
||||
next.returns(Promise.resolve('bad'));
|
||||
const chain = mappingChainFn(next);
|
||||
next.resolves('bad');
|
||||
const chain = generateMappingChain(mapping, next);
|
||||
chain({}).then(function (result) {
|
||||
expect(result).to.be('good');
|
||||
sinon.assert.notCalled(next);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should resolve result for the mapping function', function (done) {
|
||||
const mapping = sinon.stub();
|
||||
mapping.returns(Promise.resolve({ key: 'test', value: 'example' }));
|
||||
const mappingChainFn = generateMappingChain(mapping);
|
||||
mapping.resolves({ key: 'test', value: 'example' });
|
||||
const next = sinon.stub();
|
||||
const chain = mappingChainFn(next);
|
||||
const chain = generateMappingChain(mapping, next);
|
||||
chain({}).then(function (result) {
|
||||
sinon.assert.notCalled(next);
|
||||
expect(result).to.eql({ key: 'test', value: 'example' });
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should call the mapping function with the argument to the chain', function (done) {
|
||||
const mapping = sinon.stub();
|
||||
mapping.returns(Promise.resolve({ key: 'test', value: 'example' }));
|
||||
const mappingChainFn = generateMappingChain(mapping);
|
||||
mapping.resolves({ key: 'test', value: 'example' });
|
||||
const next = sinon.stub();
|
||||
const chain = mappingChainFn(next);
|
||||
const chain = generateMappingChain(mapping, next);
|
||||
chain({ test: 'example' }).then(function (result) {
|
||||
sinon.assert.calledOnce(mapping);
|
||||
expect(mapping.args[0][0]).to.eql({ test: 'example' });
|
||||
|
@ -95,38 +78,33 @@ describe('Filter Bar Directive', function () {
|
|||
expect(result).to.eql({ key: 'test', value: 'example' });
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should resolve result for the next function', function (done) {
|
||||
const filter = {};
|
||||
const mapping = sinon.stub();
|
||||
mapping.returns(Promise.reject(filter));
|
||||
const mappingChainFn = generateMappingChain(mapping);
|
||||
mapping.rejects(filter);
|
||||
const next = sinon.stub();
|
||||
next.returns(Promise.resolve({ key: 'test', value: 'example' }));
|
||||
const chain = mappingChainFn(next);
|
||||
next.resolves({ key: 'test', value: 'example' });
|
||||
const chain = generateMappingChain(mapping, next);
|
||||
chain(filter).then(function (result) {
|
||||
sinon.assert.calledOnce(mapping);
|
||||
sinon.assert.calledOnce(next);
|
||||
expect(result).to.eql({ key: 'test', value: 'example' });
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should reject with an error if no functions match', function (done) {
|
||||
const filter = {};
|
||||
const mapping = sinon.stub();
|
||||
mapping.returns(Promise.reject(filter));
|
||||
const mappingChainFn = generateMappingChain(mapping);
|
||||
const chain = mappingChainFn();
|
||||
mapping.rejects(filter);
|
||||
const chain = generateMappingChain(mapping);
|
||||
chain(filter).catch(function (err) {
|
||||
expect(err).to.be.an(Error);
|
||||
expect(err.message).to.be('No mappings have been found for filter.');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -19,24 +19,20 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarLibMapAndFlattenFiltersProvider } from '../map_and_flatten_filters';
|
||||
import { mapAndFlattenFilters } from '../map_and_flatten_filters';
|
||||
import IndexPatternMock from 'fixtures/mock_index_patterns';
|
||||
|
||||
describe('Filter Bar Directive', function () {
|
||||
describe('mapAndFlattenFilters()', function () {
|
||||
let mapAndFlattenFilters;
|
||||
let $rootScope;
|
||||
let mockIndexPatterns;
|
||||
|
||||
beforeEach(ngMock.module(
|
||||
'kibana',
|
||||
'kibana/courier',
|
||||
function ($provide) {
|
||||
$provide.service('indexPatterns', require('fixtures/mock_index_patterns'));
|
||||
}
|
||||
'kibana/courier'
|
||||
));
|
||||
|
||||
beforeEach(ngMock.inject(function (Private, _$rootScope_) {
|
||||
mapAndFlattenFilters = Private(FilterBarLibMapAndFlattenFiltersProvider);
|
||||
$rootScope = _$rootScope_;
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
mockIndexPatterns = Private(IndexPatternMock);
|
||||
}));
|
||||
|
||||
const filters = [
|
||||
|
@ -51,7 +47,7 @@ describe('Filter Bar Directive', function () {
|
|||
];
|
||||
|
||||
it('should map and flatten the filters', function (done) {
|
||||
mapAndFlattenFilters(filters).then(function (results) {
|
||||
mapAndFlattenFilters(mockIndexPatterns, filters).then(function (results) {
|
||||
expect(results).to.have.length(5);
|
||||
expect(results[0]).to.have.property('meta');
|
||||
expect(results[1]).to.have.property('meta');
|
||||
|
@ -70,7 +66,6 @@ describe('Filter Bar Directive', function () {
|
|||
expect(results[4].meta).to.have.property('value', 'apache');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -18,20 +18,11 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarLibMapDefaultProvider } from '../map_default';
|
||||
import { mapDefault } from '../map_default';
|
||||
|
||||
describe('Filter Bar Directive', function () {
|
||||
describe('mapDefault()', function () {
|
||||
|
||||
let mapDefault;
|
||||
let $rootScope;
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private, _$rootScope_) {
|
||||
$rootScope = _$rootScope_;
|
||||
mapDefault = Private(FilterBarLibMapDefaultProvider);
|
||||
}));
|
||||
|
||||
it('should return the key and value for matching filters', function (done) {
|
||||
const filter = { query: { match_all: {} } };
|
||||
mapDefault(filter).then(function (result) {
|
||||
|
@ -39,7 +30,6 @@ describe('Filter Bar Directive', function () {
|
|||
expect(result).to.have.property('value', '{"match_all":{}}');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should work with undefined filter types', function (done) {
|
||||
|
@ -57,7 +47,6 @@ describe('Filter Bar Directive', function () {
|
|||
expect(result).to.have.property('value', JSON.stringify(filter.bool));
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should return undefined if there is no valid key', function (done) {
|
||||
|
@ -66,7 +55,6 @@ describe('Filter Bar Directive', function () {
|
|||
expect(result).to.be(filter);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -19,18 +19,12 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarLibMapExistsProvider } from '../map_exists';
|
||||
import { mapExists } from '../map_exists';
|
||||
|
||||
describe('Filter Bar Directive', function () {
|
||||
describe('mapExists()', function () {
|
||||
|
||||
let mapExists;
|
||||
let $rootScope;
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private, _$rootScope_) {
|
||||
$rootScope = _$rootScope_;
|
||||
mapExists = Private(FilterBarLibMapExistsProvider);
|
||||
}));
|
||||
|
||||
it('should return the key and value for matching filters', function (done) {
|
||||
const filter = { exists: { field: '_type' } };
|
||||
|
@ -39,7 +33,6 @@ describe('Filter Bar Directive', function () {
|
|||
expect(result).to.have.property('value', 'exists');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should return undefined for none matching', function (done) {
|
||||
|
@ -48,7 +41,6 @@ describe('Filter Bar Directive', function () {
|
|||
expect(result).to.be(filter);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -19,30 +19,25 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarLibMapFilterProvider } from '../map_filter';
|
||||
import { mapFilter } from '../map_filter';
|
||||
import IndexPatternMock from 'fixtures/mock_index_patterns';
|
||||
|
||||
describe('Filter Bar Directive', function () {
|
||||
let mapFilter;
|
||||
let $rootScope;
|
||||
|
||||
let mockIndexPatterns;
|
||||
|
||||
beforeEach(ngMock.module(
|
||||
'kibana',
|
||||
'kibana/courier',
|
||||
function ($provide) {
|
||||
$provide.service('indexPatterns', require('fixtures/mock_index_patterns'));
|
||||
}
|
||||
'kibana/courier'
|
||||
));
|
||||
|
||||
beforeEach(ngMock.inject(function (_$rootScope_, Private) {
|
||||
mapFilter = Private(FilterBarLibMapFilterProvider);
|
||||
$rootScope = _$rootScope_;
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
mockIndexPatterns = Private(IndexPatternMock);
|
||||
}));
|
||||
|
||||
describe('mapFilter()', function () {
|
||||
it('should map query filters', function (done) {
|
||||
const before = { meta: { index: 'logstash-*' }, query: { match: { '_type': { query: 'apache' } } } };
|
||||
mapFilter(before).then(function (after) {
|
||||
mapFilter(mockIndexPatterns, before).then(function (after) {
|
||||
expect(after).to.have.property('meta');
|
||||
expect(after.meta).to.have.property('key', '_type');
|
||||
expect(after.meta).to.have.property('value', 'apache');
|
||||
|
@ -50,12 +45,11 @@ describe('Filter Bar Directive', function () {
|
|||
expect(after.meta).to.have.property('negate', false);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should map exists filters', function (done) {
|
||||
const before = { meta: { index: 'logstash-*' }, exists: { field: '@timestamp' } };
|
||||
mapFilter(before).then(function (after) {
|
||||
mapFilter(mockIndexPatterns, before).then(function (after) {
|
||||
expect(after).to.have.property('meta');
|
||||
expect(after.meta).to.have.property('key', '@timestamp');
|
||||
expect(after.meta).to.have.property('value', 'exists');
|
||||
|
@ -63,12 +57,11 @@ describe('Filter Bar Directive', function () {
|
|||
expect(after.meta).to.have.property('negate', false);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should map missing filters', function (done) {
|
||||
const before = { meta: { index: 'logstash-*' }, missing: { field: '@timestamp' } };
|
||||
mapFilter(before).then(function (after) {
|
||||
mapFilter(mockIndexPatterns, before).then(function (after) {
|
||||
expect(after).to.have.property('meta');
|
||||
expect(after.meta).to.have.property('key', '@timestamp');
|
||||
expect(after.meta).to.have.property('value', 'missing');
|
||||
|
@ -76,12 +69,11 @@ describe('Filter Bar Directive', function () {
|
|||
expect(after.meta).to.have.property('negate', false);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should map json filter', function (done) {
|
||||
const before = { meta: { index: 'logstash-*' }, query: { match_all: {} } };
|
||||
mapFilter(before).then(function (after) {
|
||||
mapFilter(mockIndexPatterns, before).then(function (after) {
|
||||
expect(after).to.have.property('meta');
|
||||
expect(after.meta).to.have.property('key', 'query');
|
||||
expect(after.meta).to.have.property('value', '{"match_all":{}}');
|
||||
|
@ -89,17 +81,15 @@ describe('Filter Bar Directive', function () {
|
|||
expect(after.meta).to.have.property('negate', false);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should finish with a catch', function (done) {
|
||||
const before = { meta: { index: 'logstash-*' } };
|
||||
mapFilter(before).catch(function (error) {
|
||||
mapFilter(mockIndexPatterns, before).catch(function (error) {
|
||||
expect(error).to.be.an(Error);
|
||||
expect(error.message).to.be('No mappings have been found for filter.');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -1,68 +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 expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarLibMapFlattenAndWrapFiltersProvider } from '../map_flatten_and_wrap_filters';
|
||||
|
||||
describe('Filter Bar Directive', function () {
|
||||
describe('mapFlattenAndWrapFilters()', function () {
|
||||
let mapFlattenAndWrapFilters;
|
||||
let $rootScope;
|
||||
|
||||
beforeEach(ngMock.module(
|
||||
'kibana',
|
||||
'kibana/courier',
|
||||
function ($provide) {
|
||||
$provide.service('indexPatterns', require('fixtures/mock_index_patterns'));
|
||||
}
|
||||
));
|
||||
|
||||
beforeEach(ngMock.inject(function (Private, _$rootScope_) {
|
||||
mapFlattenAndWrapFilters = Private(FilterBarLibMapFlattenAndWrapFiltersProvider);
|
||||
$rootScope = _$rootScope_;
|
||||
}));
|
||||
|
||||
const filters = [
|
||||
null,
|
||||
[
|
||||
{ meta: { index: 'logstash-*' }, exists: { field: '_type' } },
|
||||
{ meta: { index: 'logstash-*' }, missing: { field: '_type' } }
|
||||
],
|
||||
{ meta: { index: 'logstash-*' }, query: { query_string: { query: 'foo:bar' } } },
|
||||
{ meta: { index: 'logstash-*' }, range: { bytes: { lt: 2048, gt: 1024 } } },
|
||||
{ meta: { index: 'logstash-*' }, query: { match: { _type: { query: 'apache', type: 'phrase' } } } }
|
||||
];
|
||||
|
||||
it('should map, flatten and wrap filters', function (done) {
|
||||
mapFlattenAndWrapFilters(filters).then(function (results) {
|
||||
expect(results).to.have.length(5);
|
||||
_.each(results, function (filter) {
|
||||
expect(filter).to.have.property('meta');
|
||||
expect(filter.meta).to.have.property('apply', true);
|
||||
});
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
|
@ -19,24 +19,22 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarLibMapGeoBoundingBoxProvider } from '../map_geo_bounding_box';
|
||||
import { mapGeoBoundingBox } from '../map_geo_bounding_box';
|
||||
import IndexPatternMock from 'fixtures/mock_index_patterns';
|
||||
|
||||
describe('Filter Bar Directive', function () {
|
||||
describe('mapGeoBoundingBox()', function () {
|
||||
let mapGeoBoundingBox;
|
||||
let $rootScope;
|
||||
let mapGeoBoundingBoxFn;
|
||||
let mockIndexPatterns;
|
||||
|
||||
beforeEach(ngMock.module(
|
||||
'kibana',
|
||||
'kibana/courier',
|
||||
function ($provide) {
|
||||
$provide.service('indexPatterns', require('fixtures/mock_index_patterns'));
|
||||
}
|
||||
'kibana/courier'
|
||||
));
|
||||
|
||||
beforeEach(ngMock.inject(function (Private, _$rootScope_) {
|
||||
mapGeoBoundingBox = Private(FilterBarLibMapGeoBoundingBoxProvider);
|
||||
$rootScope = _$rootScope_;
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
mockIndexPatterns = Private(IndexPatternMock);
|
||||
mapGeoBoundingBoxFn = mapGeoBoundingBox(mockIndexPatterns);
|
||||
}));
|
||||
|
||||
it('should return the key and value for matching filters with bounds', function (done) {
|
||||
|
@ -51,23 +49,21 @@ describe('Filter Bar Directive', function () {
|
|||
}
|
||||
}
|
||||
};
|
||||
mapGeoBoundingBox(filter).then(function (result) {
|
||||
mapGeoBoundingBoxFn(filter).then(function (result) {
|
||||
expect(result).to.have.property('key', 'point');
|
||||
expect(result).to.have.property('value');
|
||||
// remove html entities and non-alphanumerics to get the gist of the value
|
||||
expect(result.value.replace(/&[a-z]+?;/g, '').replace(/[^a-z0-9]/g, '')).to.be('lat5lon10tolat15lon20');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should return undefined for none matching', function (done) {
|
||||
const filter = { meta: { index: 'logstash-*' }, query: { query_string: { query: 'foo:bar' } } };
|
||||
mapGeoBoundingBox(filter).catch(function (result) {
|
||||
mapGeoBoundingBoxFn(filter).catch(function (result) {
|
||||
expect(result).to.be(filter);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should return the key and value even when using ignore_unmapped', function (done) {
|
||||
|
@ -83,14 +79,13 @@ describe('Filter Bar Directive', function () {
|
|||
}
|
||||
}
|
||||
};
|
||||
mapGeoBoundingBox(filter).then(function (result) {
|
||||
mapGeoBoundingBoxFn(filter).then(function (result) {
|
||||
expect(result).to.have.property('key', 'point');
|
||||
expect(result).to.have.property('value');
|
||||
// remove html entities and non-alphanumerics to get the gist of the value
|
||||
expect(result.value.replace(/&[a-z]+?;/g, '').replace(/[^a-z0-9]/g, '')).to.be('lat5lon10tolat15lon20');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -19,24 +19,22 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarLibMapGeoPolygonProvider } from '../map_geo_polygon';
|
||||
import { mapGeoPolygon } from '../map_geo_polygon';
|
||||
import IndexPatternMock from 'fixtures/mock_index_patterns';
|
||||
|
||||
describe('Filter Bar Directive', function () {
|
||||
describe('mapGeoPolygon()', function () {
|
||||
let mapGeoPolygon;
|
||||
let $rootScope;
|
||||
let mapGeoPolygonFn;
|
||||
let mockIndexPatterns;
|
||||
|
||||
beforeEach(ngMock.module(
|
||||
'kibana',
|
||||
'kibana/courier',
|
||||
function ($provide) {
|
||||
$provide.service('indexPatterns', require('fixtures/mock_index_patterns'));
|
||||
}
|
||||
'kibana/courier'
|
||||
));
|
||||
|
||||
beforeEach(ngMock.inject(function (Private, _$rootScope_) {
|
||||
mapGeoPolygon = Private(FilterBarLibMapGeoPolygonProvider);
|
||||
$rootScope = _$rootScope_;
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
mockIndexPatterns = Private(IndexPatternMock);
|
||||
mapGeoPolygonFn = mapGeoPolygon(mockIndexPatterns);
|
||||
}));
|
||||
|
||||
it('should return the key and value for matching filters with bounds', function (done) {
|
||||
|
@ -53,23 +51,21 @@ describe('Filter Bar Directive', function () {
|
|||
}
|
||||
}
|
||||
};
|
||||
mapGeoPolygon(filter).then(function (result) {
|
||||
mapGeoPolygonFn(filter).then(function (result) {
|
||||
expect(result).to.have.property('key', 'point');
|
||||
expect(result).to.have.property('value');
|
||||
// remove html entities and non-alphanumerics to get the gist of the value
|
||||
expect(result.value.replace(/&[a-z]+?;/g, '').replace(/[^a-z0-9]/g, '')).to.be('lat5lon10lat15lon20');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should return undefined for none matching', function (done) {
|
||||
const filter = { meta: { index: 'logstash-*' }, query: { query_string: { query: 'foo:bar' } } };
|
||||
mapGeoPolygon(filter).catch(function (result) {
|
||||
mapGeoPolygonFn(filter).catch(function (result) {
|
||||
expect(result).to.be(filter);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should return the key and value even when using ignore_unmapped', function (done) {
|
||||
|
@ -87,14 +83,13 @@ describe('Filter Bar Directive', function () {
|
|||
}
|
||||
}
|
||||
};
|
||||
mapGeoPolygon(filter).then(function (result) {
|
||||
mapGeoPolygonFn(filter).then(function (result) {
|
||||
expect(result).to.have.property('key', 'point');
|
||||
expect(result).to.have.property('value');
|
||||
// remove html entities and non-alphanumerics to get the gist of the value
|
||||
expect(result.value.replace(/&[a-z]+?;/g, '').replace(/[^a-z0-9]/g, '')).to.be('lat5lon10lat15lon20');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -19,19 +19,15 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarLibMapMatchAllProvider } from '../map_match_all';
|
||||
import { mapMatchAll } from '../map_match_all';
|
||||
|
||||
describe('ui/filter_bar/lib', function () {
|
||||
describe('mapMatchAll()', function () {
|
||||
let $rootScope;
|
||||
let mapMatchAll;
|
||||
let filter;
|
||||
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private, _$rootScope_) {
|
||||
$rootScope = _$rootScope_;
|
||||
mapMatchAll = Private(FilterBarLibMapMatchAllProvider);
|
||||
beforeEach(ngMock.inject(function () {
|
||||
filter = {
|
||||
match_all: {},
|
||||
meta: {
|
||||
|
@ -48,15 +44,16 @@ describe('ui/filter_bar/lib', function () {
|
|||
expect(result).to.be(filter);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when given a match_all filter', function () {
|
||||
let result;
|
||||
beforeEach(function () {
|
||||
mapMatchAll(filter).then(r => result = r);
|
||||
$rootScope.$apply();
|
||||
beforeEach(function (done) {
|
||||
mapMatchAll(filter).then(r => {
|
||||
result = r;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('key is set to meta field', function () {
|
||||
|
|
|
@ -17,22 +17,12 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import ngMock from 'ng_mock';
|
||||
import expect from '@kbn/expect';
|
||||
import { FilterBarLibMapMissingProvider } from '../map_missing';
|
||||
import { mapMissing } from '../map_missing';
|
||||
|
||||
describe('Filter Bar Directive', function () {
|
||||
describe('mapMissing()', function () {
|
||||
|
||||
let mapMissing;
|
||||
|
||||
let $rootScope;
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private, _$rootScope_) {
|
||||
$rootScope = _$rootScope_;
|
||||
mapMissing = Private(FilterBarLibMapMissingProvider);
|
||||
}));
|
||||
|
||||
it('should return the key and value for matching filters', function (done) {
|
||||
const filter = { missing: { field: '_type' } };
|
||||
mapMissing(filter).then(function (result) {
|
||||
|
@ -40,7 +30,6 @@ describe('Filter Bar Directive', function () {
|
|||
expect(result).to.have.property('value', 'missing');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should return undefined for none matching', function (done) {
|
||||
|
@ -49,7 +38,6 @@ describe('Filter Bar Directive', function () {
|
|||
expect(result).to.be(filter);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -19,43 +19,39 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarLibMapPhraseProvider } from '../map_phrase';
|
||||
import { mapPhrase } from '../map_phrase';
|
||||
import IndexPatternMock from 'fixtures/mock_index_patterns';
|
||||
|
||||
describe('Filter Bar Directive', function () {
|
||||
describe('mapPhrase()', function () {
|
||||
let mapPhrase;
|
||||
let $rootScope;
|
||||
let mapPhraseFn;
|
||||
let mockIndexPatterns;
|
||||
|
||||
beforeEach(ngMock.module(
|
||||
'kibana',
|
||||
'kibana/courier',
|
||||
function ($provide) {
|
||||
$provide.service('indexPatterns', require('fixtures/mock_index_patterns'));
|
||||
}
|
||||
'kibana/courier'
|
||||
));
|
||||
|
||||
beforeEach(ngMock.inject(function (Private, _$rootScope_) {
|
||||
$rootScope = _$rootScope_;
|
||||
mapPhrase = Private(FilterBarLibMapPhraseProvider);
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
mockIndexPatterns = Private(IndexPatternMock);
|
||||
mapPhraseFn = mapPhrase(mockIndexPatterns);
|
||||
}));
|
||||
|
||||
it('should return the key and value for matching filters', function (done) {
|
||||
const filter = { meta: { index: 'logstash-*' }, query: { match: { _type: { query: 'apache', type: 'phrase' } } } };
|
||||
mapPhrase(filter).then(function (result) {
|
||||
mapPhraseFn(filter).then(function (result) {
|
||||
expect(result).to.have.property('key', '_type');
|
||||
expect(result).to.have.property('value', 'apache');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should return undefined for none matching', function (done) {
|
||||
const filter = { meta: { index: 'logstash-*' }, query: { query_string: { query: 'foo:bar' } } };
|
||||
mapPhrase(filter).catch(function (result) {
|
||||
mapPhraseFn(filter).catch(function (result) {
|
||||
expect(result).to.be(filter);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -18,18 +18,10 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarLibMapQueryStringProvider } from '../map_query_string';
|
||||
import { mapQueryString } from '../map_query_string';
|
||||
|
||||
describe('Filter Bar Directive', function () {
|
||||
describe('mapQueryString()', function () {
|
||||
let mapQueryString;
|
||||
let $rootScope;
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private, _$rootScope_) {
|
||||
$rootScope = _$rootScope_;
|
||||
mapQueryString = Private(FilterBarLibMapQueryStringProvider);
|
||||
}));
|
||||
|
||||
it('should return the key and value for matching filters', function (done) {
|
||||
const filter = { query: { query_string: { query: 'foo:bar' } } };
|
||||
|
@ -38,7 +30,6 @@ describe('Filter Bar Directive', function () {
|
|||
expect(result).to.have.property('value', 'foo:bar');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should return undefined for none matching', function (done) {
|
||||
|
@ -47,7 +38,6 @@ describe('Filter Bar Directive', function () {
|
|||
expect(result).to.be(filter);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -19,53 +19,48 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
import ngMock from 'ng_mock';
|
||||
import { FilterBarLibMapRangeProvider } from '../map_range';
|
||||
import { mapRange } from '../map_range';
|
||||
import IndexPatternMock from 'fixtures/mock_index_patterns';
|
||||
|
||||
describe('Filter Bar Directive', function () {
|
||||
describe('mapRange()', function () {
|
||||
let mapRange;
|
||||
let $rootScope;
|
||||
let mapRangeFn;
|
||||
let mockIndexPatterns;
|
||||
|
||||
beforeEach(ngMock.module(
|
||||
'kibana',
|
||||
'kibana/courier',
|
||||
function ($provide) {
|
||||
$provide.service('indexPatterns', require('fixtures/mock_index_patterns'));
|
||||
}
|
||||
'kibana/courier'
|
||||
));
|
||||
|
||||
beforeEach(ngMock.inject(function (Private, _$rootScope_) {
|
||||
mapRange = Private(FilterBarLibMapRangeProvider);
|
||||
$rootScope = _$rootScope_;
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
mockIndexPatterns = Private(IndexPatternMock);
|
||||
mapRangeFn = mapRange(mockIndexPatterns);
|
||||
}));
|
||||
|
||||
it('should return the key and value for matching filters with gt/lt', function (done) {
|
||||
const filter = { meta: { index: 'logstash-*' }, range: { bytes: { lt: 2048, gt: 1024 } } };
|
||||
mapRange(filter).then(function (result) {
|
||||
mapRangeFn(filter).then(function (result) {
|
||||
expect(result).to.have.property('key', 'bytes');
|
||||
expect(result).to.have.property('value', '1,024 to 2,048');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should return the key and value for matching filters with gte/lte', function (done) {
|
||||
const filter = { meta: { index: 'logstash-*' }, range: { bytes: { lte: 2048, gte: 1024 } } };
|
||||
mapRange(filter).then(function (result) {
|
||||
mapRangeFn(filter).then(function (result) {
|
||||
expect(result).to.have.property('key', 'bytes');
|
||||
expect(result).to.have.property('value', '1,024 to 2,048');
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should return undefined for none matching', function (done) {
|
||||
const filter = { meta: { index: 'logstash-*' }, query: { query_string: { query: 'foo:bar' } } };
|
||||
mapRange(filter).catch(function (result) {
|
||||
mapRangeFn(filter).catch(function (result) {
|
||||
expect(result).to.be(filter);
|
||||
done();
|
||||
});
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -19,21 +19,19 @@
|
|||
|
||||
import _ from 'lodash';
|
||||
|
||||
export function FilterBarLibExtractTimeFilterProvider(indexPatterns, Promise) {
|
||||
return Promise.method(function (filters) {
|
||||
// Assume all the index patterns are the same since they will be added
|
||||
// from the same visualization.
|
||||
const id = _.get(filters, '[0].meta.index');
|
||||
if (id == null) return;
|
||||
export async function extractTimeFilter(indexPatterns, filters) {
|
||||
// Assume all the index patterns are the same since they will be added
|
||||
// from the same visualization.
|
||||
const id = _.get(filters, '[0].meta.index');
|
||||
if (id == null) return;
|
||||
|
||||
return indexPatterns.get(id).then(function (indexPattern) {
|
||||
const filter = _.find(filters, function (obj) {
|
||||
const key = _.keys(obj.range)[0];
|
||||
return key === indexPattern.timeFieldName;
|
||||
});
|
||||
if (filter && filter.range) {
|
||||
return filter;
|
||||
}
|
||||
});
|
||||
const indexPattern = await indexPatterns.get(id);
|
||||
|
||||
const filter = _.find(filters, function (obj) {
|
||||
const key = _.keys(obj.range)[0];
|
||||
return key === indexPattern.timeFieldName;
|
||||
});
|
||||
if (filter && filter.range) {
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,24 +17,18 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export function FilterBarLibGenerateMappingChainProvider(Promise) {
|
||||
|
||||
export function generateMappingChain(fn, next) {
|
||||
const noop = function () {
|
||||
return Promise.reject(new Error('No mappings have been found for filter.'));
|
||||
throw new Error('No mappings have been found for filter.');
|
||||
};
|
||||
|
||||
return function (fn) {
|
||||
return function (next) {
|
||||
next = next || noop;
|
||||
return function (filter) {
|
||||
return fn(filter).catch(function (result) {
|
||||
if (result === filter) {
|
||||
return next(filter);
|
||||
}
|
||||
return Promise.reject(result);
|
||||
});
|
||||
};
|
||||
};
|
||||
next = next || noop;
|
||||
return async function (filter) {
|
||||
return await fn(filter).catch(function (result) {
|
||||
if (result === filter) {
|
||||
return next(filter);
|
||||
}
|
||||
throw result;
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -18,16 +18,12 @@
|
|||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
import { FilterBarLibMapFilterProvider } from './map_filter';
|
||||
import { mapFilter } from './map_filter';
|
||||
|
||||
export function FilterBarLibMapAndFlattenFiltersProvider(Private, Promise) {
|
||||
const mapFilter = Private(FilterBarLibMapFilterProvider);
|
||||
return function (filters) {
|
||||
return _(filters)
|
||||
.flatten()
|
||||
.compact()
|
||||
.map(mapFilter)
|
||||
.thru(Promise.all)
|
||||
.value();
|
||||
};
|
||||
export function mapAndFlattenFilters(indexPatterns, filters) {
|
||||
const flattened = _(filters)
|
||||
.flatten()
|
||||
.compact()
|
||||
.map(item => mapFilter(indexPatterns, item)).value();
|
||||
return Promise.all(flattened);
|
||||
}
|
||||
|
|
|
@ -20,21 +20,18 @@
|
|||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
|
||||
export function FilterBarLibMapDefaultProvider(Promise) {
|
||||
|
||||
export async function mapDefault(filter) {
|
||||
const metaProperty = /(^\$|meta)/;
|
||||
|
||||
return function (filter) {
|
||||
const key = _.find(_.keys(filter), function (key) {
|
||||
return !key.match(metaProperty);
|
||||
});
|
||||
const key = _.find(_.keys(filter), function (key) {
|
||||
return !key.match(metaProperty);
|
||||
});
|
||||
|
||||
if (key) {
|
||||
const type = 'custom';
|
||||
const value = angular.toJson(filter[key]);
|
||||
return Promise.resolve({ type, key, value });
|
||||
}
|
||||
if (key) {
|
||||
const type = 'custom';
|
||||
const value = angular.toJson(filter[key]);
|
||||
return { type, key, value };
|
||||
}
|
||||
|
||||
return Promise.reject(filter);
|
||||
};
|
||||
throw filter;
|
||||
}
|
||||
|
|
|
@ -17,14 +17,12 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export function FilterBarLibMapExistsProvider(Promise) {
|
||||
return function (filter) {
|
||||
if (filter.exists) {
|
||||
const type = 'exists';
|
||||
const key = filter.exists.field;
|
||||
const value = type;
|
||||
return Promise.resolve({ type, key, value });
|
||||
}
|
||||
return Promise.reject(filter);
|
||||
};
|
||||
export async function mapExists(filter) {
|
||||
if (filter.exists) {
|
||||
const type = 'exists';
|
||||
const key = filter.exists.field;
|
||||
const value = type;
|
||||
return { type, key, value };
|
||||
}
|
||||
throw filter;
|
||||
}
|
||||
|
|
|
@ -18,22 +18,19 @@
|
|||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
import { FilterBarLibGenerateMappingChainProvider } from './generate_mapping_chain';
|
||||
import { FilterBarLibMapMatchAllProvider } from './map_match_all';
|
||||
import { FilterBarLibMapPhraseProvider } from './map_phrase';
|
||||
import { FilterBarLibMapPhrasesProvider } from './map_phrases';
|
||||
import { FilterBarLibMapRangeProvider } from './map_range';
|
||||
import { FilterBarLibMapExistsProvider } from './map_exists';
|
||||
import { FilterBarLibMapMissingProvider } from './map_missing';
|
||||
import { FilterBarLibMapQueryStringProvider } from './map_query_string';
|
||||
import { FilterBarLibMapGeoBoundingBoxProvider } from './map_geo_bounding_box';
|
||||
import { FilterBarLibMapGeoPolygonProvider } from './map_geo_polygon';
|
||||
import { FilterBarLibMapDefaultProvider } from './map_default';
|
||||
|
||||
export function FilterBarLibMapFilterProvider(Promise, Private) {
|
||||
|
||||
const generateMappingChain = Private(FilterBarLibGenerateMappingChainProvider);
|
||||
import { mapMatchAll } from './map_match_all';
|
||||
import { mapPhrase } from './map_phrase';
|
||||
import { mapPhrases } from './map_phrases';
|
||||
import { mapRange } from './map_range';
|
||||
import { mapExists } from './map_exists';
|
||||
import { mapMissing } from './map_missing';
|
||||
import { mapQueryString } from './map_query_string';
|
||||
import { mapGeoBoundingBox } from './map_geo_bounding_box';
|
||||
import { mapGeoPolygon } from './map_geo_polygon';
|
||||
import { mapDefault } from './map_default';
|
||||
import { generateMappingChain } from './generate_mapping_chain';
|
||||
|
||||
export async function mapFilter(indexPatterns, filter) {
|
||||
/** Mappers **/
|
||||
|
||||
// Each mapper is a simple promise function that test if the mapper can
|
||||
|
@ -51,47 +48,40 @@ export function FilterBarLibMapFilterProvider(Promise, Private) {
|
|||
// that either handles the mapping operation or not
|
||||
// and add it here. ProTip: These are executed in order listed
|
||||
const mappers = [
|
||||
Private(FilterBarLibMapMatchAllProvider),
|
||||
Private(FilterBarLibMapRangeProvider),
|
||||
Private(FilterBarLibMapPhraseProvider),
|
||||
Private(FilterBarLibMapPhrasesProvider),
|
||||
Private(FilterBarLibMapExistsProvider),
|
||||
Private(FilterBarLibMapMissingProvider),
|
||||
Private(FilterBarLibMapQueryStringProvider),
|
||||
Private(FilterBarLibMapGeoBoundingBoxProvider),
|
||||
Private(FilterBarLibMapGeoPolygonProvider),
|
||||
Private(FilterBarLibMapDefaultProvider),
|
||||
mapMatchAll,
|
||||
mapRange(indexPatterns),
|
||||
mapPhrase(indexPatterns),
|
||||
mapPhrases,
|
||||
mapExists,
|
||||
mapMissing,
|
||||
mapQueryString,
|
||||
mapGeoBoundingBox(indexPatterns),
|
||||
mapGeoPolygon(indexPatterns),
|
||||
mapDefault,
|
||||
];
|
||||
|
||||
const noop = function () {
|
||||
return Promise.reject(new Error('No mappings have been found for filter.'));
|
||||
throw new Error('No mappings have been found for filter.');
|
||||
};
|
||||
|
||||
// Create a chain of responsibility by reducing all the
|
||||
// mappers down into one function.
|
||||
const mapFn = _.reduceRight(mappers, function (memo, map) {
|
||||
const filterChainFn = generateMappingChain(map);
|
||||
return filterChainFn(memo);
|
||||
return generateMappingChain(map, memo);
|
||||
}, noop);
|
||||
|
||||
/**
|
||||
* Map the filter into an object with the key and value exposed so it's
|
||||
* easier to work with in the template
|
||||
* @param {object} filter The filter the map
|
||||
* @returns {Promise}
|
||||
*/
|
||||
return function (filter) {
|
||||
// Apply the mapping function
|
||||
return mapFn(filter).then(function (result) {
|
||||
filter.meta = filter.meta || {};
|
||||
filter.meta.type = result.type;
|
||||
filter.meta.key = result.key;
|
||||
filter.meta.value = result.value;
|
||||
filter.meta.params = result.params;
|
||||
filter.meta.disabled = !!(filter.meta.disabled);
|
||||
filter.meta.negate = !!(filter.meta.negate);
|
||||
filter.meta.alias = filter.meta.alias || null;
|
||||
return filter;
|
||||
});
|
||||
};
|
||||
const mapped = await mapFn(filter);
|
||||
|
||||
// Map the filter into an object with the key and value exposed so it's
|
||||
// easier to work with in the template
|
||||
filter.meta = filter.meta || {};
|
||||
filter.meta.type = mapped.type;
|
||||
filter.meta.key = mapped.key;
|
||||
filter.meta.value = mapped.value;
|
||||
filter.meta.params = mapped.params;
|
||||
filter.meta.disabled = !!(filter.meta.disabled);
|
||||
filter.meta.negate = !!(filter.meta.negate);
|
||||
filter.meta.alias = filter.meta.alias || null;
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
|
|
@ -1,34 +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 { FilterBarLibMapAndFlattenFiltersProvider } from './map_and_flatten_filters';
|
||||
|
||||
export function FilterBarLibMapFlattenAndWrapFiltersProvider(Private) {
|
||||
const mapAndFlattenFilters = Private(FilterBarLibMapAndFlattenFiltersProvider);
|
||||
return function (filters) {
|
||||
return mapAndFlattenFilters(filters).then(function (filters) {
|
||||
return _.map(filters, function (filter) {
|
||||
filter.meta = filter.meta || {};
|
||||
filter.meta.apply = true;
|
||||
return filter;
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
|
@ -20,39 +20,39 @@
|
|||
import _ from 'lodash';
|
||||
import { SavedObjectNotFound } from '../../errors';
|
||||
|
||||
export function FilterBarLibMapGeoBoundingBoxProvider(Promise, indexPatterns) {
|
||||
return function (filter) {
|
||||
if (filter.geo_bounding_box) {
|
||||
function getParams(indexPattern) {
|
||||
const type = 'geo_bounding_box';
|
||||
const key = _.keys(filter.geo_bounding_box)
|
||||
.filter(key => key !== 'ignore_unmapped')[0];
|
||||
const params = filter.geo_bounding_box[key];
|
||||
function getParams(filter, indexPattern) {
|
||||
const type = 'geo_bounding_box';
|
||||
const key = _.keys(filter.geo_bounding_box)
|
||||
.filter(key => key !== 'ignore_unmapped')[0];
|
||||
const params = filter.geo_bounding_box[key];
|
||||
|
||||
// Sometimes a filter will end up with an invalid index param. This could happen for a lot of reasons,
|
||||
// for example a user might manually edit the url or the index pattern's ID might change due to
|
||||
// external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback
|
||||
// on displaying the raw value if the index is invalid.
|
||||
const topLeft = indexPattern
|
||||
? indexPattern.fields.byName[key].format.convert(params.top_left)
|
||||
: JSON.stringify(params.top_left);
|
||||
const bottomRight = indexPattern
|
||||
? indexPattern.fields.byName[key].format.convert(params.bottom_right)
|
||||
: JSON.stringify(params.bottom_right);
|
||||
const value = topLeft + ' to ' + bottomRight;
|
||||
return { type, key, value, params };
|
||||
}
|
||||
// Sometimes a filter will end up with an invalid index param. This could happen for a lot of reasons,
|
||||
// for example a user might manually edit the url or the index pattern's ID might change due to
|
||||
// external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback
|
||||
// on displaying the raw value if the index is invalid.
|
||||
const topLeft = indexPattern
|
||||
? indexPattern.fields.byName[key].format.convert(params.top_left)
|
||||
: JSON.stringify(params.top_left);
|
||||
const bottomRight = indexPattern
|
||||
? indexPattern.fields.byName[key].format.convert(params.bottom_right)
|
||||
: JSON.stringify(params.bottom_right);
|
||||
const value = topLeft + ' to ' + bottomRight;
|
||||
return { type, key, value, params };
|
||||
}
|
||||
|
||||
return indexPatterns
|
||||
.get(filter.meta.index)
|
||||
.then(getParams)
|
||||
.catch((error) => {
|
||||
if (error instanceof SavedObjectNotFound) {
|
||||
return getParams();
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
export function mapGeoBoundingBox(indexPatterns) {
|
||||
return async function (filter) {
|
||||
if (!filter.geo_bounding_box) {
|
||||
throw filter;
|
||||
}
|
||||
try {
|
||||
const indexPattern = await indexPatterns.get(filter.meta.index);
|
||||
return getParams(filter, indexPattern);
|
||||
} catch (error) {
|
||||
if (error instanceof SavedObjectNotFound) {
|
||||
return getParams(filter);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
return Promise.reject(filter);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -20,38 +20,39 @@
|
|||
import _ from 'lodash';
|
||||
import { SavedObjectNotFound } from '../../errors';
|
||||
|
||||
export function FilterBarLibMapGeoPolygonProvider(Promise, indexPatterns) {
|
||||
return function (filter) {
|
||||
if (filter.geo_polygon) {
|
||||
function getParams(indexPattern) {
|
||||
const type = 'geo_polygon';
|
||||
const key = _.keys(filter.geo_polygon)
|
||||
.filter(key => key !== 'ignore_unmapped')[0];
|
||||
const params = filter.geo_polygon[key];
|
||||
function getParams(filter, indexPattern) {
|
||||
const type = 'geo_polygon';
|
||||
const key = _.keys(filter.geo_polygon)
|
||||
.filter(key => key !== 'ignore_unmapped')[0];
|
||||
const params = filter.geo_polygon[key];
|
||||
|
||||
// Sometimes a filter will end up with an invalid index param. This could happen for a lot of reasons,
|
||||
// for example a user might manually edit the url or the index pattern's ID might change due to
|
||||
// external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback
|
||||
// on displaying the raw value if the index is invalid.
|
||||
const points = params.points.map((point) => {
|
||||
return indexPattern
|
||||
? indexPattern.fields.byName[key].format.convert(point)
|
||||
: JSON.stringify(point);
|
||||
});
|
||||
const value = points.join(', ');
|
||||
return { type, key, value, params };
|
||||
}
|
||||
// Sometimes a filter will end up with an invalid index param. This could happen for a lot of reasons,
|
||||
// for example a user might manually edit the url or the index pattern's ID might change due to
|
||||
// external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback
|
||||
// on displaying the raw value if the index is invalid.
|
||||
const points = params.points.map((point) => {
|
||||
return indexPattern
|
||||
? indexPattern.fields.byName[key].format.convert(point)
|
||||
: JSON.stringify(point);
|
||||
});
|
||||
const value = points.join(', ');
|
||||
return { type, key, value, params };
|
||||
}
|
||||
|
||||
return indexPatterns
|
||||
.get(filter.meta.index)
|
||||
.then(getParams)
|
||||
.catch((error) => {
|
||||
if (error instanceof SavedObjectNotFound) {
|
||||
return getParams();
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
export function mapGeoPolygon(indexPatterns) {
|
||||
return async function (filter) {
|
||||
if (!filter.geo_polygon) {
|
||||
throw filter;
|
||||
}
|
||||
|
||||
try {
|
||||
const indexPattern = await indexPatterns.get(filter.meta.index);
|
||||
return getParams(filter, indexPattern);
|
||||
} catch (error) {
|
||||
if (error instanceof SavedObjectNotFound) {
|
||||
return getParams(filter);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
return Promise.reject(filter);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -17,14 +17,12 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export function FilterBarLibMapMatchAllProvider(Promise) {
|
||||
return function (filter) {
|
||||
if (filter.match_all) {
|
||||
const type = 'match_all';
|
||||
const key = filter.meta.field;
|
||||
const value = filter.meta.formattedValue || 'all';
|
||||
return Promise.resolve({ type, key, value });
|
||||
}
|
||||
return Promise.reject(filter);
|
||||
};
|
||||
export async function mapMatchAll(filter) {
|
||||
if (filter.match_all) {
|
||||
const type = 'match_all';
|
||||
const key = filter.meta.field;
|
||||
const value = filter.meta.formattedValue || 'all';
|
||||
return { type, key, value };
|
||||
}
|
||||
throw filter;
|
||||
}
|
||||
|
|
|
@ -17,14 +17,12 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export function FilterBarLibMapMissingProvider(Promise) {
|
||||
return function (filter) {
|
||||
if (filter.missing) {
|
||||
const type = 'missing';
|
||||
const key = filter.missing.field;
|
||||
const value = type;
|
||||
return Promise.resolve({ type, key, value });
|
||||
}
|
||||
return Promise.reject(filter);
|
||||
};
|
||||
export async function mapMissing(filter) {
|
||||
if (filter.missing) {
|
||||
const type = 'missing';
|
||||
const key = filter.missing.field;
|
||||
const value = type;
|
||||
return { type, key, value };
|
||||
}
|
||||
throw filter;
|
||||
}
|
||||
|
|
|
@ -20,40 +20,41 @@
|
|||
import _ from 'lodash';
|
||||
import { SavedObjectNotFound } from '../../errors';
|
||||
|
||||
export function FilterBarLibMapPhraseProvider(Promise, indexPatterns) {
|
||||
return function (filter) {
|
||||
const isScriptedPhraseFilter = isScriptedPhrase(filter);
|
||||
if (!_.has(filter, ['query', 'match']) && !isScriptedPhraseFilter) {
|
||||
return Promise.reject(filter);
|
||||
}
|
||||
|
||||
function getParams(indexPattern) {
|
||||
const type = 'phrase';
|
||||
const key = isScriptedPhraseFilter ? filter.meta.field : Object.keys(filter.query.match)[0];
|
||||
const query = isScriptedPhraseFilter ? filter.script.script.params.value : filter.query.match[key].query;
|
||||
const params = { query };
|
||||
|
||||
// Sometimes a filter will end up with an invalid index or field param. This could happen for a lot of reasons,
|
||||
// for example a user might manually edit the url or the index pattern's ID might change due to
|
||||
// external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback
|
||||
// on displaying the raw value if the index or field is invalid.
|
||||
const value = (indexPattern && indexPattern.fields.byName[key]) ? indexPattern.fields.byName[key].format.convert(query) : query;
|
||||
return { type, key, value, params };
|
||||
}
|
||||
|
||||
return indexPatterns
|
||||
.get(filter.meta.index)
|
||||
.then(getParams)
|
||||
.catch((error) => {
|
||||
if (error instanceof SavedObjectNotFound) {
|
||||
return getParams();
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function isScriptedPhrase(filter) {
|
||||
const value = _.get(filter, ['script', 'script', 'params', 'value']);
|
||||
return typeof value !== 'undefined';
|
||||
}
|
||||
|
||||
function getParams(filter, indexPattern) {
|
||||
const isScriptedPhraseFilter = isScriptedPhrase(filter);
|
||||
const type = 'phrase';
|
||||
const key = isScriptedPhraseFilter ? filter.meta.field : Object.keys(filter.query.match)[0];
|
||||
const query = isScriptedPhraseFilter ? filter.script.script.params.value : filter.query.match[key].query;
|
||||
const params = { query };
|
||||
|
||||
// Sometimes a filter will end up with an invalid index or field param. This could happen for a lot of reasons,
|
||||
// for example a user might manually edit the url or the index pattern's ID might change due to
|
||||
// external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback
|
||||
// on displaying the raw value if the index or field is invalid.
|
||||
const value = (indexPattern && indexPattern.fields.byName[key]) ? indexPattern.fields.byName[key].format.convert(query) : query;
|
||||
return { type, key, value, params };
|
||||
}
|
||||
|
||||
export function mapPhrase(indexPatterns) {
|
||||
return async function (filter) {
|
||||
const isScriptedPhraseFilter = isScriptedPhrase(filter);
|
||||
if (!_.has(filter, ['query', 'match']) && !isScriptedPhraseFilter) {
|
||||
throw filter;
|
||||
}
|
||||
|
||||
try {
|
||||
const indexPattern = await indexPatterns.get(filter.meta.index);
|
||||
return getParams(filter, indexPattern);
|
||||
} catch (error) {
|
||||
if (error instanceof SavedObjectNotFound) {
|
||||
return getParams(filter);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -17,13 +17,11 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export function FilterBarLibMapPhrasesProvider(Promise) {
|
||||
return function (filter) {
|
||||
const { type, key, value, params } = filter.meta;
|
||||
if (type !== 'phrases') {
|
||||
return Promise.reject(filter);
|
||||
} else {
|
||||
return Promise.resolve({ type, key, value, params });
|
||||
}
|
||||
};
|
||||
export async function mapPhrases(filter) {
|
||||
const { type, key, value, params } = filter.meta;
|
||||
if (type !== 'phrases') {
|
||||
throw filter;
|
||||
} else {
|
||||
return { type, key, value, params };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,14 +17,12 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export function FilterBarLibMapQueryStringProvider(Promise) {
|
||||
return function (filter) {
|
||||
if (filter.query && filter.query.query_string) {
|
||||
const type = 'query_string';
|
||||
const key = 'query';
|
||||
const value = filter.query.query_string.query;
|
||||
return Promise.resolve({ type, key, value });
|
||||
}
|
||||
return Promise.reject(filter);
|
||||
};
|
||||
export async function mapQueryString(filter) {
|
||||
if (filter.query && filter.query.query_string) {
|
||||
const type = 'query_string';
|
||||
const key = 'query';
|
||||
const value = filter.query.query_string.query;
|
||||
return { type, key, value };
|
||||
}
|
||||
throw filter;
|
||||
}
|
||||
|
|
|
@ -20,51 +20,52 @@
|
|||
import { has, get } from 'lodash';
|
||||
import { SavedObjectNotFound } from '../../errors';
|
||||
|
||||
export function FilterBarLibMapRangeProvider(Promise, indexPatterns) {
|
||||
return function (filter) {
|
||||
const isScriptedRangeFilter = isScriptedRange(filter);
|
||||
if (!filter.range && !isScriptedRangeFilter) {
|
||||
return Promise.reject(filter);
|
||||
}
|
||||
|
||||
function getParams(indexPattern) {
|
||||
const type = 'range';
|
||||
const key = isScriptedRangeFilter ? filter.meta.field : Object.keys(filter.range)[0];
|
||||
const params = isScriptedRangeFilter ? filter.script.script.params : filter.range[key];
|
||||
|
||||
let left = has(params, 'gte') ? params.gte : params.gt;
|
||||
if (left == null) left = -Infinity;
|
||||
|
||||
let right = has(params, 'lte') ? params.lte : params.lt;
|
||||
if (right == null) right = Infinity;
|
||||
|
||||
// Sometimes a filter will end up with an invalid index param. This could happen for a lot of reasons,
|
||||
// for example a user might manually edit the url or the index pattern's ID might change due to
|
||||
// external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback
|
||||
// on displaying the raw value if the index is invalid.
|
||||
let value = `${left} to ${right}`;
|
||||
if (indexPattern) {
|
||||
const convert = indexPattern.fields.byName[key].format.getConverterFor('text');
|
||||
value = `${convert(left)} to ${convert(right)}`;
|
||||
}
|
||||
|
||||
return { type, key, value, params };
|
||||
}
|
||||
|
||||
return indexPatterns
|
||||
.get(filter.meta.index)
|
||||
.then(getParams)
|
||||
.catch((error) => {
|
||||
if (error instanceof SavedObjectNotFound) {
|
||||
return getParams();
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
function isScriptedRange(filter) {
|
||||
const params = get(filter, ['script', 'script', 'params']);
|
||||
return params && Object.keys(params).find(key => ['gte', 'gt', 'lte', 'lt'].includes(key));
|
||||
}
|
||||
|
||||
function getParams(filter, indexPattern) {
|
||||
const isScriptedRangeFilter = isScriptedRange(filter);
|
||||
const type = 'range';
|
||||
const key = isScriptedRangeFilter ? filter.meta.field : Object.keys(filter.range)[0];
|
||||
const params = isScriptedRangeFilter ? filter.script.script.params : filter.range[key];
|
||||
|
||||
let left = has(params, 'gte') ? params.gte : params.gt;
|
||||
if (left == null) left = -Infinity;
|
||||
|
||||
let right = has(params, 'lte') ? params.lte : params.lt;
|
||||
if (right == null) right = Infinity;
|
||||
|
||||
// Sometimes a filter will end up with an invalid index param. This could happen for a lot of reasons,
|
||||
// for example a user might manually edit the url or the index pattern's ID might change due to
|
||||
// external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback
|
||||
// on displaying the raw value if the index is invalid.
|
||||
let value = `${left} to ${right}`;
|
||||
if (indexPattern) {
|
||||
const convert = indexPattern.fields.byName[key].format.getConverterFor('text');
|
||||
value = `${convert(left)} to ${convert(right)}`;
|
||||
}
|
||||
|
||||
return { type, key, value, params };
|
||||
}
|
||||
|
||||
export function mapRange(indexPatterns) {
|
||||
return async function (filter) {
|
||||
const isScriptedRangeFilter = isScriptedRange(filter);
|
||||
if (!filter.range && !isScriptedRangeFilter) {
|
||||
throw filter;
|
||||
}
|
||||
|
||||
try {
|
||||
const indexPattern = await indexPatterns.get(filter.meta.index);
|
||||
return getParams(filter, indexPattern);
|
||||
} catch (error) {
|
||||
if (error instanceof SavedObjectNotFound) {
|
||||
return getParams(filter);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,34 +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';
|
||||
|
||||
export function FilterBarPushFilterProvider() {
|
||||
return function ($state) {
|
||||
if (!_.isObject($state)) throw new Error('pushFilters requires a state object');
|
||||
return function (filter, negate, index) {
|
||||
// Hierarchical and tabular data set their aggConfigResult parameter
|
||||
// differently because of how the point is rewritten between the two. So
|
||||
// we need to check if the point.orig is set, if not use try the point.aggConfigResult
|
||||
const pendingFilter = { meta: { negate: negate, index: index } };
|
||||
_.extend(pendingFilter, filter);
|
||||
$state.$newFilters = [pendingFilter];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -19,11 +19,9 @@
|
|||
|
||||
import _ from 'lodash';
|
||||
|
||||
export function FilterBarPushFiltersProvider() {
|
||||
return function ($state) {
|
||||
if (!_.isObject($state)) throw new Error('pushFilters requires a state object');
|
||||
return function (filters) {
|
||||
$state.$newFilters = filters;
|
||||
};
|
||||
};
|
||||
// TODO: should it be here or in vis filters (only place where it's used).
|
||||
// $newFilters is not defined by filter_bar as well.
|
||||
export function pushFilterBarFilters($state, filters) {
|
||||
if (!_.isObject($state)) throw new Error('pushFilters requires a state object');
|
||||
$state.$newFilters = filters;
|
||||
}
|
||||
|
|
|
@ -23,14 +23,12 @@ import { onlyStateChanged } from './lib/only_state_changed';
|
|||
import { uniqFilters } from './lib/uniq_filters';
|
||||
import { compareFilters } from './lib/compare_filters';
|
||||
import { EventsProvider } from '../events';
|
||||
import { FilterBarLibMapAndFlattenFiltersProvider } from './lib/map_and_flatten_filters';
|
||||
import { FilterBarLibExtractTimeFilterProvider } from './lib/extract_time_filter';
|
||||
import { mapAndFlattenFilters } from './lib/map_and_flatten_filters';
|
||||
import { extractTimeFilter } from './lib/extract_time_filter';
|
||||
import { changeTimeFilter } from './lib/change_time_filter';
|
||||
|
||||
export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, globalState, config) {
|
||||
export function FilterBarQueryFilterProvider(Private, Promise, indexPatterns, $rootScope, getAppState, globalState, config) {
|
||||
const EventEmitter = Private(EventsProvider);
|
||||
const mapAndFlattenFilters = Private(FilterBarLibMapAndFlattenFiltersProvider);
|
||||
const extractTimeFilter = Private(FilterBarLibExtractTimeFilterProvider);
|
||||
|
||||
const queryFilter = new EventEmitter();
|
||||
|
||||
|
@ -85,7 +83,7 @@ export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, g
|
|||
filters = [filters];
|
||||
}
|
||||
|
||||
return mapAndFlattenFilters(filters)
|
||||
return Promise.resolve(mapAndFlattenFilters(indexPatterns, filters))
|
||||
.then(function (filters) {
|
||||
if (!filterState.filters) {
|
||||
filterState.filters = [];
|
||||
|
@ -220,7 +218,7 @@ export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, g
|
|||
};
|
||||
|
||||
queryFilter.setFilters = filters => {
|
||||
return mapAndFlattenFilters(filters)
|
||||
return Promise.resolve(mapAndFlattenFilters(indexPatterns, filters))
|
||||
.then(mappedFilters => {
|
||||
const appState = getAppState();
|
||||
const [globalFilters, appFilters] = _.partition(mappedFilters, filter => {
|
||||
|
@ -232,7 +230,7 @@ export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, g
|
|||
};
|
||||
|
||||
queryFilter.addFiltersAndChangeTimeFilter = async filters => {
|
||||
const timeFilter = await extractTimeFilter(filters);
|
||||
const timeFilter = await extractTimeFilter(indexPatterns, filters);
|
||||
if (timeFilter) changeTimeFilter(timeFilter);
|
||||
queryFilter.addFilters(filters.filter(filter => filter !== timeFilter));
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
import { FilterBarPushFiltersProvider } from '../filter_bar/push_filters';
|
||||
import { pushFilterBarFilters } from '../filter_bar/push_filters';
|
||||
import { FilterBarQueryFilterProvider } from '../filter_bar/query_filter';
|
||||
import { onBrushEvent } from '../utils/brush_event';
|
||||
|
||||
|
@ -84,7 +84,6 @@ const createFilter = (aggConfigs, table, columnIndex, rowIndex, cellValue) => {
|
|||
};
|
||||
|
||||
const VisFiltersProvider = (Private, getAppState) => {
|
||||
const filterBarPushFilters = Private(FilterBarPushFiltersProvider);
|
||||
const queryFilter = Private(FilterBarQueryFilterProvider);
|
||||
|
||||
const pushFilters = (filters, simulate) => {
|
||||
|
@ -92,7 +91,7 @@ const VisFiltersProvider = (Private, getAppState) => {
|
|||
if (filters.length && !simulate) {
|
||||
const flatFilters = _.flatten(filters);
|
||||
const deduplicatedFilters = flatFilters.filter((v, i) => i === flatFilters.findIndex(f => _.isEqual(v, f)));
|
||||
filterBarPushFilters(appState)(deduplicatedFilters);
|
||||
pushFilterBarFilters(appState, deduplicatedFilters);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue