mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[ML] Client side cut over (#60100)
* [ML] Client side cut over * updating paths and commented code * changes based on review * disabling telemetry tests * fixing start job stylesheets * fixing everything that is broken * fixing types and ml icon order * using icon constant
This commit is contained in:
parent
54f55f66a6
commit
35302ed273
1286 changed files with 572 additions and 712 deletions
|
@ -142,7 +142,7 @@ module.exports = {
|
|||
},
|
||||
},
|
||||
{
|
||||
files: ['x-pack/legacy/plugins/ml/**/*.{js,ts,tsx}'],
|
||||
files: ['x-pack/plugins/ml/**/*.{js,ts,tsx}'],
|
||||
rules: {
|
||||
'react-hooks/exhaustive-deps': 'off',
|
||||
},
|
||||
|
|
|
@ -9,7 +9,6 @@ import { graph } from './legacy/plugins/graph';
|
|||
import { monitoring } from './legacy/plugins/monitoring';
|
||||
import { reporting } from './legacy/plugins/reporting';
|
||||
import { security } from './legacy/plugins/security';
|
||||
import { ml } from './legacy/plugins/ml';
|
||||
import { tilemap } from './legacy/plugins/tilemap';
|
||||
import { grokdebugger } from './legacy/plugins/grokdebugger';
|
||||
import { dashboardMode } from './legacy/plugins/dashboard_mode';
|
||||
|
@ -45,7 +44,6 @@ module.exports = function(kibana) {
|
|||
reporting(kibana),
|
||||
spaces(kibana),
|
||||
security(kibana),
|
||||
ml(kibana),
|
||||
tilemap(kibana),
|
||||
grokdebugger(kibana),
|
||||
dashboardMode(kibana),
|
||||
|
|
|
@ -1,57 +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 { resolve } from 'path';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Server } from 'src/legacy/server/kbn_server';
|
||||
import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/utils';
|
||||
// @ts-ignore: could not find declaration file for module
|
||||
import { mirrorPluginStatus } from '../../server/lib/mirror_plugin_status';
|
||||
// @ts-ignore: importing JSON file
|
||||
import mappings from './mappings';
|
||||
|
||||
export const ml = (kibana: any) => {
|
||||
return new kibana.Plugin({
|
||||
require: ['kibana', 'elasticsearch', 'xpack_main'],
|
||||
id: 'ml',
|
||||
configPrefix: 'xpack.ml',
|
||||
publicDir: resolve(__dirname, 'public'),
|
||||
|
||||
uiExports: {
|
||||
managementSections: ['plugins/ml/application/management'],
|
||||
app: {
|
||||
title: i18n.translate('xpack.ml.mlNavTitle', {
|
||||
defaultMessage: 'Machine Learning',
|
||||
}),
|
||||
description: i18n.translate('xpack.ml.mlNavDescription', {
|
||||
defaultMessage: 'Machine Learning for the Elastic Stack',
|
||||
}),
|
||||
icon: 'plugins/ml/application/ml.svg',
|
||||
euiIconType: 'machineLearningApp',
|
||||
main: 'plugins/ml/legacy',
|
||||
category: DEFAULT_APP_CATEGORIES.analyze,
|
||||
},
|
||||
styleSheetPaths: resolve(__dirname, 'public/application/index.scss'),
|
||||
savedObjectSchemas: {
|
||||
'ml-telemetry': {
|
||||
isNamespaceAgnostic: true,
|
||||
},
|
||||
},
|
||||
mappings,
|
||||
home: ['plugins/ml/register_feature'],
|
||||
injectDefaultVars(server: any) {
|
||||
const config = server.config();
|
||||
return {
|
||||
mlEnabled: config.get('xpack.ml.enabled'),
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
async init(server: Server) {
|
||||
mirrorPluginStatus(server.plugins.xpack_main, this);
|
||||
},
|
||||
});
|
||||
};
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"baseUrl": "../../../.",
|
||||
"paths": {
|
||||
"ui/*": [
|
||||
"src/legacy/ui/public/*"
|
||||
],
|
||||
"plugins/ml/*": [
|
||||
"x-pack/legacy/plugins/ml/public/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"build"
|
||||
]
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
@import 'time_range_selector/index';
|
|
@ -1 +0,0 @@
|
|||
@import 'time_range_selector';
|
|
@ -1,84 +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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 { npSetup, npStart } from 'ui/new_platform';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import chrome from 'ui/chrome';
|
||||
import { metadata } from 'ui/metadata';
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
import { ManagementSetup } from '../../../../../../../src/plugins/management/public';
|
||||
|
||||
import {
|
||||
LicensingPluginSetup,
|
||||
LICENSE_CHECK_STATE,
|
||||
} from '../../../../../../plugins/licensing/public';
|
||||
|
||||
import { PLUGIN_ID } from '../../../common/constants/app';
|
||||
import { MINIMUM_FULL_LICENSE } from '../../../common/license';
|
||||
|
||||
import { setDependencyCache } from '../util/dependency_cache';
|
||||
|
||||
import { getJobsListBreadcrumbs } from './breadcrumbs';
|
||||
import { renderApp } from './jobs_list';
|
||||
|
||||
type PluginsSetupExtended = typeof npSetup.plugins & {
|
||||
// adds licensing which isn't in the PluginsSetup interface, but does exist
|
||||
licensing: LicensingPluginSetup;
|
||||
};
|
||||
|
||||
const plugins = npSetup.plugins as PluginsSetupExtended;
|
||||
// only need to register once
|
||||
const licensing = plugins.licensing.license$.pipe(take(1));
|
||||
licensing.subscribe(license => {
|
||||
if (license.check(PLUGIN_ID, MINIMUM_FULL_LICENSE).state === LICENSE_CHECK_STATE.Valid) {
|
||||
initManagementSection(plugins.management);
|
||||
}
|
||||
});
|
||||
function initManagementSection(management: ManagementSetup) {
|
||||
const legacyBasePath = {
|
||||
prepend: chrome.addBasePath,
|
||||
get: chrome.getBasePath,
|
||||
remove: () => {},
|
||||
};
|
||||
const legacyDocLinks = {
|
||||
ELASTIC_WEBSITE_URL: 'https://www.elastic.co/',
|
||||
DOC_LINK_VERSION: metadata.branch,
|
||||
};
|
||||
|
||||
setDependencyCache({
|
||||
docLinks: legacyDocLinks as any,
|
||||
basePath: legacyBasePath as any,
|
||||
http: npStart.core.http,
|
||||
});
|
||||
|
||||
const mlSection = management.sections.register({
|
||||
id: 'ml',
|
||||
title: i18n.translate('xpack.ml.management.mlTitle', {
|
||||
defaultMessage: 'Machine Learning',
|
||||
}),
|
||||
order: 100,
|
||||
icon: 'machineLearningApp',
|
||||
});
|
||||
|
||||
mlSection.registerApp({
|
||||
id: 'jobsListLink',
|
||||
title: i18n.translate('xpack.ml.management.jobsListTitle', {
|
||||
defaultMessage: 'Jobs list',
|
||||
}),
|
||||
order: 10,
|
||||
async mount({ element, setBreadcrumbs }) {
|
||||
setBreadcrumbs(getJobsListBreadcrumbs());
|
||||
return renderApp(element, {});
|
||||
},
|
||||
});
|
||||
}
|
|
@ -1,29 +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 { npSetup, npStart } from 'ui/new_platform';
|
||||
import { PluginInitializerContext } from 'kibana/public';
|
||||
import { SecurityPluginSetup } from '../../../../plugins/security/public';
|
||||
import { LicensingPluginSetup } from '../../../../plugins/licensing/public';
|
||||
|
||||
import { plugin } from '.';
|
||||
|
||||
const pluginInstance = plugin({} as PluginInitializerContext);
|
||||
|
||||
type PluginsSetupExtended = typeof npSetup.plugins & {
|
||||
// adds plugins which aren't in the PluginsSetup interface, but do exist
|
||||
security: SecurityPluginSetup;
|
||||
licensing: LicensingPluginSetup;
|
||||
};
|
||||
|
||||
const setupDependencies = npSetup.plugins as PluginsSetupExtended;
|
||||
|
||||
export const setup = pluginInstance.setup(npSetup.core, {
|
||||
data: npStart.plugins.data,
|
||||
security: setupDependencies.security,
|
||||
licensing: setupDependencies.licensing,
|
||||
});
|
||||
export const start = pluginInstance.start(npStart.core, npStart.plugins);
|
|
@ -1,40 +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 { Plugin, CoreStart, CoreSetup } from 'kibana/public';
|
||||
import { MlDependencies } from './application/app';
|
||||
|
||||
export class MlPlugin implements Plugin<Setup, Start> {
|
||||
setup(core: CoreSetup, { data, security, licensing }: MlDependencies) {
|
||||
core.application.register({
|
||||
id: 'ml',
|
||||
title: 'Machine learning',
|
||||
async mount(context, params) {
|
||||
const [coreStart, depsStart] = await core.getStartServices();
|
||||
const { renderApp: renderMlApp } = await import('./application/app');
|
||||
return renderMlApp(coreStart, depsStart, {
|
||||
element: params.element,
|
||||
appBasePath: params.appBasePath,
|
||||
onAppLeave: params.onAppLeave,
|
||||
history: params.history,
|
||||
data,
|
||||
security,
|
||||
licensing,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
start(core: CoreStart, deps: any) {
|
||||
return {};
|
||||
}
|
||||
public stop() {}
|
||||
}
|
||||
|
||||
export type Setup = ReturnType<MlPlugin['setup']>;
|
||||
export type Start = ReturnType<MlPlugin['start']>;
|
|
@ -1,28 +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 { npSetup } from 'ui/new_platform';
|
||||
import { FeatureCatalogueCategory } from '../../../../../src/plugins/home/public';
|
||||
|
||||
npSetup.plugins.home.featureCatalogue.register({
|
||||
id: 'ml',
|
||||
title: i18n.translate('xpack.ml.machineLearningTitle', {
|
||||
defaultMessage: 'Machine Learning',
|
||||
}),
|
||||
description: i18n.translate('xpack.ml.machineLearningDescription', {
|
||||
defaultMessage:
|
||||
'Automatically model the normal behavior of your time series data to detect anomalies.',
|
||||
}),
|
||||
icon: 'machineLearningApp',
|
||||
path: '/app/ml',
|
||||
showOnHomePage: true,
|
||||
category: FeatureCatalogueCategory.DATA,
|
||||
});
|
||||
|
||||
npSetup.plugins.home.environment.update({
|
||||
ml: npSetup.core.injectedMetadata.getInjectedVar('mlEnabled') as boolean,
|
||||
});
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.json"
|
||||
}
|
|
@ -5,3 +5,4 @@
|
|||
*/
|
||||
|
||||
export const PLUGIN_ID = 'ml';
|
||||
export const PLUGIN_ICON = 'machineLearningApp';
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { ILicense, LICENSE_CHECK_STATE } from '../../../../../plugins/licensing/common/types';
|
||||
import { ILicense, LICENSE_CHECK_STATE } from '../../../licensing/common/types';
|
||||
import { PLUGIN_ID } from '../constants/app';
|
||||
|
||||
export const MINIMUM_LICENSE = 'basic';
|
|
@ -4,13 +4,13 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { ES_FIELD_TYPES } from '../../../../../../src/plugins/data/common';
|
||||
import { ES_FIELD_TYPES } from '../../../../../src/plugins/data/common';
|
||||
import {
|
||||
ML_JOB_AGGREGATION,
|
||||
KIBANA_AGGREGATION,
|
||||
ES_AGGREGATION,
|
||||
} from '../../common/constants/aggregation_types';
|
||||
import { MLCATEGORY } from '../../common/constants/field_types';
|
||||
} from '../constants/aggregation_types';
|
||||
import { MLCATEGORY } from '../constants/field_types';
|
||||
|
||||
export const EVENT_RATE_FIELD_ID = '__ml_event_rate_count__';
|
||||
export const METRIC_AGG_TYPE = 'metrics';
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { SavedObjectAttributes } from 'kibana/public';
|
||||
import { Datafeed, Job } from '../types/anomaly_detection_jobs';
|
||||
import { Datafeed, Job } from './anomaly_detection_jobs';
|
||||
|
||||
export interface ModuleJob {
|
||||
id: string;
|
|
@ -11,7 +11,7 @@ import numeral from '@elastic/numeral';
|
|||
import { ALLOWED_DATA_UNITS, JOB_ID_MAX_LENGTH } from '../constants/validation';
|
||||
import { parseInterval } from './parse_interval';
|
||||
import { maxLengthValidator } from './validators';
|
||||
import { CREATED_BY_LABEL } from '../../common/constants/new_job';
|
||||
import { CREATED_BY_LABEL } from '../constants/new_job';
|
||||
|
||||
// work out the default frequency based on the bucket_span in seconds
|
||||
export function calculateDatafeedFrequencyDefaultSeconds(bucketSpanSeconds) {
|
12
x-pack/plugins/ml/jsconfig.json
Normal file
12
x-pack/plugins/ml/jsconfig.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"baseUrl": "../../../.",
|
||||
"paths": {
|
||||
"ui/*": ["src/legacy/ui/public/*"],
|
||||
"plugins/ml/*": ["x-pack/plugins/ml/public/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "build"]
|
||||
}
|
|
@ -1,10 +1,24 @@
|
|||
{
|
||||
"id": "ml",
|
||||
"version": "0.0.1",
|
||||
"version": "8.0.0",
|
||||
"kibanaVersion": "kibana",
|
||||
"configPath": ["ml"],
|
||||
"requiredPlugins": ["cloud", "features", "home", "licensing", "usageCollection"],
|
||||
"optionalPlugins": ["security", "spaces"],
|
||||
"configPath": [
|
||||
"xpack",
|
||||
"ml"
|
||||
],
|
||||
"requiredPlugins": [
|
||||
"data",
|
||||
"cloud",
|
||||
"features",
|
||||
"home",
|
||||
"licensing",
|
||||
"usageCollection"
|
||||
],
|
||||
"optionalPlugins": [
|
||||
"security",
|
||||
"spaces",
|
||||
"management"
|
||||
],
|
||||
"server": true,
|
||||
"ui": false
|
||||
"ui": true
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
// Protect the rest of Kibana from ML generic namespacing
|
||||
// SASSTODO: Prefix ml selectors instead
|
||||
#ml-app {
|
||||
.ml-app {
|
||||
// App level
|
||||
@import 'app';
|
||||
|
|
@ -7,32 +7,24 @@
|
|||
import React, { FC } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
// needed to make syntax highlighting work in ace editors
|
||||
import 'ace';
|
||||
import { AppMountParameters, CoreStart } from 'kibana/public';
|
||||
|
||||
import { DataPublicPluginStart } from 'src/plugins/data/public';
|
||||
import { SecurityPluginSetup } from '../../../../../plugins/security/public';
|
||||
import { LicensingPluginSetup } from '../../../../../plugins/licensing/public';
|
||||
|
||||
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public';
|
||||
import { setDependencyCache, clearCache } from './util/dependency_cache';
|
||||
import { setLicenseCache } from './license';
|
||||
import { MlSetupDependencies, MlStartDependencies } from '../plugin';
|
||||
|
||||
import { MlRouter } from './routing';
|
||||
|
||||
export interface MlDependencies extends AppMountParameters {
|
||||
data: DataPublicPluginStart;
|
||||
security: SecurityPluginSetup;
|
||||
licensing: LicensingPluginSetup;
|
||||
}
|
||||
type MlDependencies = MlSetupDependencies & MlStartDependencies;
|
||||
|
||||
interface AppProps {
|
||||
coreStart: CoreStart;
|
||||
deps: MlDependencies;
|
||||
appMountParams: AppMountParameters;
|
||||
}
|
||||
|
||||
const App: FC<AppProps> = ({ coreStart, deps }) => {
|
||||
const App: FC<AppProps> = ({ coreStart, deps, appMountParams }) => {
|
||||
setDependencyCache({
|
||||
indexPatterns: deps.data.indexPatterns,
|
||||
timefilter: deps.data.query.timefilter,
|
||||
|
@ -53,7 +45,7 @@ const App: FC<AppProps> = ({ coreStart, deps }) => {
|
|||
|
||||
const mlLicense = setLicenseCache(deps.licensing);
|
||||
|
||||
deps.onAppLeave(actions => {
|
||||
appMountParams.onAppLeave(actions => {
|
||||
mlLicense.unsubscribe();
|
||||
clearCache();
|
||||
return actions.default();
|
||||
|
@ -82,8 +74,15 @@ const App: FC<AppProps> = ({ coreStart, deps }) => {
|
|||
);
|
||||
};
|
||||
|
||||
export const renderApp = (coreStart: CoreStart, depsStart: object, deps: MlDependencies) => {
|
||||
ReactDOM.render(<App coreStart={coreStart} deps={deps} />, deps.element);
|
||||
export const renderApp = (
|
||||
coreStart: CoreStart,
|
||||
deps: MlDependencies,
|
||||
appMountParams: AppMountParameters
|
||||
) => {
|
||||
ReactDOM.render(
|
||||
<App coreStart={coreStart} deps={deps} appMountParams={appMountParams} />,
|
||||
appMountParams.element
|
||||
);
|
||||
|
||||
return () => ReactDOM.unmountComponentAtNode(deps.element);
|
||||
return () => ReactDOM.unmountComponentAtNode(appMountParams.element);
|
||||
};
|
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