mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[ML] Transforms: Migrate client plugin to NP. (#59443)
Migrates the client side plugin of transforms to NP. - Gets rid of the last parts of the shim (http, documentation links) - Moves the plugin from x-pack/legacy/plugins/transform/public to x-pack/plugins/transform - Creates a custom mock for appDependencies based on NP services - Fixes jest tests to get rid of all act() related warnings
This commit is contained in:
parent
708d92a00e
commit
f4f956dfeb
217 changed files with 456 additions and 650 deletions
|
@ -39,7 +39,7 @@
|
|||
"xpack.snapshotRestore": "plugins/snapshot_restore",
|
||||
"xpack.spaces": ["legacy/plugins/spaces", "plugins/spaces"],
|
||||
"xpack.taskManager": "legacy/plugins/task_manager",
|
||||
"xpack.transform": ["legacy/plugins/transform", "plugins/transform"],
|
||||
"xpack.transform": "plugins/transform",
|
||||
"xpack.triggersActionsUI": "plugins/triggers_actions_ui",
|
||||
"xpack.upgradeAssistant": "plugins/upgrade_assistant",
|
||||
"xpack.uptime": "legacy/plugins/uptime",
|
||||
|
|
|
@ -4,19 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { PLUGIN } from './common/constants';
|
||||
|
||||
export function transform(kibana: any) {
|
||||
return new kibana.Plugin({
|
||||
id: PLUGIN.ID,
|
||||
id: 'transform',
|
||||
configPrefix: 'xpack.transform',
|
||||
publicDir: resolve(__dirname, 'public'),
|
||||
require: ['kibana', 'elasticsearch', 'xpack_main'],
|
||||
uiExports: {
|
||||
styleSheetPaths: resolve(__dirname, 'public/app/index.scss'),
|
||||
managementSections: ['plugins/transform'],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,102 +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 { useAppDependencies } from '../app_dependencies';
|
||||
import { PreviewRequestBody, TransformId } from '../common';
|
||||
import { httpFactory, Http } from '../services/http_service';
|
||||
|
||||
import { EsIndex, TransformEndpointRequest, TransformEndpointResult } from './use_api_types';
|
||||
|
||||
const apiFactory = (basePath: string, indicesBasePath: string, http: Http) => ({
|
||||
getTransforms(transformId?: TransformId): Promise<any> {
|
||||
const transformIdString = transformId !== undefined ? `/${transformId}` : '';
|
||||
return http({
|
||||
url: `${basePath}/transforms${transformIdString}`,
|
||||
method: 'GET',
|
||||
});
|
||||
},
|
||||
getTransformsStats(transformId?: TransformId): Promise<any> {
|
||||
if (transformId !== undefined) {
|
||||
return http({
|
||||
url: `${basePath}/transforms/${transformId}/_stats`,
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
|
||||
return http({
|
||||
url: `${basePath}/transforms/_stats`,
|
||||
method: 'GET',
|
||||
});
|
||||
},
|
||||
createTransform(transformId: TransformId, transformConfig: any): Promise<any> {
|
||||
return http({
|
||||
url: `${basePath}/transforms/${transformId}`,
|
||||
method: 'PUT',
|
||||
data: transformConfig,
|
||||
});
|
||||
},
|
||||
deleteTransforms(transformsInfo: TransformEndpointRequest[]) {
|
||||
return http({
|
||||
url: `${basePath}/delete_transforms`,
|
||||
method: 'POST',
|
||||
data: transformsInfo,
|
||||
}) as Promise<TransformEndpointResult>;
|
||||
},
|
||||
getTransformsPreview(obj: PreviewRequestBody): Promise<any> {
|
||||
return http({
|
||||
url: `${basePath}/transforms/_preview`,
|
||||
method: 'POST',
|
||||
data: obj,
|
||||
});
|
||||
},
|
||||
startTransforms(transformsInfo: TransformEndpointRequest[]) {
|
||||
return http({
|
||||
url: `${basePath}/start_transforms`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
transformsInfo,
|
||||
},
|
||||
}) as Promise<TransformEndpointResult>;
|
||||
},
|
||||
stopTransforms(transformsInfo: TransformEndpointRequest[]) {
|
||||
return http({
|
||||
url: `${basePath}/stop_transforms`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
transformsInfo,
|
||||
},
|
||||
}) as Promise<TransformEndpointResult>;
|
||||
},
|
||||
getTransformAuditMessages(transformId: TransformId): Promise<any> {
|
||||
return http({
|
||||
url: `${basePath}/transforms/${transformId}/messages`,
|
||||
method: 'GET',
|
||||
});
|
||||
},
|
||||
esSearch(payload: any) {
|
||||
return http({
|
||||
url: `${basePath}/es_search`,
|
||||
method: 'POST',
|
||||
data: payload,
|
||||
}) as Promise<any>;
|
||||
},
|
||||
getIndices() {
|
||||
return http({
|
||||
url: `${indicesBasePath}/index_management/indices`,
|
||||
method: 'GET',
|
||||
}) as Promise<EsIndex[]>;
|
||||
},
|
||||
});
|
||||
|
||||
export const useApi = () => {
|
||||
const appDeps = useAppDependencies();
|
||||
|
||||
const basePath = '/api/transform';
|
||||
const indicesBasePath = '/api';
|
||||
const http = httpFactory(appDeps.core.http);
|
||||
|
||||
return apiFactory(basePath, indicesBasePath, http);
|
||||
};
|
|
@ -1,25 +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 { TransformId, TRANSFORM_STATE } from '../common';
|
||||
|
||||
export interface EsIndex {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface TransformEndpointRequest {
|
||||
id: TransformId;
|
||||
state?: TRANSFORM_STATE;
|
||||
}
|
||||
|
||||
export interface ResultData {
|
||||
success: boolean;
|
||||
error?: any;
|
||||
}
|
||||
|
||||
export interface TransformEndpointResult {
|
||||
[key: string]: ResultData;
|
||||
}
|
|
@ -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, { FC } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
import { SimpleQuery } from '../../../../common';
|
||||
import {
|
||||
SOURCE_INDEX_STATUS,
|
||||
useSourceIndexData,
|
||||
UseSourceIndexDataReturnType,
|
||||
} from './use_source_index_data';
|
||||
|
||||
jest.mock('../../../../hooks/use_api');
|
||||
|
||||
type Callback = () => void;
|
||||
interface TestHookProps {
|
||||
callback: Callback;
|
||||
}
|
||||
|
||||
const TestHook: FC<TestHookProps> = ({ callback }) => {
|
||||
callback();
|
||||
return null;
|
||||
};
|
||||
|
||||
const testHook = (callback: Callback) => {
|
||||
const container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
act(() => {
|
||||
ReactDOM.render(<TestHook callback={callback} />, container);
|
||||
});
|
||||
};
|
||||
|
||||
const query: SimpleQuery = {
|
||||
query_string: {
|
||||
query: '*',
|
||||
default_operator: 'AND',
|
||||
},
|
||||
};
|
||||
|
||||
let sourceIndexObj: UseSourceIndexDataReturnType;
|
||||
|
||||
describe('useSourceIndexData', () => {
|
||||
test('indexPattern set triggers loading', () => {
|
||||
testHook(() => {
|
||||
act(() => {
|
||||
sourceIndexObj = useSourceIndexData(
|
||||
{ id: 'the-id', title: 'the-title', fields: [] },
|
||||
query,
|
||||
{ pageIndex: 0, pageSize: 10 }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
expect(sourceIndexObj.errorMessage).toBe('');
|
||||
expect(sourceIndexObj.status).toBe(SOURCE_INDEX_STATUS.LOADING);
|
||||
expect(sourceIndexObj.tableItems).toEqual([]);
|
||||
});
|
||||
|
||||
// TODO add more tests to check data retrieved via `api.esSearch()`.
|
||||
// This needs more investigation in regards to jest/enzyme's React Hooks support.
|
||||
});
|
|
@ -1,51 +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 { HttpSetup } from 'kibana/public';
|
||||
// service for interacting with the server
|
||||
import { Dictionary } from '../../../common/types/common';
|
||||
|
||||
export type Http = (options: Dictionary<any>) => Promise<unknown>;
|
||||
|
||||
export function httpFactory(httpSetup: HttpSetup) {
|
||||
return function http(options: Dictionary<any>) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (options && options.url) {
|
||||
let url = '';
|
||||
url = url + (options.url || '');
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers,
|
||||
};
|
||||
|
||||
const allHeaders =
|
||||
options.headers === undefined ? headers : { ...options.headers, ...headers };
|
||||
const body = options.data === undefined ? null : JSON.stringify(options.data);
|
||||
|
||||
const payload: Dictionary<any> = {
|
||||
method: options.method || 'GET',
|
||||
headers: allHeaders,
|
||||
credentials: 'same-origin',
|
||||
};
|
||||
|
||||
if (body !== null) {
|
||||
payload.body = body;
|
||||
}
|
||||
|
||||
httpSetup
|
||||
.fetch(url, payload)
|
||||
.then(resp => {
|
||||
resolve(resp);
|
||||
})
|
||||
.catch(resp => {
|
||||
reject(resp);
|
||||
});
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
|
@ -1,25 +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 { UIM_APP_NAME } from '../../constants';
|
||||
import {
|
||||
createUiStatsReporter,
|
||||
METRIC_TYPE,
|
||||
} from '../../../../../../../../src/legacy/core_plugins/ui_metric/public';
|
||||
|
||||
class UiMetricService {
|
||||
track?: ReturnType<typeof createUiStatsReporter>;
|
||||
|
||||
public init = (getReporter: typeof createUiStatsReporter): void => {
|
||||
this.track = getReporter(UIM_APP_NAME);
|
||||
};
|
||||
|
||||
public trackUiMetric = (eventName: string): void => {
|
||||
if (!this.track) throw Error('UiMetricService not initialized.');
|
||||
return this.track(METRIC_TYPE.COUNT, eventName);
|
||||
};
|
||||
}
|
||||
|
||||
export const uiMetricService = new UiMetricService();
|
|
@ -1,80 +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 { i18n } from '@kbn/i18n';
|
||||
import { renderApp } from './app/app';
|
||||
import { ShimCore, ShimPlugins } from './shim';
|
||||
|
||||
import { breadcrumbService } from './app/services/navigation';
|
||||
import { docTitleService } from './app/services/navigation';
|
||||
import { textService } from './app/services/text';
|
||||
import { uiMetricService } from './app/services/ui_metric';
|
||||
|
||||
export class Plugin {
|
||||
public start(core: ShimCore, plugins: ShimPlugins): void {
|
||||
const {
|
||||
http,
|
||||
chrome,
|
||||
documentation,
|
||||
docLinks,
|
||||
docTitle,
|
||||
injectedMetadata,
|
||||
notifications,
|
||||
uiSettings,
|
||||
savedObjects,
|
||||
overlays,
|
||||
} = core;
|
||||
const { data, management, uiMetric } = plugins;
|
||||
|
||||
// AppCore/AppPlugins to be passed on as React context
|
||||
const appDependencies = {
|
||||
core: {
|
||||
chrome,
|
||||
documentation,
|
||||
docLinks,
|
||||
http,
|
||||
i18n: core.i18n,
|
||||
injectedMetadata,
|
||||
notifications,
|
||||
uiSettings,
|
||||
savedObjects,
|
||||
overlays,
|
||||
},
|
||||
plugins: {
|
||||
data,
|
||||
management,
|
||||
},
|
||||
};
|
||||
|
||||
// Register management section
|
||||
const esSection = management.sections.getSection('elasticsearch');
|
||||
if (esSection !== undefined) {
|
||||
esSection.registerApp({
|
||||
id: 'transform',
|
||||
title: i18n.translate('xpack.transform.appTitle', {
|
||||
defaultMessage: 'Transforms',
|
||||
}),
|
||||
order: 3,
|
||||
mount(params) {
|
||||
breadcrumbService.setup(params.setBreadcrumbs);
|
||||
params.setBreadcrumbs([
|
||||
{
|
||||
text: i18n.translate('xpack.transform.breadcrumbsTitle', {
|
||||
defaultMessage: 'Transforms',
|
||||
}),
|
||||
},
|
||||
]);
|
||||
|
||||
return renderApp(params.element, appDependencies);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize services
|
||||
textService.init();
|
||||
uiMetricService.init(uiMetric.createUiStatsReporter);
|
||||
docTitleService.init(docTitle.change);
|
||||
}
|
||||
}
|
|
@ -1,91 +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 { npStart } from 'ui/new_platform';
|
||||
|
||||
import { docTitle } from 'ui/doc_title/doc_title';
|
||||
|
||||
// @ts-ignore: allow traversal to fail on x-pack build
|
||||
import { createUiStatsReporter } from '../../../../../src/legacy/core_plugins/ui_metric/public';
|
||||
|
||||
import { TRANSFORM_DOC_PATHS } from './app/constants';
|
||||
|
||||
export type NpCore = typeof npStart.core;
|
||||
export type NpPlugins = typeof npStart.plugins;
|
||||
|
||||
// AppCore/AppPlugins is the set of core features/plugins
|
||||
// we pass on via context/hooks to the app and its components.
|
||||
export type AppCore = Pick<
|
||||
ShimCore,
|
||||
| 'chrome'
|
||||
| 'documentation'
|
||||
| 'docLinks'
|
||||
| 'http'
|
||||
| 'i18n'
|
||||
| 'injectedMetadata'
|
||||
| 'savedObjects'
|
||||
| 'uiSettings'
|
||||
| 'overlays'
|
||||
| 'notifications'
|
||||
>;
|
||||
export type AppPlugins = Pick<ShimPlugins, 'data' | 'management'>;
|
||||
|
||||
export interface AppDependencies {
|
||||
core: AppCore;
|
||||
plugins: AppPlugins;
|
||||
}
|
||||
|
||||
export interface ShimCore extends NpCore {
|
||||
documentation: Record<
|
||||
| 'esDocBasePath'
|
||||
| 'esIndicesCreateIndex'
|
||||
| 'esPluginDocBasePath'
|
||||
| 'esQueryDsl'
|
||||
| 'esStackOverviewDocBasePath'
|
||||
| 'esTransform'
|
||||
| 'esTransformPivot'
|
||||
| 'mlDocBasePath',
|
||||
string
|
||||
>;
|
||||
docTitle: {
|
||||
change: typeof docTitle.change;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ShimPlugins extends NpPlugins {
|
||||
uiMetric: {
|
||||
createUiStatsReporter: typeof createUiStatsReporter;
|
||||
};
|
||||
}
|
||||
|
||||
export function createPublicShim(): { core: ShimCore; plugins: ShimPlugins } {
|
||||
const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = npStart.core.docLinks;
|
||||
|
||||
return {
|
||||
core: {
|
||||
...npStart.core,
|
||||
documentation: {
|
||||
esDocBasePath: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/`,
|
||||
esIndicesCreateIndex: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/indices-create-index.html#indices-create-index`,
|
||||
esPluginDocBasePath: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/plugins/${DOC_LINK_VERSION}/`,
|
||||
esQueryDsl: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/query-dsl.html`,
|
||||
esStackOverviewDocBasePath: `${ELASTIC_WEBSITE_URL}guide/en/elastic-stack-overview/${DOC_LINK_VERSION}/`,
|
||||
esTransform: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/${TRANSFORM_DOC_PATHS.transforms}`,
|
||||
esTransformPivot: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/put-transform.html#put-transform-request-body`,
|
||||
mlDocBasePath: `${ELASTIC_WEBSITE_URL}guide/en/machine-learning/${DOC_LINK_VERSION}/`,
|
||||
},
|
||||
docTitle: {
|
||||
change: docTitle.change,
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
...npStart.plugins,
|
||||
uiMetric: {
|
||||
createUiStatsReporter,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { LICENSE_TYPE_BASIC, LicenseType } from '../../../common/constants';
|
||||
import { LICENSE_TYPE_BASIC, LicenseType } from '../../../legacy/common/constants';
|
||||
|
||||
export const DEFAULT_REFRESH_INTERVAL_MS = 30000;
|
||||
export const MINIMUM_REFRESH_INTERVAL_MS = 1000;
|
40
x-pack/plugins/transform/common/index.ts
Normal file
40
x-pack/plugins/transform/common/index.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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 interface MissingPrivileges {
|
||||
[key: string]: string[] | undefined;
|
||||
}
|
||||
|
||||
export interface Privileges {
|
||||
hasAllPrivileges: boolean;
|
||||
missingPrivileges: MissingPrivileges;
|
||||
}
|
||||
|
||||
export type TransformId = string;
|
||||
|
||||
// reflects https://github.com/elastic/elasticsearch/blob/master/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/dataframe/transforms/DataFrameTransformStats.java#L243
|
||||
export enum TRANSFORM_STATE {
|
||||
ABORTING = 'aborting',
|
||||
FAILED = 'failed',
|
||||
INDEXING = 'indexing',
|
||||
STARTED = 'started',
|
||||
STOPPED = 'stopped',
|
||||
STOPPING = 'stopping',
|
||||
}
|
||||
|
||||
export interface TransformEndpointRequest {
|
||||
id: TransformId;
|
||||
state?: TRANSFORM_STATE;
|
||||
}
|
||||
|
||||
export interface ResultData {
|
||||
success: boolean;
|
||||
error?: any;
|
||||
}
|
||||
|
||||
export interface TransformEndpointResult {
|
||||
[key: string]: ResultData;
|
||||
}
|
|
@ -2,13 +2,15 @@
|
|||
"id": "transform",
|
||||
"version": "kibana",
|
||||
"server": true,
|
||||
"ui": false,
|
||||
"ui": true,
|
||||
"requiredPlugins": [
|
||||
"data",
|
||||
"home",
|
||||
"licensing",
|
||||
"management"
|
||||
],
|
||||
"optionalPlugins": [
|
||||
"security",
|
||||
"usageCollection"
|
||||
],
|
||||
"configPath": ["xpack", "transform"]
|
||||
|
|
|
@ -14,6 +14,6 @@ export const useRequest = jest.fn(() => ({
|
|||
error: null,
|
||||
data: undefined,
|
||||
}));
|
||||
export { mlInMemoryTableBasicFactory } from '../../../ml/public/application/components/ml_in_memory_table';
|
||||
export { mlInMemoryTableBasicFactory } from '../../../../legacy/plugins/ml/public/application/components/ml_in_memory_table';
|
||||
export const SORT_DIRECTION = { ASC: 'asc' };
|
||||
export const KqlFilterBar = jest.fn(() => null);
|
|
@ -14,7 +14,7 @@ import { SectionError } from './components';
|
|||
import { CLIENT_BASE_PATH, SECTION_SLUG } from './constants';
|
||||
import { getAppProviders } from './app_dependencies';
|
||||
import { AuthorizationContext } from './lib/authorization';
|
||||
import { AppDependencies } from '../shim';
|
||||
import { AppDependencies } from './app_dependencies';
|
||||
|
||||
import { CloneTransformSection } from './sections/clone_transform';
|
||||
import { CreateTransformSection } from './sections/create_transform';
|
28
x-pack/plugins/transform/public/app/app_dependencies.mock.ts
Normal file
28
x-pack/plugins/transform/public/app/app_dependencies.mock.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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 { coreMock } from '../../../../../src/core/public/mocks';
|
||||
import { dataPluginMock } from '../../../../../src/plugins/data/public/mocks';
|
||||
|
||||
import { getAppProviders, AppDependencies } from './app_dependencies';
|
||||
|
||||
const coreSetup = coreMock.createSetup();
|
||||
const coreStart = coreMock.createStart();
|
||||
const dataStart = dataPluginMock.createStartContract();
|
||||
|
||||
const appDependencies: AppDependencies = {
|
||||
chrome: coreStart.chrome,
|
||||
data: dataStart,
|
||||
docLinks: coreStart.docLinks,
|
||||
i18n: coreStart.i18n,
|
||||
notifications: coreStart.notifications,
|
||||
uiSettings: coreStart.uiSettings,
|
||||
savedObjects: coreStart.savedObjects,
|
||||
overlays: coreStart.overlays,
|
||||
http: coreSetup.http,
|
||||
};
|
||||
|
||||
export const Providers = getAppProviders(appDependencies);
|
|
@ -7,25 +7,39 @@
|
|||
import React, { createContext, useContext, ReactNode } from 'react';
|
||||
import { HashRouter } from 'react-router-dom';
|
||||
|
||||
import { CoreSetup, CoreStart } from 'src/core/public';
|
||||
import { DataPublicPluginStart } from 'src/plugins/data/public';
|
||||
|
||||
import { API_BASE_PATH } from '../../common/constants';
|
||||
|
||||
import { setDependencyCache } from '../shared_imports';
|
||||
import { AppDependencies } from '../shim';
|
||||
|
||||
import { AuthorizationProvider } from './lib/authorization';
|
||||
|
||||
export interface AppDependencies {
|
||||
chrome: CoreStart['chrome'];
|
||||
data: DataPublicPluginStart;
|
||||
docLinks: CoreStart['docLinks'];
|
||||
http: CoreSetup['http'];
|
||||
i18n: CoreStart['i18n'];
|
||||
notifications: CoreStart['notifications'];
|
||||
uiSettings: CoreStart['uiSettings'];
|
||||
savedObjects: CoreStart['savedObjects'];
|
||||
overlays: CoreStart['overlays'];
|
||||
}
|
||||
|
||||
let DependenciesContext: React.Context<AppDependencies>;
|
||||
|
||||
const setAppDependencies = (deps: AppDependencies) => {
|
||||
const legacyBasePath = {
|
||||
prepend: deps.core.http.basePath.prepend,
|
||||
get: deps.core.http.basePath.get,
|
||||
prepend: deps.http.basePath.prepend,
|
||||
get: deps.http.basePath.get,
|
||||
remove: () => {},
|
||||
};
|
||||
|
||||
setDependencyCache({
|
||||
autocomplete: deps.plugins.data.autocomplete,
|
||||
docLinks: deps.core.docLinks,
|
||||
autocomplete: deps.data.autocomplete,
|
||||
docLinks: deps.docLinks,
|
||||
basePath: legacyBasePath as any,
|
||||
});
|
||||
DependenciesContext = createContext<AppDependencies>(deps);
|
||||
|
@ -40,24 +54,15 @@ export const useAppDependencies = () => {
|
|||
return useContext<AppDependencies>(DependenciesContext);
|
||||
};
|
||||
|
||||
export const useDocumentationLinks = () => {
|
||||
const {
|
||||
core: { documentation },
|
||||
} = useAppDependencies();
|
||||
return documentation;
|
||||
};
|
||||
|
||||
export const useToastNotifications = () => {
|
||||
const {
|
||||
core: {
|
||||
notifications: { toasts: toastNotifications },
|
||||
},
|
||||
notifications: { toasts: toastNotifications },
|
||||
} = useAppDependencies();
|
||||
return toastNotifications;
|
||||
};
|
||||
|
||||
export const getAppProviders = (deps: AppDependencies) => {
|
||||
const I18nContext = deps.core.i18n.Context;
|
||||
const I18nContext = deps.i18n.Context;
|
||||
|
||||
// Create App dependencies context and get its provider
|
||||
const AppDependenciesProvider = setAppDependencies(deps);
|
|
@ -4,7 +4,10 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { composeValidators, patternValidator } from '../../../../ml/common/util/validators';
|
||||
import {
|
||||
composeValidators,
|
||||
patternValidator,
|
||||
} from '../../../../../legacy/plugins/ml/common/util/validators';
|
||||
|
||||
export type AggName = string;
|
||||
|
|
@ -22,7 +22,6 @@ export {
|
|||
useRefreshTransformList,
|
||||
CreateRequestBody,
|
||||
PreviewRequestBody,
|
||||
TransformId,
|
||||
TransformPivotConfig,
|
||||
IndexName,
|
||||
IndexPattern,
|
||||
|
@ -35,7 +34,6 @@ export {
|
|||
isTransformStats,
|
||||
TransformStats,
|
||||
TRANSFORM_MODE,
|
||||
TRANSFORM_STATE,
|
||||
} from './transform_stats';
|
||||
export { getDiscoverUrl } from './navigation';
|
||||
export {
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { Dictionary } from '../../../common/types/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../../src/plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../src/plugins/data/common';
|
||||
|
||||
import { AggName } from './aggregations';
|
||||
import { EsFieldName } from './fields';
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { Dictionary } from '../../../common/types/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../../src/plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../src/plugins/data/common';
|
||||
|
||||
import { AggName } from './aggregations';
|
||||
import { EsFieldName } from './fields';
|
|
@ -12,7 +12,7 @@ import { SavedSearchQuery } from '../hooks/use_search_items';
|
|||
import { StepDefineExposedState } from '../sections/create_transform/components/step_define/step_define_form';
|
||||
import { StepDetailsExposedState } from '../sections/create_transform/components/step_details/step_details_form';
|
||||
|
||||
import { IndexPattern } from '../../../../../../../src/plugins/data/public';
|
||||
import { IndexPattern } from '../../../../../../src/plugins/data/public';
|
||||
|
||||
import {
|
||||
getEsAggFromAggConfig,
|
|
@ -9,12 +9,13 @@ import { BehaviorSubject } from 'rxjs';
|
|||
import { filter, distinctUntilChanged } from 'rxjs/operators';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import { TransformId } from '../../../common';
|
||||
|
||||
import { PivotAggDict } from './pivot_aggs';
|
||||
import { PivotGroupByDict } from './pivot_group_by';
|
||||
|
||||
export type IndexName = string;
|
||||
export type IndexPattern = string;
|
||||
export type TransformId = string;
|
||||
|
||||
// Transform name must contain lowercase alphanumeric (a-z and 0-9), hyphens or underscores;
|
||||
// It must also start and end with an alphanumeric character.
|
|
@ -4,7 +4,8 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { TransformId, TransformPivotConfig } from './transform';
|
||||
import { TransformId } from '../../../common';
|
||||
import { TransformPivotConfig } from './transform';
|
||||
import { TransformStats } from './transform_stats';
|
||||
|
||||
// Used to pass on attribute names to table columns
|
|
@ -4,18 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { TransformId } from './transform';
|
||||
import { TransformListRow } from './transform_list';
|
||||
import { TransformId, TRANSFORM_STATE } from '../../../common';
|
||||
|
||||
// reflects https://github.com/elastic/elasticsearch/blob/master/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/dataframe/transforms/DataFrameTransformStats.java#L243
|
||||
export enum TRANSFORM_STATE {
|
||||
ABORTING = 'aborting',
|
||||
FAILED = 'failed',
|
||||
INDEXING = 'indexing',
|
||||
STARTED = 'started',
|
||||
STOPPED = 'stopped',
|
||||
STOPPING = 'stopping',
|
||||
}
|
||||
import { TransformListRow } from './transform_list';
|
||||
|
||||
export enum TRANSFORM_MODE {
|
||||
BATCH = 'batch',
|
|
@ -7,8 +7,7 @@
|
|||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { createPublicShim } from '../../shim';
|
||||
import { getAppProviders } from '../app_dependencies';
|
||||
import { Providers } from '../app_dependencies.mock';
|
||||
|
||||
import { ToastNotificationText } from './toast_notification_text';
|
||||
|
||||
|
@ -17,7 +16,6 @@ jest.mock('ui/new_platform');
|
|||
|
||||
describe('ToastNotificationText', () => {
|
||||
test('should render the text as plain text', () => {
|
||||
const Providers = getAppProviders(createPublicShim());
|
||||
const props = {
|
||||
text: 'a short text message',
|
||||
};
|
||||
|
@ -30,7 +28,6 @@ describe('ToastNotificationText', () => {
|
|||
});
|
||||
|
||||
test('should render the text within a modal', () => {
|
||||
const Providers = getAppProviders(createPublicShim());
|
||||
const props = {
|
||||
text:
|
||||
'a text message that is longer than 140 characters. a text message that is longer than 140 characters. a text message that is longer than 140 characters. ',
|
|
@ -18,16 +18,14 @@ import {
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { toMountPoint } from '../../../../../../../src/plugins/kibana_react/public';
|
||||
import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public';
|
||||
|
||||
import { useAppDependencies } from '../app_dependencies';
|
||||
|
||||
const MAX_SIMPLE_MESSAGE_LENGTH = 140;
|
||||
|
||||
export const ToastNotificationText: FC<{ text: any }> = ({ text }) => {
|
||||
const {
|
||||
core: { overlays },
|
||||
} = useAppDependencies();
|
||||
const { overlays } = useAppDependencies();
|
||||
|
||||
if (typeof text === 'string' && text.length <= MAX_SIMPLE_MESSAGE_LENGTH) {
|
||||
return text;
|
|
@ -4,9 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { PreviewRequestBody, TransformId } from '../../common';
|
||||
import { TransformId, TransformEndpointRequest } from '../../../../common';
|
||||
|
||||
import { TransformEndpointRequest } from '../use_api_types';
|
||||
import { PreviewRequestBody } from '../../common';
|
||||
|
||||
const apiFactory = () => ({
|
||||
getTransforms(transformId?: TransformId): Promise<any> {
|
63
x-pack/plugins/transform/public/app/hooks/use_api.ts
Normal file
63
x-pack/plugins/transform/public/app/hooks/use_api.ts
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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 { TransformId, TransformEndpointRequest, TransformEndpointResult } from '../../../common';
|
||||
import { API_BASE_PATH } from '../../../common/constants';
|
||||
|
||||
import { useAppDependencies } from '../app_dependencies';
|
||||
import { PreviewRequestBody } from '../common';
|
||||
|
||||
import { EsIndex } from './use_api_types';
|
||||
|
||||
export const useApi = () => {
|
||||
const { http } = useAppDependencies();
|
||||
|
||||
return {
|
||||
getTransforms(transformId?: TransformId): Promise<any> {
|
||||
const transformIdString = transformId !== undefined ? `/${transformId}` : '';
|
||||
return http.get(`${API_BASE_PATH}transforms${transformIdString}`);
|
||||
},
|
||||
getTransformsStats(transformId?: TransformId): Promise<any> {
|
||||
if (transformId !== undefined) {
|
||||
return http.get(`${API_BASE_PATH}transforms/${transformId}/_stats`);
|
||||
}
|
||||
|
||||
return http.get(`${API_BASE_PATH}transforms/_stats`);
|
||||
},
|
||||
createTransform(transformId: TransformId, transformConfig: any): Promise<any> {
|
||||
return http.put(`${API_BASE_PATH}transforms/${transformId}`, {
|
||||
body: JSON.stringify(transformConfig),
|
||||
});
|
||||
},
|
||||
deleteTransforms(transformsInfo: TransformEndpointRequest[]): Promise<TransformEndpointResult> {
|
||||
return http.post(`${API_BASE_PATH}delete_transforms`, {
|
||||
body: JSON.stringify(transformsInfo),
|
||||
});
|
||||
},
|
||||
getTransformsPreview(obj: PreviewRequestBody): Promise<any> {
|
||||
return http.post(`${API_BASE_PATH}transforms/_preview`, { body: JSON.stringify(obj) });
|
||||
},
|
||||
startTransforms(transformsInfo: TransformEndpointRequest[]): Promise<TransformEndpointResult> {
|
||||
return http.post(`${API_BASE_PATH}start_transforms`, {
|
||||
body: JSON.stringify(transformsInfo),
|
||||
});
|
||||
},
|
||||
stopTransforms(transformsInfo: TransformEndpointRequest[]): Promise<TransformEndpointResult> {
|
||||
return http.post(`${API_BASE_PATH}stop_transforms`, {
|
||||
body: JSON.stringify(transformsInfo),
|
||||
});
|
||||
},
|
||||
getTransformAuditMessages(transformId: TransformId): Promise<any> {
|
||||
return http.get(`${API_BASE_PATH}transforms/${transformId}/messages`);
|
||||
},
|
||||
esSearch(payload: any): Promise<any> {
|
||||
return http.post(`${API_BASE_PATH}es_search`, { body: JSON.stringify(payload) });
|
||||
},
|
||||
getIndices(): Promise<EsIndex[]> {
|
||||
return http.get(`/api/index_management/indices`);
|
||||
},
|
||||
};
|
||||
};
|
|
@ -3,4 +3,7 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
export { uiMetricService } from './ui_metric';
|
||||
|
||||
export interface EsIndex {
|
||||
name: string;
|
||||
}
|
|
@ -7,14 +7,15 @@
|
|||
import React from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { toMountPoint } from '../../../../../../../src/plugins/kibana_react/public';
|
||||
import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public';
|
||||
|
||||
import { TransformEndpointRequest, TransformEndpointResult } from '../../../common';
|
||||
|
||||
import { useToastNotifications } from '../app_dependencies';
|
||||
import { TransformListRow, refreshTransformList$, REFRESH_TRANSFORM_LIST_STATE } from '../common';
|
||||
import { ToastNotificationText } from '../components';
|
||||
|
||||
import { useApi } from './use_api';
|
||||
import { TransformEndpointRequest, TransformEndpointResult } from './use_api_types';
|
||||
|
||||
export const useDeleteTransforms = () => {
|
||||
const toastNotifications = useToastNotifications();
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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 { useAppDependencies } from '../app_dependencies';
|
||||
|
||||
import { TRANSFORM_DOC_PATHS } from '../constants';
|
||||
|
||||
export const useDocumentationLinks = () => {
|
||||
const deps = useAppDependencies();
|
||||
const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = deps.docLinks;
|
||||
return {
|
||||
esDocBasePath: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/`,
|
||||
esIndicesCreateIndex: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/indices-create-index.html#indices-create-index`,
|
||||
esPluginDocBasePath: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/plugins/${DOC_LINK_VERSION}/`,
|
||||
esQueryDsl: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/query-dsl.html`,
|
||||
esStackOverviewDocBasePath: `${ELASTIC_WEBSITE_URL}guide/en/elastic-stack-overview/${DOC_LINK_VERSION}/`,
|
||||
esTransform: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/${TRANSFORM_DOC_PATHS.transforms}`,
|
||||
esTransformPivot: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/put-transform.html#put-transform-request-body`,
|
||||
mlDocBasePath: `${ELASTIC_WEBSITE_URL}guide/en/machine-learning/${DOC_LINK_VERSION}/`,
|
||||
};
|
||||
};
|
|
@ -9,8 +9,6 @@ import { UseRequestConfig, useRequest as _useRequest } from '../../shared_import
|
|||
import { useAppDependencies } from '../app_dependencies';
|
||||
|
||||
export const useRequest = (config: UseRequestConfig) => {
|
||||
const {
|
||||
core: { http },
|
||||
} = useAppDependencies();
|
||||
const { http } = useAppDependencies();
|
||||
return _useRequest(http, config);
|
||||
};
|
|
@ -10,7 +10,7 @@ import {
|
|||
esQuery,
|
||||
IndexPatternsContract,
|
||||
IndexPatternAttributes,
|
||||
} from '../../../../../../../../src/plugins/data/public';
|
||||
} from '../../../../../../../src/plugins/data/public';
|
||||
|
||||
import { matchAllQuery } from '../../common';
|
||||
|
|
@ -23,14 +23,14 @@ export const useSearchItems = (defaultSavedObjectId: string | undefined) => {
|
|||
const [savedObjectId, setSavedObjectId] = useState(defaultSavedObjectId);
|
||||
|
||||
const appDeps = useAppDependencies();
|
||||
const indexPatterns = appDeps.plugins.data.indexPatterns;
|
||||
const uiSettings = appDeps.core.uiSettings;
|
||||
const savedObjectsClient = appDeps.core.savedObjects.client;
|
||||
const indexPatterns = appDeps.data.indexPatterns;
|
||||
const uiSettings = appDeps.uiSettings;
|
||||
const savedObjectsClient = appDeps.savedObjects.client;
|
||||
const savedSearches = createSavedSearchesLoader({
|
||||
savedObjectsClient,
|
||||
indexPatterns,
|
||||
chrome: appDeps.core.chrome,
|
||||
overlays: appDeps.core.overlays,
|
||||
chrome: appDeps.chrome,
|
||||
overlays: appDeps.overlays,
|
||||
});
|
||||
|
||||
const [searchItems, setSearchItems] = useState<SearchItems | undefined>(undefined);
|
|
@ -6,11 +6,12 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { TransformEndpointRequest, TransformEndpointResult } from '../../../common';
|
||||
|
||||
import { useToastNotifications } from '../app_dependencies';
|
||||
import { TransformListRow, refreshTransformList$, REFRESH_TRANSFORM_LIST_STATE } from '../common';
|
||||
|
||||
import { useApi } from './use_api';
|
||||
import { TransformEndpointRequest, TransformEndpointResult } from './use_api_types';
|
||||
|
||||
export const useStartTransforms = () => {
|
||||
const toastNotifications = useToastNotifications();
|
|
@ -6,11 +6,12 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { TransformEndpointRequest, TransformEndpointResult } from '../../../common';
|
||||
|
||||
import { useToastNotifications } from '../app_dependencies';
|
||||
import { TransformListRow, refreshTransformList$, REFRESH_TRANSFORM_LIST_STATE } from '../common';
|
||||
|
||||
import { useApi } from './use_api';
|
||||
import { TransformEndpointRequest, TransformEndpointResult } from './use_api_types';
|
||||
|
||||
export const useStopTransforms = () => {
|
||||
const toastNotifications = useToastNotifications();
|
|
@ -5,8 +5,12 @@
|
|||
*/
|
||||
|
||||
import React, { createContext } from 'react';
|
||||
|
||||
import { Privileges } from '../../../../../common';
|
||||
|
||||
import { useRequest } from '../../../hooks';
|
||||
import { hasPrivilegeFactory, Capabilities, Privileges } from './common';
|
||||
|
||||
import { hasPrivilegeFactory, Capabilities } from './common';
|
||||
|
||||
interface Authorization {
|
||||
isLoading: boolean;
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { Privileges } from '../../../../../common';
|
||||
|
||||
export interface Capabilities {
|
||||
canGetTransform: boolean;
|
||||
canDeleteTransform: boolean;
|
||||
|
@ -16,11 +18,6 @@ export interface Capabilities {
|
|||
|
||||
export type Privilege = [string, string];
|
||||
|
||||
export interface Privileges {
|
||||
hasAllPrivileges: boolean;
|
||||
missingPrivileges: MissingPrivileges;
|
||||
}
|
||||
|
||||
function isPrivileges(arg: any): arg is Privileges {
|
||||
return (
|
||||
typeof arg === 'object' &&
|
||||
|
@ -33,9 +30,6 @@ function isPrivileges(arg: any): arg is Privileges {
|
|||
);
|
||||
}
|
||||
|
||||
export interface MissingPrivileges {
|
||||
[key: string]: string[] | undefined;
|
||||
}
|
||||
export const toArray = (value: string | string[]): string[] =>
|
||||
Array.isArray(value) ? value : [value];
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export { createCapabilityFailureMessage, Privileges } from './common';
|
||||
export { createCapabilityFailureMessage } from './common';
|
||||
export { AuthorizationProvider, AuthorizationContext } from './authorization_provider';
|
||||
export { PrivilegesWrapper } from './with_privileges';
|
||||
export { NotAuthorizedSection } from './not_authorized_section';
|
|
@ -10,11 +10,13 @@ import { EuiPageContent } from '@elastic/eui';
|
|||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { MissingPrivileges } from '../../../../../common';
|
||||
|
||||
import { SectionLoading } from '../../../components';
|
||||
|
||||
import { AuthorizationContext } from './authorization_provider';
|
||||
import { NotAuthorizedSection } from './not_authorized_section';
|
||||
import { hasPrivilegeFactory, toArray, MissingPrivileges, Privilege } from './common';
|
||||
import { hasPrivilegeFactory, toArray, Privilege } from './common';
|
||||
|
||||
interface Props {
|
||||
/**
|
|
@ -22,11 +22,12 @@ import {
|
|||
} from '@elastic/eui';
|
||||
|
||||
import { useApi } from '../../hooks/use_api';
|
||||
import { useDocumentationLinks } from '../../hooks/use_documentation_links';
|
||||
import { useSearchItems } from '../../hooks/use_search_items';
|
||||
|
||||
import { APP_CREATE_TRANSFORM_CLUSTER_PRIVILEGES } from '../../../../common/constants';
|
||||
|
||||
import { useAppDependencies, useDocumentationLinks } from '../../app_dependencies';
|
||||
import { useAppDependencies } from '../../app_dependencies';
|
||||
import { TransformPivotConfig } from '../../common';
|
||||
import { breadcrumbService, docTitleService, BREADCRUMB_SECTION } from '../../services/navigation';
|
||||
import { PrivilegesWrapper } from '../../lib/authorization';
|
||||
|
@ -65,8 +66,8 @@ export const CloneTransformSection: FC<Props> = ({ match }) => {
|
|||
const api = useApi();
|
||||
|
||||
const appDeps = useAppDependencies();
|
||||
const savedObjectsClient = appDeps.core.savedObjects.client;
|
||||
const indexPatterns = appDeps.plugins.data.indexPatterns;
|
||||
const savedObjectsClient = appDeps.savedObjects.client;
|
||||
const indexPatterns = appDeps.data.indexPatterns;
|
||||
|
||||
const { esTransform } = useDocumentationLinks();
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue