From 87072c85d1c883657733f29d8eb944402575168b Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 8 Apr 2021 12:49:48 -0600 Subject: [PATCH 1/8] [Maps] fix Kibana does not recognize a valid geo_shape index when attempting to create a Tracking Containment alert --- .../index_pattern_select.tsx | 114 +++++++++++------- 1 file changed, 72 insertions(+), 42 deletions(-) diff --git a/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx b/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx index aa36323d11bcc..d27110bb81a5d 100644 --- a/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx +++ b/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx @@ -25,7 +25,6 @@ export type IndexPatternSelectProps = Required< indexPatternId: string; fieldTypes?: string[]; onNoIndexPatterns?: () => void; - maxIndexPatterns?: number; }; export type IndexPatternSelectInternalProps = IndexPatternSelectProps & { @@ -42,10 +41,6 @@ interface IndexPatternSelectState { // Needed for React.lazy // eslint-disable-next-line import/no-default-export export default class IndexPatternSelect extends Component { - static defaultProps: { - maxIndexPatterns: 1000; - }; - private isMounted: boolean = false; state: IndexPatternSelectState; @@ -67,7 +62,8 @@ export default class IndexPatternSelect extends Component { - const { fieldTypes, onNoIndexPatterns, indexPatternService } = this.props; - const indexPatterns = await indexPatternService.find( - `${searchValue}*`, - this.props.maxIndexPatterns - ); + debouncedFetch = _.debounce( + async (searchValue: string, forceIndexPatternCacheRefresh: boolean) => { + const isCurrentSearch = () => { + return this.isMounted && searchValue === this.state.searchValue; + }; + + const idsAndTitles = await this.props.indexPatternService.getIdsWithTitle( + forceIndexPatternCacheRefresh + ); + if (!isCurrentSearch()) { + return; + } + + const options = []; + for (let i = 0; i < idsAndTitles.length; i++) { + if ( + searchValue.length && + !idsAndTitles[i].title.toLowerCase().includes(searchValue.toLowerCase()) + ) { + // index pattern excluded due to title not matching search + continue; + } + + if (this.props.fieldTypes) { + try { + const indexPattern = await this.props.indexPatternService.get(idsAndTitles[i].id); + if (!isCurrentSearch()) { + return; + } + const hasRequiredFieldTypes = indexPattern.fields.some((field) => { + return this.props.fieldTypes.includes(field.type); + }); + if (!hasRequiredFieldTypes) { + continue; + } + } catch (err) { + // could not load index pattern, exclude it from list. + continue; + } + } + + options.push({ + label: idsAndTitles[i].title, + value: idsAndTitles[i].id, + }); + + // Loading each index pattern object requires a network call so just find small number of matching index patterns + // Users can use 'searchValue' to further refine the list and locate their index pattern. + if (options.length > 15) { + break; + } + } - // We need this check to handle the case where search results come back in a different - // order than they were sent out. Only load results for the most recent search. - if (searchValue !== this.state.searchValue || !this.isMounted) { - return; - } - - const options = indexPatterns - .filter((indexPattern) => { - return fieldTypes - ? indexPattern.fields.some((field) => { - return fieldTypes.includes(field.type); - }) - : true; - }) - .map((indexPattern) => { - return { - label: indexPattern.title, - value: indexPattern.id, - }; + this.setState({ + isLoading: false, + options, }); - this.setState({ - isLoading: false, - options, - }); - if (onNoIndexPatterns && searchValue === '' && options.length === 0) { - onNoIndexPatterns(); - } - }, 300); + if (this.props.onNoIndexPatterns && searchValue === '' && options.length === 0) { + this.props.onNoIndexPatterns(); + } + }, + 300 + ); + + onSearchChange = (searchValue = '') => { + this.fetchOptions(searchValue, false); + }; - fetchOptions = (searchValue = '') => { + fetchOptions = (searchValue: string, forceIndexPatternCacheRefresh: boolean) => { this.setState( { isLoading: true, searchValue, }, - this.debouncedFetch.bind(null, searchValue) + () => { + this.debouncedFetch(searchValue, forceIndexPatternCacheRefresh); + } ); }; @@ -174,7 +204,7 @@ export default class IndexPatternSelect extends Component Date: Thu, 8 Apr 2021 13:25:23 -0600 Subject: [PATCH 2/8] tslint --- .../public/ui/index_pattern_select/index_pattern_select.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx b/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx index d27110bb81a5d..d9d76ac895db0 100644 --- a/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx +++ b/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx @@ -132,7 +132,7 @@ export default class IndexPatternSelect extends Component { - return this.props.fieldTypes.includes(field.type); + return this.props.fieldTypes!.includes(field.type); }); if (!hasRequiredFieldTypes) { continue; From a21b45ea0ad3ccf65588d438d05ae5736e80d4be Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 8 Apr 2021 14:21:33 -0600 Subject: [PATCH 3/8] instead of forcing refresh on getIdsAndTitles, update index pattern service to add saved object to cache when index pattern is created --- .../index_patterns/index_patterns.ts | 1 + .../index_pattern_select.tsx | 114 ++++++++---------- 2 files changed, 53 insertions(+), 62 deletions(-) diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts index 805eccd1ee31b..3708dc8aa403c 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts @@ -535,6 +535,7 @@ export class IndexPatternsService { }); indexPattern.id = response.id; this.indexPatternCache.set(indexPattern.id, Promise.resolve(indexPattern)); + this.savedObjectsCache.push(response); return indexPattern; } diff --git a/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx b/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx index d9d76ac895db0..e52afe98617e0 100644 --- a/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx +++ b/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx @@ -62,8 +62,7 @@ export default class IndexPatternSelect extends Component { - const isCurrentSearch = () => { - return this.isMounted && searchValue === this.state.searchValue; - }; - - const idsAndTitles = await this.props.indexPatternService.getIdsWithTitle( - forceIndexPatternCacheRefresh - ); - if (!isCurrentSearch()) { - return; - } + debouncedFetch = _.debounce(async (searchValue: string) => { + const isCurrentSearch = () => { + return this.isMounted && searchValue === this.state.searchValue; + }; - const options = []; - for (let i = 0; i < idsAndTitles.length; i++) { - if ( - searchValue.length && - !idsAndTitles[i].title.toLowerCase().includes(searchValue.toLowerCase()) - ) { - // index pattern excluded due to title not matching search - continue; - } + const idsAndTitles = await this.props.indexPatternService.getIdsWithTitle(); + if (!isCurrentSearch()) { + return; + } - if (this.props.fieldTypes) { - try { - const indexPattern = await this.props.indexPatternService.get(idsAndTitles[i].id); - if (!isCurrentSearch()) { - return; - } - const hasRequiredFieldTypes = indexPattern.fields.some((field) => { - return this.props.fieldTypes!.includes(field.type); - }); - if (!hasRequiredFieldTypes) { - continue; - } - } catch (err) { - // could not load index pattern, exclude it from list. + const options = []; + for (let i = 0; i < idsAndTitles.length; i++) { + if ( + searchValue.length && + !idsAndTitles[i].title.toLowerCase().includes(searchValue.toLowerCase()) + ) { + // index pattern excluded due to title not matching search + continue; + } + + if (this.props.fieldTypes) { + try { + const indexPattern = await this.props.indexPatternService.get(idsAndTitles[i].id); + if (!isCurrentSearch()) { + return; + } + const hasRequiredFieldTypes = indexPattern.fields.some((field) => { + return this.props.fieldTypes!.includes(field.type); + }); + if (!hasRequiredFieldTypes) { continue; } - } - - options.push({ - label: idsAndTitles[i].title, - value: idsAndTitles[i].id, - }); - - // Loading each index pattern object requires a network call so just find small number of matching index patterns - // Users can use 'searchValue' to further refine the list and locate their index pattern. - if (options.length > 15) { - break; + } catch (err) { + // could not load index pattern, exclude it from list. + continue; } } - this.setState({ - isLoading: false, - options, + options.push({ + label: idsAndTitles[i].title, + value: idsAndTitles[i].id, }); - if (this.props.onNoIndexPatterns && searchValue === '' && options.length === 0) { - this.props.onNoIndexPatterns(); + // Loading each index pattern object requires a network call so just find small number of matching index patterns + // Users can use 'searchValue' to further refine the list and locate their index pattern. + if (options.length > 15) { + break; } - }, - 300 - ); + } - onSearchChange = (searchValue = '') => { - this.fetchOptions(searchValue, false); - }; + this.setState({ + isLoading: false, + options, + }); + + if (this.props.onNoIndexPatterns && searchValue === '' && options.length === 0) { + this.props.onNoIndexPatterns(); + } + }, 300); - fetchOptions = (searchValue: string, forceIndexPatternCacheRefresh: boolean) => { + fetchOptions = (searchValue: string) => { this.setState( { isLoading: true, searchValue, }, () => { - this.debouncedFetch(searchValue, forceIndexPatternCacheRefresh); + this.debouncedFetch(searchValue); } ); }; @@ -204,7 +194,7 @@ export default class IndexPatternSelect extends Component Date: Thu, 8 Apr 2021 14:28:18 -0600 Subject: [PATCH 4/8] simplify title check --- .../public/ui/index_pattern_select/index_pattern_select.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx b/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx index e52afe98617e0..023c49c9b2882 100644 --- a/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx +++ b/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx @@ -113,10 +113,7 @@ export default class IndexPatternSelect extends Component Date: Thu, 8 Apr 2021 14:35:35 -0600 Subject: [PATCH 5/8] revert unneeded changes --- .../public/ui/index_pattern_select/index_pattern_select.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx b/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx index 023c49c9b2882..04bdb7a690268 100644 --- a/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx +++ b/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx @@ -158,15 +158,13 @@ export default class IndexPatternSelect extends Component { + fetchOptions = (searchValue = '') => { this.setState( { isLoading: true, searchValue, }, - () => { - this.debouncedFetch(searchValue); - } + this.debouncedFetch.bind(null, searchValue) ); }; From 0ed884362b46015f67438cad6e42715911fccc9a Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 8 Apr 2021 15:31:49 -0600 Subject: [PATCH 6/8] tslint --- .../common/index_patterns/index_patterns/index_patterns.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts index 3708dc8aa403c..04d2785137719 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts @@ -535,7 +535,9 @@ export class IndexPatternsService { }); indexPattern.id = response.id; this.indexPatternCache.set(indexPattern.id, Promise.resolve(indexPattern)); - this.savedObjectsCache.push(response); + if (this.savedObjectsCache) { + this.savedObjectsCache.push(response as SavedObject); + } return indexPattern; } From f4535ad2a01492bff541398faca9011733194d91 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 8 Apr 2021 16:28:38 -0600 Subject: [PATCH 7/8] api doc updates --- ...bana-plugin-plugins-data-public.indexpatternselectprops.md | 1 - .../public/kibana-plugin-plugins-data-public.searchbar.md | 4 ++-- src/plugins/data/public/public.api.md | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternselectprops.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternselectprops.md index 80f4832ba5643..5cfd5e1bc9929 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternselectprops.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternselectprops.md @@ -12,6 +12,5 @@ export declare type IndexPatternSelectProps = Required void; - maxIndexPatterns?: number; }; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md index 7c7f2a53aca92..193a2e5a24f3f 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md @@ -7,7 +7,7 @@ Signature: ```typescript -SearchBar: React.ComponentClass, "query" | "placeholder" | "isLoading" | "iconType" | "indexPatterns" | "filters" | "dataTestSubj" | "isClearable" | "isInvalid" | "storageKey" | "refreshInterval" | "nonKqlMode" | "nonKqlModeHelpText" | "screenTitle" | "disableLanguageSwitcher" | "autoSubmit" | "onRefresh" | "onRefreshChange" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated">, any> & { - WrappedComponent: React.ComponentType & ReactIntl.InjectedIntlProps>; +SearchBar: React.ComponentClass, "query" | "placeholder" | "isLoading" | "iconType" | "indexPatterns" | "filters" | "dataTestSubj" | "isClearable" | "refreshInterval" | "nonKqlMode" | "nonKqlModeHelpText" | "screenTitle" | "onRefresh" | "onRefreshChange" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated">, any> & { + WrappedComponent: React.ComponentType & ReactIntl.InjectedIntlProps>; } ``` diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 05925f097de24..c80f008636ba6 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -1560,7 +1560,6 @@ export type IndexPatternSelectProps = Required, 'isLo indexPatternId: string; fieldTypes?: string[]; onNoIndexPatterns?: () => void; - maxIndexPatterns?: number; }; // Warning: (ae-missing-release-tag) "IndexPatternSpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) From 3ea0e2f9f72908456656d43ceb9fdfd9e2e04783 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 8 Apr 2021 18:06:05 -0600 Subject: [PATCH 8/8] fix functional test --- .../apps/visualize/input_control_vis/input_control_options.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/apps/visualize/input_control_vis/input_control_options.ts b/test/functional/apps/visualize/input_control_vis/input_control_options.ts index dc02cada9a712..2e3b5d758436e 100644 --- a/test/functional/apps/visualize/input_control_vis/input_control_options.ts +++ b/test/functional/apps/visualize/input_control_vis/input_control_options.ts @@ -31,7 +31,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); await PageObjects.visEditor.clickVisEditorTab('controls'); await PageObjects.visEditor.addInputControl(); - await comboBox.set('indexPatternSelect-0', 'logstash- '); + await comboBox.set('indexPatternSelect-0', 'logstash-'); await comboBox.set('fieldSelect-0', FIELD_NAME); await PageObjects.visEditor.clickGo(); });