From 0ab55da15b946fa911fbcbed2562e9c38f412341 Mon Sep 17 00:00:00 2001
From: Uladzislau Lasitsa
Date: Mon, 25 May 2020 15:07:59 +0300
Subject: [PATCH] KibanaContext in index pattern managment ui (#66985)
* Using KibanaContext instead of passing dependencies.
* Fixed comments
* Delete index.scss
* Added comment for workaround
* Fixed tests
* Fixed eslint
Co-authored-by: Alexey Antonov
Co-authored-by: Elastic Machine
---
.../create_index_pattern_wizard.test.tsx.snap | 121 ------
.../header/__snapshots__/header.test.tsx.snap | 317 +++++++++++-----
.../components/header/header.test.tsx | 39 +-
.../components/header/header.tsx | 5 +-
.../step_index_pattern.test.tsx | 111 ++++--
.../step_index_pattern/step_index_pattern.tsx | 49 ++-
.../step_time_field/step_time_field.test.tsx | 227 +++++------
.../step_time_field/step_time_field.tsx | 12 +-
.../create_index_pattern_wizard.test.tsx | 96 +++--
.../create_index_pattern_wizard.tsx | 87 ++---
.../create_edit_field/create_edit_field.tsx | 45 +--
.../create_edit_field_container.tsx | 50 +--
.../edit_index_pattern/edit_index_pattern.tsx | 73 ++--
.../edit_index_pattern_container.tsx | 42 +--
.../edit_index_pattern/tabs/tabs.tsx | 36 +-
.../__snapshots__/field_editor.test.tsx.snap | 26 +-
.../warning_call_out.test.tsx.snap | 212 ++++++++---
.../warning_call_out.test.tsx | 34 +-
.../scripting_call_outs/warning_call_out.tsx | 12 +-
.../__snapshots__/help_flyout.test.tsx.snap | 54 +--
.../scripting_help/help_flyout.test.tsx | 18 -
.../components/scripting_help/help_flyout.tsx | 17 +-
.../scripting_help/scripting_syntax.tsx | 354 +++++++++---------
.../components/scripting_help/test_script.tsx | 31 +-
.../field_editor/field_editor.test.tsx | 120 +++---
.../components/field_editor/field_editor.tsx | 69 ++--
.../index_pattern_table.tsx | 52 ++-
.../public/components/test_utils.tsx | 40 ++
.../mount_management_section.tsx | 110 ++----
.../index_pattern_management/public/mocks.ts | 29 ++
.../index_pattern_management/public/types.ts | 51 +++
31 files changed, 1283 insertions(+), 1256 deletions(-)
create mode 100644 src/plugins/index_pattern_management/public/components/test_utils.tsx
create mode 100644 src/plugins/index_pattern_management/public/types.ts
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap
index 9a390f84ef5dc0..5c955bbd3283ec 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap
@@ -6,7 +6,6 @@ exports[`CreateIndexPatternWizard defaults to the loading state 1`] = `
>
-
-
- Create test index pattern
-
-
-
-
-
-
+ Test prompt
+
+ }
+>
+
+
+
+ Create test index pattern
+
+
+
+ Beta
+
+
+
+
+
-
-
-
+
-
-
-
-
-
-
-
-
- Test prompt
+
+
+
+
+
+
+
+ Kibana uses index patterns to retrieve data from Elasticsearch indices for things like visualizations.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Test prompt
+
+
+
+
-
-
+
`;
exports[`Header should render normally 1`] = `
-
-
-
- Create test index pattern
-
-
-
-
+
+
+
+ Create test index pattern
+
+
+
-
-
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ Kibana uses index patterns to retrieve data from Elasticsearch indices for things like visualizations.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
`;
exports[`Header should render without including system indices 1`] = `
-
-
-
- Create test index pattern
-
-
-
-
+
+
+
+ Create test index pattern
+
+
+
-
-
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ Kibana uses index patterns to retrieve data from Elasticsearch indices for things like visualizations.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
`;
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.test.tsx
index d70746dd930e45..d12e0401380b9e 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.test.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.test.tsx
@@ -19,46 +19,65 @@
import React from 'react';
import { Header } from '../header';
-import { shallowWithI18nProvider } from 'test_utils/enzyme_helpers';
+import { mount } from 'enzyme';
+import { KibanaContextProvider } from 'src/plugins/kibana_react/public';
+import { mockManagementPlugin } from '../../../../mocks';
describe('Header', () => {
const indexPatternName = 'test index pattern';
+ const mockedContext = mockManagementPlugin.createIndexPatternManagmentContext();
+
it('should render normally', () => {
- const component = shallowWithI18nProvider(
+ const component = mount(
{}}
- changeTitle={() => {}}
- />
+ />,
+ {
+ wrappingComponent: KibanaContextProvider,
+ wrappingComponentProps: {
+ services: mockedContext,
+ },
+ }
);
expect(component).toMatchSnapshot();
});
it('should render without including system indices', () => {
- const component = shallowWithI18nProvider(
+ const component = mount(
{}}
- changeTitle={() => {}}
- />
+ />,
+ {
+ wrappingComponent: KibanaContextProvider,
+ wrappingComponentProps: {
+ services: mockedContext,
+ },
+ }
);
expect(component).toMatchSnapshot();
});
it('should render a different name, prompt, and beta tag if provided', () => {
- const component = shallowWithI18nProvider(
+ const component = mount(
{}}
prompt={Test prompt
}
indexPatternName={indexPatternName}
isBeta={true}
- changeTitle={() => {}}
- />
+ />,
+ {
+ wrappingComponent: KibanaContextProvider,
+ wrappingComponentProps: {
+ services: mockedContext,
+ },
+ }
);
expect(component).toMatchSnapshot();
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.tsx
index 1be33e3edc3bc5..35c6e67d0ea0e7 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.tsx
@@ -32,6 +32,8 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
+import { useKibana } from '../../../../../../../plugins/kibana_react/public';
+import { IndexPatternManagmentContext } from '../../../../types';
export const Header = ({
prompt,
@@ -40,7 +42,6 @@ export const Header = ({
isIncludingSystemIndices,
onChangeIncludingSystemIndices,
isBeta = false,
- changeTitle,
}: {
prompt?: React.ReactNode;
indexPatternName: string;
@@ -48,8 +49,8 @@ export const Header = ({
isIncludingSystemIndices: boolean;
onChangeIncludingSystemIndices: () => void;
isBeta?: boolean;
- changeTitle: (title: string) => void;
}) => {
+ const changeTitle = useKibana().services.chrome.docTitle.change;
const createIndexPatternHeader = i18n.translate(
'indexPatternManagement.createIndexPatternHeader',
{
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx
index 28b2884e9a65f0..053940270c2b6d 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx
@@ -18,13 +18,12 @@
*/
import React from 'react';
+import { SavedObjectsFindResponsePublic } from 'kibana/public';
import { StepIndexPattern } from '../step_index_pattern';
-import { shallowWithI18nProvider } from 'test_utils/enzyme_helpers';
import { Header } from './components/header';
import { IndexPatternCreationConfig } from '../../../../../../../plugins/index_pattern_management/public';
-import { coreMock } from '../../../../../../../core/public/mocks';
-import { dataPluginMock } from '../../../../../../../plugins/data/public/mocks';
-import { SavedObjectsFindResponsePublic } from 'src/core/public';
+import { mockManagementPlugin } from '../../../../mocks';
+import { createComponentWithContext } from '../../../test_utils';
jest.mock('../../lib/ensure_minimum_time', () => ({
ensureMinimumTime: async (promises: Array>) =>
@@ -53,37 +52,40 @@ const allIndices = [
const goToNextStep = () => {};
-const savedObjectClient = coreMock.createStart().savedObjects.client;
-savedObjectClient.find = () =>
- new Promise>(() => ({ savedObjects: [] }));
-
-const uiSettings = coreMock.createSetup().uiSettings;
-uiSettings.get.mockReturnValue('');
-
-const createComponent = (props?: Record) => {
- return shallowWithI18nProvider(
-
- );
-};
+const mockContext = mockManagementPlugin.createIndexPatternManagmentContext();
+
+mockContext.savedObjects.client.find = async () =>
+ Promise.resolve(({ savedObjects: [] } as unknown) as SavedObjectsFindResponsePublic);
+mockContext.uiSettings.get.mockReturnValue('');
describe('StepIndexPattern', () => {
it('renders the loading state', () => {
- const component = createComponent();
+ const component = createComponentWithContext(
+ StepIndexPattern,
+ {
+ allIndices,
+ isIncludingSystemIndices: false,
+ goToNextStep,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
+ );
component.setState({ isLoadingIndices: true });
expect(component.find('[data-test-subj="createIndexPatternStep1Loading"]')).toMatchSnapshot();
});
it('renders indices which match the initial query', async () => {
- const component = createComponent({ initialQuery: 'kibana' });
+ const component = createComponentWithContext(
+ StepIndexPattern,
+ {
+ allIndices,
+ isIncludingSystemIndices: false,
+ goToNextStep,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ initialQuery: 'kibana',
+ },
+ mockContext
+ );
// Ensure all promises resolve
await new Promise((resolve) => process.nextTick(resolve));
@@ -96,7 +98,16 @@ describe('StepIndexPattern', () => {
});
it('renders errors when input is invalid', async () => {
- const component = createComponent();
+ const component = createComponentWithContext(
+ StepIndexPattern,
+ {
+ allIndices,
+ isIncludingSystemIndices: false,
+ goToNextStep,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
+ );
const instance = component.instance() as StepIndexPattern;
instance.onQueryChanged({ target: { value: '?' } } as React.ChangeEvent);
@@ -110,7 +121,16 @@ describe('StepIndexPattern', () => {
});
it('renders matching indices when input is valid', async () => {
- const component = createComponent();
+ const component = createComponentWithContext(
+ StepIndexPattern,
+ {
+ allIndices,
+ isIncludingSystemIndices: false,
+ goToNextStep,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
+ );
const instance = component.instance() as StepIndexPattern;
instance.onQueryChanged({ target: { value: 'k' } } as React.ChangeEvent);
@@ -125,20 +145,47 @@ describe('StepIndexPattern', () => {
});
it('appends a wildcard automatically to queries', async () => {
- const component = createComponent();
+ const component = createComponentWithContext(
+ StepIndexPattern,
+ {
+ allIndices,
+ isIncludingSystemIndices: false,
+ goToNextStep,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
+ );
const instance = component.instance() as StepIndexPattern;
instance.onQueryChanged({ target: { value: 'k' } } as React.ChangeEvent);
expect(component.state('query')).toBe('k*');
});
it('disables the next step if the index pattern exists', async () => {
- const component = createComponent();
+ const component = createComponentWithContext(
+ StepIndexPattern,
+ {
+ allIndices,
+ isIncludingSystemIndices: false,
+ goToNextStep,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
+ );
component.setState({ indexPatternExists: true });
expect(component.find(Header).prop('isNextStepDisabled')).toBe(true);
});
it('ensures the response of the latest request is persisted', async () => {
- const component = createComponent();
+ const component = createComponentWithContext(
+ StepIndexPattern,
+ {
+ allIndices,
+ isIncludingSystemIndices: false,
+ goToNextStep,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
+ );
const instance = component.instance() as StepIndexPattern;
instance.onQueryChanged({ target: { value: 'e' } } as React.ChangeEvent);
instance.lastQuery = 'k';
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx
index 952eff45363462..edb96f119385ec 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx
@@ -21,12 +21,7 @@ import React, { Component } from 'react';
import { EuiPanel, EuiSpacer, EuiCallOut } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
-import {
- indexPatterns,
- DataPublicPluginStart,
- IndexPatternAttributes,
-} from '../../../../../../../plugins/data/public';
-import { SavedObjectsClientContract, IUiSettingsClient } from '../../../../../../../core/public';
+import { indexPatterns, IndexPatternAttributes } from '../../../../../../../plugins/data/public';
import { MAX_SEARCH_SIZE } from '../../constants';
import {
getIndices,
@@ -39,18 +34,17 @@ import { LoadingIndices } from './components/loading_indices';
import { StatusMessage } from './components/status_message';
import { IndicesList } from './components/indices_list';
import { Header } from './components/header';
+import { context as contextType } from '../../../../../../kibana_react/public';
import { IndexPatternCreationConfig } from '../../../../../../../plugins/index_pattern_management/public';
import { MatchedIndex } from '../../types';
+import { IndexPatternManagmentContextValue } from '../../../../types';
interface StepIndexPatternProps {
allIndices: MatchedIndex[];
isIncludingSystemIndices: boolean;
- esService: DataPublicPluginStart['search']['__LEGACY']['esClient'];
- savedObjectsClient: SavedObjectsClientContract;
indexPatternCreationType: IndexPatternCreationConfig;
goToNextStep: (query: string) => void;
initialQuery?: string;
- uiSettings: IUiSettingsClient;
}
interface StepIndexPatternState {
@@ -66,6 +60,10 @@ interface StepIndexPatternState {
}
export class StepIndexPattern extends Component {
+ static contextType = contextType;
+
+ public readonly context!: IndexPatternManagmentContextValue;
+
state = {
partialMatchedIndices: [],
exactMatchedIndices: [],
@@ -80,11 +78,11 @@ export class StepIndexPattern extends Component {
- const { savedObjects } = await this.props.savedObjectsClient.find({
+ const { savedObjects } = await this.context.services.savedObjects.client.find<
+ IndexPatternAttributes
+ >({
type: 'index-pattern',
fields: ['title'],
perPage: 10000,
@@ -111,7 +111,7 @@ export class StepIndexPattern extends Component {
- const { esService, indexPatternCreationType } = this.props;
+ const { indexPatternCreationType } = this.props;
const { existingIndexPatterns } = this.state;
if ((existingIndexPatterns as string[]).includes(query)) {
@@ -123,7 +123,12 @@ export class StepIndexPattern extends Component {};
+const mockContext = mockManagementPlugin.createIndexPatternManagmentContext();
const fields = [
{
name: '@timestamp',
type: 'date',
},
];
-const indexPatternsService = {
+mockContext.data.indexPatterns = {
make: () => ({
fieldsFetcher: {
fetchForWildcard: jest.fn().mockReturnValue(Promise.resolve(fields)),
@@ -55,28 +57,30 @@ const indexPatternsService = {
describe('StepTimeField', () => {
it('should render normally', () => {
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ StepTimeField,
+ {
+ indexPattern: 'ki*',
+ goToPreviousStep: noop,
+ createIndexPattern: noop,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
);
expect(component).toMatchSnapshot();
});
it('should render timeFields', () => {
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ StepTimeField,
+ {
+ indexPattern: 'ki*',
+ goToPreviousStep: noop,
+ createIndexPattern: noop,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
);
component.setState({
@@ -90,14 +94,15 @@ describe('StepTimeField', () => {
});
it('should render a selected timeField', () => {
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ StepTimeField,
+ {
+ indexPattern: 'ki*',
+ goToPreviousStep: noop,
+ createIndexPattern: noop,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
);
component.setState({
@@ -113,14 +118,15 @@ describe('StepTimeField', () => {
});
it('should ensure disabled time field options work properly', () => {
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ StepTimeField,
+ {
+ indexPattern: 'ki*',
+ goToPreviousStep: noop,
+ createIndexPattern: noop,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
);
component.setState({
@@ -146,14 +152,15 @@ describe('StepTimeField', () => {
});
it('should disable the action button if an invalid time field is selected', () => {
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ StepTimeField,
+ {
+ indexPattern: 'ki*',
+ goToPreviousStep: noop,
+ createIndexPattern: noop,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
);
component.setState({
@@ -172,14 +179,15 @@ describe('StepTimeField', () => {
});
it('should enable the action button if the user decides to not select a time field', () => {
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ StepTimeField,
+ {
+ indexPattern: 'ki*',
+ goToPreviousStep: noop,
+ createIndexPattern: noop,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
);
component.setState({
@@ -198,14 +206,15 @@ describe('StepTimeField', () => {
});
it('should render advanced options', () => {
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ StepTimeField,
+ {
+ indexPattern: 'ki*',
+ goToPreviousStep: noop,
+ createIndexPattern: noop,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
);
component.setState({ showingAdvancedOptions: true });
@@ -214,14 +223,15 @@ describe('StepTimeField', () => {
});
it('should render advanced options with an index pattern id', () => {
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ StepTimeField,
+ {
+ indexPattern: 'ki*',
+ goToPreviousStep: noop,
+ createIndexPattern: noop,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
);
component.setState({
@@ -233,14 +243,15 @@ describe('StepTimeField', () => {
});
it('should render a loading state when creating the index pattern', () => {
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ StepTimeField,
+ {
+ indexPattern: 'ki*',
+ goToPreviousStep: noop,
+ createIndexPattern: noop,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
);
component.setState({ isCreating: true });
@@ -249,14 +260,15 @@ describe('StepTimeField', () => {
});
it('should render any error message', () => {
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ StepTimeField,
+ {
+ indexPattern: 'ki*',
+ goToPreviousStep: noop,
+ createIndexPattern: noop,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
);
component.setState({ error: 'foobar' });
@@ -265,14 +277,15 @@ describe('StepTimeField', () => {
});
it('should render "Custom index pattern ID already exists" when error is "Conflict"', () => {
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ StepTimeField,
+ {
+ indexPattern: 'ki*',
+ goToPreviousStep: noop,
+ createIndexPattern: noop,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
);
component.setState({ error: 'Conflict' });
@@ -284,14 +297,15 @@ describe('StepTimeField', () => {
const createIndexPattern = async () => {
throw new Error('foobar');
};
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ StepTimeField,
+ {
+ indexPattern: 'ki*',
+ goToPreviousStep: noop,
+ createIndexPattern,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
);
await (component.instance() as StepTimeField).createIndexPattern();
@@ -305,14 +319,15 @@ describe('StepTimeField', () => {
it('should call createIndexPattern with undefined time field when no time filter chosen', async () => {
const createIndexPattern = jest.fn();
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ StepTimeField,
+ {
+ indexPattern: 'ki*',
+ goToPreviousStep: noop,
+ createIndexPattern,
+ indexPatternCreationType: mockIndexPatternCreationType,
+ },
+ mockContext
);
await (component.instance() as StepTimeField).fetchTimeFields();
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx
index 98e06d8a0f6975..98ce22cd14227c 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx
@@ -34,12 +34,12 @@ import { Header } from './components/header';
import { TimeField } from './components/time_field';
import { AdvancedOptions } from './components/advanced_options';
import { ActionButtons } from './components/action_buttons';
+import { context } from '../../../../../../kibana_react/public';
+import { IndexPatternManagmentContextValue } from '../../../../types';
import { IndexPatternCreationConfig } from '../../../..';
-import { DataPublicPluginStart } from '../../../../../../data/public';
interface StepTimeFieldProps {
indexPattern: string;
- indexPatternsService: DataPublicPluginStart['indexPatterns'];
goToPreviousStep: () => void;
createIndexPattern: (selectedTimeField: string | undefined, indexPatternId: string) => void;
indexPatternCreationType: IndexPatternCreationConfig;
@@ -65,6 +65,10 @@ interface TimeFieldConfig {
}
export class StepTimeField extends Component {
+ static contextType = context;
+
+ public readonly context!: IndexPatternManagmentContextValue;
+
state = {
error: '',
timeFields: [],
@@ -96,10 +100,10 @@ export class StepTimeField extends Component {
- const { indexPatternsService, indexPattern: pattern } = this.props;
+ const { indexPattern: pattern } = this.props;
const { getFetchForWildcardOptions } = this.props.indexPatternCreationType;
- const indexPattern = await indexPatternsService.make();
+ const indexPattern = await this.context.services.data.indexPatterns.make();
indexPattern.title = pattern;
this.setState({ isFetchingTimeFields: true });
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx
index f526aa35c2afe7..b14cd526d7e276 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx
@@ -17,18 +17,11 @@
* under the License.
*/
-import React from 'react';
-import { shallow } from 'enzyme';
-
-import {
- CreateIndexPatternWizard,
- CreateIndexPatternWizardProps,
-} from './create_index_pattern_wizard';
-import { coreMock } from '../../../../../core/public/mocks';
-import { dataPluginMock } from '../../../../../plugins/data/public/mocks';
+import { CreateIndexPatternWizard } from './create_index_pattern_wizard';
import { IndexPattern } from '../../../../../plugins/data/public';
-import { SavedObjectsClient } from '../../../../../core/public';
-import { IndexPatternCreationConfig } from '../../service/creation';
+import { mockManagementPlugin } from '../../mocks';
+import { IndexPatternCreationConfig } from '../../';
+import { createComponentWithContext } from '../test_utils';
jest.mock('./components/step_index_pattern', () => ({ StepIndexPattern: 'StepIndexPattern' }));
jest.mock('./components/step_time_field', () => ({ StepTimeField: 'StepTimeField' }));
@@ -40,30 +33,6 @@ jest.mock('./lib/get_indices', () => ({
return [{ name: 'kibana' }];
},
}));
-
-const { savedObjects, overlays, uiSettings, chrome, http } = coreMock.createStart();
-const { indexPatterns, search } = dataPluginMock.createStartContract();
-
-const mockIndexPatternCreationType = new IndexPatternCreationConfig({
- type: 'default',
- name: 'name',
-});
-
-const services = ({
- indexPatternCreation: {
- getType: jest.fn(() => mockIndexPatternCreationType),
- },
- es: search.__LEGACY.esClient,
- indexPatterns,
- savedObjectsClient: savedObjects.client as SavedObjectsClient,
- uiSettings,
- changeUrl: jest.fn(),
- openConfirm: overlays.openConfirm,
- setBreadcrumbs: jest.fn(),
- docTitle: chrome.docTitle,
- prependBasePath: http.basePath.prepend,
-} as unknown) as CreateIndexPatternWizardProps['services'];
-
const routeComponentPropsMock = {
history: {
push: jest.fn(),
@@ -71,19 +40,30 @@ const routeComponentPropsMock = {
location: {} as any,
match: {} as any,
};
+const mockContext = mockManagementPlugin.createIndexPatternManagmentContext();
+mockContext.indexPatternManagementStart.creation.getType = () => {
+ return new IndexPatternCreationConfig({
+ type: 'default',
+ name: 'name',
+ });
+};
describe('CreateIndexPatternWizard', () => {
test(`defaults to the loading state`, () => {
- const component = shallow(
-
+ const component = createComponentWithContext(
+ CreateIndexPatternWizard,
+ { ...routeComponentPropsMock },
+ mockContext
);
expect(component).toMatchSnapshot();
});
test('renders the empty state when there are no indices', async () => {
- const component = shallow(
-
+ const component = createComponentWithContext(
+ CreateIndexPatternWizard,
+ { ...routeComponentPropsMock },
+ mockContext
);
component.setState({
@@ -97,8 +77,10 @@ describe('CreateIndexPatternWizard', () => {
});
test('renders when there are no indices but there are remote clusters', async () => {
- const component = shallow(
-
+ const component = createComponentWithContext(
+ CreateIndexPatternWizard,
+ { ...routeComponentPropsMock },
+ mockContext
);
component.setState({
@@ -112,8 +94,10 @@ describe('CreateIndexPatternWizard', () => {
});
test('shows system indices even if there are no other indices if the include system indices is toggled', async () => {
- const component = shallow(
-
+ const component = createComponentWithContext(
+ CreateIndexPatternWizard,
+ { ...routeComponentPropsMock },
+ mockContext
);
component.setState({
@@ -127,8 +111,10 @@ describe('CreateIndexPatternWizard', () => {
});
test('renders index pattern step when there are indices', async () => {
- const component = shallow(
-
+ const component = createComponentWithContext(
+ CreateIndexPatternWizard,
+ { ...routeComponentPropsMock },
+ mockContext
);
component.setState({
@@ -141,8 +127,10 @@ describe('CreateIndexPatternWizard', () => {
});
test('renders time field step when step is set to 2', async () => {
- const component = shallow(
-
+ const component = createComponentWithContext(
+ CreateIndexPatternWizard,
+ { ...routeComponentPropsMock },
+ mockContext
);
component.setState({
@@ -158,7 +146,7 @@ describe('CreateIndexPatternWizard', () => {
test('invokes the provided services when creating an index pattern', async () => {
const create = jest.fn().mockImplementation(() => 'id');
const clear = jest.fn();
- services.indexPatterns.clearCache = clear;
+ mockContext.data.indexPatterns.clearCache = clear;
const indexPattern = ({
id: '1',
title: 'my-fake-index-pattern',
@@ -166,17 +154,19 @@ describe('CreateIndexPatternWizard', () => {
fields: [],
create,
} as unknown) as IndexPattern;
- services.indexPatterns.make = async () => {
+ mockContext.data.indexPatterns.make = async () => {
return indexPattern;
};
- const component = shallow(
-
+ const component = createComponentWithContext(
+ CreateIndexPatternWizard,
+ { ...routeComponentPropsMock },
+ mockContext
);
component.setState({ indexPattern: 'foo' });
- await component.instance().createIndexPattern(undefined, 'id');
- expect(services.uiSettings.get).toBeCalled();
+ await (component.instance() as CreateIndexPatternWizard).createIndexPattern(undefined, 'id');
+ expect(mockContext.uiSettings.get).toBeCalled();
expect(create).toBeCalled();
expect(clear).toBeCalledWith('id');
expect(routeComponentPropsMock.history.push).toBeCalledWith(`/patterns/id`);
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx
index 89ed7dd97c3b61..111be41cfc53a9 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx
@@ -23,42 +23,20 @@ import { EuiGlobalToastList, EuiGlobalToastListToast, EuiPanel } from '@elastic/
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import { withRouter, RouteComponentProps } from 'react-router-dom';
-
-import {
- SavedObjectsClientContract,
- IUiSettingsClient,
- OverlayStart,
- ChromeDocTitle,
- IBasePath,
-} from 'src/core/public';
-import { DataPublicPluginStart } from 'src/plugins/data/public';
-import { ManagementAppMountParams } from '../../../../management/public';
import { StepIndexPattern } from './components/step_index_pattern';
import { StepTimeField } from './components/step_time_field';
import { Header } from './components/header';
import { LoadingState } from './components/loading_state';
import { EmptyState } from './components/empty_state';
+import { context as contextType } from '../../../../kibana_react/public';
import { getCreateBreadcrumbs } from '../breadcrumbs';
import { MAX_SEARCH_SIZE } from './constants';
import { ensureMinimumTime, getIndices } from './lib';
-import { IndexPatternCreationConfig, IndexPatternManagementStart } from '../..';
+import { IndexPatternCreationConfig } from '../..';
+import { IndexPatternManagmentContextValue } from '../../types';
import { MatchedIndex } from './types';
-export interface CreateIndexPatternWizardProps extends RouteComponentProps {
- services: {
- indexPatternCreation: IndexPatternManagementStart['creation'];
- es: DataPublicPluginStart['search']['__LEGACY']['esClient'];
- indexPatterns: DataPublicPluginStart['indexPatterns'];
- savedObjectsClient: SavedObjectsClientContract;
- uiSettings: IUiSettingsClient;
- openConfirm: OverlayStart['openConfirm'];
- setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs'];
- docTitle: ChromeDocTitle;
- prependBasePath: IBasePath['prepend'];
- };
-}
-
interface CreateIndexPatternWizardState {
step: number;
indexPattern: string;
@@ -71,19 +49,19 @@ interface CreateIndexPatternWizardState {
}
export class CreateIndexPatternWizard extends Component<
- CreateIndexPatternWizardProps,
+ RouteComponentProps,
CreateIndexPatternWizardState
> {
- constructor(props: CreateIndexPatternWizardProps) {
- super(props);
- const {
- services: { indexPatternCreation, setBreadcrumbs },
- location,
- } = props;
+ static contextType = contextType;
- setBreadcrumbs(getCreateBreadcrumbs());
+ public readonly context!: IndexPatternManagmentContextValue;
- const type = new URLSearchParams(location.search).get('type') || undefined;
+ constructor(props: RouteComponentProps, context: IndexPatternManagmentContextValue) {
+ super(props, context);
+
+ context.services.setBreadcrumbs(getCreateBreadcrumbs());
+
+ const type = new URLSearchParams(props.location.search).get('type') || undefined;
this.state = {
step: 1,
@@ -93,7 +71,7 @@ export class CreateIndexPatternWizard extends Component<
isInitiallyLoadingIndices: true,
isIncludingSystemIndices: false,
toasts: [],
- indexPatternCreationType: indexPatternCreation.getType(type),
+ indexPatternCreationType: context.services.indexPatternManagementStart.creation.getType(type),
};
}
@@ -124,8 +102,6 @@ export class CreateIndexPatternWizard extends Component<
};
fetchData = async () => {
- const { services } = this.props;
-
this.setState({
allIndices: [],
isInitiallyLoadingIndices: true,
@@ -149,7 +125,12 @@ export class CreateIndexPatternWizard extends Component<
// query local and remote indices, updating state independently
ensureMinimumTime(
this.catchAndWarn(
- getIndices(services.es, this.state.indexPatternCreationType, `*`, MAX_SEARCH_SIZE),
+ getIndices(
+ this.context.services.data.search.__LEGACY.esClient,
+ this.state.indexPatternCreationType,
+ `*`,
+ MAX_SEARCH_SIZE
+ ),
[],
indicesFailMsg
)
@@ -160,7 +141,12 @@ export class CreateIndexPatternWizard extends Component<
this.catchAndWarn(
// if we get an error from remote cluster query, supply fallback value that allows user entry.
// ['a'] is fallback value
- getIndices(services.es, this.state.indexPatternCreationType, `*:*`, 1),
+ getIndices(
+ this.context.services.data.search.__LEGACY.esClient,
+ this.state.indexPatternCreationType,
+ `*:*`,
+ 1
+ ),
['a'],
clustersFailMsg
).then((remoteIndices: string[] | MatchedIndex[]) =>
@@ -169,10 +155,10 @@ export class CreateIndexPatternWizard extends Component<
};
createIndexPattern = async (timeFieldName: string | undefined, indexPatternId: string) => {
- const { services, history } = this.props;
+ const { history } = this.props;
const { indexPattern } = this.state;
- const emptyPattern = await services.indexPatterns.make();
+ const emptyPattern = await this.context.services.data.indexPatterns.make();
Object.assign(emptyPattern, {
id: indexPatternId,
@@ -191,7 +177,7 @@ export class CreateIndexPatternWizard extends Component<
}
);
- const isConfirmed = await services.openConfirm(confirmMessage, {
+ const isConfirmed = await this.context.services.overlays.openConfirm(confirmMessage, {
confirmButtonText: i18n.translate(
'indexPatternManagement.indexPattern.goToPatternButtonLabel',
{
@@ -207,11 +193,11 @@ export class CreateIndexPatternWizard extends Component<
}
}
- if (!services.uiSettings.get('defaultIndex')) {
- await services.uiSettings.set('defaultIndex', createdId);
+ if (!this.context.services.uiSettings.get('defaultIndex')) {
+ await this.context.services.uiSettings.set('defaultIndex', createdId);
}
- services.indexPatterns.clearCache(createdId);
+ this.context.services.data.indexPatterns.clearCache(createdId);
history.push(`/patterns/${createdId}`);
};
@@ -231,7 +217,6 @@ export class CreateIndexPatternWizard extends Component<
renderHeader() {
const { isIncludingSystemIndices } = this.state;
- const { services } = this.props;
return (
);
}
@@ -265,13 +249,13 @@ export class CreateIndexPatternWizard extends Component<
return (
);
}
if (step === 1) {
- const { services, location } = this.props;
+ const { location } = this.props;
const initialQuery = new URLSearchParams(location.search).get('id') || undefined;
return (
@@ -279,21 +263,16 @@ export class CreateIndexPatternWizard extends Component<
allIndices={allIndices}
initialQuery={indexPattern || initialQuery}
isIncludingSystemIndices={isIncludingSystemIndices}
- esService={services.es}
- savedObjectsClient={services.savedObjectsClient}
indexPatternCreationType={this.state.indexPatternCreationType}
goToNextStep={this.goToTimeFieldStep}
- uiSettings={services.uiSettings}
/>
);
}
if (step === 2) {
- const { services } = this.props;
return (
{
+ ({ indexPattern, mode, fieldName, history }: CreateEditFieldProps) => {
+ const { data, uiSettings, chrome, notifications } = useKibana<
+ IndexPatternManagmentContext
+ >().services;
const field =
mode === 'edit' && fieldName
? indexPattern.fields.getByName(fieldName)
- : services.indexPatterns.createField(
+ : data.indexPatterns.createField(
indexPattern,
{
scripted: true,
@@ -85,13 +70,13 @@ export const CreateEditField = withRouter(
values: { indexPatternTitle: indexPattern.title, fieldName },
}
);
- services.toasts.addWarning(message);
+ notifications.toasts.addWarning(message);
history.push(url);
}
const docFieldName = field?.name || newFieldPlaceholder;
- services.docTitle.change([docFieldName, indexPattern.title]);
+ chrome.docTitle.change([docFieldName, indexPattern.title]);
const redirectAway = () => {
history.push(`${url}?_a=(tab:${field?.scripted ? TAB_SCRIPTED_FIELDS : TAB_INDEXED_FIELDS})`);
@@ -104,7 +89,7 @@ export const CreateEditField = withRouter(
@@ -112,15 +97,7 @@ export const CreateEditField = withRouter(
indexPattern={indexPattern}
field={field}
services={{
- uiSettings: services.uiSettings,
- http: services.http,
- fieldFormatEditors,
redirectAway,
- docLinksScriptedFields: services.docLinksScriptedFields,
- SearchBar: services.SearchBar,
- toasts: services.toasts,
- fieldFormats: services.fieldFormats,
- indexPatterns: services.indexPatterns,
}}
/>
diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field_container.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field_container.tsx
index 70851b712d756c..39c0add40e9ad4 100644
--- a/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field_container.tsx
+++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field_container.tsx
@@ -20,53 +20,30 @@
import React, { useEffect, useState } from 'react';
import { withRouter, RouteComponentProps } from 'react-router-dom';
-import {
- HttpStart,
- DocLinksStart,
- ChromeDocTitle,
- NotificationsStart,
- IUiSettingsClient,
-} from 'src/core/public';
-
-import { IndexPattern, DataPublicPluginStart } from '../../../../../../plugins/data/public';
-import { ManagementAppMountParams } from '../../../../../management/public';
+import { IndexPattern } from '../../../../../../plugins/data/public';
import { getEditFieldBreadcrumbs, getCreateFieldBreadcrumbs } from '../../breadcrumbs';
+import { useKibana } from '../../../../../../plugins/kibana_react/public';
+import { IndexPatternManagmentContext } from '../../../types';
import { CreateEditField } from './create_edit_field';
-export interface CreateEditFieldContainerProps
- extends RouteComponentProps<{ id: string; fieldName: string }> {
- getIndexPattern: (id: string) => Promise;
- fieldFormatEditors: any;
- getConfig: IUiSettingsClient;
- services: {
- uiSettings: IUiSettingsClient;
- notifications: NotificationsStart;
- docTitle: ChromeDocTitle;
- http: HttpStart;
- docLinksScriptedFields: DocLinksStart['links']['scriptedFields'];
- SearchBar: DataPublicPluginStart['ui']['SearchBar'];
- toasts: NotificationsStart['toasts'];
- fieldFormats: DataPublicPluginStart['fieldFormats'];
- indexPatterns: DataPublicPluginStart['indexPatterns'];
- setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs'];
- };
-}
+export type CreateEditFieldContainerProps = RouteComponentProps<{ id: string; fieldName: string }>;
const CreateEditFieldCont: React.FC = ({ ...props }) => {
+ const { setBreadcrumbs, data } = useKibana().services;
const [indexPattern, setIndexPattern] = useState();
useEffect(() => {
- props.getIndexPattern(props.match.params.id).then((ip: IndexPattern) => {
+ data.indexPatterns.get(props.match.params.id).then((ip: IndexPattern) => {
setIndexPattern(ip);
if (ip) {
- props.services.setBreadcrumbs(
+ setBreadcrumbs(
props.match.params.fieldName
? getEditFieldBreadcrumbs(ip, props.match.params.fieldName)
: getCreateFieldBreadcrumbs(ip)
);
}
});
- }, [props.match.params.id, props.getIndexPattern, props]);
+ }, [props.match.params.id, props.match.params.fieldName, setBreadcrumbs, data.indexPatterns]);
if (indexPattern) {
return (
@@ -74,17 +51,6 @@ const CreateEditFieldCont: React.FC = ({ ...props
indexPattern={indexPattern}
mode={props.match.params.fieldName ? 'edit' : 'create'}
fieldName={props.match.params.fieldName}
- fieldFormatEditors={props.fieldFormatEditors}
- services={{
- uiSettings: props.services.uiSettings,
- http: props.services.http,
- docLinksScriptedFields: props.services.docLinksScriptedFields,
- SearchBar: props.services.SearchBar,
- toasts: props.services.toasts,
- fieldFormats: props.services.fieldFormats,
- docTitle: props.services.docTitle,
- indexPatterns: props.services.indexPatterns,
- }}
/>
);
} else {
diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx
index ec28719429fba9..eab8b2c231c9ca 100644
--- a/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx
+++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx
@@ -33,31 +33,16 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
-import {
- ChromeDocTitle,
- NotificationsStart,
- OverlayStart,
- IUiSettingsClient,
- SavedObjectsClientContract,
-} from 'src/core/public';
import { IndexPattern, IndexPatternField } from '../../../../../plugins/data/public';
-import { IndexPatternManagementStart } from '../..';
+import { useKibana } from '../../../../../plugins/kibana_react/public';
+import { IndexPatternManagmentContext } from '../../types';
import { Tabs } from './tabs';
import { IndexHeader } from './index_header';
import { IndexPatternTableItem } from '../types';
import { getIndexPatterns } from '../utils';
-interface EditIndexPatternProps extends RouteComponentProps {
+export interface EditIndexPatternProps extends RouteComponentProps {
indexPattern: IndexPattern;
- config: IUiSettingsClient;
- services: {
- notifications: NotificationsStart;
- docTitle: ChromeDocTitle;
- overlays: OverlayStart;
- savedObjectsClient: SavedObjectsClientContract;
- indexPatternManagement: IndexPatternManagementStart;
- painlessDocLink: string;
- };
}
const mappingAPILink = i18n.translate(
@@ -97,12 +82,15 @@ const confirmModalOptionsDelete = {
};
export const EditIndexPattern = withRouter(
- ({ indexPattern, config, services, history, location }: EditIndexPatternProps) => {
+ ({ indexPattern, history, location }: EditIndexPatternProps) => {
+ const { uiSettings, indexPatternManagementStart, overlays, savedObjects, chrome } = useKibana<
+ IndexPatternManagmentContext
+ >().services;
const [fields, setFields] = useState(indexPattern.getNonScriptedFields());
const [conflictedFields, setConflictedFields] = useState(
indexPattern.fields.filter((field) => field.type === 'conflict')
);
- const [defaultIndex, setDefaultIndex] = useState(config.get('defaultIndex'));
+ const [defaultIndex, setDefaultIndex] = useState(uiSettings.get('defaultIndex'));
const [tags, setTags] = useState([]);
useEffect(() => {
@@ -112,44 +100,42 @@ export const EditIndexPattern = withRouter(
useEffect(() => {
const indexPatternTags =
- services.indexPatternManagement.list.getIndexPatternTags(
+ indexPatternManagementStart.list.getIndexPatternTags(
indexPattern,
indexPattern.id === defaultIndex
) || [];
setTags(indexPatternTags);
- }, [defaultIndex, indexPattern, services.indexPatternManagement.list]);
+ }, [defaultIndex, indexPattern, indexPatternManagementStart.list]);
const setDefaultPattern = useCallback(() => {
- config.set('defaultIndex', indexPattern.id);
+ uiSettings.set('defaultIndex', indexPattern.id);
setDefaultIndex(indexPattern.id || '');
- }, [config, indexPattern.id]);
+ }, [uiSettings, indexPattern.id]);
const refreshFields = () => {
- services.overlays
- .openConfirm(confirmMessage, confirmModalOptionsRefresh)
- .then(async (isConfirmed) => {
- if (isConfirmed) {
- await indexPattern.init(true);
- setFields(indexPattern.getNonScriptedFields());
- }
- });
+ overlays.openConfirm(confirmMessage, confirmModalOptionsRefresh).then(async (isConfirmed) => {
+ if (isConfirmed) {
+ await indexPattern.init(true);
+ setFields(indexPattern.getNonScriptedFields());
+ }
+ });
};
- const removePatternClick = () => {
+ const removePattern = () => {
async function doRemove() {
if (indexPattern.id === defaultIndex) {
const indexPatterns: IndexPatternTableItem[] = await getIndexPatterns(
- services.savedObjectsClient,
- config.get('defaultIndex'),
- services.indexPatternManagement
+ savedObjects.client,
+ uiSettings.get('defaultIndex'),
+ indexPatternManagementStart
);
- config.remove('defaultIndex');
+ uiSettings.remove('defaultIndex');
const otherPatterns = filter(indexPatterns, (pattern) => {
return pattern.id !== indexPattern.id;
});
if (otherPatterns.length) {
- config.set('defaultIndex', otherPatterns[0].id);
+ uiSettings.set('defaultIndex', otherPatterns[0].id);
}
}
@@ -158,7 +144,7 @@ export const EditIndexPattern = withRouter(
});
}
- services.overlays.openConfirm('', confirmModalOptionsDelete).then((isConfirmed) => {
+ overlays.openConfirm('', confirmModalOptionsDelete).then((isConfirmed) => {
if (isConfirmed) {
doRemove();
}
@@ -186,7 +172,7 @@ export const EditIndexPattern = withRouter(
defaultMessage: 'Index pattern details',
});
- services.docTitle.change(indexPattern.title);
+ chrome.docTitle.change(indexPattern.title);
const showTagsSection = Boolean(indexPattern.timeFieldName || (tags && tags.length > 0));
@@ -199,7 +185,7 @@ export const EditIndexPattern = withRouter(
indexPattern={indexPattern}
setDefault={setDefaultPattern}
refreshFields={refreshFields}
- deleteIndexPatternClick={removePatternClick}
+ deleteIndexPatternClick={removePattern}
defaultIndex={defaultIndex}
/>
@@ -244,11 +230,6 @@ export const EditIndexPattern = withRouter(
diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_container.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_container.tsx
index 2f02765cd0596f..9bd42ed8d64ee4 100644
--- a/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_container.tsx
+++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_container.tsx
@@ -19,52 +19,26 @@
import React, { useEffect, useState } from 'react';
import { withRouter, RouteComponentProps } from 'react-router-dom';
-import {
- ChromeDocTitle,
- NotificationsStart,
- OverlayStart,
- IUiSettingsClient,
- SavedObjectsClientContract,
-} from 'src/core/public';
import { IndexPattern } from '../../../../../plugins/data/public';
-import { ManagementAppMountParams } from '../../../../management/public';
-import { IndexPatternManagementStart } from '../..';
+import { useKibana } from '../../../../../plugins/kibana_react/public';
+import { IndexPatternManagmentContext } from '../../types';
import { getEditBreadcrumbs } from '../breadcrumbs';
import { EditIndexPattern } from '../edit_index_pattern';
-interface EditIndexPatternContainerProps extends RouteComponentProps<{ id: string }> {
- getIndexPattern: (id: string) => Promise;
- config: IUiSettingsClient;
- services: {
- notifications: NotificationsStart;
- docTitle: ChromeDocTitle;
- overlays: OverlayStart;
- savedObjectsClient: SavedObjectsClientContract;
- setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs'];
- indexPatternManagement: IndexPatternManagementStart;
- painlessDocLink: string;
- };
-}
-
-const EditIndexPatternCont: React.FC = ({ ...props }) => {
+const EditIndexPatternCont: React.FC> = ({ ...props }) => {
+ const { data, setBreadcrumbs } = useKibana().services;
const [indexPattern, setIndexPattern] = useState();
useEffect(() => {
- props.getIndexPattern(props.match.params.id).then((ip: IndexPattern) => {
+ data.indexPatterns.get(props.match.params.id).then((ip: IndexPattern) => {
setIndexPattern(ip);
- props.services.setBreadcrumbs(getEditBreadcrumbs(ip));
+ setBreadcrumbs(getEditBreadcrumbs(ip));
});
- }, [props.match.params.id, props.getIndexPattern, props]);
+ }, [data.indexPatterns, props.match.params.id, setBreadcrumbs]);
if (indexPattern) {
- return (
-
- );
+ return ;
} else {
return <>>;
}
diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/tabs.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/tabs.tsx
index c364fb89dc41a3..719df9d8d4cb51 100644
--- a/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/tabs.tsx
+++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/tabs.tsx
@@ -31,9 +31,9 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { fieldWildcardMatcher } from '../../../../../kibana_utils/public';
-import { IndexPatternManagementStart } from '../../../../../index_pattern_management/public';
-import { IndexPattern, IndexPatternField } from '../../../../../data/public';
-import { META_FIELDS_SETTING } from '../../../../../data/common';
+import { IndexPattern, IndexPatternField } from '../../../../../../plugins/data/public';
+import { useKibana } from '../../../../../../plugins/kibana_react/public';
+import { IndexPatternManagmentContext } from '../../../types';
import { createEditIndexPatternPageStateContainer } from '../edit_index_pattern_state_container';
import { TAB_INDEXED_FIELDS, TAB_SCRIPTED_FIELDS, TAB_SOURCE_FILTERS } from '../constants';
import { SourceFiltersTable } from '../source_filters_table';
@@ -43,12 +43,7 @@ import { getTabs, getPath, convertToEuiSelectOption } from './utils';
interface TabsProps extends Pick {
indexPattern: IndexPattern;
- config: Record;
fields: IndexPatternField[];
- services: {
- indexPatternManagement: IndexPatternManagementStart;
- painlessDocLink: string;
- };
}
const searchAriaLabel = i18n.translate(
@@ -72,7 +67,10 @@ const filterPlaceholder = i18n.translate(
}
);
-export function Tabs({ config, indexPattern, fields, services, history, location }: TabsProps) {
+export function Tabs({ indexPattern, fields, history, location }: TabsProps) {
+ const { uiSettings, indexPatternManagementStart, docLinks } = useKibana<
+ IndexPatternManagmentContext
+ >().services;
const [fieldFilter, setFieldFilter] = useState('');
const [indexedFieldTypeFilter, setIndexedFieldTypeFilter] = useState('');
const [scriptedFieldLanguageFilter, setScriptedFieldLanguageFilter] = useState('');
@@ -106,8 +104,8 @@ export function Tabs({ config, indexPattern, fields, services, history, location
}, [indexPattern, indexPattern.fields, refreshFilters]);
const fieldWildcardMatcherDecorated = useCallback(
- (filters: string[]) => fieldWildcardMatcher(filters, config.get(META_FIELDS_SETTING)),
- [config]
+ (filters: string[]) => fieldWildcardMatcher(filters, uiSettings.get('metaFields')),
+ [uiSettings]
);
const getFilterSection = useCallback(
@@ -175,7 +173,7 @@ export function Tabs({ config, indexPattern, fields, services, history, location
redirectToRoute: (field: IndexPatternField) => {
history.push(getPath(field));
},
- getFieldInfo: services.indexPatternManagement.list.getFieldInfo,
+ getFieldInfo: indexPatternManagementStart.list.getFieldInfo,
}}
/>
@@ -196,7 +194,7 @@ export function Tabs({ config, indexPattern, fields, services, history, location
},
}}
onRemoveField={refreshFilters}
- painlessDocLink={services.painlessDocLink}
+ painlessDocLink={docLinks.links.scriptedFields.painless}
/>
);
@@ -217,23 +215,23 @@ export function Tabs({ config, indexPattern, fields, services, history, location
}
},
[
+ docLinks.links.scriptedFields.painless,
fieldFilter,
fieldWildcardMatcherDecorated,
fields,
getFilterSection,
history,
indexPattern,
+ indexPatternManagementStart.list.getFieldInfo,
indexedFieldTypeFilter,
refreshFilters,
scriptedFieldLanguageFilter,
- services.indexPatternManagement.list.getFieldInfo,
- services.painlessDocLink,
]
);
const euiTabs: EuiTabbedContentTab[] = useMemo(
() =>
- getTabs(indexPattern, fieldFilter, services.indexPatternManagement.list).map(
+ getTabs(indexPattern, fieldFilter, indexPatternManagementStart.list).map(
(tab: Pick) => {
return {
...tab,
@@ -241,7 +239,7 @@ export function Tabs({ config, indexPattern, fields, services, history, location
};
}
),
- [fieldFilter, getContent, indexPattern, services.indexPatternManagement.list]
+ [fieldFilter, getContent, indexPattern, indexPatternManagementStart.list]
);
const [selectedTabId, setSelectedTabId] = useState(euiTabs[0].id);
@@ -253,7 +251,7 @@ export function Tabs({ config, indexPattern, fields, services, history, location
setCurrentTab,
getCurrentTab,
} = createEditIndexPatternPageStateContainer({
- useHashedUrl: config.get('state:storeInSessionStorage'),
+ useHashedUrl: uiSettings.get('state:storeInSessionStorage'),
defaultTab: TAB_INDEXED_FIELDS,
});
@@ -267,7 +265,7 @@ export function Tabs({ config, indexPattern, fields, services, history, location
return () => {
stopSyncingState();
};
- }, [config]);
+ }, [uiSettings]);
return (
,
"painlessLink":
+
}
>
-
-
+
+
+
+
+
+
+
+
+ ,
+ "scriptsInAggregation":
+
+
+
+ ,
+ }
+ }
>
-
-
-
- ,
- "scriptsInAggregation":
+ Please familiarize yourself with
+
+
+
+
+ script fields
+
+
+
+
+
+
+
+
+ and with
+
+
+
+
+ scripts in aggregations
+
+
+
+
+
+
+
+
+ before using scripted fields.
+
+
+
+
+
-
-
-
- ,
- }
- }
- />
-
-
-
-
+
+ Scripted fields can be used to display and aggregate calculated values. As such, they can be very slow, and if done incorrectly, can cause Kibana to be unusable. There's no safety net here. If you make a typo, unexpected exceptions will be thrown all over the place!
+
+
+
+
+
+
-
+ >
+
+
+
`;
-exports[`ScriptingWarningCallOut should render nothing if not visible 1`] = `""`;
+exports[`ScriptingWarningCallOut should render nothing if not visible 1`] = `
+
+`;
diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.test.tsx
index d659ac83d7b796..6af85a3cc472b2 100644
--- a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.test.tsx
+++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.test.tsx
@@ -18,32 +18,32 @@
*/
import React from 'react';
-import { shallow } from 'enzyme';
-
+import { mount } from 'enzyme';
+import { KibanaContextProvider } from 'src/plugins/kibana_react/public';
+import { mockManagementPlugin } from '../../../../mocks';
import { ScriptingWarningCallOut } from './warning_call_out';
-// eslint-disable-next-line
-import { docLinksServiceMock } from '../../../../../../../core/public/doc_links/doc_links_service.mock';
describe('ScriptingWarningCallOut', () => {
- const docLinksScriptedFields = docLinksServiceMock.createStartContract().links.scriptedFields;
+ const mockedContext = mockManagementPlugin.createIndexPatternManagmentContext();
+
it('should render normally', async () => {
- const component = shallow(
-
- );
+ const component = mount(, {
+ wrappingComponent: KibanaContextProvider,
+ wrappingComponentProps: {
+ services: mockedContext,
+ },
+ });
expect(component).toMatchSnapshot();
});
it('should render nothing if not visible', async () => {
- const component = shallow(
-
- );
+ const component = mount(, {
+ wrappingComponent: KibanaContextProvider,
+ wrappingComponentProps: {
+ services: mockedContext,
+ },
+ });
expect(component).toMatchSnapshot();
});
diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.tsx
index fed756f11f08b8..1704911214535e 100644
--- a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.tsx
+++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.tsx
@@ -18,21 +18,21 @@
*/
import React, { Fragment } from 'react';
-import { DocLinksStart } from 'src/core/public';
import { EuiCallOut, EuiIcon, EuiLink, EuiSpacer } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
+import { useKibana } from '../../../../../../../plugins/kibana_react/public';
+import { IndexPatternManagmentContext } from '../../../../types';
+
export interface ScriptingWarningCallOutProps {
isVisible: boolean;
- docLinksScriptedFields: DocLinksStart['links']['scriptedFields'];
}
-export const ScriptingWarningCallOut = ({
- isVisible = false,
- docLinksScriptedFields,
-}: ScriptingWarningCallOutProps) => {
+export const ScriptingWarningCallOut = ({ isVisible = false }: ScriptingWarningCallOutProps) => {
+ const docLinksScriptedFields = useKibana().services.docLinks?.links
+ .scriptedFields;
return isVisible ? (
,
+ "content": ,
"data-test-subj": "syntaxTab",
"id": "syntax",
"name": "Syntax",
@@ -21,37 +19,16 @@ exports[`ScriptingHelpFlyout should render normally 1`] = `
tabs={
Array [
Object {
- "content": ,
+ "content": ,
"data-test-subj": "syntaxTab",
"id": "syntax",
"name": "Syntax",
},
Object {
"content": ,
"data-test-subj": "testTab",
"id": "test",
@@ -74,9 +51,7 @@ exports[`ScriptingHelpFlyout should render nothing if not visible 1`] = `
autoFocus="initial"
initialSelectedTab={
Object {
- "content": ,
+ "content": ,
"data-test-subj": "syntaxTab",
"id": "syntax",
"name": "Syntax",
@@ -85,37 +60,16 @@ exports[`ScriptingHelpFlyout should render nothing if not visible 1`] = `
tabs={
Array [
Object {
- "content": ,
+ "content": ,
"data-test-subj": "syntaxTab",
"id": "syntax",
"name": "Syntax",
},
Object {
"content": ,
"data-test-subj": "testTab",
"id": "test",
diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.test.tsx
index fa2d97be60000a..83e40145f2a462 100644
--- a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.test.tsx
+++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.test.tsx
@@ -19,9 +19,6 @@
import React from 'react';
import { shallow } from 'enzyme';
-import { HttpStart } from 'src/core/public';
-// eslint-disable-next-line
-import { docLinksServiceMock } from '../../../../../../../core/public/doc_links/doc_links_service.mock';
import { ScriptingHelpFlyout } from './help_flyout';
@@ -29,22 +26,15 @@ import { IndexPattern } from '../../../../../../data/public';
import { ExecuteScript } from '../../types';
-import { coreMock } from '../../../../../../../core/public/mocks';
-import { dataPluginMock } from '../../../../../../../plugins/data/public/mocks';
-
jest.mock('./test_script', () => ({
TestScript: () => {
return `mockTestScript
`;
},
}));
-const { uiSettings } = coreMock.createStart();
-const { ui } = dataPluginMock.createStartContract();
-
const indexPatternMock = {} as IndexPattern;
describe('ScriptingHelpFlyout', () => {
- const docLinksScriptedFields = docLinksServiceMock.createStartContract().links.scriptedFields;
it('should render normally', async () => {
const component = shallow(
{
lang="painless"
executeScript={((() => {}) as unknown) as ExecuteScript}
onClose={() => {}}
- http={({} as unknown) as HttpStart}
- docLinksScriptedFields={{} as typeof docLinksScriptedFields}
- uiSettings={uiSettings}
- SearchBar={ui.SearchBar}
/>
);
@@ -71,10 +57,6 @@ describe('ScriptingHelpFlyout', () => {
lang="painless"
executeScript={((() => {}) as unknown) as ExecuteScript}
onClose={() => {}}
- http={({} as unknown) as HttpStart}
- docLinksScriptedFields={{} as typeof docLinksScriptedFields}
- uiSettings={uiSettings}
- SearchBar={ui.SearchBar}
/>
);
diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.tsx
index b74d56e1c28781..953bc238322b6e 100644
--- a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.tsx
+++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.tsx
@@ -18,15 +18,13 @@
*/
import React from 'react';
-import { HttpStart, DocLinksStart, IUiSettingsClient } from 'src/core/public';
-
import { EuiFlyout, EuiFlyoutBody, EuiTabbedContent } from '@elastic/eui';
import { ScriptingSyntax } from './scripting_syntax';
import { TestScript } from './test_script';
import { ExecuteScript } from '../../types';
-import { IndexPattern, DataPublicPluginStart } from '../../../../../../data/public';
+import { IndexPattern } from '../../../../../../data/public';
interface ScriptingHelpFlyoutProps {
indexPattern: IndexPattern;
@@ -36,10 +34,6 @@ interface ScriptingHelpFlyoutProps {
executeScript: ExecuteScript;
isVisible: boolean;
onClose: () => void;
- http: HttpStart;
- docLinksScriptedFields: DocLinksStart['links']['scriptedFields'];
- uiSettings: IUiSettingsClient;
- SearchBar: DataPublicPluginStart['ui']['SearchBar'];
}
export const ScriptingHelpFlyout: React.FC = ({
@@ -50,17 +44,13 @@ export const ScriptingHelpFlyout: React.FC = ({
name,
script,
executeScript,
- http,
- docLinksScriptedFields,
- uiSettings,
- SearchBar,
}) => {
const tabs = [
{
id: 'syntax',
name: 'Syntax',
['data-test-subj']: 'syntaxTab',
- content: ,
+ content: ,
},
{
id: 'test',
@@ -73,9 +63,6 @@ export const ScriptingHelpFlyout: React.FC = ({
name={name}
script={script}
executeScript={executeScript}
- http={http}
- uiSettings={uiSettings}
- SearchBar={SearchBar}
/>
),
},
diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/scripting_syntax.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/scripting_syntax.tsx
index 9a78c3695ea7c2..9139d28e780228 100644
--- a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/scripting_syntax.tsx
+++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/scripting_syntax.tsx
@@ -18,201 +18,201 @@
*/
import React, { Fragment } from 'react';
-import { DocLinksStart } from 'src/core/public';
-
import { EuiCode, EuiIcon, EuiLink, EuiText, EuiSpacer } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
+import { useKibana } from '../../../../../../../plugins/kibana_react/public';
+import { IndexPatternManagmentContext } from '../../../../types';
-export interface ScriptingSyntaxProps {
- docLinksScriptedFields: DocLinksStart['links']['scriptedFields'];
-}
-
-export const ScriptingSyntax = ({ docLinksScriptedFields }: ScriptingSyntaxProps) => (
-
-
-
-
-
-
-
-
- {' '}
-
-
- ),
- }}
- />
-
-
-
-
-
-
-
-
-
-
-
-
- ),
- syntax: (
-
-
-
-
-
- ),
- }}
- />
-
-
-
-
-
-
-
-
-
-
- ),
- }}
- />
-
-
-
-
-
-
-
-
-
- -
+export const ScriptingSyntax = () => {
+ const docLinksScriptedFields = useKibana().services.docLinks?.links
+ .scriptedFields;
+ return (
+
+
+
+
+
+
+
+ - * / % }}
- />
-
- -
- | & ^ ~ << >> >>>,
+ painless: (
+
+ {' '}
+
+
+ ),
}}
/>
-
- -
+
+
+
+
+
+
+
&& || ! ?: }}
- />
-
-
- < <= == >= > }}
+ id="indexPatternManagement.syntax.painlessLabel.painlessDetail"
+ defaultMessage="Painless is powerful but easy to use. It provides access to many {javaAPIs}. Read up on its {syntax} and
+ you'll be up to speed in no time!"
+ values={{
+ javaAPIs: (
+
+
+
+
+
+ ),
+ syntax: (
+
+
+
+
+
+ ),
+ }}
/>
-
-
+
+
abs ceil exp floor ln log10 logn max min sqrt pow }}
+ id="indexPatternManagement.syntax.kibanaLabel"
+ defaultMessage="Kibana currently imposes one special limitation on the painless scripts you write. They cannot contain named
+ functions."
/>
-
-
+
+
acosh acos asinh asin atanh atan atan2 cosh cos sinh sin tanh tan
+ lucene: (
+
+
+
+
+
),
}}
/>
-
-
+
+
haversin }}
+ id="indexPatternManagement.syntax.lucene.limitsLabel"
+ defaultMessage="There are a few limitations when using Lucene Expressions:"
/>
-
-
+
+
+
min, max }}
+ id="indexPatternManagement.syntax.lucene.operationsLabel"
+ defaultMessage="Here are all the operations available to lucene expressions:"
/>
-
-
-
-
-);
+
+
+ -
+ + - * / % }}
+ />
+
+ -
+ | & ^ ~ << >> >>>,
+ }}
+ />
+
+ -
+ && || ! ?: }}
+ />
+
+ -
+ < <= == >= > }}
+ />
+
+ -
+ abs ceil exp floor ln log10 logn max min sqrt pow }}
+ />
+
+ -
+ acosh acos asinh asin atanh atan atan2 cosh cos sinh sin tanh tan
+ ),
+ }}
+ />
+
+ -
+ haversin }}
+ />
+
+ -
+ min, max }}
+ />
+
+
+
+
+ );
+};
diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx
index 207b0b96ee7c80..a1b7289efee210 100644
--- a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx
+++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx
@@ -20,8 +20,6 @@
import './test_script.scss';
import React, { Component, Fragment } from 'react';
-import { HttpStart, IUiSettingsClient } from 'src/core/public';
-import { DataPublicPluginStart } from 'src/plugins/data/public';
import {
EuiButton,
@@ -38,6 +36,8 @@ import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import { esQuery, IndexPattern, Query } from '../../../../../../../plugins/data/public';
+import { context as contextType } from '../../../../../../kibana_react/public';
+import { IndexPatternManagmentContextValue } from '../../../../types';
import { ExecuteScript } from '../../types';
interface TestScriptProps {
@@ -46,9 +46,6 @@ interface TestScriptProps {
name?: string;
script?: string;
executeScript: ExecuteScript;
- http: HttpStart;
- uiSettings: IUiSettingsClient;
- SearchBar: DataPublicPluginStart['ui']['SearchBar'];
}
interface AdditionalField {
@@ -63,6 +60,10 @@ interface TestScriptState {
}
export class TestScript extends Component {
+ static contextType = contextType;
+
+ public readonly context!: IndexPatternManagmentContextValue;
+
defaultProps = {
name: 'myScriptedField',
};
@@ -80,7 +81,7 @@ export class TestScript extends Component {
}
previewScript = async (searchContext?: { query?: Query | undefined }) => {
- const { indexPattern, lang, name, script, executeScript, http } = this.props;
+ const { indexPattern, lang, name, script, executeScript } = this.props;
if (!script || script.length === 0) {
return;
@@ -92,7 +93,7 @@ export class TestScript extends Component {
let query;
if (searchContext) {
- const esQueryConfigs = esQuery.getEsQueryConfig(this.props.uiSettings);
+ const esQueryConfigs = esQuery.getEsQueryConfig(this.context.services.uiSettings);
query = esQuery.buildEsQuery(
this.props.indexPattern,
searchContext.query || [],
@@ -108,7 +109,7 @@ export class TestScript extends Component {
indexPatternTitle: indexPattern.title,
query,
additionalFields: this.state.additionalFields.map((option: AdditionalField) => option.value),
- http,
+ http: this.context.services.http,
});
if (scriptResponse.status !== 200) {
@@ -121,7 +122,7 @@ export class TestScript extends Component {
this.setState({
isLoading: false,
- previewData: scriptResponse.hits.hits.map((hit) => ({
+ previewData: scriptResponse.hits.hits.map((hit: any) => ({
_id: hit._id,
...hit._source,
...hit.fields,
@@ -182,7 +183,7 @@ export class TestScript extends Component {
);
}
- renderToolbar(SearchBar: DataPublicPluginStart['ui']['SearchBar']) {
+ renderToolbar() {
const fieldsByTypeMap = new Map();
const fields: EuiComboBoxOptionOption[] = [];
@@ -237,12 +238,15 @@ export class TestScript extends Component {
-
{
}
render() {
- const { SearchBar } = this.props;
return (
@@ -285,7 +288,7 @@ export class TestScript extends Component {
- {this.renderToolbar(SearchBar)}
+ {this.renderToolbar()}
{this.renderPreview(this.state.previewData)}
diff --git a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx
index 1898e2397ae7f5..e0e053d8b606bd 100644
--- a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx
+++ b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx
@@ -17,9 +17,6 @@
* under the License.
*/
-import React from 'react';
-
-import { shallowWithI18nProvider } from 'test_utils/enzyme_helpers';
import {
IndexPattern,
IndexPatternField,
@@ -27,12 +24,12 @@ import {
FieldFormatInstanceType,
} from 'src/plugins/data/public';
-import { coreMock } from '../../../../../core/public/mocks';
-
jest.mock('brace/mode/groovy', () => ({}));
-import { FieldEdiorProps, FieldEditor } from './field_editor';
-import { dataPluginMock } from '../../../../data/public/mocks';
+import { FieldEditor } from './field_editor';
+
+import { mockManagementPlugin } from '../../mocks';
+import { createComponentWithContext } from '../test_utils';
jest.mock('@elastic/eui', () => ({
EuiBasicTable: 'eui-basic-table',
@@ -99,50 +96,35 @@ const field = {
};
describe('FieldEditor', () => {
- const dataStartServices = dataPluginMock.createStartContract();
- const coreStartServices = coreMock.createStart();
-
let indexPattern: IndexPattern;
- const services: FieldEdiorProps['services'] = ({
- Field: () => {},
- getConfig: () => {},
- fieldFormatEditors: [],
- redirectAway: () => {},
- docLinksScriptedFields: {},
- fieldFormats: dataStartServices.fieldFormats,
- toasts: coreStartServices.notifications.toasts,
- http: {},
- uiSettings: {},
- SearchBar: dataStartServices.ui.SearchBar,
- indexPatterns: dataStartServices.indexPatterns,
- } as unknown) as FieldEdiorProps['services'];
+ const mockContext = mockManagementPlugin.createIndexPatternManagmentContext();
+ mockContext.data.fieldFormats.getDefaultType = jest.fn(
+ () => (({} as unknown) as FieldFormatInstanceType)
+ );
+ mockContext.data.fieldFormats.getByFieldType = jest.fn((fieldType) => {
+ if (fieldType === 'number') {
+ return [({} as unknown) as FieldFormatInstanceType];
+ } else {
+ return [];
+ }
+ });
beforeEach(() => {
indexPattern = ({
fields: fields as IIndexPatternFieldList,
} as unknown) as IndexPattern;
-
- services.fieldFormats.getDefaultType = jest.fn(
- () => (({} as unknown) as FieldFormatInstanceType)
- );
-
- services.fieldFormats.getByFieldType = jest.fn((fieldType) => {
- if (fieldType === 'number') {
- return [({} as unknown) as FieldFormatInstanceType];
- } else {
- return [];
- }
- });
});
it('should render create new scripted field correctly', async () => {
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ FieldEditor,
+ {
+ indexPattern,
+ field: (field as unknown) as IndexPatternField,
+ services: { redirectAway: () => {} },
+ },
+ mockContext
);
await new Promise((resolve) => process.nextTick(resolve));
@@ -164,12 +146,14 @@ describe('FieldEditor', () => {
return flds[name] as IndexPatternField;
};
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ FieldEditor,
+ {
+ indexPattern,
+ field: (testField as unknown) as IndexPatternField,
+ services: { redirectAway: () => {} },
+ },
+ mockContext
);
await new Promise((resolve) => process.nextTick(resolve));
@@ -192,12 +176,14 @@ describe('FieldEditor', () => {
return flds[name] as IndexPatternField;
};
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ FieldEditor,
+ {
+ indexPattern,
+ field: (testField as unknown) as IndexPatternField,
+ services: { redirectAway: () => {} },
+ },
+ mockContext
);
await new Promise((resolve) => process.nextTick(resolve));
@@ -207,12 +193,14 @@ describe('FieldEditor', () => {
it('should show conflict field warning', async () => {
const testField = { ...field };
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ FieldEditor,
+ {
+ indexPattern,
+ field: (testField as unknown) as IndexPatternField,
+ services: { redirectAway: () => {} },
+ },
+ mockContext
);
await new Promise((resolve) => process.nextTick(resolve));
@@ -230,12 +218,14 @@ describe('FieldEditor', () => {
text: ['index_name_3'],
},
};
- const component = shallowWithI18nProvider(
-
+ const component = createComponentWithContext(
+ FieldEditor,
+ {
+ indexPattern,
+ field: (testField as unknown) as IndexPatternField,
+ services: { redirectAway: () => {} },
+ },
+ mockContext
);
await new Promise((resolve) => process.nextTick(resolve));
diff --git a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx
index ace6167239b8ce..5ae50098e79e7c 100644
--- a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx
+++ b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx
@@ -19,7 +19,6 @@
import React, { PureComponent, Fragment } from 'react';
import { intersection, union, get } from 'lodash';
-import { HttpStart, DocLinksStart, NotificationsStart, IUiSettingsClient } from 'src/core/public';
import {
EuiBasicTable,
@@ -60,6 +59,7 @@ import {
ES_FIELD_TYPES,
DataPublicPluginStart,
} from '../../../../../plugins/data/public';
+import { context as contextType } from '../../../../kibana_react/public';
import {
ScriptingDisabledCallOut,
ScriptingWarningCallOut,
@@ -67,7 +67,7 @@ import {
import { ScriptingHelpFlyout } from './components/scripting_help';
import { FieldFormatEditor } from './components/field_format_editor';
-import { IndexPatternManagementStart } from '../../plugin';
+import { IndexPatternManagmentContextValue } from '../../types';
import { FIELD_TYPES_BY_LANG, DEFAULT_FIELD_TYPES } from './constants';
import { executeScript, isScriptValid } from './lib';
@@ -135,23 +135,19 @@ export interface FieldEdiorProps {
indexPattern: IndexPattern;
field: IndexPatternField;
services: {
- http: HttpStart;
- fieldFormatEditors: IndexPatternManagementStart['fieldFormatEditors'];
redirectAway: () => void;
- docLinksScriptedFields: DocLinksStart['links']['scriptedFields'];
- fieldFormats: DataPublicPluginStart['fieldFormats'];
- toasts: NotificationsStart['toasts'];
- uiSettings: IUiSettingsClient;
- SearchBar: DataPublicPluginStart['ui']['SearchBar'];
- indexPatterns: DataPublicPluginStart['indexPatterns'];
};
}
export class FieldEditor extends PureComponent {
+ static contextType = contextType;
+
+ public readonly context!: IndexPatternManagmentContextValue;
+
supportedLangs: string[] = [];
deprecatedLangs: string[] = [];
- constructor(props: FieldEdiorProps) {
- super(props);
+ constructor(props: FieldEdiorProps, context: IndexPatternManagmentContextValue) {
+ super(props, context);
const { field, indexPattern } = props;
@@ -174,15 +170,15 @@ export class FieldEditor extends PureComponent {
- const { uiSettings } = this.props.services;
+ const { uiSettings, data } = this.context.services;
const { field } = this.state;
- const DefaultFieldFormat = this.props.services.fieldFormats.getDefaultType(
- type
- ) as FieldFormatInstanceType;
+ const DefaultFieldFormat = data.fieldFormats.getDefaultType(type) as FieldFormatInstanceType;
field.type = type;
field.format = new DefaultFieldFormat(null, (key) => uiSettings.get(key));
this.setState({
- fieldTypeFormats: getFieldTypeFormatsList(
- field,
- DefaultFieldFormat,
- this.props.services.fieldFormats
- ),
+ fieldTypeFormats: getFieldTypeFormatsList(field, DefaultFieldFormat, data.fieldFormats),
fieldFormatId: DefaultFieldFormat.id,
fieldFormatParams: field.format.params(),
});
@@ -255,9 +245,9 @@ export class FieldEditor extends PureComponent {
const { field, fieldTypeFormats } = this.state;
- const { uiSettings, fieldFormats } = this.props.services;
+ const { uiSettings, data } = this.context.services;
- const FieldFormat = fieldFormats.getType(
+ const FieldFormat = data.fieldFormats.getType(
formatId || (fieldTypeFormats[0] as InitialFieldTypeFormat).defaultFieldFormat.id
) as FieldFormatInstanceType;
@@ -369,7 +359,7 @@ export class FieldEditor extends PureComponent
@@ -748,10 +738,7 @@ export class FieldEditor extends PureComponent
-
+
);
@@ -781,7 +764,7 @@ export class FieldEditor extends PureComponent {
+export const IndexPatternTable = ({ canSave, history }: Props) => {
+ const {
+ setBreadcrumbs,
+ savedObjects,
+ uiSettings,
+ indexPatternManagementStart,
+ chrome,
+ } = useKibana().services;
const [showFlyout, setShowFlyout] = useState(false);
const [indexPatterns, setIndexPatterns] = useState([]);
const [creationOptions, setCreationOptions] = useState([]);
- services.setBreadcrumbs(getListBreadcrumbs());
+ setBreadcrumbs(getListBreadcrumbs());
useEffect(() => {
(async function () {
- const options = await getIndexPatternCreationOptions(history.push);
+ const options = await indexPatternManagementStart.creation.getIndexPatternCreationOptions(
+ history.push
+ );
const gettedIndexPatterns: IndexPatternTableItem[] = await getIndexPatterns(
- services.savedObjectsClient,
- services.uiSettings.get('defaultIndex'),
- services.indexPatternManagement
+ savedObjects.client,
+ uiSettings.get('defaultIndex'),
+ indexPatternManagementStart
);
setCreationOptions(options);
setIndexPatterns(gettedIndexPatterns);
setShowFlyout(gettedIndexPatterns.length === 0);
})();
}, [
- getIndexPatternCreationOptions,
history.push,
indexPatterns.length,
- services.indexPatternManagement,
- services.savedObjectsClient,
- services.uiSettings,
+ indexPatternManagementStart,
+ uiSettings,
+ savedObjects.client,
]);
- services.docTitle.change(title);
+ chrome.docTitle.change(title);
const createButton = canSave ? (
diff --git a/src/plugins/index_pattern_management/public/components/test_utils.tsx b/src/plugins/index_pattern_management/public/components/test_utils.tsx
new file mode 100644
index 00000000000000..938547cca04ab6
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/components/test_utils.tsx
@@ -0,0 +1,40 @@
+/*
+ * 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 PropTypes from 'prop-types';
+import { shallow } from 'enzyme';
+
+// since the 'shallow' from 'enzyme' doesn't support context API for React 16 and above (https://github.com/facebook/react/pull/14329)
+// we use this workaround where define legacy contextTypes for react class component
+export function createComponentWithContext(
+ MyComponent: React.ComponentClass,
+ props: Record,
+ mockedContext: Record
+) {
+ MyComponent.contextTypes = {
+ services: PropTypes.object,
+ };
+
+ return shallow(, {
+ context: {
+ services: mockedContext,
+ },
+ });
+}
diff --git a/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx b/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx
index b6b58d8f006c84..f707467cb10c6a 100644
--- a/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx
+++ b/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx
@@ -25,6 +25,7 @@ import { i18n } from '@kbn/i18n';
import { I18nProvider } from '@kbn/i18n/react';
import { StartServicesAccessor } from 'src/core/public';
+import { KibanaContextProvider } from '../../../kibana_react/public';
import { ManagementAppMountParams } from '../../../management/public';
import {
IndexPatternTableWithRouter,
@@ -33,6 +34,7 @@ import {
CreateIndexPatternWizardWithRouter,
} from '../components';
import { IndexPatternManagementStartDependencies, IndexPatternManagementStart } from '../plugin';
+import { IndexPatternManagmentContext } from '../types';
const readOnlyBadge = {
text: i18n.translate('indexPatternManagement.indexPatterns.badge.readOnly.text', {
@@ -59,81 +61,41 @@ export async function mountManagementSection(
chrome.setBadge(readOnlyBadge);
}
+ const deps: IndexPatternManagmentContext = {
+ chrome,
+ application,
+ savedObjects,
+ uiSettings,
+ notifications,
+ overlays,
+ http,
+ docLinks,
+ data,
+ indexPatternManagementStart: indexPatternManagementStart as IndexPatternManagementStart,
+ setBreadcrumbs: params.setBreadcrumbs,
+ };
+
ReactDOM.render(
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ,
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ,
params.element
);
diff --git a/src/plugins/index_pattern_management/public/mocks.ts b/src/plugins/index_pattern_management/public/mocks.ts
index 6a2a63d776c673..93574cde7dc857 100644
--- a/src/plugins/index_pattern_management/public/mocks.ts
+++ b/src/plugins/index_pattern_management/public/mocks.ts
@@ -76,8 +76,37 @@ const createInstance = async () => {
};
};
+const createIndexPatternManagmentContext = () => {
+ const {
+ chrome,
+ application,
+ savedObjects,
+ uiSettings,
+ notifications,
+ overlays,
+ docLinks,
+ } = coreMock.createStart();
+ const { http } = coreMock.createSetup();
+ const data = dataPluginMock.createStartContract();
+
+ return {
+ chrome,
+ application,
+ savedObjects,
+ uiSettings,
+ notifications,
+ overlays,
+ http,
+ docLinks,
+ data,
+ indexPatternManagementStart: createStartContract(),
+ setBreadcrumbs: () => {},
+ };
+};
+
export const mockManagementPlugin = {
createSetupContract,
createStartContract,
createInstance,
+ createIndexPatternManagmentContext,
};
diff --git a/src/plugins/index_pattern_management/public/types.ts b/src/plugins/index_pattern_management/public/types.ts
new file mode 100644
index 00000000000000..97941687e652de
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/types.ts
@@ -0,0 +1,51 @@
+/*
+ * 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 {
+ ChromeStart,
+ ApplicationStart,
+ IUiSettingsClient,
+ OverlayStart,
+ SavedObjectsStart,
+ NotificationsStart,
+ DocLinksStart,
+ HttpSetup,
+} from 'src/core/public';
+import { DataPublicPluginStart } from 'src/plugins/data/public';
+import { ManagementAppMountParams } from '../../management/public';
+import { IndexPatternManagementStart } from './index';
+import { KibanaReactContextValue } from '../../kibana_react/public';
+
+export interface IndexPatternManagmentContext {
+ chrome: ChromeStart;
+ application: ApplicationStart;
+ savedObjects: SavedObjectsStart;
+ uiSettings: IUiSettingsClient;
+ notifications: NotificationsStart;
+ overlays: OverlayStart;
+ http: HttpSetup;
+ docLinks: DocLinksStart;
+ data: DataPublicPluginStart;
+ indexPatternManagementStart: IndexPatternManagementStart;
+ setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs'];
+}
+
+export type IndexPatternManagmentContextValue = KibanaReactContextValue<
+ IndexPatternManagmentContext
+>;