diff --git a/src/ui/public/filter_bar/lib/__tests__/map_script.js b/src/ui/public/filter_bar/lib/__tests__/map_script.js deleted file mode 100644 index a64e88a2d04f7..0000000000000 --- a/src/ui/public/filter_bar/lib/__tests__/map_script.js +++ /dev/null @@ -1,69 +0,0 @@ -import expect from 'expect.js'; -import ngMock from 'ng_mock'; -import { FilterBarLibMapScriptProvider } from 'ui/filter_bar/lib/map_script'; - -describe('Filter Bar Directive', function () { - describe('mapScript()', function () { - let mapScript; - let $rootScope; - - beforeEach(ngMock.module( - 'kibana', - 'kibana/courier', - function ($provide) { - $provide.service('courier', require('fixtures/mock_courier')); - } - )); - - beforeEach(ngMock.inject(function (Private, _$rootScope_) { - $rootScope = _$rootScope_; - mapScript = Private(FilterBarLibMapScriptProvider); - })); - - it('should return the key and value for matching filters', function (done) { - const filter = { - meta: { index: 'logstash-*', field: 'script number' }, - script: { script: { inline: 'doc["script number"].value * 5', params: { value: 35 } } } - }; - mapScript(filter).then(function (result) { - expect(result).to.have.property('key', 'script number'); - expect(result).to.have.property('value', '35'); - done(); - }); - $rootScope.$apply(); - }); - - it('should return undefined for none matching', function (done) { - const filter = { meta: { index: 'logstash-*' }, query: { query_string: { query: 'foo:bar' } } }; - mapScript(filter).catch(function (result) { - expect(result).to.be(filter); - done(); - }); - $rootScope.$apply(); - }); - - it('should return a value for a range/histogram filter from a scripted field', (done) => { - const filter = { - meta: { - index: 'logstash-*', - formattedValue: '1,000.00 to 2,000.00', - field: 'script number' - }, - script: { - script: { - params: { - gte: 1000, - lt: 2000, - value: '>=1,000.00 <2,000.00' - } - } - } - }; - mapScript(filter).then((result) => { - expect(result).to.have.property('value', filter.meta.formattedValue); - done(); - }); - $rootScope.$apply(); - }); - }); -}); diff --git a/src/ui/public/filter_bar/lib/map_filter.js b/src/ui/public/filter_bar/lib/map_filter.js index a186258c047bc..50c080098ae6f 100644 --- a/src/ui/public/filter_bar/lib/map_filter.js +++ b/src/ui/public/filter_bar/lib/map_filter.js @@ -9,7 +9,6 @@ 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 { FilterBarLibMapScriptProvider } from './map_script'; import { FilterBarLibMapDefaultProvider } from './map_default'; export function FilterBarLibMapFilterProvider(Promise, Private) { @@ -42,7 +41,6 @@ export function FilterBarLibMapFilterProvider(Promise, Private) { Private(FilterBarLibMapQueryStringProvider), Private(FilterBarLibMapGeoBoundingBoxProvider), Private(FilterBarLibMapGeoPolygonProvider), - Private(FilterBarLibMapScriptProvider), Private(FilterBarLibMapDefaultProvider), ]; diff --git a/src/ui/public/filter_bar/lib/map_geo_bounding_box.js b/src/ui/public/filter_bar/lib/map_geo_bounding_box.js index 5a73f44db9159..31a21a3b5c1e4 100644 --- a/src/ui/public/filter_bar/lib/map_geo_bounding_box.js +++ b/src/ui/public/filter_bar/lib/map_geo_bounding_box.js @@ -1,20 +1,38 @@ import _ from 'lodash'; +import { SavedObjectNotFound } from '../../errors'; export function FilterBarLibMapGeoBoundingBoxProvider(Promise, courier) { return function (filter) { if (filter.geo_bounding_box) { - return courier - .indexPatterns - .get(filter.meta.index).then(function (indexPattern) { + function getParams(indexPattern) { const type = 'geo_bounding_box'; const key = _.keys(filter.geo_bounding_box) .filter(key => key !== 'ignore_unmapped')[0]; - const field = indexPattern.fields.byName[key]; const params = filter.geo_bounding_box[key]; - const topLeft = field.format.convert(params.top_left); - const bottomRight = field.format.convert(params.bottom_right); + + // 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 courier + .indexPatterns + .get(filter.meta.index) + .then(getParams) + .catch((error) => { + if (error instanceof SavedObjectNotFound) { + return getParams(); + } + throw error; }); } return Promise.reject(filter); diff --git a/src/ui/public/filter_bar/lib/map_geo_polygon.js b/src/ui/public/filter_bar/lib/map_geo_polygon.js index f7553303a52bd..8466c8479057c 100644 --- a/src/ui/public/filter_bar/lib/map_geo_polygon.js +++ b/src/ui/public/filter_bar/lib/map_geo_polygon.js @@ -1,19 +1,37 @@ import _ from 'lodash'; +import { SavedObjectNotFound } from '../../errors'; export function FilterBarLibMapGeoPolygonProvider(Promise, courier) { return function (filter) { if (filter.geo_polygon) { - return courier - .indexPatterns - .get(filter.meta.index).then(function (indexPattern) { + function getParams(indexPattern) { const type = 'geo_polygon'; const key = _.keys(filter.geo_polygon) .filter(key => key !== 'ignore_unmapped')[0]; - const field = indexPattern.fields.byName[key]; const params = filter.geo_polygon[key]; - const points = params.points.map((point) => field.format.convert(point)); + + // 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 courier + .indexPatterns + .get(filter.meta.index) + .then(getParams) + .catch((error) => { + if (error instanceof SavedObjectNotFound) { + return getParams(); + } + throw error; }); } return Promise.reject(filter); diff --git a/src/ui/public/filter_bar/lib/map_phrase.js b/src/ui/public/filter_bar/lib/map_phrase.js index 8bbd78cd48994..3f924a2ef4b9c 100644 --- a/src/ui/public/filter_bar/lib/map_phrase.js +++ b/src/ui/public/filter_bar/lib/map_phrase.js @@ -1,4 +1,5 @@ import _ from 'lodash'; +import { SavedObjectNotFound } from '../../errors'; export function FilterBarLibMapPhraseProvider(Promise, courier) { return function (filter) { @@ -7,16 +8,29 @@ export function FilterBarLibMapPhraseProvider(Promise, courier) { return Promise.reject(filter); } - return courier - .indexPatterns - .get(filter.meta.index).then(function (indexPattern) { + function getParams(indexPattern) { const type = 'phrase'; const key = isScriptedPhraseFilter ? filter.meta.field : Object.keys(filter.query.match)[0]; - const field = indexPattern.fields.byName[key]; const params = isScriptedPhraseFilter ? filter.script.script.params : filter.query.match[key]; const query = isScriptedPhraseFilter ? params.value : params.query; - const value = field.format.convert(query); + + // 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 value = indexPattern ? indexPattern.fields.byName[key].format.convert(query) : query; return { type, key, value, params }; + } + + return courier + .indexPatterns + .get(filter.meta.index) + .then(getParams) + .catch((error) => { + if (error instanceof SavedObjectNotFound) { + return getParams(); + } + throw error; }); }; } diff --git a/src/ui/public/filter_bar/lib/map_range.js b/src/ui/public/filter_bar/lib/map_range.js index a8c94a14f4101..dcd82486ea5c4 100644 --- a/src/ui/public/filter_bar/lib/map_range.js +++ b/src/ui/public/filter_bar/lib/map_range.js @@ -1,4 +1,5 @@ import { has, get } from 'lodash'; +import { SavedObjectNotFound } from '../../errors'; export function FilterBarLibMapRangeProvider(Promise, courier) { return function (filter) { @@ -7,13 +8,9 @@ export function FilterBarLibMapRangeProvider(Promise, courier) { return Promise.reject(filter); } - return courier - .indexPatterns - .get(filter.meta.index) - .then(function (indexPattern) { + function getParams(indexPattern) { const type = 'range'; const key = isScriptedRangeFilter ? filter.meta.field : Object.keys(filter.range)[0]; - const convert = indexPattern.fields.byName[key].format.getConverterFor('text'); const params = isScriptedRangeFilter ? filter.script.script.params : filter.range[key]; let left = has(params, 'gte') ? params.gte : params.gt; @@ -22,9 +19,28 @@ export function FilterBarLibMapRangeProvider(Promise, courier) { let right = has(params, 'lte') ? params.lte : params.lt; if (right == null) right = Infinity; - const value = `${convert(left)} to ${convert(right)}`; + // 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 courier + .indexPatterns + .get(filter.meta.index) + .then(getParams) + .catch((error) => { + if (error instanceof SavedObjectNotFound) { + return getParams(); + } + throw error; }); }; diff --git a/src/ui/public/filter_bar/lib/map_script.js b/src/ui/public/filter_bar/lib/map_script.js deleted file mode 100644 index 90674aa3f6017..0000000000000 --- a/src/ui/public/filter_bar/lib/map_script.js +++ /dev/null @@ -1,24 +0,0 @@ -export function FilterBarLibMapScriptProvider(Promise, courier) { - return function (filter) { - if (filter.script) { - return courier - .indexPatterns - .get(filter.meta.index).then(function (indexPattern) { - const type = 'scripted'; - const key = filter.meta.field; - const field = indexPattern.fields.byName[key]; - - let value; - if (filter.meta.formattedValue) { - value = filter.meta.formattedValue; - } else { - value = filter.script.script.params.value; - value = field.format.convert(value); - } - - return { type, key, value }; - }); - } - return Promise.reject(filter); - }; -}