mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* [ML] Use context and custom hooks to manage legacy dependencies. (#42244) * [ML] [Job wizards] switching to new kibana context provider (#42512)
This commit is contained in:
parent
975a4a2936
commit
7a1348ff09
62 changed files with 616 additions and 463 deletions
|
@ -12,11 +12,6 @@ import { uiModules } from 'ui/modules';
|
|||
const module = uiModules.get('apps/ml');
|
||||
|
||||
import 'ui/directives/kbn_href';
|
||||
import chrome from 'ui/chrome';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
|
||||
import { NavigationMenuContext } from '../../util/context_utils';
|
||||
|
||||
import { NavigationMenu } from './navigation_menu';
|
||||
|
||||
|
@ -25,12 +20,7 @@ module.directive('mlNavMenu', function () {
|
|||
restrict: 'E',
|
||||
transclude: true,
|
||||
link: function (scope, element, attrs) {
|
||||
ReactDOM.render(
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }}>
|
||||
<NavigationMenu tabId={attrs.name} />
|
||||
</NavigationMenuContext.Provider>,
|
||||
element[0]
|
||||
);
|
||||
ReactDOM.render(<NavigationMenu tabId={attrs.name} />, element[0]);
|
||||
|
||||
element.on('$destroy', () => {
|
||||
ReactDOM.unmountComponentAtNode(element[0]);
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { FC, Fragment, useContext, useState, useEffect } from 'react';
|
||||
import React, { FC, Fragment, useState, useEffect } from 'react';
|
||||
import { EuiSuperDatePicker } from '@elastic/eui';
|
||||
import { TimeHistory, TimeRange } from 'ui/timefilter/time_history';
|
||||
|
||||
import { mlTimefilterRefresh$ } from '../../../services/timefilter_refresh_service';
|
||||
import { NavigationMenuContext } from '../../../util/context_utils';
|
||||
import { useUiContext } from '../../../contexts/ui/use_ui_context';
|
||||
|
||||
interface Duration {
|
||||
start: string;
|
||||
|
@ -28,9 +28,8 @@ function getRecentlyUsedRangesFactory(timeHistory: TimeHistory) {
|
|||
}
|
||||
|
||||
export const TopNav: FC = () => {
|
||||
const navigationMenuContext = useContext(NavigationMenuContext);
|
||||
const timefilter = navigationMenuContext.timefilter;
|
||||
const getRecentlyUsedRanges = getRecentlyUsedRangesFactory(navigationMenuContext.timeHistory);
|
||||
const { chrome, timefilter, timeHistory } = useUiContext();
|
||||
const getRecentlyUsedRanges = getRecentlyUsedRangesFactory(timeHistory);
|
||||
|
||||
const [refreshInterval, setRefreshInterval] = useState(timefilter.getRefreshInterval());
|
||||
const [time, setTime] = useState(timefilter.getTime());
|
||||
|
@ -42,7 +41,7 @@ export const TopNav: FC = () => {
|
|||
timefilter.isTimeRangeSelectorEnabled
|
||||
);
|
||||
|
||||
const dateFormat = navigationMenuContext.chrome.getUiSettingsClient().get('dateFormat');
|
||||
const dateFormat = chrome.getUiSettingsClient().get('dateFormat');
|
||||
|
||||
useEffect(() => {
|
||||
timefilter.on('refreshIntervalUpdate', timefilterUpdateListener);
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { IndexPattern } from 'ui/index_patterns';
|
||||
|
||||
export const indexPatternMock = ({
|
||||
id: 'the-index-pattern-id',
|
||||
title: 'the-index-pattern-title',
|
||||
fields: [],
|
||||
} as unknown) as IndexPattern;
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { IndexPatterns } from 'ui/index_patterns';
|
||||
|
||||
export const indexPatternsMock = (new (class {
|
||||
fieldFormats = [];
|
||||
config = {};
|
||||
savedObjectsClient = {};
|
||||
refreshSavedObjectsCache = {};
|
||||
clearCache = jest.fn();
|
||||
get = jest.fn();
|
||||
getDefault = jest.fn();
|
||||
getFields = jest.fn();
|
||||
getIds = jest.fn();
|
||||
getTitles = jest.fn();
|
||||
make = jest.fn();
|
||||
})() as unknown) as IndexPatterns;
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export const kibanaConfigMock = {
|
||||
get: <T>(key: string): T => ({} as T),
|
||||
has: (key: string) => false,
|
||||
set: (key: string, value: any) => {},
|
||||
};
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { indexPatternMock } from './index_pattern';
|
||||
import { indexPatternsMock } from './index_patterns';
|
||||
import { kibanaConfigMock } from './kibana_config';
|
||||
import { savedSearchMock } from './saved_search';
|
||||
|
||||
export const kibanaContextValueMock = {
|
||||
combinedQuery: {
|
||||
query: 'the-query-string',
|
||||
language: 'the-query-language',
|
||||
},
|
||||
currentIndexPattern: indexPatternMock,
|
||||
currentSavedSearch: savedSearchMock,
|
||||
indexPatterns: indexPatternsMock,
|
||||
kbnBaseUrl: 'url',
|
||||
kibanaConfig: kibanaConfigMock,
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export const savedSearchMock = {
|
||||
id: 'the-saved-search-id',
|
||||
title: 'the-saved-search-title',
|
||||
searchSource: {},
|
||||
columns: [],
|
||||
sort: [],
|
||||
destroy: () => {},
|
||||
};
|
15
x-pack/legacy/plugins/ml/public/contexts/kibana/index.ts
Normal file
15
x-pack/legacy/plugins/ml/public/contexts/kibana/index.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export {
|
||||
KibanaContext,
|
||||
KibanaContextValue,
|
||||
SavedSearchQuery,
|
||||
KibanaConfigTypeFix,
|
||||
} from './kibana_context';
|
||||
export { useKibanaContext } from './use_kibana_context';
|
||||
export { useCurrentIndexPattern } from './use_current_index_pattern';
|
||||
export { useCurrentSavedSearch } from './use_current_saved_search';
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { KibanaConfig } from 'src/legacy/server/kbn_server';
|
||||
import { SavedSearch } from 'src/legacy/core_plugins/kibana/public/discover/types';
|
||||
|
||||
import { IndexPattern, IndexPatterns } from 'ui/index_patterns';
|
||||
|
||||
// set() method is missing in original d.ts
|
||||
export interface KibanaConfigTypeFix extends KibanaConfig {
|
||||
set(key: string, value: any): void;
|
||||
}
|
||||
|
||||
export interface KibanaContextValue {
|
||||
combinedQuery: any;
|
||||
currentIndexPattern: IndexPattern;
|
||||
currentSavedSearch: SavedSearch;
|
||||
indexPatterns: IndexPatterns;
|
||||
kbnBaseUrl: string;
|
||||
kibanaConfig: KibanaConfigTypeFix;
|
||||
}
|
||||
|
||||
export type SavedSearchQuery = object;
|
||||
|
||||
// This context provides dependencies which can be injected
|
||||
// via angularjs only (like services, currentIndexPattern etc.).
|
||||
// Because we cannot just import these dependencies, the default value
|
||||
// for the context is just {} and of type `Partial<KibanaContextValue>`
|
||||
// for the angularjs based dependencies. Therefore, the
|
||||
// actual dependencies are set like we did previously with KibanaContext
|
||||
// in the wrapping angularjs directive. In the custom hook we check if
|
||||
// the dependencies are present with error reporting if they weren't
|
||||
// added properly. That's why in tests, these custom hooks must not
|
||||
// be mocked, instead <UiChrome.Provider value="mocked-value">` needs
|
||||
// to be used. This guarantees that we have both properly set up
|
||||
// TypeScript support and runtime checks for these dependencies.
|
||||
// Multiple custom hooks can be created to access subsets of
|
||||
// the overall context value if necessary too,
|
||||
// see useCurrentIndexPattern() for example.
|
||||
export const KibanaContext = React.createContext<Partial<KibanaContextValue>>({});
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { KibanaContext } from './kibana_context';
|
||||
|
||||
export const useCurrentIndexPattern = () => {
|
||||
const context = useContext(KibanaContext);
|
||||
|
||||
if (context.currentIndexPattern === undefined) {
|
||||
throw new Error('currentIndexPattern is undefined');
|
||||
}
|
||||
|
||||
return context.currentIndexPattern;
|
||||
};
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { KibanaContext } from './kibana_context';
|
||||
|
||||
export const useCurrentSavedSearch = () => {
|
||||
const context = useContext(KibanaContext);
|
||||
|
||||
if (context.currentSavedSearch === undefined) {
|
||||
throw new Error('currentSavedSearch is undefined');
|
||||
}
|
||||
|
||||
return context.currentSavedSearch;
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { KibanaContext, KibanaContextValue } from './kibana_context';
|
||||
|
||||
export const useKibanaContext = () => {
|
||||
const context = useContext(KibanaContext);
|
||||
|
||||
if (
|
||||
context.combinedQuery === undefined ||
|
||||
context.currentIndexPattern === undefined ||
|
||||
context.currentSavedSearch === undefined ||
|
||||
context.indexPatterns === undefined ||
|
||||
context.kbnBaseUrl === undefined ||
|
||||
context.kibanaConfig === undefined
|
||||
) {
|
||||
throw new Error('required attribute is undefined');
|
||||
}
|
||||
|
||||
return context as KibanaContextValue;
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export const uiChromeMock = {
|
||||
getBasePath: () => 'basePath',
|
||||
getUiSettingsClient: () => {
|
||||
return {
|
||||
get: (key: string) => {
|
||||
switch (key) {
|
||||
case 'dateFormat':
|
||||
case 'timepicker:timeDefaults':
|
||||
return {};
|
||||
case 'timepicker:refreshIntervalDefaults':
|
||||
return { pause: false, value: 0 };
|
||||
default:
|
||||
throw new Error(`Unexpected config key: ${key}`);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export const uiTimefilterMock = {
|
||||
getRefreshInterval: () => '30s',
|
||||
getTime: () => ({ from: 0, to: 0 }),
|
||||
on: (event: string, reload: () => void) => {},
|
||||
};
|
||||
|
||||
export const uiTimeHistoryMock = {
|
||||
get: () => [{ from: 0, to: 0 }],
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { uiChromeMock } from './mocks';
|
||||
|
||||
export const useUiChromeContext = () => uiChromeMock;
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { uiChromeMock, uiTimefilterMock, uiTimeHistoryMock } from './mocks';
|
||||
|
||||
export const useUiContext = () => ({
|
||||
chrome: uiChromeMock,
|
||||
timefilter: uiTimefilterMock,
|
||||
timeHistory: uiTimeHistoryMock,
|
||||
});
|
9
x-pack/legacy/plugins/ml/public/contexts/ui/index.ts
Normal file
9
x-pack/legacy/plugins/ml/public/contexts/ui/index.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
// We only export UiContext but not any custom hooks, because if we'd import them
|
||||
// from here, mocking the hook from jest tests won't work as expected.
|
||||
export { UiContext } from './ui_context';
|
27
x-pack/legacy/plugins/ml/public/contexts/ui/ui_context.tsx
Normal file
27
x-pack/legacy/plugins/ml/public/contexts/ui/ui_context.tsx
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
|
||||
// This provides ui/* based imports via React Context.
|
||||
// Because these dependencies can use regular imports,
|
||||
// they are just passed on as the default value
|
||||
// of the Context which means it's not necessary
|
||||
// to add <UiContext.Provider value="..." />... to the
|
||||
// wrapping angular directive, reducing a lot of boilerplate.
|
||||
// The custom hooks like useUiContext() need to be mocked in
|
||||
// tests because we rely on the properly set up default value.
|
||||
// Different custom hooks can be created to access parts only
|
||||
// from the full context value, see useUiChromeContext() as an example.
|
||||
export const UiContext = React.createContext({
|
||||
chrome,
|
||||
timefilter,
|
||||
timeHistory,
|
||||
});
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { UiContext } from './ui_context';
|
||||
|
||||
export const useUiChromeContext = () => {
|
||||
return useContext(UiContext).chrome;
|
||||
};
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { UiContext } from './ui_context';
|
||||
|
||||
export const useUiContext = () => {
|
||||
return useContext(UiContext);
|
||||
};
|
|
@ -16,13 +16,6 @@ export {
|
|||
MAX_COLUMNS,
|
||||
} from './fields';
|
||||
export { DropDownLabel, DropDownOption, Label } from './dropdown';
|
||||
export {
|
||||
KibanaContext,
|
||||
KibanaContextValue,
|
||||
isKibanaContext,
|
||||
NullableKibanaContextValue,
|
||||
SavedSearchQuery,
|
||||
} from './kibana_context';
|
||||
export {
|
||||
isTransformIdValid,
|
||||
refreshTransformList$,
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { IndexPattern } from 'ui/index_patterns';
|
||||
|
||||
export interface KibanaContextValue {
|
||||
combinedQuery: any;
|
||||
currentIndexPattern: IndexPattern;
|
||||
currentSavedSearch: any;
|
||||
indexPatterns: any;
|
||||
kbnBaseUrl: string;
|
||||
kibanaConfig: any;
|
||||
}
|
||||
|
||||
export type SavedSearchQuery = object;
|
||||
|
||||
// Because we're only getting the actual contextvalue within a wrapping angular component,
|
||||
// we need to initialize here with `null` because TypeScript doesn't allow createContext()
|
||||
// without a default value. The nullable union type takes care of allowing
|
||||
// the actual required type and `null`.
|
||||
export type NullableKibanaContextValue = KibanaContextValue | null;
|
||||
export const KibanaContext = React.createContext<NullableKibanaContextValue>(null);
|
||||
|
||||
export function isKibanaContext(arg: any): arg is KibanaContextValue {
|
||||
return (
|
||||
arg.combinedQuery !== undefined &&
|
||||
arg.currentIndexPattern !== undefined &&
|
||||
arg.currentSavedSearch !== undefined &&
|
||||
arg.indexPatterns !== undefined &&
|
||||
typeof arg.kbnBaseUrl === 'string' &&
|
||||
arg.kibanaConfig !== undefined
|
||||
);
|
||||
}
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
import rison from 'rison-node';
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
|
||||
export function moveToDataFrameWizard() {
|
||||
window.location.href = '#/data_frames/new_transform';
|
||||
}
|
||||
|
@ -16,7 +14,7 @@ export function moveToDataFrameTransformList() {
|
|||
window.location.href = '#/data_frames';
|
||||
}
|
||||
|
||||
export function moveToDiscover(indexPatternId: string, kbnBaseUrl: string) {
|
||||
export function moveToDiscover(indexPatternId: string, baseUrl: string) {
|
||||
const _g = rison.encode({});
|
||||
|
||||
// Add the index pattern ID to the appState part of the URL.
|
||||
|
@ -24,7 +22,6 @@ export function moveToDiscover(indexPatternId: string, kbnBaseUrl: string) {
|
|||
index: indexPatternId,
|
||||
});
|
||||
|
||||
const baseUrl = chrome.addBasePath(kbnBaseUrl);
|
||||
const hash = `#/discover?_g=${_g}&_a=${_a}`;
|
||||
|
||||
window.location.href = `${baseUrl}${hash}`;
|
||||
|
|
|
@ -9,6 +9,7 @@ import { DefaultOperator } from 'elasticsearch';
|
|||
import { IndexPattern } from 'ui/index_patterns';
|
||||
|
||||
import { dictionaryToArray } from '../../../common/types/common';
|
||||
import { SavedSearchQuery } from '../../contexts/kibana';
|
||||
|
||||
import { StepDefineExposedState } from '../pages/data_frame_new_pivot/components/step_define/step_define_form';
|
||||
import { StepDetailsExposedState } from '../pages/data_frame_new_pivot/components/step_details/step_details_form';
|
||||
|
@ -24,7 +25,6 @@ import {
|
|||
|
||||
import { PivotAggsConfig } from './pivot_aggs';
|
||||
import { DateHistogramAgg, HistogramAgg, TermsAgg } from './pivot_group_by';
|
||||
import { SavedSearchQuery } from './kibana_context';
|
||||
import { PreviewRequestBody, CreateRequestBody } from './transform';
|
||||
|
||||
export interface SimpleQuery {
|
||||
|
|
|
@ -14,13 +14,8 @@ import uiChrome from 'ui/chrome';
|
|||
const module = uiModules.get('apps/ml', ['react']);
|
||||
|
||||
import { I18nContext } from 'ui/i18n';
|
||||
import chrome from 'ui/chrome';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
import { InjectorService } from '../../../../common/types/angular';
|
||||
|
||||
import { NavigationMenuContext } from '../../../util/context_utils';
|
||||
|
||||
import { Page } from './page';
|
||||
|
||||
module.directive('mlDataFrameAccessDenied', ($injector: InjectorService) => {
|
||||
|
@ -41,9 +36,7 @@ module.directive('mlDataFrameAccessDenied', ($injector: InjectorService) => {
|
|||
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }}>
|
||||
<Page goToKibana={goToKibana} retry={retry} />
|
||||
</NavigationMenuContext.Provider>
|
||||
<Page goToKibana={goToKibana} retry={retry} />
|
||||
</I18nContext>,
|
||||
element[0]
|
||||
);
|
||||
|
|
|
@ -5,16 +5,42 @@ exports[`Data Frame: <SourceIndexPreview /> Minimal initialization 1`] = `
|
|||
<ContextProvider
|
||||
value={
|
||||
Object {
|
||||
"combinedQuery": Object {},
|
||||
"combinedQuery": Object {
|
||||
"language": "the-query-language",
|
||||
"query": "the-query-string",
|
||||
},
|
||||
"currentIndexPattern": Object {
|
||||
"fields": Array [],
|
||||
"id": "the-index-pattern-id",
|
||||
"title": "the-index-pattern-title",
|
||||
},
|
||||
"currentSavedSearch": Object {},
|
||||
"indexPatterns": Object {},
|
||||
"currentSavedSearch": Object {
|
||||
"columns": Array [],
|
||||
"destroy": [Function],
|
||||
"id": "the-saved-search-id",
|
||||
"searchSource": Object {},
|
||||
"sort": Array [],
|
||||
"title": "the-saved-search-title",
|
||||
},
|
||||
"indexPatterns": _temp {
|
||||
"clearCache": [MockFunction],
|
||||
"config": Object {},
|
||||
"fieldFormats": Array [],
|
||||
"get": [MockFunction],
|
||||
"getDefault": [MockFunction],
|
||||
"getFields": [MockFunction],
|
||||
"getIds": [MockFunction],
|
||||
"getTitles": [MockFunction],
|
||||
"make": [MockFunction],
|
||||
"refreshSavedObjectsCache": Object {},
|
||||
"savedObjectsClient": Object {},
|
||||
},
|
||||
"kbnBaseUrl": "url",
|
||||
"kibanaConfig": Object {},
|
||||
"kibanaConfig": Object {
|
||||
"get": [Function],
|
||||
"has": [Function],
|
||||
"set": [Function],
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { IndexPattern } from 'ui/index_patterns';
|
||||
import { getPivotQuery, KibanaContext } from '../../../../common';
|
||||
import { KibanaContext } from '../../../../../contexts/kibana';
|
||||
import { kibanaContextValueMock } from '../../../../../contexts/kibana/__mocks__/kibana_context_value';
|
||||
|
||||
import { getPivotQuery } from '../../../../common';
|
||||
|
||||
import { SourceIndexPreview } from './source_index_preview';
|
||||
|
||||
|
@ -20,12 +22,6 @@ jest.mock('react', () => {
|
|||
|
||||
describe('Data Frame: <SourceIndexPreview />', () => {
|
||||
test('Minimal initialization', () => {
|
||||
const currentIndexPattern = ({
|
||||
id: 'the-index-pattern-id',
|
||||
title: 'the-index-pattern-title',
|
||||
fields: [],
|
||||
} as unknown) as IndexPattern;
|
||||
|
||||
const props = {
|
||||
query: getPivotQuery('the-query'),
|
||||
};
|
||||
|
@ -34,16 +30,7 @@ describe('Data Frame: <SourceIndexPreview />', () => {
|
|||
// with the Provider being the outer most component.
|
||||
const wrapper = shallow(
|
||||
<div>
|
||||
<KibanaContext.Provider
|
||||
value={{
|
||||
combinedQuery: {},
|
||||
currentIndexPattern,
|
||||
currentSavedSearch: {},
|
||||
indexPatterns: {},
|
||||
kbnBaseUrl: 'url',
|
||||
kibanaConfig: {},
|
||||
}}
|
||||
>
|
||||
<KibanaContext.Provider value={kibanaContextValueMock}>
|
||||
<SourceIndexPreview {...props} />
|
||||
</KibanaContext.Provider>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { FunctionComponent, useContext, useState } from 'react';
|
||||
import React, { FunctionComponent, useState } from 'react';
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -43,13 +43,13 @@ import { KBN_FIELD_TYPES } from '../../../../../../common/constants/field_types'
|
|||
import { Dictionary } from '../../../../../../common/types/common';
|
||||
import { formatHumanReadableDateTimeSeconds } from '../../../../../util/date_utils';
|
||||
|
||||
import { useCurrentIndexPattern } from '../../../../../contexts/kibana';
|
||||
|
||||
import {
|
||||
isKibanaContext,
|
||||
toggleSelectedField,
|
||||
EsDoc,
|
||||
EsFieldName,
|
||||
MAX_COLUMNS,
|
||||
KibanaContext,
|
||||
PivotQuery,
|
||||
} from '../../../../common';
|
||||
|
||||
|
@ -100,13 +100,7 @@ interface Props {
|
|||
export const SourceIndexPreview: React.SFC<Props> = React.memo(({ cellClick, query }) => {
|
||||
const [clearTable, setClearTable] = useState(false);
|
||||
|
||||
const kibanaContext = useContext(KibanaContext);
|
||||
|
||||
if (!isKibanaContext(kibanaContext)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const indexPattern = kibanaContext.currentIndexPattern;
|
||||
const indexPattern = useCurrentIndexPattern();
|
||||
|
||||
const [selectedFields, setSelectedFields] = useState([] as EsFieldName[]);
|
||||
const [isColumnsPopoverVisible, setColumnsPopoverVisible] = useState(false);
|
||||
|
|
|
@ -5,16 +5,42 @@ exports[`Data Frame: <StepCreateForm /> Minimal initialization 1`] = `
|
|||
<ContextProvider
|
||||
value={
|
||||
Object {
|
||||
"combinedQuery": Object {},
|
||||
"combinedQuery": Object {
|
||||
"language": "the-query-language",
|
||||
"query": "the-query-string",
|
||||
},
|
||||
"currentIndexPattern": Object {
|
||||
"fields": Array [],
|
||||
"id": "the-index-pattern-id",
|
||||
"title": "the-index-pattern-title",
|
||||
},
|
||||
"currentSavedSearch": Object {},
|
||||
"indexPatterns": Object {},
|
||||
"currentSavedSearch": Object {
|
||||
"columns": Array [],
|
||||
"destroy": [Function],
|
||||
"id": "the-saved-search-id",
|
||||
"searchSource": Object {},
|
||||
"sort": Array [],
|
||||
"title": "the-saved-search-title",
|
||||
},
|
||||
"indexPatterns": _temp {
|
||||
"clearCache": [MockFunction],
|
||||
"config": Object {},
|
||||
"fieldFormats": Array [],
|
||||
"get": [MockFunction],
|
||||
"getDefault": [MockFunction],
|
||||
"getFields": [MockFunction],
|
||||
"getIds": [MockFunction],
|
||||
"getTitles": [MockFunction],
|
||||
"make": [MockFunction],
|
||||
"refreshSavedObjectsCache": Object {},
|
||||
"savedObjectsClient": Object {},
|
||||
},
|
||||
"kbnBaseUrl": "url",
|
||||
"kibanaConfig": Object {},
|
||||
"kibanaConfig": Object {
|
||||
"get": [Function],
|
||||
"has": [Function],
|
||||
"set": [Function],
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { KibanaContext } from '../../../../common';
|
||||
import { KibanaContext } from '../../../../../contexts/kibana';
|
||||
import { kibanaContextValueMock } from '../../../../../contexts/kibana/__mocks__/kibana_context_value';
|
||||
|
||||
import { StepCreateForm } from './step_create_form';
|
||||
import { IndexPattern } from 'ui/index_patterns';
|
||||
|
||||
jest.mock('../../../../../contexts/ui/use_ui_chrome_context');
|
||||
|
||||
// workaround to make React.memo() work with enzyme
|
||||
jest.mock('react', () => {
|
||||
|
@ -28,26 +30,11 @@ describe('Data Frame: <StepCreateForm />', () => {
|
|||
onChange() {},
|
||||
};
|
||||
|
||||
const currentIndexPattern = ({
|
||||
id: 'the-index-pattern-id',
|
||||
title: 'the-index-pattern-title',
|
||||
fields: [],
|
||||
} as unknown) as IndexPattern;
|
||||
|
||||
// Using a wrapping <div> element because shallow() would fail
|
||||
// with the Provider being the outer most component.
|
||||
const wrapper = shallow(
|
||||
<div>
|
||||
<KibanaContext.Provider
|
||||
value={{
|
||||
combinedQuery: {},
|
||||
currentIndexPattern,
|
||||
currentSavedSearch: {},
|
||||
indexPatterns: {},
|
||||
kbnBaseUrl: 'url',
|
||||
kibanaConfig: {},
|
||||
}}
|
||||
>
|
||||
<KibanaContext.Provider value={kibanaContextValueMock}>
|
||||
<StepCreateForm {...props} />
|
||||
</KibanaContext.Provider>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { Fragment, SFC, useContext, useEffect, useState } from 'react';
|
||||
import React, { Fragment, SFC, useEffect, useState } from 'react';
|
||||
import { idx } from '@kbn/elastic-idx';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { toastNotifications } from 'ui/notify';
|
||||
|
@ -31,14 +31,11 @@ import {
|
|||
} from '@elastic/eui';
|
||||
|
||||
import { ml } from '../../../../../services/ml_api_service';
|
||||
import { useKibanaContext } from '../../../../../contexts/kibana/use_kibana_context';
|
||||
import { useUiChromeContext } from '../../../../../contexts/ui/use_ui_chrome_context';
|
||||
import { PROGRESS_JOBS_REFRESH_INTERVAL_MS } from '../../../../../../common/constants/jobs_list';
|
||||
|
||||
import {
|
||||
isKibanaContext,
|
||||
KibanaContext,
|
||||
moveToDataFrameTransformList,
|
||||
moveToDiscover,
|
||||
} from '../../../../common';
|
||||
import { moveToDataFrameTransformList, moveToDiscover } from '../../../../common';
|
||||
|
||||
export interface StepDetailsExposedState {
|
||||
created: boolean;
|
||||
|
@ -73,11 +70,8 @@ export const StepCreateForm: SFC<Props> = React.memo(
|
|||
undefined
|
||||
);
|
||||
|
||||
const kibanaContext = useContext(KibanaContext);
|
||||
|
||||
if (!isKibanaContext(kibanaContext)) {
|
||||
return null;
|
||||
}
|
||||
const kibanaContext = useKibanaContext();
|
||||
const baseUrl = useUiChromeContext().addBasePath(kibanaContext.kbnBaseUrl);
|
||||
|
||||
useEffect(() => {
|
||||
onChange({ created, started, indexPatternId });
|
||||
|
@ -156,6 +150,18 @@ export const StepCreateForm: SFC<Props> = React.memo(
|
|||
|
||||
const id = await newIndexPattern.create();
|
||||
|
||||
// id returns false if there's a duplicate index pattern.
|
||||
if (id === false) {
|
||||
toastNotifications.addDanger(
|
||||
i18n.translate('xpack.ml.dataframe.stepCreateForm.duplicateIndexPatternErrorMessage', {
|
||||
defaultMessage:
|
||||
'An error occurred creating the Kibana index pattern {indexPatternName}: The index pattern already exists.',
|
||||
values: { indexPatternName },
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if there's a default index pattern, if not,
|
||||
// set the newly created one as the default index pattern.
|
||||
if (!kibanaContext.kibanaConfig.get('defaultIndex')) {
|
||||
|
@ -163,7 +169,7 @@ export const StepCreateForm: SFC<Props> = React.memo(
|
|||
}
|
||||
|
||||
toastNotifications.addSuccess(
|
||||
i18n.translate('xpack.ml.dataframe.stepCreateForm.reateIndexPatternSuccessMessage', {
|
||||
i18n.translate('xpack.ml.dataframe.stepCreateForm.createIndexPatternSuccessMessage', {
|
||||
defaultMessage: 'Kibana index pattern {indexPatternName} created successfully.',
|
||||
values: { indexPatternName },
|
||||
})
|
||||
|
@ -391,7 +397,7 @@ export const StepCreateForm: SFC<Props> = React.memo(
|
|||
defaultMessage: 'Use Discover to explore the data frame pivot.',
|
||||
}
|
||||
)}
|
||||
onClick={() => moveToDiscover(indexPatternId, kibanaContext.kbnBaseUrl)}
|
||||
onClick={() => moveToDiscover(indexPatternId, baseUrl)}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
|
|
|
@ -5,16 +5,42 @@ exports[`Data Frame: <PivotPreview /> Minimal initialization 1`] = `
|
|||
<ContextProvider
|
||||
value={
|
||||
Object {
|
||||
"combinedQuery": Object {},
|
||||
"combinedQuery": Object {
|
||||
"language": "the-query-language",
|
||||
"query": "the-query-string",
|
||||
},
|
||||
"currentIndexPattern": Object {
|
||||
"fields": Array [],
|
||||
"id": "the-index-pattern-id",
|
||||
"title": "the-index-pattern-title",
|
||||
},
|
||||
"currentSavedSearch": Object {},
|
||||
"indexPatterns": Object {},
|
||||
"currentSavedSearch": Object {
|
||||
"columns": Array [],
|
||||
"destroy": [Function],
|
||||
"id": "the-saved-search-id",
|
||||
"searchSource": Object {},
|
||||
"sort": Array [],
|
||||
"title": "the-saved-search-title",
|
||||
},
|
||||
"indexPatterns": _temp {
|
||||
"clearCache": [MockFunction],
|
||||
"config": Object {},
|
||||
"fieldFormats": Array [],
|
||||
"get": [MockFunction],
|
||||
"getDefault": [MockFunction],
|
||||
"getFields": [MockFunction],
|
||||
"getIds": [MockFunction],
|
||||
"getTitles": [MockFunction],
|
||||
"make": [MockFunction],
|
||||
"refreshSavedObjectsCache": Object {},
|
||||
"savedObjectsClient": Object {},
|
||||
},
|
||||
"kbnBaseUrl": "url",
|
||||
"kibanaConfig": Object {},
|
||||
"kibanaConfig": Object {
|
||||
"get": [Function],
|
||||
"has": [Function],
|
||||
"set": [Function],
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
|
|
|
@ -5,16 +5,42 @@ exports[`Data Frame: <DefinePivotForm /> Minimal initialization 1`] = `
|
|||
<ContextProvider
|
||||
value={
|
||||
Object {
|
||||
"combinedQuery": Object {},
|
||||
"combinedQuery": Object {
|
||||
"language": "the-query-language",
|
||||
"query": "the-query-string",
|
||||
},
|
||||
"currentIndexPattern": Object {
|
||||
"fields": Array [],
|
||||
"id": "the-index-pattern-id",
|
||||
"title": "the-index-pattern-title",
|
||||
},
|
||||
"currentSavedSearch": Object {},
|
||||
"indexPatterns": Object {},
|
||||
"currentSavedSearch": Object {
|
||||
"columns": Array [],
|
||||
"destroy": [Function],
|
||||
"id": "the-saved-search-id",
|
||||
"searchSource": Object {},
|
||||
"sort": Array [],
|
||||
"title": "the-saved-search-title",
|
||||
},
|
||||
"indexPatterns": _temp {
|
||||
"clearCache": [MockFunction],
|
||||
"config": Object {},
|
||||
"fieldFormats": Array [],
|
||||
"get": [MockFunction],
|
||||
"getDefault": [MockFunction],
|
||||
"getFields": [MockFunction],
|
||||
"getIds": [MockFunction],
|
||||
"getTitles": [MockFunction],
|
||||
"make": [MockFunction],
|
||||
"refreshSavedObjectsCache": Object {},
|
||||
"savedObjectsClient": Object {},
|
||||
},
|
||||
"kbnBaseUrl": "url",
|
||||
"kibanaConfig": Object {},
|
||||
"kibanaConfig": Object {
|
||||
"get": [Function],
|
||||
"has": [Function],
|
||||
"set": [Function],
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
|
|
|
@ -5,16 +5,42 @@ exports[`Data Frame: <DefinePivotSummary /> Minimal initialization 1`] = `
|
|||
<ContextProvider
|
||||
value={
|
||||
Object {
|
||||
"combinedQuery": Object {},
|
||||
"combinedQuery": Object {
|
||||
"language": "the-query-language",
|
||||
"query": "the-query-string",
|
||||
},
|
||||
"currentIndexPattern": Object {
|
||||
"fields": Array [],
|
||||
"id": "the-index-pattern-id",
|
||||
"title": "the-index-pattern-title",
|
||||
},
|
||||
"currentSavedSearch": Object {},
|
||||
"indexPatterns": Object {},
|
||||
"currentSavedSearch": Object {
|
||||
"columns": Array [],
|
||||
"destroy": [Function],
|
||||
"id": "the-saved-search-id",
|
||||
"searchSource": Object {},
|
||||
"sort": Array [],
|
||||
"title": "the-saved-search-title",
|
||||
},
|
||||
"indexPatterns": _temp {
|
||||
"clearCache": [MockFunction],
|
||||
"config": Object {},
|
||||
"fieldFormats": Array [],
|
||||
"get": [MockFunction],
|
||||
"getDefault": [MockFunction],
|
||||
"getFields": [MockFunction],
|
||||
"getIds": [MockFunction],
|
||||
"getTitles": [MockFunction],
|
||||
"make": [MockFunction],
|
||||
"refreshSavedObjectsCache": Object {},
|
||||
"savedObjectsClient": Object {},
|
||||
},
|
||||
"kbnBaseUrl": "url",
|
||||
"kibanaConfig": Object {},
|
||||
"kibanaConfig": Object {
|
||||
"get": [Function],
|
||||
"has": [Function],
|
||||
"set": [Function],
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
|
|
|
@ -7,17 +7,17 @@
|
|||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { KibanaContext } from '../../../../../contexts/kibana';
|
||||
import { kibanaContextValueMock } from '../../../../../contexts/kibana/__mocks__/kibana_context_value';
|
||||
|
||||
import {
|
||||
getPivotQuery,
|
||||
KibanaContext,
|
||||
PivotAggsConfig,
|
||||
PivotGroupByConfig,
|
||||
PIVOT_SUPPORTED_AGGS,
|
||||
PIVOT_SUPPORTED_GROUP_BY_AGGS,
|
||||
} from '../../../../common';
|
||||
|
||||
import { IndexPattern } from 'ui/index_patterns';
|
||||
|
||||
import { PivotPreview } from './pivot_preview';
|
||||
|
||||
// workaround to make React.memo() work with enzyme
|
||||
|
@ -28,12 +28,6 @@ jest.mock('react', () => {
|
|||
|
||||
describe('Data Frame: <PivotPreview />', () => {
|
||||
test('Minimal initialization', () => {
|
||||
const currentIndexPattern = ({
|
||||
id: 'the-index-pattern-id',
|
||||
title: 'the-index-pattern-title',
|
||||
fields: [],
|
||||
} as unknown) as IndexPattern;
|
||||
|
||||
const groupBy: PivotGroupByConfig = {
|
||||
agg: PIVOT_SUPPORTED_GROUP_BY_AGGS.TERMS,
|
||||
field: 'the-group-by-field',
|
||||
|
@ -56,16 +50,7 @@ describe('Data Frame: <PivotPreview />', () => {
|
|||
// with the Provider being the outer most component.
|
||||
const wrapper = shallow(
|
||||
<div>
|
||||
<KibanaContext.Provider
|
||||
value={{
|
||||
combinedQuery: {},
|
||||
currentIndexPattern,
|
||||
currentSavedSearch: {},
|
||||
indexPatterns: {},
|
||||
kbnBaseUrl: 'url',
|
||||
kibanaConfig: {},
|
||||
}}
|
||||
>
|
||||
<KibanaContext.Provider value={kibanaContextValueMock}>
|
||||
<PivotPreview {...props} />
|
||||
</KibanaContext.Provider>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { SFC, useContext, useEffect, useRef, useState } from 'react';
|
||||
import React, { SFC, useEffect, useRef, useState } from 'react';
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -28,11 +28,11 @@ import { Dictionary, dictionaryToArray } from '../../../../../../common/types/co
|
|||
import { ES_FIELD_TYPES } from '../../../../../../common/constants/field_types';
|
||||
import { formatHumanReadableDateTimeSeconds } from '../../../../../util/date_utils';
|
||||
|
||||
import { useCurrentIndexPattern } from '../../../../../contexts/kibana';
|
||||
|
||||
import {
|
||||
getFlattenedFields,
|
||||
isKibanaContext,
|
||||
PreviewRequestBody,
|
||||
KibanaContext,
|
||||
PivotAggsConfigDict,
|
||||
PivotGroupByConfig,
|
||||
PivotGroupByConfigDict,
|
||||
|
@ -139,13 +139,8 @@ interface PivotPreviewProps {
|
|||
export const PivotPreview: SFC<PivotPreviewProps> = React.memo(({ aggs, groupBy, query }) => {
|
||||
const [clearTable, setClearTable] = useState(false);
|
||||
|
||||
const kibanaContext = useContext(KibanaContext);
|
||||
const indexPattern = useCurrentIndexPattern();
|
||||
|
||||
if (!isKibanaContext(kibanaContext)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const indexPattern = kibanaContext.currentIndexPattern;
|
||||
const {
|
||||
dataFramePreviewData,
|
||||
dataFramePreviewMappings,
|
||||
|
|
|
@ -7,14 +7,15 @@
|
|||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { KibanaContext } from '../../../../../contexts/kibana';
|
||||
import { kibanaContextValueMock } from '../../../../../contexts/kibana/__mocks__/kibana_context_value';
|
||||
|
||||
import {
|
||||
KibanaContext,
|
||||
PivotAggsConfigDict,
|
||||
PivotGroupByConfigDict,
|
||||
PIVOT_SUPPORTED_AGGS,
|
||||
PIVOT_SUPPORTED_GROUP_BY_AGGS,
|
||||
} from '../../../../common';
|
||||
import { IndexPattern } from 'ui/index_patterns';
|
||||
import { StepDefineForm, isAggNameConflict } from './step_define_form';
|
||||
|
||||
// workaround to make React.memo() work with enzyme
|
||||
|
@ -25,26 +26,11 @@ jest.mock('react', () => {
|
|||
|
||||
describe('Data Frame: <DefinePivotForm />', () => {
|
||||
test('Minimal initialization', () => {
|
||||
const currentIndexPattern = ({
|
||||
id: 'the-index-pattern-id',
|
||||
title: 'the-index-pattern-title',
|
||||
fields: [],
|
||||
} as unknown) as IndexPattern;
|
||||
|
||||
// Using a wrapping <div> element because shallow() would fail
|
||||
// with the Provider being the outer most component.
|
||||
const wrapper = shallow(
|
||||
<div>
|
||||
<KibanaContext.Provider
|
||||
value={{
|
||||
combinedQuery: {},
|
||||
currentIndexPattern,
|
||||
currentSavedSearch: {},
|
||||
indexPatterns: {},
|
||||
kbnBaseUrl: 'url',
|
||||
kibanaConfig: {},
|
||||
}}
|
||||
>
|
||||
<KibanaContext.Provider value={kibanaContextValueMock}>
|
||||
<StepDefineForm onChange={() => {}} />
|
||||
</KibanaContext.Provider>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { Fragment, SFC, useContext, useEffect, useState } from 'react';
|
||||
import React, { Fragment, SFC, useEffect, useState } from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
|
@ -37,14 +37,17 @@ import { PivotPreview } from './pivot_preview';
|
|||
import { KqlFilterBar } from '../../../../../components/kql_filter_bar';
|
||||
import { SwitchModal } from './switch_modal';
|
||||
|
||||
import {
|
||||
useKibanaContext,
|
||||
KibanaContextValue,
|
||||
SavedSearchQuery,
|
||||
} from '../../../../../contexts/kibana';
|
||||
|
||||
import {
|
||||
AggName,
|
||||
DropDownLabel,
|
||||
getPivotQuery,
|
||||
getPreviewRequestBody,
|
||||
isKibanaContext,
|
||||
KibanaContext,
|
||||
KibanaContextValue,
|
||||
PivotAggDict,
|
||||
PivotAggsConfig,
|
||||
PivotAggsConfigDict,
|
||||
|
@ -53,7 +56,6 @@ import {
|
|||
PivotGroupByConfigDict,
|
||||
PivotSupportedGroupByAggs,
|
||||
PIVOT_SUPPORTED_AGGS,
|
||||
SavedSearchQuery,
|
||||
} from '../../../../common';
|
||||
|
||||
import { getPivotDropdownOptions } from './common';
|
||||
|
@ -197,11 +199,7 @@ interface Props {
|
|||
}
|
||||
|
||||
export const StepDefineForm: SFC<Props> = React.memo(({ overrides = {}, onChange }) => {
|
||||
const kibanaContext = useContext(KibanaContext);
|
||||
|
||||
if (!isKibanaContext(kibanaContext)) {
|
||||
return null;
|
||||
}
|
||||
const kibanaContext = useKibanaContext();
|
||||
|
||||
const indexPattern = kibanaContext.currentIndexPattern;
|
||||
|
||||
|
|
|
@ -7,14 +7,15 @@
|
|||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { KibanaContext } from '../../../../../contexts/kibana';
|
||||
import { kibanaContextValueMock } from '../../../../../contexts/kibana/__mocks__/kibana_context_value';
|
||||
|
||||
import {
|
||||
KibanaContext,
|
||||
PivotAggsConfig,
|
||||
PivotGroupByConfig,
|
||||
PIVOT_SUPPORTED_AGGS,
|
||||
PIVOT_SUPPORTED_GROUP_BY_AGGS,
|
||||
} from '../../../../common';
|
||||
import { IndexPattern } from 'ui/index_patterns';
|
||||
import { StepDefineExposedState } from './step_define_form';
|
||||
import { StepDefineSummary } from './step_define_summary';
|
||||
|
||||
|
@ -26,12 +27,6 @@ jest.mock('react', () => {
|
|||
|
||||
describe('Data Frame: <DefinePivotSummary />', () => {
|
||||
test('Minimal initialization', () => {
|
||||
const currentIndexPattern = ({
|
||||
id: 'the-index-pattern-id',
|
||||
title: 'the-index-pattern-title',
|
||||
fields: [],
|
||||
} as unknown) as IndexPattern;
|
||||
|
||||
const groupBy: PivotGroupByConfig = {
|
||||
agg: PIVOT_SUPPORTED_GROUP_BY_AGGS.TERMS,
|
||||
field: 'the-group-by-field',
|
||||
|
@ -59,16 +54,7 @@ describe('Data Frame: <DefinePivotSummary />', () => {
|
|||
// with the Provider being the outer most component.
|
||||
const wrapper = shallow(
|
||||
<div>
|
||||
<KibanaContext.Provider
|
||||
value={{
|
||||
combinedQuery: {},
|
||||
currentIndexPattern,
|
||||
currentSavedSearch: {},
|
||||
indexPatterns: {},
|
||||
kbnBaseUrl: 'url',
|
||||
kibanaConfig: {},
|
||||
}}
|
||||
>
|
||||
<KibanaContext.Provider value={kibanaContextValueMock}>
|
||||
<StepDefineSummary {...props} />
|
||||
</KibanaContext.Provider>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { Fragment, SFC, useContext } from 'react';
|
||||
import React, { Fragment, SFC } from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
|
@ -17,11 +17,13 @@ import {
|
|||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { useKibanaContext } from '../../../../../contexts/kibana';
|
||||
|
||||
import { AggListSummary } from '../aggregation_list';
|
||||
import { GroupByListSummary } from '../group_by_list';
|
||||
import { PivotPreview } from './pivot_preview';
|
||||
|
||||
import { getPivotQuery, isKibanaContext, KibanaContext } from '../../../../common';
|
||||
import { getPivotQuery } from '../../../../common';
|
||||
import { StepDefineExposedState } from './step_define_form';
|
||||
|
||||
const defaultSearch = '*';
|
||||
|
@ -33,11 +35,7 @@ export const StepDefineSummary: SFC<StepDefineExposedState> = ({
|
|||
groupByList,
|
||||
aggList,
|
||||
}) => {
|
||||
const kibanaContext = useContext(KibanaContext);
|
||||
|
||||
if (!isKibanaContext(kibanaContext)) {
|
||||
return null;
|
||||
}
|
||||
const kibanaContext = useKibanaContext();
|
||||
|
||||
const pivotQuery = getPivotQuery(searchQuery);
|
||||
let useCodeBlock = false;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { Fragment, SFC, useContext, useEffect, useState } from 'react';
|
||||
import React, { Fragment, SFC, useEffect, useState } from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { metadata } from 'ui/metadata';
|
||||
|
@ -12,17 +12,16 @@ import { toastNotifications } from 'ui/notify';
|
|||
|
||||
import { EuiLink, EuiSwitch, EuiFieldText, EuiForm, EuiFormRow, EuiSelect } from '@elastic/eui';
|
||||
|
||||
import { useKibanaContext } from '../../../../../contexts/kibana';
|
||||
import { isValidIndexName } from '../../../../../../common/util/es_utils';
|
||||
|
||||
import { ml } from '../../../../../services/ml_api_service';
|
||||
|
||||
import {
|
||||
delayFormatRegex,
|
||||
isKibanaContext,
|
||||
isTransformIdValid,
|
||||
DataFrameTransformId,
|
||||
DataFrameTransformPivotConfig,
|
||||
KibanaContext,
|
||||
} from '../../../../common';
|
||||
import { EsIndexName, IndexPatternTitle } from './common';
|
||||
|
||||
|
@ -58,11 +57,7 @@ interface Props {
|
|||
}
|
||||
|
||||
export const StepDetailsForm: SFC<Props> = React.memo(({ overrides = {}, onChange }) => {
|
||||
const kibanaContext = useContext(KibanaContext);
|
||||
|
||||
if (!isKibanaContext(kibanaContext)) {
|
||||
return null;
|
||||
}
|
||||
const kibanaContext = useKibanaContext();
|
||||
|
||||
const defaults = { ...getDefaultStepDetailsState(), ...overrides };
|
||||
|
||||
|
@ -123,7 +118,7 @@ export const StepDetailsForm: SFC<Props> = React.memo(({ overrides = {}, onChang
|
|||
}
|
||||
|
||||
try {
|
||||
setIndexPatternTitles(await kibanaContext.indexPatterns.getTitles());
|
||||
setIndexPatternTitles((await kibanaContext.indexPatterns.getTitles(false)) as string[]);
|
||||
} catch (e) {
|
||||
toastNotifications.addDanger(
|
||||
i18n.translate('xpack.ml.dataframe.stepDetailsForm.errorGettingIndexPatternTitles', {
|
||||
|
|
|
@ -4,13 +4,15 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { Fragment, SFC, useContext, useRef, useState } from 'react';
|
||||
import React, { Fragment, SFC, useRef, useState } from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { EuiSteps, EuiStepStatus } from '@elastic/eui';
|
||||
|
||||
import { isKibanaContext, getCreateRequestBody, KibanaContext } from '../../../../common';
|
||||
import { useKibanaContext } from '../../../../../contexts/kibana';
|
||||
|
||||
import { getCreateRequestBody } from '../../../../common';
|
||||
|
||||
import {
|
||||
StepDefineExposedState,
|
||||
|
@ -61,11 +63,7 @@ const StepDefine: SFC<DefinePivotStepProps> = ({
|
|||
};
|
||||
|
||||
export const Wizard: SFC = React.memo(() => {
|
||||
const kibanaContext = useContext(KibanaContext);
|
||||
|
||||
if (!isKibanaContext(kibanaContext)) {
|
||||
return null;
|
||||
}
|
||||
const kibanaContext = useKibanaContext();
|
||||
|
||||
const indexPattern = kibanaContext.currentIndexPattern;
|
||||
|
||||
|
|
|
@ -7,16 +7,15 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
// @ts-ignore
|
||||
import { uiModules } from 'ui/modules';
|
||||
const module = uiModules.get('apps/ml', ['react']);
|
||||
|
||||
import { IndexPattern } from 'ui/index_patterns';
|
||||
import { IndexPattern, IndexPatterns } from 'ui/index_patterns';
|
||||
import { I18nContext } from 'ui/i18n';
|
||||
import { IPrivate } from 'ui/private';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
|
||||
import { InjectorService } from '../../../../common/types/angular';
|
||||
|
||||
// @ts-ignore
|
||||
|
@ -28,8 +27,7 @@ type CreateSearchItems = () => {
|
|||
combinedQuery: any;
|
||||
};
|
||||
|
||||
import { NavigationMenuContext } from '../../../util/context_utils';
|
||||
import { KibanaContext } from '../../common';
|
||||
import { KibanaConfigTypeFix, KibanaContext } from '../../../contexts/kibana';
|
||||
import { Page } from './page';
|
||||
|
||||
module.directive('mlNewDataFrame', ($injector: InjectorService) => {
|
||||
|
@ -37,10 +35,10 @@ module.directive('mlNewDataFrame', ($injector: InjectorService) => {
|
|||
scope: {},
|
||||
restrict: 'E',
|
||||
link: (scope: ng.IScope, element: ng.IAugmentedJQuery) => {
|
||||
const indexPatterns = $injector.get('indexPatterns');
|
||||
const indexPatterns = $injector.get<IndexPatterns>('indexPatterns');
|
||||
const kbnBaseUrl = $injector.get<string>('kbnBaseUrl');
|
||||
const kibanaConfig = $injector.get('config');
|
||||
const Private: IPrivate = $injector.get('Private');
|
||||
const kibanaConfig = $injector.get<KibanaConfigTypeFix>('config');
|
||||
const Private = $injector.get<IPrivate>('Private');
|
||||
|
||||
timefilter.disableTimeRangeSelector();
|
||||
timefilter.disableAutoRefreshSelector();
|
||||
|
@ -59,11 +57,9 @@ module.directive('mlNewDataFrame', ($injector: InjectorService) => {
|
|||
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }}>
|
||||
<KibanaContext.Provider value={kibanaContext}>
|
||||
<Page />
|
||||
</KibanaContext.Provider>
|
||||
</NavigationMenuContext.Provider>
|
||||
<KibanaContext.Provider value={kibanaContext}>
|
||||
<Page />
|
||||
</KibanaContext.Provider>
|
||||
</I18nContext>,
|
||||
element[0]
|
||||
);
|
||||
|
|
|
@ -10,12 +10,8 @@ import ReactDOM from 'react-dom';
|
|||
// @ts-ignore
|
||||
import { uiModules } from 'ui/modules';
|
||||
const module = uiModules.get('apps/ml', ['react']);
|
||||
import chrome from 'ui/chrome';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
|
||||
import { I18nContext } from 'ui/i18n';
|
||||
import { NavigationMenuContext } from '../../../util/context_utils';
|
||||
import { Page } from './page';
|
||||
|
||||
module.directive('mlDataFramePage', () => {
|
||||
|
@ -25,9 +21,7 @@ module.directive('mlDataFramePage', () => {
|
|||
link: (scope: ng.IScope, element: ng.IAugmentedJQuery) => {
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }}>
|
||||
<Page />
|
||||
</NavigationMenuContext.Provider>
|
||||
<Page />
|
||||
</I18nContext>,
|
||||
element[0]
|
||||
);
|
||||
|
|
|
@ -22,11 +22,8 @@ import {
|
|||
|
||||
import { isFullLicense } from '../../license/check_license';
|
||||
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||
import chrome from 'ui/chrome';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
|
||||
import { NavigationMenuContext } from '../../util/context_utils';
|
||||
import { NavigationMenu } from '../../components/navigation_menu/navigation_menu';
|
||||
|
||||
function startTrialDescription() {
|
||||
|
@ -57,7 +54,7 @@ export const DatavisualizerSelector = injectI18n(function (props) {
|
|||
const startTrialVisible = isFullLicense() === false;
|
||||
|
||||
return (
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }}>
|
||||
<Fragment>
|
||||
<NavigationMenu tabId="datavisualizer" />
|
||||
<EuiPage restrictWidth={1000}>
|
||||
<EuiPageBody>
|
||||
|
@ -182,6 +179,6 @@ export const DatavisualizerSelector = injectI18n(function (props) {
|
|||
)}
|
||||
</EuiPageBody>
|
||||
</EuiPage>
|
||||
</NavigationMenuContext.Provider>
|
||||
</Fragment>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -17,12 +17,8 @@ import { uiModules } from 'ui/modules';
|
|||
const module = uiModules.get('apps/ml');
|
||||
|
||||
import { I18nContext } from 'ui/i18n';
|
||||
import chrome from 'ui/chrome';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
|
||||
import { jobSelectServiceFactory } from '../components/job_selector/job_select_service_utils';
|
||||
import { NavigationMenuContext } from '../util/context_utils';
|
||||
|
||||
import { Explorer } from './explorer';
|
||||
import { EXPLORER_ACTION } from './explorer_constants';
|
||||
|
@ -37,17 +33,15 @@ module.directive('mlExplorerReactWrapper', function (config, globalState) {
|
|||
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }}>
|
||||
<Explorer {...{
|
||||
appStateHandler: scope.appStateHandler,
|
||||
config,
|
||||
dateFormatTz,
|
||||
globalState,
|
||||
jobSelectService,
|
||||
MlTimeBuckets: scope.MlTimeBuckets,
|
||||
}}
|
||||
/>
|
||||
</NavigationMenuContext.Provider>
|
||||
<Explorer {...{
|
||||
appStateHandler: scope.appStateHandler,
|
||||
config,
|
||||
dateFormatTz,
|
||||
globalState,
|
||||
jobSelectService,
|
||||
MlTimeBuckets: scope.MlTimeBuckets,
|
||||
}}
|
||||
/>
|
||||
</I18nContext>,
|
||||
element[0]
|
||||
);
|
||||
|
|
|
@ -4,25 +4,22 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { FileDataVisualizerView } from './components/file_datavisualizer_view';
|
||||
import React, { Fragment } from 'react';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
|
||||
import { NavigationMenuContext } from '../util/context_utils';
|
||||
import { NavigationMenu } from '../components/navigation_menu/navigation_menu';
|
||||
|
||||
import { FileDataVisualizerView } from './components/file_datavisualizer_view';
|
||||
|
||||
export function FileDataVisualizerPage({ indexPatterns, kibanaConfig }) {
|
||||
timefilter.disableTimeRangeSelector();
|
||||
timefilter.disableAutoRefreshSelector();
|
||||
|
||||
return (
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }}>
|
||||
<Fragment>
|
||||
<NavigationMenu tabId="datavisualizer" />
|
||||
<FileDataVisualizerView indexPatterns={indexPatterns} kibanaConfig={kibanaConfig} />
|
||||
</NavigationMenuContext.Provider>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -17,12 +17,8 @@ import { checkGetJobsPrivilege } from 'plugins/ml/privilege/check_privilege';
|
|||
import { getMlNodeCount } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
|
||||
import { getJobManagementBreadcrumbs } from 'plugins/ml/jobs/breadcrumbs';
|
||||
import { loadNewJobDefaults } from 'plugins/ml/jobs/new_job/utils/new_job_defaults';
|
||||
import { NavigationMenuContext } from '../../util/context_utils';
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
|
||||
const template = `<jobs-page data-test-subj="mlPageJobManagement" />`;
|
||||
|
||||
|
@ -49,9 +45,7 @@ module.directive('jobsPage', function () {
|
|||
link: (scope, element) => {
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }}>
|
||||
<JobsPage angularWrapperScope={scope} />
|
||||
</NavigationMenuContext.Provider>
|
||||
<JobsPage angularWrapperScope={scope} />
|
||||
</I18nContext>,
|
||||
element[0]
|
||||
);
|
||||
|
|
|
@ -12,7 +12,7 @@ import moment from 'moment';
|
|||
import { WizardNav } from '../wizard_nav';
|
||||
import { WIZARD_STEPS, StepProps } from '../step_types';
|
||||
import { JobCreatorContext } from '../job_creator_context';
|
||||
import { KibanaContext, isKibanaContext } from '../../../../../data_frame/common/kibana_context';
|
||||
import { useKibanaContext } from '../../../../../contexts/kibana';
|
||||
import { FullTimeRangeSelector } from '../../../../../components/full_time_range_selector';
|
||||
import { EventRateChart } from '../charts/event_rate_chart';
|
||||
import { LineChartPoint } from '../../../common/chart_loader';
|
||||
|
@ -26,10 +26,7 @@ export interface TimeRange {
|
|||
end: number;
|
||||
}
|
||||
export const TimeRangeStep: FC<StepProps> = ({ setCurrentStep, isCurrentStep }) => {
|
||||
const kibanaContext = useContext(KibanaContext);
|
||||
if (!isKibanaContext(kibanaContext)) {
|
||||
return null;
|
||||
}
|
||||
const kibanaContext = useKibanaContext();
|
||||
|
||||
const {
|
||||
jobCreator,
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
*/
|
||||
|
||||
import moment from 'moment';
|
||||
import React, { Fragment, FC, useContext, useState, useEffect } from 'react';
|
||||
import React, { Fragment, FC, useState, useEffect } from 'react';
|
||||
import { EuiDatePickerRange, EuiDatePicker } from '@elastic/eui';
|
||||
|
||||
import { KibanaContext, isKibanaContext } from '../../../../../data_frame/common/kibana_context';
|
||||
import { useKibanaContext } from '../../../../../contexts/kibana';
|
||||
import { TimeRange } from './time_range';
|
||||
|
||||
const WIDTH = '512px';
|
||||
|
@ -21,11 +21,8 @@ interface Props {
|
|||
type Moment = moment.Moment;
|
||||
|
||||
export const TimeRangePicker: FC<Props> = ({ setTimeRange, timeRange }) => {
|
||||
const kibanaContext = useContext(KibanaContext);
|
||||
if (!isKibanaContext(kibanaContext)) {
|
||||
return null;
|
||||
}
|
||||
const dateFormat = kibanaContext.kibanaConfig.get('dateFormat');
|
||||
const kibanaContext = useKibanaContext();
|
||||
const dateFormat: string = kibanaContext.kibanaConfig.get('dateFormat');
|
||||
|
||||
const [startMoment, setStartMoment] = useState<Moment | undefined>(moment(timeRange.start));
|
||||
const [endMoment, setEndMoment] = useState<Moment | undefined>(moment(timeRange.end));
|
||||
|
|
|
@ -11,6 +11,7 @@ import ReactDOM from 'react-dom';
|
|||
import { uiModules } from 'ui/modules';
|
||||
const module = uiModules.get('apps/ml', ['react']);
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { IndexPatterns } from 'ui/index_patterns';
|
||||
|
||||
import { I18nContext } from 'ui/i18n';
|
||||
import { IPrivate } from 'ui/private';
|
||||
|
@ -20,7 +21,7 @@ import { SearchItemsProvider } from '../../../new_job/utils/new_job_utils';
|
|||
import { Page, PageProps } from './page';
|
||||
import { JOB_TYPE } from '../../common/job_creator/util/constants';
|
||||
|
||||
import { KibanaContext } from '../../../../data_frame/common/kibana_context';
|
||||
import { KibanaContext, KibanaConfigTypeFix } from '../../../../contexts/kibana';
|
||||
|
||||
module.directive('mlNewJobPage', ($injector: InjectorService) => {
|
||||
return {
|
||||
|
@ -30,10 +31,10 @@ module.directive('mlNewJobPage', ($injector: InjectorService) => {
|
|||
timefilter.disableTimeRangeSelector();
|
||||
timefilter.disableAutoRefreshSelector();
|
||||
|
||||
const indexPatterns = $injector.get('indexPatterns');
|
||||
const indexPatterns = $injector.get<IndexPatterns>('indexPatterns');
|
||||
const kbnBaseUrl = $injector.get<string>('kbnBaseUrl');
|
||||
const kibanaConfig = $injector.get('config');
|
||||
const Private: IPrivate = $injector.get('Private');
|
||||
const kibanaConfig = $injector.get<KibanaConfigTypeFix>('config');
|
||||
const Private = $injector.get<IPrivate>('Private');
|
||||
const $route = $injector.get<any>('$route');
|
||||
const existingJobsAndGroups = $route.current.locals.existingJobsAndGroups;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { FC, useContext, useEffect, Fragment } from 'react';
|
||||
import React, { FC, useEffect, Fragment } from 'react';
|
||||
|
||||
import { EuiPage, EuiPageBody, EuiPageContentBody } from '@elastic/eui';
|
||||
import { Wizard } from './wizard';
|
||||
|
@ -21,7 +21,7 @@ import {
|
|||
import { ChartLoader } from '../../common/chart_loader';
|
||||
import { ResultsLoader } from '../../common/results_loader';
|
||||
import { JobValidator } from '../../common/job_validator';
|
||||
import { KibanaContext, isKibanaContext } from '../../../../data_frame/common/kibana_context';
|
||||
import { useKibanaContext } from '../../../../contexts/kibana';
|
||||
import { getTimeFilterRange } from '../../../../components/full_time_range_selector';
|
||||
import { MlTimeBuckets } from '../../../../util/ml_time_buckets';
|
||||
import { newJobDefaults } from '../../../new_job/utils/new_job_defaults';
|
||||
|
@ -38,10 +38,7 @@ export interface PageProps {
|
|||
}
|
||||
|
||||
export const Page: FC<PageProps> = ({ existingJobsAndGroups, jobType }) => {
|
||||
const kibanaContext = useContext(KibanaContext);
|
||||
if (!isKibanaContext(kibanaContext)) {
|
||||
return null;
|
||||
}
|
||||
const kibanaContext = useKibanaContext();
|
||||
|
||||
const jobDefaults = newJobDefaults();
|
||||
|
||||
|
|
|
@ -17,14 +17,9 @@ import { checkGetJobsPrivilege, checkPermission } from '../../../privilege/check
|
|||
import { checkMlNodesAvailable } from '../../../ml_nodes_check/check_ml_nodes';
|
||||
import { getCreateCalendarBreadcrumbs, getEditCalendarBreadcrumbs } from '../../breadcrumbs';
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
import { I18nContext } from 'ui/i18n';
|
||||
|
||||
import { NavigationMenuContext } from '../../../util/context_utils';
|
||||
|
||||
const template = `
|
||||
<div class="euiSpacer euiSpacer--s" />
|
||||
<ml-new-calendar />
|
||||
|
@ -66,9 +61,7 @@ module.directive('mlNewCalendar', function ($route) {
|
|||
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }}>
|
||||
<NewCalendar {...props} />
|
||||
</NavigationMenuContext.Provider>
|
||||
<NewCalendar {...props} />
|
||||
</I18nContext>,
|
||||
element[0]
|
||||
);
|
||||
|
|
|
@ -16,14 +16,9 @@ import { checkGetJobsPrivilege, checkPermission } from '../../../privilege/check
|
|||
import { getMlNodeCount } from '../../../ml_nodes_check/check_ml_nodes';
|
||||
import { getCalendarManagementBreadcrumbs } from '../../breadcrumbs';
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
import { I18nContext } from 'ui/i18n';
|
||||
|
||||
import { NavigationMenuContext } from '../../../util/context_utils';
|
||||
|
||||
const template = `
|
||||
<div class="euiSpacer euiSpacer--s" />
|
||||
<ml-calendars-list />
|
||||
|
@ -54,9 +49,7 @@ module.directive('mlCalendarsList', function () {
|
|||
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }}>
|
||||
<CalendarsList {...props} />
|
||||
</NavigationMenuContext.Provider>
|
||||
<CalendarsList {...props} />
|
||||
</I18nContext>,
|
||||
element[0]
|
||||
);
|
||||
|
|
|
@ -18,14 +18,9 @@ import { checkGetJobsPrivilege, checkPermission } from 'plugins/ml/privilege/che
|
|||
import { getMlNodeCount } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
|
||||
import { EditFilterList } from './edit_filter_list';
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
import { I18nContext } from 'ui/i18n';
|
||||
|
||||
import { NavigationMenuContext } from '../../../util/context_utils';
|
||||
|
||||
const template = `
|
||||
<div class="euiSpacer euiSpacer--s" />
|
||||
<ml-edit-filter-list />
|
||||
|
@ -65,9 +60,7 @@ module.directive('mlEditFilterList', function ($route) {
|
|||
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }}>
|
||||
<EditFilterList {...props} />
|
||||
</NavigationMenuContext.Provider>
|
||||
<EditFilterList {...props} />
|
||||
</I18nContext>,
|
||||
element[0]
|
||||
);
|
||||
|
|
|
@ -18,14 +18,9 @@ import { checkGetJobsPrivilege, checkPermission } from 'plugins/ml/privilege/che
|
|||
import { getMlNodeCount } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
|
||||
import { FilterLists } from './filter_lists';
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
import { I18nContext } from 'ui/i18n';
|
||||
|
||||
import { NavigationMenuContext } from '../../../util/context_utils';
|
||||
|
||||
const template = `
|
||||
<div class="euiSpacer euiSpacer--s" />
|
||||
<ml-filter-lists />
|
||||
|
@ -55,9 +50,7 @@ module.directive('mlFilterLists', function () {
|
|||
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }}>
|
||||
<FilterLists {...props} />
|
||||
</NavigationMenuContext.Provider>
|
||||
<FilterLists {...props} />
|
||||
</I18nContext>,
|
||||
element[0]
|
||||
);
|
||||
|
|
|
@ -22,14 +22,14 @@ import {
|
|||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { useNavigationMenuContext } from '../util/context_utils';
|
||||
import { useUiChromeContext } from '../contexts/ui/use_ui_chrome_context';
|
||||
import { NavigationMenu } from '../components/navigation_menu/navigation_menu';
|
||||
|
||||
export function Settings({
|
||||
canGetFilters,
|
||||
canGetCalendars
|
||||
}) {
|
||||
const basePath = useNavigationMenuContext().chrome.getBasePath();
|
||||
const basePath = useUiChromeContext().getBasePath();
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
|
|
@ -5,27 +5,18 @@
|
|||
*/
|
||||
|
||||
import { mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
import * as ContextUtils from '../util/context_utils';
|
||||
import { Settings } from './settings';
|
||||
|
||||
const navigationMenuMock = ContextUtils.navigationMenuMock;
|
||||
const mountOptions = {
|
||||
context: { NavigationMenuContext: navigationMenuMock },
|
||||
childContextTypes: { NavigationMenuContext: PropTypes.object }
|
||||
};
|
||||
|
||||
jest.mock('../contexts/ui/use_ui_chrome_context');
|
||||
jest.mock('../components/navigation_menu/navigation_menu', () => ({
|
||||
NavigationMenu: () => <div id="mockNavigationMenu" />
|
||||
NavigationMenu: () => <div id="mockNavigationMenu" />,
|
||||
}));
|
||||
jest.spyOn(ContextUtils, 'useNavigationMenuContext').mockImplementation(() => navigationMenuMock);
|
||||
|
||||
|
||||
describe('Settings', () => {
|
||||
test('Renders settings page with all buttons enabled.', () => {
|
||||
const wrapper = mountWithIntl(<Settings canGetFilters={true} canGetCalendars={true} />, mountOptions);
|
||||
const wrapper = mountWithIntl(<Settings canGetFilters={true} canGetCalendars={true} />);
|
||||
|
||||
const filterButton = wrapper
|
||||
.find('[data-test-subj="ml_filter_lists_button"]')
|
||||
|
@ -39,7 +30,7 @@ describe('Settings', () => {
|
|||
});
|
||||
|
||||
test('Filter Lists button disabled if canGetFilters is false', () => {
|
||||
const wrapper = mountWithIntl(<Settings canGetFilters={false} canGetCalendars={true} />, mountOptions);
|
||||
const wrapper = mountWithIntl(<Settings canGetFilters={false} canGetCalendars={true} />);
|
||||
|
||||
const filterButton = wrapper
|
||||
.find('[data-test-subj="ml_filter_lists_button"]')
|
||||
|
@ -53,7 +44,7 @@ describe('Settings', () => {
|
|||
});
|
||||
|
||||
test('Calendar management button disabled if canGetCalendars is false', () => {
|
||||
const wrapper = mountWithIntl(<Settings canGetFilters={true} canGetCalendars={false} />, mountOptions);
|
||||
const wrapper = mountWithIntl(<Settings canGetFilters={true} canGetCalendars={false} />);
|
||||
|
||||
const filterButton = wrapper
|
||||
.find('[data-test-subj="ml_filter_lists_button"]')
|
||||
|
|
|
@ -15,14 +15,11 @@ const module = uiModules.get('apps/ml', ['react']);
|
|||
import { checkFullLicense } from '../license/check_license';
|
||||
import { checkGetJobsPrivilege, checkPermission } from '../privilege/check_privilege';
|
||||
import { getMlNodeCount } from '../ml_nodes_check/check_ml_nodes';
|
||||
import { NavigationMenuContext } from '../util/context_utils';
|
||||
import { getSettingsBreadcrumbs } from './breadcrumbs';
|
||||
|
||||
import { I18nContext } from 'ui/i18n';
|
||||
import chrome from 'ui/chrome';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
|
||||
const template = `
|
||||
<div class="euiSpacer euiSpacer--s" />
|
||||
|
@ -58,9 +55,7 @@ module.directive('mlSettings', function () {
|
|||
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }} >
|
||||
<Settings canGetCalendars={canGetCalendars} canGetFilters={canGetFilters} />
|
||||
</NavigationMenuContext.Provider>
|
||||
<Settings canGetCalendars={canGetCalendars} canGetFilters={canGetFilters} />
|
||||
</I18nContext>,
|
||||
element[0]
|
||||
);
|
||||
|
|
|
@ -14,9 +14,7 @@ import ReactDOM from 'react-dom';
|
|||
import { uiModules } from 'ui/modules';
|
||||
const module = uiModules.get('apps/ml');
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { timeHistory } from 'ui/timefilter/time_history';
|
||||
import { I18nContext } from 'ui/i18n';
|
||||
|
||||
import '../components/controls';
|
||||
|
@ -24,7 +22,6 @@ import '../components/controls';
|
|||
import { severity$ } from '../components/controls/select_severity/select_severity';
|
||||
import { interval$ } from '../components/controls/select_interval/select_interval';
|
||||
import { subscribeAppStateToObservable } from '../util/app_state_utils';
|
||||
import { NavigationMenuContext } from '../util/context_utils';
|
||||
|
||||
import { TimeSeriesExplorer } from './timeseriesexplorer';
|
||||
import { APP_STATE_ACTION } from './timeseriesexplorer_constants';
|
||||
|
@ -88,15 +85,13 @@ module.directive('mlTimeSeriesExplorer', function ($injector) {
|
|||
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
<NavigationMenuContext.Provider value={{ chrome, timefilter, timeHistory }}>
|
||||
<TimeSeriesExplorer {...{
|
||||
appStateHandler,
|
||||
dateFormatTz,
|
||||
globalState,
|
||||
timefilter,
|
||||
}}
|
||||
/>
|
||||
</NavigationMenuContext.Provider>
|
||||
<TimeSeriesExplorer {...{
|
||||
appStateHandler,
|
||||
dateFormatTz,
|
||||
globalState,
|
||||
timefilter,
|
||||
}}
|
||||
/>
|
||||
</I18nContext>,
|
||||
$element[0]
|
||||
);
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { useContext } from 'react';
|
||||
|
||||
import { Chrome } from 'ui/chrome';
|
||||
import { Timefilter } from 'ui/timefilter';
|
||||
import { TimeHistory } from 'ui/timefilter/time_history';
|
||||
|
||||
export const ChromeContext = React.createContext<Chrome>({} as Chrome);
|
||||
export const TimefilterContext = React.createContext<Timefilter>({} as Timefilter);
|
||||
export const TimeHistoryContext = React.createContext<TimeHistory>({} as TimeHistory);
|
||||
|
||||
interface NavigationMenuContextValue {
|
||||
chrome: Chrome;
|
||||
timefilter: Timefilter;
|
||||
timeHistory: TimeHistory;
|
||||
}
|
||||
export const NavigationMenuContext = React.createContext<NavigationMenuContextValue>({
|
||||
chrome: {} as Chrome,
|
||||
timefilter: {} as Timefilter,
|
||||
timeHistory: {} as TimeHistory,
|
||||
});
|
||||
|
||||
export const useNavigationMenuContext = () => {
|
||||
return useContext(NavigationMenuContext);
|
||||
};
|
||||
|
||||
// testing mocks
|
||||
export const chromeMock = {
|
||||
getBasePath: () => 'basePath',
|
||||
getUiSettingsClient: () => {
|
||||
return {
|
||||
get: (key: string) => {
|
||||
switch (key) {
|
||||
case 'dateFormat':
|
||||
case 'timepicker:timeDefaults':
|
||||
return {};
|
||||
case 'timepicker:refreshIntervalDefaults':
|
||||
return { pause: false, value: 0 };
|
||||
default:
|
||||
throw new Error(`Unexpected config key: ${key}`);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
} as Chrome;
|
||||
|
||||
export const timefilterMock = ({
|
||||
getRefreshInterval: () => '30s',
|
||||
getTime: () => ({ from: 0, to: 0 }),
|
||||
on: (event: string, reload: () => void) => {},
|
||||
} as unknown) as Timefilter;
|
||||
|
||||
export const timeHistoryMock = ({
|
||||
get: () => [{ from: 0, to: 0 }],
|
||||
} as unknown) as TimeHistory;
|
||||
|
||||
export const navigationMenuMock = {
|
||||
chrome: chromeMock,
|
||||
timefilter: timefilterMock,
|
||||
timeHistory: timeHistoryMock,
|
||||
};
|
|
@ -6023,7 +6023,7 @@
|
|||
"xpack.ml.dataframe.stepCreateForm.transformListCardTitle": "データフレームジョブ",
|
||||
"xpack.ml.dataframe.stepCreateForm.progressErrorMessage": "進捗パーセンテージの取得中にエラーが発生しました: {error}",
|
||||
"xpack.ml.dataframe.stepCreateForm.progressTitle": "進捗",
|
||||
"xpack.ml.dataframe.stepCreateForm.reateIndexPatternSuccessMessage": "Kibana インデックスパターン {indexPatternName} が作成されました",
|
||||
"xpack.ml.dataframe.stepCreateForm.createIndexPatternSuccessMessage": "Kibana インデックスパターン {indexPatternName} が作成されました",
|
||||
"xpack.ml.dataframe.stepCreateForm.startDataFrameButton": "開始",
|
||||
"xpack.ml.dataframe.stepCreateForm.startDataFrameDescription": "データフレームジョブを開始します。データフレームジョブは、クラスターの検索とインデックスによる負荷を増やします。過剰な負荷が生じた場合はジョブを停止してください。ジョブの開始後、データフレームジョブの閲覧を続けるオプションが提供されます。",
|
||||
"xpack.ml.dataframe.stepCreateForm.startTransformErrorMessage": "データフレームジョブ {transformId} の開始中にエラーが発生しました: {error}",
|
||||
|
|
|
@ -6166,7 +6166,7 @@
|
|||
"xpack.ml.dataframe.stepCreateForm.transformListCardTitle": "数据帧作业",
|
||||
"xpack.ml.dataframe.stepCreateForm.progressErrorMessage": "获取进度百分比时出错:{error}",
|
||||
"xpack.ml.dataframe.stepCreateForm.progressTitle": "进度",
|
||||
"xpack.ml.dataframe.stepCreateForm.reateIndexPatternSuccessMessage": "Kibana 索引模式 {indexPatternName} 成功创建。",
|
||||
"xpack.ml.dataframe.stepCreateForm.createIndexPatternSuccessMessage": "Kibana 索引模式 {indexPatternName} 成功创建。",
|
||||
"xpack.ml.dataframe.stepCreateForm.startDataFrameButton": "开始",
|
||||
"xpack.ml.dataframe.stepCreateForm.startDataFrameDescription": "启动数据帧作业。数据帧作业将增加集群的搜索和索引负荷。如果负荷超载,请停止作业。作业启动后,系统将为您提供继续浏览数据帧作业的选项。",
|
||||
"xpack.ml.dataframe.stepCreateForm.startTransformErrorMessage": "启动数据帧作业 {transformId} 时发生错误:{error}",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue