[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:
James Gowdy 2020-03-13 19:16:41 +00:00 committed by GitHub
parent 54f55f66a6
commit 35302ed273
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
1286 changed files with 572 additions and 712 deletions

View file

@ -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',
},

View file

@ -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),

View file

@ -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);
},
});
};

View file

@ -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"
]
}

View file

@ -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, {});
},
});
}

View file

@ -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);

View file

@ -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']>;

View file

@ -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,
});

View file

@ -1,3 +0,0 @@
{
"extends": "../../../tsconfig.json"
}

View file

@ -5,3 +5,4 @@
*/
export const PLUGIN_ID = 'ml';
export const PLUGIN_ICON = 'machineLearningApp';

View file

@ -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';

View file

@ -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';

View file

@ -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;

View file

@ -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) {

View 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"]
}

View file

@ -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
}

View file

@ -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';

View file

@ -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