diff --git a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js
index e316dd3254cc0..c2be750ec7f63 100644
--- a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js
+++ b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js
@@ -127,13 +127,6 @@ describe('discover field chooser directives', function () {
};
};
- describe('Index list', function () {
- it('should be in alphabetical order', function () {
- $elem.find('.ui-select-toggle').click();
- expect($elem.find('[role=option]').text().replace(/\W+/g, '')).to.be('abc');
- });
- });
-
describe('Field listing', function () {
it('should have Selected Fields, Fields and Popular Fields sections', function () {
const headers = $elem.find('.sidebar-list-header');
diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/__snapshots__/discover_index_pattern.test.tsx.snap b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/__snapshots__/discover_index_pattern.test.tsx.snap
new file mode 100644
index 0000000000000..d7737bbfe4078
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/__snapshots__/discover_index_pattern.test.tsx.snap
@@ -0,0 +1,11 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`DiscoverIndexPattern A single index pattern is just displayed 1`] = `
+
+`;
+
+exports[`DiscoverIndexPattern Invalid props dont cause an exception: "" 1`] = `""`;
diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern.test.tsx b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern.test.tsx
new file mode 100644
index 0000000000000..68ef0f5b46694
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern.test.tsx
@@ -0,0 +1,75 @@
+/*
+ * 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 React from 'react';
+import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers';
+// @ts-ignore
+import { findTestSubject } from '@elastic/eui/lib/test';
+import { SavedObject } from 'kibana/server';
+import { DiscoverIndexPattern, DiscoverIndexPatternProps } from './discover_index_pattern';
+import { comboBoxKeyCodes } from '@elastic/eui';
+
+const indexPattern1 = {
+ id: 'test1',
+ attributes: {
+ title: 'test1',
+ },
+} as SavedObject;
+
+const indexPattern2 = {
+ id: 'test2',
+ attributes: {
+ title: 'test2',
+ },
+} as SavedObject;
+
+describe('DiscoverIndexPattern', () => {
+ test('Invalid props dont cause an exception', () => {
+ const props = {
+ indexPatternList: null,
+ selectedIndexPattern: null,
+ setIndexPattern: jest.fn(),
+ } as any;
+
+ expect(shallowWithIntl()).toMatchSnapshot(`""`);
+ });
+ test('A single index pattern is just displayed', () => {
+ const props = {
+ indexPatternList: [indexPattern1],
+ selectedIndexPattern: indexPattern1,
+ setIndexPattern: jest.fn(),
+ } as DiscoverIndexPatternProps;
+
+ expect(shallowWithIntl()).toMatchSnapshot();
+ });
+
+ test('Multiple index patterns are selectable', () => {
+ const props = {
+ indexPatternList: [indexPattern1, indexPattern2],
+ selectedIndexPattern: indexPattern2,
+ setIndexPattern: jest.fn(),
+ } as DiscoverIndexPatternProps;
+ const component = mountWithIntl();
+ findTestSubject(component, 'indexPattern-switch-link').simulate('click');
+
+ const searchInput = findTestSubject(component, 'comboBoxSearchInput');
+ searchInput.simulate('change', { target: { value: 'test1' } });
+ searchInput.simulate('keyDown', { keyCode: comboBoxKeyCodes.ENTER });
+ expect(props.setIndexPattern).toBeCalledWith('test1');
+ });
+});
diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern.tsx b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern.tsx
new file mode 100644
index 0000000000000..55f58d352ac23
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern.tsx
@@ -0,0 +1,107 @@
+/*
+ * 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 React, { useState } from 'react';
+import { EuiComboBox } from '@elastic/eui';
+import { SavedObject } from 'kibana/server';
+import { DiscoverIndexPatternTitle } from './discover_index_pattern_title';
+
+export interface DiscoverIndexPatternProps {
+ /**
+ * list of available index patterns, if length > 1, component offers a "change" link
+ */
+ indexPatternList: SavedObject[];
+ /**
+ * currently selected index pattern, due to angular issues it's undefined at first rendering
+ */
+ selectedIndexPattern: SavedObject;
+ /**
+ * triggered when user selects a new index pattern
+ */
+ setIndexPattern: (id: string) => void;
+}
+
+/**
+ * Component allows you to select an index pattern in discovers side bar
+ */
+export function DiscoverIndexPattern({
+ indexPatternList,
+ selectedIndexPattern,
+ setIndexPattern,
+}: DiscoverIndexPatternProps) {
+ if (!indexPatternList || indexPatternList.length === 0 || !selectedIndexPattern) {
+ // just in case, shouldn't happen
+ return null;
+ }
+ const [selected, setSelected] = useState(selectedIndexPattern);
+ const [showCombo, setShowCombo] = useState(false);
+ const options = indexPatternList.map(entity => ({
+ value: entity.id,
+ label: entity.attributes!.title,
+ }));
+ const selectedOptions = selected
+ ? [{ value: selected.id, label: selected.attributes.title }]
+ : [];
+
+ const findIndexPattern = (id?: string) => indexPatternList.find(entity => entity.id === id);
+
+ if (!showCombo) {
+ return (
+ 1}
+ onChange={() => setShowCombo(true)}
+ title={selected.attributes ? selected.attributes.title : ''}
+ />
+ );
+ }
+
+ /**
+ * catches a EuiComboBox related 'Can't perform a React state update on an unmounted component'
+ * warning in console by delaying the hiding/removal of the EuiComboBox a bit
+ */
+ function hideCombo() {
+ setTimeout(() => setShowCombo(false), 50);
+ }
+
+ return (
+ hideCombo()}
+ onChange={choices => {
+ const newSelected = choices[0] && findIndexPattern(choices[0].value);
+ if (newSelected) {
+ setSelected(newSelected);
+ setIndexPattern(newSelected.id);
+ }
+ hideCombo();
+ }}
+ inputRef={el => {
+ // auto focus input element when combo box is displayed
+ if (el) {
+ el.focus();
+ }
+ }}
+ options={options}
+ selectedOptions={selectedOptions}
+ singleSelection={{ asPlainText: true }}
+ />
+ );
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern_directive.ts b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern_directive.ts
new file mode 100644
index 0000000000000..938d6cc226f2f
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern_directive.ts
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+// @ts-ignore
+import { uiModules } from 'ui/modules';
+import { wrapInI18nContext } from 'ui/i18n';
+import { DiscoverIndexPattern } from './discover_index_pattern';
+
+const app = uiModules.get('apps/discover');
+
+app.directive('discoverIndexPatternSelect', function(reactDirective: any) {
+ return reactDirective(wrapInI18nContext(DiscoverIndexPattern), [
+ ['indexPatternList', { watchDepth: 'reference' }],
+ ['selectedIndexPattern', { watchDepth: 'reference' }],
+ ['setIndexPattern', { watchDepth: 'reference' }],
+ ]);
+});
diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern_title.tsx b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern_title.tsx
new file mode 100644
index 0000000000000..23679c4db5a7f
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern_title.tsx
@@ -0,0 +1,85 @@
+/*
+ * 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 React from 'react';
+import { EuiToolTip, EuiFlexItem, EuiFlexGroup, EuiTitle, EuiButtonEmpty } from '@elastic/eui';
+
+import { FormattedMessage } from '@kbn/i18n/react';
+
+export interface DiscoverIndexPatternTitleProps {
+ /**
+ * determines whether the change link is displayed
+ */
+ isChangeable: boolean;
+ /**
+ * function triggered when the change link is clicked
+ */
+ onChange: () => void;
+ /**
+ * title of the current index pattern
+ */
+ title: string;
+}
+
+/**
+ * Component displaying the title of the current selected index pattern
+ * and if changeable is true, a link is provided to change the index pattern
+ */
+export function DiscoverIndexPatternTitle({
+ isChangeable,
+ onChange,
+ title,
+}: DiscoverIndexPatternTitleProps) {
+ return (
+
+
+
+
+ {title}
+
+
+
+ {isChangeable && (
+
+
+ }
+ >
+ onChange()}
+ >
+ (
+
+ )
+
+
+
+ )}
+
+ );
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/field_chooser.html b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/field_chooser.html
index 55c52baee7ba8..96aa1582b5243 100644
--- a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/field_chooser.html
+++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/field_chooser.html
@@ -1,39 +1,14 @@