) {
+ this.factory = factory;
+ }
+
+ start(
+ coreSetup: CoreSetup,
+ coreStart: CoreStart,
+ canvasSetupPlugins: CanvasSetupDeps,
+ canvasStartPlugins: CanvasStartDeps
+ ) {
+ this.service = this.factory(coreSetup, coreStart, canvasSetupPlugins, canvasStartPlugins);
+ }
+
+ getService(): Service {
+ if (!this.service) {
+ throw new Error('Service not ready');
+ }
+
+ return this.service;
+ }
+
+ stop() {
+ this.service = undefined;
+ }
+}
+
+export type ServiceFromProvider = P extends CanvasServiceProvider ? T : never;
+
+export const services = {
+ notify: new CanvasServiceProvider(notifyServiceFactory),
+};
+
+export interface CanvasServices {
+ notify: ServiceFromProvider;
+}
+
+export const startServices = (
+ coreSetup: CoreSetup,
+ coreStart: CoreStart,
+ canvasSetupPlugins: CanvasSetupDeps,
+ canvasStartPlugins: CanvasStartDeps
+) => {
+ Object.entries(services).forEach(([key, provider]) =>
+ provider.start(coreSetup, coreStart, canvasSetupPlugins, canvasStartPlugins)
+ );
+};
+
+export const stopServices = () => {
+ Object.entries(services).forEach(([key, provider]) => provider.stop());
+};
+
+export const { notify: notifyService } = services;
diff --git a/x-pack/legacy/plugins/canvas/public/services/notify.ts b/x-pack/legacy/plugins/canvas/public/services/notify.ts
new file mode 100644
index 0000000000000..3e18e2178a818
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/public/services/notify.ts
@@ -0,0 +1,57 @@
+/*
+ * 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 { get } from 'lodash';
+import { CanvasServiceFactory } from '.';
+import { formatMsg } from '../../../../../../src/plugins/kibana_legacy/public';
+import { ToastInputFields } from '../../../../../../src/core/public';
+
+const getToast = (err: Error | string, opts: ToastInputFields = {}) => {
+ const errData = (get(err, 'response') || err) as Error | string;
+ const errMsg = formatMsg(errData);
+ const { title, ...rest } = opts;
+ let text;
+
+ if (title) {
+ text = errMsg;
+ }
+
+ return {
+ ...rest,
+ title: title || errMsg,
+ text,
+ };
+};
+
+interface NotifyService {
+ error: (err: string | Error, opts?: ToastInputFields) => void;
+ warning: (err: string | Error, opts?: ToastInputFields) => void;
+ info: (err: string | Error, opts?: ToastInputFields) => void;
+ success: (err: string | Error, opts?: ToastInputFields) => void;
+}
+
+export const notifyServiceFactory: CanvasServiceFactory = (setup, start) => {
+ const toasts = start.notifications.toasts;
+
+ return {
+ /*
+ * @param {(string | Object)} err: message or Error object
+ * @param {Object} opts: option to override toast title or icon, see https://github.com/elastic/kibana/blob/master/src/legacy/ui/public/notify/toasts/TOAST_NOTIFICATIONS.md
+ */
+ error(err, opts) {
+ toasts.addDanger(getToast(err, opts));
+ },
+ warning(err, opts) {
+ toasts.addWarning(getToast(err, opts));
+ },
+ info(err, opts) {
+ toasts.add(getToast(err, opts));
+ },
+ success(err, opts) {
+ toasts.addSuccess(getToast(err, opts));
+ },
+ };
+};
diff --git a/x-pack/legacy/plugins/canvas/public/state/actions/elements.js b/x-pack/legacy/plugins/canvas/public/state/actions/elements.js
index 1798aaab22f06..f4a3393b8962d 100644
--- a/x-pack/legacy/plugins/canvas/public/state/actions/elements.js
+++ b/x-pack/legacy/plugins/canvas/public/state/actions/elements.js
@@ -13,9 +13,9 @@ import { getPages, getNodeById, getNodes, getSelectedPageIndex } from '../select
import { getValue as getResolvedArgsValue } from '../selectors/resolved_args';
import { getDefaultElement } from '../defaults';
import { ErrorStrings } from '../../../i18n';
-import { notify } from '../../lib/notify';
import { runInterpreter, interpretAst } from '../../lib/run_interpreter';
import { subMultitree } from '../../lib/aeroelastic/functional';
+import { services } from '../../services';
import { selectToplevelNodes } from './transient';
import * as args from './resolved_args';
@@ -134,7 +134,7 @@ const fetchRenderableWithContextFn = ({ dispatch }, element, ast, context) => {
dispatch(getAction(renderable));
})
.catch(err => {
- notify.error(err);
+ services.notify.getService().error(err);
dispatch(getAction(err));
});
};
@@ -176,7 +176,7 @@ export const fetchAllRenderables = createThunk(
return runInterpreter(ast, null, { castToRender: true })
.then(renderable => ({ path: argumentPath, value: renderable }))
.catch(err => {
- notify.error(err);
+ services.notify.getService().error(err);
return { path: argumentPath, value: err };
});
});
@@ -293,7 +293,7 @@ const setAst = createThunk('setAst', ({ dispatch }, ast, element, pageId, doRend
const expression = toExpression(ast);
dispatch(setExpression(expression, element.id, pageId, doRender));
} catch (err) {
- notify.error(err);
+ services.notify.getService().error(err);
// TODO: remove this, may have been added just to cause a re-render, but why?
dispatch(setExpression(element.expression, element.id, pageId, doRender));
diff --git a/x-pack/legacy/plugins/canvas/public/state/middleware/es_persist.js b/x-pack/legacy/plugins/canvas/public/state/middleware/es_persist.js
index bcbfc3544981a..a197cdf893244 100644
--- a/x-pack/legacy/plugins/canvas/public/state/middleware/es_persist.js
+++ b/x-pack/legacy/plugins/canvas/public/state/middleware/es_persist.js
@@ -14,7 +14,7 @@ import { setAssets, resetAssets } from '../actions/assets';
import * as transientActions from '../actions/transient';
import * as resolvedArgsActions from '../actions/resolved_args';
import { update, updateAssets, updateWorkpad } from '../../lib/workpad_service';
-import { notify } from '../../lib/notify';
+import { services } from '../../services';
import { canUserWrite } from '../selectors/app';
const { esPersist: strings } = ErrorStrings;
@@ -62,15 +62,15 @@ export const esPersistMiddleware = ({ getState }) => {
const statusCode = err.response && err.response.status;
switch (statusCode) {
case 400:
- return notify.error(err.response, {
+ return services.notify.getService().error(err.response, {
title: strings.getSaveFailureTitle(),
});
case 413:
- return notify.error(strings.getTooLargeErrorMessage(), {
+ return services.notify.getService().error(strings.getTooLargeErrorMessage(), {
title: strings.getSaveFailureTitle(),
});
default:
- return notify.error(err, {
+ return services.notify.getService().error(err, {
title: strings.getUpdateFailureTitle(),
});
}
diff --git a/x-pack/legacy/plugins/canvas/shareable_runtime/api/index.ts b/x-pack/legacy/plugins/canvas/shareable_runtime/api/index.ts
index b05379df6b0b1..0780ab46cd873 100644
--- a/x-pack/legacy/plugins/canvas/shareable_runtime/api/index.ts
+++ b/x-pack/legacy/plugins/canvas/shareable_runtime/api/index.ts
@@ -4,7 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import 'core-js/stable';
+import 'regenerator-runtime/runtime';
import 'whatwg-fetch';
-import 'babel-polyfill';
export * from './shareable';
diff --git a/x-pack/legacy/plugins/graph/index.ts b/x-pack/legacy/plugins/graph/index.ts
deleted file mode 100644
index 5c7f8fa46c18b..0000000000000
--- a/x-pack/legacy/plugins/graph/index.ts
+++ /dev/null
@@ -1,32 +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.
- */
-
-// @ts-ignore
-import migrations from './migrations';
-import mappings from './mappings.json';
-import { LegacyPluginInitializer } from '../../../../src/legacy/plugin_discovery/types';
-
-export const graph: LegacyPluginInitializer = kibana => {
- return new kibana.Plugin({
- id: 'graph',
- configPrefix: 'xpack.graph',
- require: ['kibana', 'elasticsearch', 'xpack_main'],
- uiExports: {
- mappings,
- migrations,
- },
-
- config(Joi: any) {
- return Joi.object({
- enabled: Joi.boolean().default(true),
- canEditDrillDownUrls: Joi.boolean().default(true),
- savePolicy: Joi.string()
- .valid(['config', 'configAndDataWithConsent', 'configAndData', 'none'])
- .default('configAndData'),
- }).default();
- },
- });
-};
diff --git a/x-pack/legacy/plugins/graph/mappings.json b/x-pack/legacy/plugins/graph/mappings.json
deleted file mode 100644
index f1950c459eee5..0000000000000
--- a/x-pack/legacy/plugins/graph/mappings.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "graph-workspace": {
- "properties": {
- "description": {
- "type": "text"
- },
- "kibanaSavedObjectMeta": {
- "properties": {
- "searchSourceJSON": {
- "type": "text"
- }
- }
- },
- "numLinks": {
- "type": "integer"
- },
- "numVertices": {
- "type": "integer"
- },
- "title": {
- "type": "text"
- },
- "version": {
- "type": "integer"
- },
- "wsState": {
- "type": "text"
- }
- }
- }
-}
diff --git a/x-pack/legacy/plugins/graph/migrations.js b/x-pack/legacy/plugins/graph/migrations.js
deleted file mode 100644
index 0cefe6217b45d..0000000000000
--- a/x-pack/legacy/plugins/graph/migrations.js
+++ /dev/null
@@ -1,41 +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 { get } from 'lodash';
-
-export default {
- 'graph-workspace': {
- '7.0.0': doc => {
- // Set new "references" attribute
- doc.references = doc.references || [];
- // Migrate index pattern
- const wsState = get(doc, 'attributes.wsState');
- if (typeof wsState !== 'string') {
- return doc;
- }
- let state;
- try {
- state = JSON.parse(JSON.parse(wsState));
- } catch (e) {
- // Let it go, the data is invalid and we'll leave it as is
- return doc;
- }
- const { indexPattern } = state;
- if (!indexPattern) {
- return doc;
- }
- state.indexPatternRefName = 'indexPattern_0';
- delete state.indexPattern;
- doc.attributes.wsState = JSON.stringify(JSON.stringify(state));
- doc.references.push({
- name: 'indexPattern_0',
- type: 'index-pattern',
- id: indexPattern,
- });
- return doc;
- },
- },
-};
diff --git a/x-pack/legacy/plugins/graph/migrations.test.js b/x-pack/legacy/plugins/graph/migrations.test.js
deleted file mode 100644
index 93162d94857ce..0000000000000
--- a/x-pack/legacy/plugins/graph/migrations.test.js
+++ /dev/null
@@ -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 migrations from './migrations';
-
-describe('graph-workspace', () => {
- describe('7.0.0', () => {
- const migration = migrations['graph-workspace']['7.0.0'];
-
- test('returns doc on empty object', () => {
- expect(migration({})).toMatchInlineSnapshot(`
-Object {
- "references": Array [],
-}
-`);
- });
-
- test('returns doc when wsState is not a string', () => {
- const doc = {
- id: '1',
- attributes: {
- wsState: true,
- },
- };
- expect(migration(doc)).toMatchInlineSnapshot(`
-Object {
- "attributes": Object {
- "wsState": true,
- },
- "id": "1",
- "references": Array [],
-}
-`);
- });
-
- test('returns doc when wsState is not valid JSON', () => {
- const doc = {
- id: '1',
- attributes: {
- wsState: '123abc',
- },
- };
- expect(migration(doc)).toMatchInlineSnapshot(`
-Object {
- "attributes": Object {
- "wsState": "123abc",
- },
- "id": "1",
- "references": Array [],
-}
-`);
- });
-
- test('returns doc when "indexPattern" is missing from wsState', () => {
- const doc = {
- id: '1',
- attributes: {
- wsState: JSON.stringify(JSON.stringify({ foo: true })),
- },
- };
- expect(migration(doc)).toMatchInlineSnapshot(`
-Object {
- "attributes": Object {
- "wsState": "\\"{\\\\\\"foo\\\\\\":true}\\"",
- },
- "id": "1",
- "references": Array [],
-}
-`);
- });
-
- test('extract "indexPattern" attribute from doc', () => {
- const doc = {
- id: '1',
- attributes: {
- wsState: JSON.stringify(JSON.stringify({ foo: true, indexPattern: 'pattern*' })),
- bar: true,
- },
- };
- const migratedDoc = migration(doc);
- expect(migratedDoc).toMatchInlineSnapshot(`
-Object {
- "attributes": Object {
- "bar": true,
- "wsState": "\\"{\\\\\\"foo\\\\\\":true,\\\\\\"indexPatternRefName\\\\\\":\\\\\\"indexPattern_0\\\\\\"}\\"",
- },
- "id": "1",
- "references": Array [
- Object {
- "id": "pattern*",
- "name": "indexPattern_0",
- "type": "index-pattern",
- },
- ],
-}
-`);
- });
- });
-});
diff --git a/x-pack/legacy/plugins/ingest_manager/index.ts b/x-pack/legacy/plugins/ingest_manager/index.ts
index 47c6478f66471..df9923d9f11ec 100644
--- a/x-pack/legacy/plugins/ingest_manager/index.ts
+++ b/x-pack/legacy/plugins/ingest_manager/index.ts
@@ -4,43 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { resolve } from 'path';
-import {
- savedObjectMappings,
- OUTPUT_SAVED_OBJECT_TYPE,
- AGENT_CONFIG_SAVED_OBJECT_TYPE,
- DATASOURCE_SAVED_OBJECT_TYPE,
- PACKAGES_SAVED_OBJECT_TYPE,
-} from '../../../plugins/ingest_manager/server';
-
-// TODO https://github.com/elastic/kibana/issues/46373
-// const INDEX_NAMES = {
-// INGEST: '.kibana',
-// };
export function ingestManager(kibana: any) {
return new kibana.Plugin({
id: 'ingestManager',
publicDir: resolve(__dirname, '../../../plugins/ingest_manager/public'),
- uiExports: {
- savedObjectSchemas: {
- [AGENT_CONFIG_SAVED_OBJECT_TYPE]: {
- isNamespaceAgnostic: true,
- // indexPattern: INDEX_NAMES.INGEST,
- },
- [OUTPUT_SAVED_OBJECT_TYPE]: {
- isNamespaceAgnostic: true,
- // indexPattern: INDEX_NAMES.INGEST,
- },
- [DATASOURCE_SAVED_OBJECT_TYPE]: {
- isNamespaceAgnostic: true,
- // indexPattern: INDEX_NAMES.INGEST,
- },
- [PACKAGES_SAVED_OBJECT_TYPE]: {
- isNamespaceAgnostic: true,
- // indexPattern: INDEX_NAMES.INGEST,
- },
- },
- mappings: savedObjectMappings,
- },
});
}
diff --git a/x-pack/legacy/plugins/maps/index.js b/x-pack/legacy/plugins/maps/index.js
index 8546e3712c763..d1e8892fa2c98 100644
--- a/x-pack/legacy/plugins/maps/index.js
+++ b/x-pack/legacy/plugins/maps/index.js
@@ -57,7 +57,6 @@ export function maps(kibana) {
tilemap: _.get(mapConfig, 'tilemap', []),
};
},
- embeddableFactories: ['plugins/maps/embeddable/map_embeddable_factory'],
styleSheetPaths: `${__dirname}/public/index.scss`,
savedObjectSchemas: {
'maps-telemetry': {
diff --git a/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts b/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts
deleted file mode 100644
index 90b17412377f5..0000000000000
--- a/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts
+++ /dev/null
@@ -1,30 +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.
- */
-
-/*
- Maintain legacy embeddable legacy present while apps switch over
- */
-
-import { npSetup, npStart } from 'ui/new_platform';
-import {
- bindSetupCoreAndPlugins,
- bindStartCoreAndPlugins,
- // eslint-disable-next-line @kbn/eslint/no-restricted-paths
-} from '../../../../../plugins/maps/public/plugin';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { MAP_SAVED_OBJECT_TYPE } from '../../../../../plugins/maps/common/constants';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { MapEmbeddableFactory } from '../../../../../plugins/maps/public/embeddable';
-
-bindSetupCoreAndPlugins(npSetup.core, npSetup.plugins);
-bindStartCoreAndPlugins(npStart.core, npStart.plugins);
-
-export * from '../../../../../plugins/maps/public/embeddable/map_embeddable_factory';
-
-npSetup.plugins.embeddable.registerEmbeddableFactory(
- MAP_SAVED_OBJECT_TYPE,
- new MapEmbeddableFactory()
-);
diff --git a/x-pack/legacy/plugins/rollup/common/index.ts b/x-pack/legacy/plugins/rollup/common/index.ts
deleted file mode 100644
index 526af055a3ef6..0000000000000
--- a/x-pack/legacy/plugins/rollup/common/index.ts
+++ /dev/null
@@ -1,19 +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 { LICENSE_TYPE_BASIC, LicenseType } from '../../../common/constants';
-
-export const PLUGIN = {
- ID: 'rollup',
- MINIMUM_LICENSE_REQUIRED: LICENSE_TYPE_BASIC as LicenseType,
- getI18nName: (i18n: any): string => {
- return i18n.translate('xpack.rollupJobs.appName', {
- defaultMessage: 'Rollup jobs',
- });
- },
-};
-
-export * from '../../../../plugins/rollup/common';
diff --git a/x-pack/legacy/plugins/rollup/index.ts b/x-pack/legacy/plugins/rollup/index.ts
deleted file mode 100644
index f33ae7cfee0a2..0000000000000
--- a/x-pack/legacy/plugins/rollup/index.ts
+++ /dev/null
@@ -1,43 +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 { PluginInitializerContext } from 'src/core/server';
-import { RollupSetup } from '../../../plugins/rollup/server';
-import { PLUGIN } from './common';
-import { plugin } from './server';
-
-export function rollup(kibana: any) {
- return new kibana.Plugin({
- id: PLUGIN.ID,
- configPrefix: 'xpack.rollup',
- require: ['kibana', 'elasticsearch', 'xpack_main'],
- init(server: any) {
- const { core: coreSetup, plugins } = server.newPlatform.setup;
- const { usageCollection, visTypeTimeseries, indexManagement } = plugins;
-
- const rollupSetup = (plugins.rollup as unknown) as RollupSetup;
-
- const initContext = ({
- config: rollupSetup.__legacy.config,
- logger: rollupSetup.__legacy.logger,
- } as unknown) as PluginInitializerContext;
-
- const rollupPluginInstance = plugin(initContext);
-
- rollupPluginInstance.setup(coreSetup, {
- usageCollection,
- visTypeTimeseries,
- indexManagement,
- __LEGACY: {
- plugins: {
- xpack_main: server.plugins.xpack_main,
- rollup: server.plugins[PLUGIN.ID],
- },
- },
- });
- },
- });
-}
diff --git a/x-pack/legacy/plugins/rollup/kibana.json b/x-pack/legacy/plugins/rollup/kibana.json
deleted file mode 100644
index 78458c9218be3..0000000000000
--- a/x-pack/legacy/plugins/rollup/kibana.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "id": "rollup",
- "version": "kibana",
- "requiredPlugins": [
- "home",
- "index_management",
- "visTypeTimeseries",
- "indexPatternManagement"
- ],
- "optionalPlugins": [
- "usageCollection"
- ],
- "server": true,
- "ui": false
-}
diff --git a/x-pack/legacy/plugins/rollup/server/lib/__tests__/fixtures/jobs.js b/x-pack/legacy/plugins/rollup/server/lib/__tests__/fixtures/jobs.js
deleted file mode 100644
index eb16b211da3fd..0000000000000
--- a/x-pack/legacy/plugins/rollup/server/lib/__tests__/fixtures/jobs.js
+++ /dev/null
@@ -1,98 +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.
- */
-
-export const jobs = [
- {
- "job_id" : "foo1",
- "rollup_index" : "foo_rollup",
- "index_pattern" : "foo-*",
- "fields" : {
- "node" : [
- {
- "agg" : "terms"
- }
- ],
- "temperature" : [
- {
- "agg" : "min"
- },
- {
- "agg" : "max"
- },
- {
- "agg" : "sum"
- }
- ],
- "timestamp" : [
- {
- "agg" : "date_histogram",
- "time_zone" : "UTC",
- "interval" : "1h",
- "delay": "7d"
- }
- ],
- "voltage" : [
- {
- "agg" : "histogram",
- "interval": 5
- },
- {
- "agg" : "sum"
- }
- ]
- }
- },
- {
- "job_id" : "foo2",
- "rollup_index" : "foo_rollup",
- "index_pattern" : "foo-*",
- "fields" : {
- "host" : [
- {
- "agg" : "terms"
- }
- ],
- "timestamp" : [
- {
- "agg" : "date_histogram",
- "time_zone" : "UTC",
- "interval" : "1h",
- "delay": "7d"
- }
- ],
- "voltage" : [
- {
- "agg" : "histogram",
- "interval": 20
- }
- ]
- }
- },
- {
- "job_id" : "foo3",
- "rollup_index" : "foo_rollup",
- "index_pattern" : "foo-*",
- "fields" : {
- "timestamp" : [
- {
- "agg" : "date_histogram",
- "time_zone" : "PST",
- "interval" : "1h",
- "delay": "7d"
- }
- ],
- "voltage" : [
- {
- "agg" : "histogram",
- "interval": 5
- },
- {
- "agg" : "sum"
- }
- ]
- }
- }
-];
diff --git a/x-pack/legacy/plugins/rollup/server/lib/call_with_request_factory/call_with_request_factory.ts b/x-pack/legacy/plugins/rollup/server/lib/call_with_request_factory/call_with_request_factory.ts
deleted file mode 100644
index 883b3552a7c02..0000000000000
--- a/x-pack/legacy/plugins/rollup/server/lib/call_with_request_factory/call_with_request_factory.ts
+++ /dev/null
@@ -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 { ElasticsearchServiceSetup } from 'kibana/server';
-import { once } from 'lodash';
-import { elasticsearchJsPlugin } from '../../client/elasticsearch_rollup';
-
-const callWithRequest = once((elasticsearchService: ElasticsearchServiceSetup) => {
- const config = { plugins: [elasticsearchJsPlugin] };
- return elasticsearchService.createClient('rollup', config);
-});
-
-export const callWithRequestFactory = (
- elasticsearchService: ElasticsearchServiceSetup,
- request: any
-) => {
- return (...args: any[]) => {
- return (
- callWithRequest(elasticsearchService)
- .asScoped(request)
- // @ts-ignore
- .callAsCurrentUser(...args)
- );
- };
-};
diff --git a/x-pack/legacy/plugins/rollup/server/lib/license_pre_routing_factory/license_pre_routing_factory.test.js b/x-pack/legacy/plugins/rollup/server/lib/license_pre_routing_factory/license_pre_routing_factory.test.js
deleted file mode 100644
index b6cea09e0ea3c..0000000000000
--- a/x-pack/legacy/plugins/rollup/server/lib/license_pre_routing_factory/license_pre_routing_factory.test.js
+++ /dev/null
@@ -1,62 +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 expect from '@kbn/expect';
-import { licensePreRoutingFactory } from '.';
-import {
- LICENSE_STATUS_VALID,
- LICENSE_STATUS_INVALID,
-} from '../../../../../common/constants/license_status';
-import { kibanaResponseFactory } from '../../../../../../../src/core/server';
-
-describe('licensePreRoutingFactory()', () => {
- let mockServer;
- let mockLicenseCheckResults;
-
- beforeEach(() => {
- mockServer = {
- plugins: {
- xpack_main: {
- info: {
- feature: () => ({
- getLicenseCheckResults: () => mockLicenseCheckResults,
- }),
- },
- },
- },
- };
- });
-
- describe('status is invalid', () => {
- beforeEach(() => {
- mockLicenseCheckResults = {
- status: LICENSE_STATUS_INVALID,
- };
- });
-
- it('replies with 403', () => {
- const routeWithLicenseCheck = licensePreRoutingFactory(mockServer, () => {});
- const stubRequest = {};
- const response = routeWithLicenseCheck({}, stubRequest, kibanaResponseFactory);
- expect(response.status).to.be(403);
- });
- });
-
- describe('status is valid', () => {
- beforeEach(() => {
- mockLicenseCheckResults = {
- status: LICENSE_STATUS_VALID,
- };
- });
-
- it('replies with nothing', () => {
- const routeWithLicenseCheck = licensePreRoutingFactory(mockServer, () => null);
- const stubRequest = {};
- const response = routeWithLicenseCheck({}, stubRequest, kibanaResponseFactory);
- expect(response).to.be(null);
- });
- });
-});
diff --git a/x-pack/legacy/plugins/rollup/server/lib/license_pre_routing_factory/license_pre_routing_factory.ts b/x-pack/legacy/plugins/rollup/server/lib/license_pre_routing_factory/license_pre_routing_factory.ts
deleted file mode 100644
index 353510d96a00d..0000000000000
--- a/x-pack/legacy/plugins/rollup/server/lib/license_pre_routing_factory/license_pre_routing_factory.ts
+++ /dev/null
@@ -1,43 +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 {
- KibanaRequest,
- KibanaResponseFactory,
- RequestHandler,
- RequestHandlerContext,
-} from 'src/core/server';
-import { PLUGIN } from '../../../common';
-import { LICENSE_STATUS_VALID } from '../../../../../common/constants/license_status';
-import { ServerShim } from '../../types';
-
-export const licensePreRoutingFactory = (
- server: ServerShim,
- handler: RequestHandler
-): RequestHandler => {
- const xpackMainPlugin = server.plugins.xpack_main;
-
- // License checking and enable/disable logic
- return function licensePreRouting(
- ctx: RequestHandlerContext,
- request: KibanaRequest,
- response: KibanaResponseFactory
- ) {
- const licenseCheckResults = xpackMainPlugin.info.feature(PLUGIN.ID).getLicenseCheckResults();
- const { status } = licenseCheckResults;
-
- if (status !== LICENSE_STATUS_VALID) {
- return response.customError({
- body: {
- message: licenseCheckResults.messsage,
- },
- statusCode: 403,
- });
- }
-
- return handler(ctx, request, response);
- };
-};
diff --git a/x-pack/legacy/plugins/rollup/server/plugin.ts b/x-pack/legacy/plugins/rollup/server/plugin.ts
deleted file mode 100644
index 05c22b030fff9..0000000000000
--- a/x-pack/legacy/plugins/rollup/server/plugin.ts
+++ /dev/null
@@ -1,95 +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 { CoreSetup, Plugin, PluginInitializerContext, Logger } from 'src/core/server';
-import { first } from 'rxjs/operators';
-import { i18n } from '@kbn/i18n';
-
-import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
-import { VisTypeTimeseriesSetup } from 'src/plugins/vis_type_timeseries/server';
-import { IndexManagementPluginSetup } from '../../../../plugins/index_management/server';
-import { registerLicenseChecker } from '../../../server/lib/register_license_checker';
-import { PLUGIN } from '../common';
-import { ServerShim, RouteDependencies } from './types';
-
-import {
- registerIndicesRoute,
- registerFieldsForWildcardRoute,
- registerSearchRoute,
- registerJobsRoute,
-} from './routes/api';
-
-import { registerRollupUsageCollector } from './collectors';
-
-import { rollupDataEnricher } from './rollup_data_enricher';
-import { registerRollupSearchStrategy } from './lib/search_strategies';
-
-export class RollupsServerPlugin implements Plugin {
- log: Logger;
-
- constructor(private readonly initializerContext: PluginInitializerContext) {
- this.log = initializerContext.logger.get();
- }
-
- async setup(
- { http, elasticsearch: elasticsearchService }: CoreSetup,
- {
- __LEGACY: serverShim,
- usageCollection,
- visTypeTimeseries,
- indexManagement,
- }: {
- __LEGACY: ServerShim;
- usageCollection?: UsageCollectionSetup;
- visTypeTimeseries?: VisTypeTimeseriesSetup;
- indexManagement?: IndexManagementPluginSetup;
- }
- ) {
- const elasticsearch = await elasticsearchService.adminClient;
- const router = http.createRouter();
- const routeDependencies: RouteDependencies = {
- elasticsearch,
- elasticsearchService,
- router,
- };
-
- registerLicenseChecker(
- serverShim as any,
- PLUGIN.ID,
- PLUGIN.getI18nName(i18n),
- PLUGIN.MINIMUM_LICENSE_REQUIRED
- );
-
- registerIndicesRoute(routeDependencies, serverShim);
- registerFieldsForWildcardRoute(routeDependencies, serverShim);
- registerSearchRoute(routeDependencies, serverShim);
- registerJobsRoute(routeDependencies, serverShim);
-
- if (usageCollection) {
- this.initializerContext.config.legacy.globalConfig$
- .pipe(first())
- .toPromise()
- .then(config => {
- registerRollupUsageCollector(usageCollection, config.kibana.index);
- })
- .catch(e => {
- this.log.warn(`Registering Rollup collector failed: ${e}`);
- });
- }
-
- if (indexManagement && indexManagement.indexDataEnricher) {
- indexManagement.indexDataEnricher.add(rollupDataEnricher);
- }
-
- if (visTypeTimeseries) {
- const { addSearchStrategy } = visTypeTimeseries;
- registerRollupSearchStrategy(routeDependencies, addSearchStrategy);
- }
- }
-
- start() {}
-
- stop() {}
-}
diff --git a/x-pack/legacy/plugins/rollup/server/routes/api/index.ts b/x-pack/legacy/plugins/rollup/server/routes/api/index.ts
deleted file mode 100644
index 146c3e973f9ea..0000000000000
--- a/x-pack/legacy/plugins/rollup/server/routes/api/index.ts
+++ /dev/null
@@ -1,10 +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.
- */
-
-export { registerIndicesRoute } from './indices';
-export { registerFieldsForWildcardRoute } from './index_patterns';
-export { registerSearchRoute } from './search';
-export { registerJobsRoute } from './jobs';
diff --git a/x-pack/legacy/plugins/rollup/server/routes/api/index_patterns.ts b/x-pack/legacy/plugins/rollup/server/routes/api/index_patterns.ts
deleted file mode 100644
index 2516840bd9537..0000000000000
--- a/x-pack/legacy/plugins/rollup/server/routes/api/index_patterns.ts
+++ /dev/null
@@ -1,131 +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 { schema } from '@kbn/config-schema';
-import { RequestHandler } from 'src/core/server';
-
-import { indexBy } from 'lodash';
-import { IndexPatternsFetcher } from '../../shared_imports';
-import { RouteDependencies, ServerShim } from '../../types';
-import { callWithRequestFactory } from '../../lib/call_with_request_factory';
-import { isEsError } from '../../lib/is_es_error';
-import { licensePreRoutingFactory } from '../../lib/license_pre_routing_factory';
-import { getCapabilitiesForRollupIndices } from '../../lib/map_capabilities';
-import { mergeCapabilitiesWithFields, Field } from '../../lib/merge_capabilities_with_fields';
-
-const parseMetaFields = (metaFields: string | string[]) => {
- let parsedFields: string[] = [];
- if (typeof metaFields === 'string') {
- parsedFields = JSON.parse(metaFields);
- } else {
- parsedFields = metaFields;
- }
- return parsedFields;
-};
-
-const getFieldsForWildcardRequest = async (context: any, request: any, response: any) => {
- const { callAsCurrentUser } = context.core.elasticsearch.dataClient;
- const indexPatterns = new IndexPatternsFetcher(callAsCurrentUser);
- const { pattern, meta_fields: metaFields } = request.query;
-
- let parsedFields: string[] = [];
- try {
- parsedFields = parseMetaFields(metaFields);
- } catch (error) {
- return response.badRequest({
- body: error,
- });
- }
-
- try {
- const fields = await indexPatterns.getFieldsForWildcard({
- pattern,
- metaFields: parsedFields,
- });
-
- return response.ok({
- body: { fields },
- headers: {
- 'content-type': 'application/json',
- },
- });
- } catch (error) {
- return response.notFound();
- }
-};
-
-/**
- * Get list of fields for rollup index pattern, in the format of regular index pattern fields
- */
-export function registerFieldsForWildcardRoute(deps: RouteDependencies, legacy: ServerShim) {
- const handler: RequestHandler = async (ctx, request, response) => {
- const { params, meta_fields: metaFields } = request.query;
-
- try {
- // Make call and use field information from response
- const { payload } = await getFieldsForWildcardRequest(ctx, request, response);
- const fields = payload.fields;
- const parsedParams = JSON.parse(params);
- const rollupIndex = parsedParams.rollup_index;
- const callWithRequest = callWithRequestFactory(deps.elasticsearchService, request);
- const rollupFields: Field[] = [];
- const fieldsFromFieldCapsApi: { [key: string]: any } = indexBy(fields, 'name');
- const rollupIndexCapabilities = getCapabilitiesForRollupIndices(
- await callWithRequest('rollup.rollupIndexCapabilities', {
- indexPattern: rollupIndex,
- })
- )[rollupIndex].aggs;
- // Keep meta fields
- metaFields.forEach(
- (field: string) =>
- fieldsFromFieldCapsApi[field] && rollupFields.push(fieldsFromFieldCapsApi[field])
- );
- const mergedRollupFields = mergeCapabilitiesWithFields(
- rollupIndexCapabilities,
- fieldsFromFieldCapsApi,
- rollupFields
- );
- return response.ok({ body: { fields: mergedRollupFields } });
- } catch (err) {
- if (isEsError(err)) {
- return response.customError({ statusCode: err.statusCode, body: err });
- }
- return response.internalError({ body: err });
- }
- };
-
- deps.router.get(
- {
- path: '/api/index_patterns/rollup/_fields_for_wildcard',
- validate: {
- query: schema.object({
- pattern: schema.string(),
- meta_fields: schema.arrayOf(schema.string(), {
- defaultValue: [],
- }),
- params: schema.string({
- validate(value) {
- try {
- const params = JSON.parse(value);
- const keys = Object.keys(params);
- const { rollup_index: rollupIndex } = params;
-
- if (!rollupIndex) {
- return '[request query.params]: "rollup_index" is required';
- } else if (keys.length > 1) {
- const invalidParams = keys.filter(key => key !== 'rollup_index');
- return `[request query.params]: ${invalidParams.join(', ')} is not allowed`;
- }
- } catch (err) {
- return '[request query.params]: expected JSON string';
- }
- },
- }),
- }),
- },
- },
- licensePreRoutingFactory(legacy, handler)
- );
-}
diff --git a/x-pack/legacy/plugins/rollup/server/routes/api/indices.ts b/x-pack/legacy/plugins/rollup/server/routes/api/indices.ts
deleted file mode 100644
index e78f09a71876b..0000000000000
--- a/x-pack/legacy/plugins/rollup/server/routes/api/indices.ts
+++ /dev/null
@@ -1,175 +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 { schema } from '@kbn/config-schema';
-import { RequestHandler } from 'src/core/server';
-import { callWithRequestFactory } from '../../lib/call_with_request_factory';
-import { isEsError } from '../../lib/is_es_error';
-import { licensePreRoutingFactory } from '../../lib/license_pre_routing_factory';
-import { getCapabilitiesForRollupIndices } from '../../lib/map_capabilities';
-import { API_BASE_PATH } from '../../../common';
-import { RouteDependencies, ServerShim } from '../../types';
-
-type NumericField =
- | 'long'
- | 'integer'
- | 'short'
- | 'byte'
- | 'scaled_float'
- | 'double'
- | 'float'
- | 'half_float';
-
-interface FieldCapability {
- date?: any;
- keyword?: any;
- long?: any;
- integer?: any;
- short?: any;
- byte?: any;
- double?: any;
- float?: any;
- half_float?: any;
- scaled_float?: any;
-}
-
-interface FieldCapabilities {
- fields: FieldCapability[];
-}
-
-function isNumericField(fieldCapability: FieldCapability) {
- const numericTypes = [
- 'long',
- 'integer',
- 'short',
- 'byte',
- 'double',
- 'float',
- 'half_float',
- 'scaled_float',
- ];
- return numericTypes.some(numericType => fieldCapability[numericType as NumericField] != null);
-}
-
-export function registerIndicesRoute(deps: RouteDependencies, legacy: ServerShim) {
- const getIndicesHandler: RequestHandler = async (ctx, request, response) => {
- const callWithRequest = callWithRequestFactory(deps.elasticsearchService, request);
-
- try {
- const data = await callWithRequest('rollup.rollupIndexCapabilities', {
- indexPattern: '_all',
- });
- return response.ok({ body: getCapabilitiesForRollupIndices(data) });
- } catch (err) {
- if (isEsError(err)) {
- return response.customError({ statusCode: err.statusCode, body: err });
- }
- return response.internalError({ body: err });
- }
- };
-
- const validateIndexPatternHandler: RequestHandler = async (
- ctx,
- request,
- response
- ) => {
- const callWithRequest = callWithRequestFactory(deps.elasticsearchService, request);
-
- try {
- const { indexPattern } = request.params;
- const [fieldCapabilities, rollupIndexCapabilities]: [
- FieldCapabilities,
- { [key: string]: any }
- ] = await Promise.all([
- callWithRequest('rollup.fieldCapabilities', { indexPattern }),
- callWithRequest('rollup.rollupIndexCapabilities', { indexPattern }),
- ]);
-
- const doesMatchIndices = Object.entries(fieldCapabilities.fields).length !== 0;
- const doesMatchRollupIndices = Object.entries(rollupIndexCapabilities).length !== 0;
-
- const dateFields: string[] = [];
- const numericFields: string[] = [];
- const keywordFields: string[] = [];
-
- const fieldCapabilitiesEntries = Object.entries(fieldCapabilities.fields);
-
- fieldCapabilitiesEntries.forEach(
- ([fieldName, fieldCapability]: [string, FieldCapability]) => {
- if (fieldCapability.date) {
- dateFields.push(fieldName);
- return;
- }
-
- if (isNumericField(fieldCapability)) {
- numericFields.push(fieldName);
- return;
- }
-
- if (fieldCapability.keyword) {
- keywordFields.push(fieldName);
- }
- }
- );
-
- const body = {
- doesMatchIndices,
- doesMatchRollupIndices,
- dateFields,
- numericFields,
- keywordFields,
- };
-
- return response.ok({ body });
- } catch (err) {
- // 404s are still valid results.
- if (err.statusCode === 404) {
- const notFoundBody = {
- doesMatchIndices: false,
- doesMatchRollupIndices: false,
- dateFields: [],
- numericFields: [],
- keywordFields: [],
- };
- return response.ok({ body: notFoundBody });
- }
-
- if (isEsError(err)) {
- return response.customError({ statusCode: err.statusCode, body: err });
- }
-
- return response.internalError({ body: err });
- }
- };
-
- /**
- * Returns a list of all rollup index names
- */
- deps.router.get(
- {
- path: `${API_BASE_PATH}/indices`,
- validate: false,
- },
- licensePreRoutingFactory(legacy, getIndicesHandler)
- );
-
- /**
- * Returns information on validity of an index pattern for creating a rollup job:
- * - Does the index pattern match any indices?
- * - Does the index pattern match rollup indices?
- * - Which date fields, numeric fields, and keyword fields are available in the matching indices?
- */
- deps.router.get(
- {
- path: `${API_BASE_PATH}/index_pattern_validity/{indexPattern}`,
- validate: {
- params: schema.object({
- indexPattern: schema.string(),
- }),
- },
- },
- licensePreRoutingFactory(legacy, validateIndexPatternHandler)
- );
-}
diff --git a/x-pack/legacy/plugins/rollup/server/routes/api/jobs.ts b/x-pack/legacy/plugins/rollup/server/routes/api/jobs.ts
deleted file mode 100644
index e45713e2b807c..0000000000000
--- a/x-pack/legacy/plugins/rollup/server/routes/api/jobs.ts
+++ /dev/null
@@ -1,178 +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 { schema } from '@kbn/config-schema';
-import { RequestHandler } from 'src/core/server';
-import { callWithRequestFactory } from '../../lib/call_with_request_factory';
-import { isEsError } from '../../lib/is_es_error';
-import { licensePreRoutingFactory } from '../../lib/license_pre_routing_factory';
-import { API_BASE_PATH } from '../../../common';
-import { RouteDependencies, ServerShim } from '../../types';
-
-export function registerJobsRoute(deps: RouteDependencies, legacy: ServerShim) {
- const getJobsHandler: RequestHandler = async (ctx, request, response) => {
- const callWithRequest = callWithRequestFactory(deps.elasticsearchService, request);
-
- try {
- const data = await callWithRequest('rollup.jobs');
- return response.ok({ body: data });
- } catch (err) {
- if (isEsError(err)) {
- return response.customError({ statusCode: err.statusCode, body: err });
- }
- return response.internalError({ body: err });
- }
- };
-
- const createJobsHandler: RequestHandler = async (ctx, request, response) => {
- try {
- const { id, ...rest } = request.body.job;
- const callWithRequest = callWithRequestFactory(deps.elasticsearchService, request);
- // Create job.
- await callWithRequest('rollup.createJob', {
- id,
- body: rest,
- });
- // Then request the newly created job.
- const results = await callWithRequest('rollup.job', { id });
- return response.ok({ body: results.jobs[0] });
- } catch (err) {
- if (isEsError(err)) {
- return response.customError({ statusCode: err.statusCode, body: err });
- }
- return response.internalError({ body: err });
- }
- };
-
- const startJobsHandler: RequestHandler = async (ctx, request, response) => {
- try {
- const { jobIds } = request.body;
- const callWithRequest = callWithRequestFactory(deps.elasticsearchService, request);
-
- const data = await Promise.all(
- jobIds.map((id: string) => callWithRequest('rollup.startJob', { id }))
- ).then(() => ({ success: true }));
- return response.ok({ body: data });
- } catch (err) {
- if (isEsError(err)) {
- return response.customError({ statusCode: err.statusCode, body: err });
- }
- return response.internalError({ body: err });
- }
- };
-
- const stopJobsHandler: RequestHandler = async (ctx, request, response) => {
- try {
- const { jobIds } = request.body;
- // For our API integration tests we need to wait for the jobs to be stopped
- // in order to be able to delete them sequencially.
- const { waitForCompletion } = request.query;
- const callWithRequest = callWithRequestFactory(deps.elasticsearchService, request);
- const stopRollupJob = (id: string) =>
- callWithRequest('rollup.stopJob', {
- id,
- waitForCompletion: waitForCompletion === 'true',
- });
- const data = await Promise.all(jobIds.map(stopRollupJob)).then(() => ({ success: true }));
- return response.ok({ body: data });
- } catch (err) {
- if (isEsError(err)) {
- return response.customError({ statusCode: err.statusCode, body: err });
- }
- return response.internalError({ body: err });
- }
- };
-
- const deleteJobsHandler: RequestHandler = async (ctx, request, response) => {
- try {
- const { jobIds } = request.body;
- const callWithRequest = callWithRequestFactory(deps.elasticsearchService, request);
- const data = await Promise.all(
- jobIds.map((id: string) => callWithRequest('rollup.deleteJob', { id }))
- ).then(() => ({ success: true }));
- return response.ok({ body: data });
- } catch (err) {
- // There is an issue opened on ES to handle the following error correctly
- // https://github.com/elastic/elasticsearch/issues/42908
- // Until then we'll modify the response here.
- if (err.response && err.response.includes('Job must be [STOPPED] before deletion')) {
- err.status = 400;
- err.statusCode = 400;
- err.displayName = 'Bad request';
- err.message = JSON.parse(err.response).task_failures[0].reason.reason;
- }
- if (isEsError(err)) {
- return response.customError({ statusCode: err.statusCode, body: err });
- }
- return response.internalError({ body: err });
- }
- };
-
- deps.router.get(
- {
- path: `${API_BASE_PATH}/jobs`,
- validate: false,
- },
- licensePreRoutingFactory(legacy, getJobsHandler)
- );
-
- deps.router.put(
- {
- path: `${API_BASE_PATH}/create`,
- validate: {
- body: schema.object({
- job: schema.object(
- {
- id: schema.string(),
- },
- { unknowns: 'allow' }
- ),
- }),
- },
- },
- licensePreRoutingFactory(legacy, createJobsHandler)
- );
-
- deps.router.post(
- {
- path: `${API_BASE_PATH}/start`,
- validate: {
- body: schema.object({
- jobIds: schema.arrayOf(schema.string()),
- }),
- query: schema.maybe(
- schema.object({
- waitForCompletion: schema.maybe(schema.string()),
- })
- ),
- },
- },
- licensePreRoutingFactory(legacy, startJobsHandler)
- );
-
- deps.router.post(
- {
- path: `${API_BASE_PATH}/stop`,
- validate: {
- body: schema.object({
- jobIds: schema.arrayOf(schema.string()),
- }),
- },
- },
- licensePreRoutingFactory(legacy, stopJobsHandler)
- );
-
- deps.router.post(
- {
- path: `${API_BASE_PATH}/delete`,
- validate: {
- body: schema.object({
- jobIds: schema.arrayOf(schema.string()),
- }),
- },
- },
- licensePreRoutingFactory(legacy, deleteJobsHandler)
- );
-}
diff --git a/x-pack/legacy/plugins/rollup/server/routes/api/search.ts b/x-pack/legacy/plugins/rollup/server/routes/api/search.ts
deleted file mode 100644
index 97999a4b5ce8d..0000000000000
--- a/x-pack/legacy/plugins/rollup/server/routes/api/search.ts
+++ /dev/null
@@ -1,50 +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 { schema } from '@kbn/config-schema';
-import { RequestHandler } from 'src/core/server';
-import { callWithRequestFactory } from '../../lib/call_with_request_factory';
-import { isEsError } from '../../lib/is_es_error';
-import { licensePreRoutingFactory } from '../../lib/license_pre_routing_factory';
-import { API_BASE_PATH } from '../../../common';
-import { RouteDependencies, ServerShim } from '../../types';
-
-export function registerSearchRoute(deps: RouteDependencies, legacy: ServerShim) {
- const handler: RequestHandler = async (ctx, request, response) => {
- const callWithRequest = callWithRequestFactory(deps.elasticsearchService, request);
- try {
- const requests = request.body.map(({ index, query }: { index: string; query: any }) =>
- callWithRequest('rollup.search', {
- index,
- rest_total_hits_as_int: true,
- body: query,
- })
- );
- const data = await Promise.all(requests);
- return response.ok({ body: data });
- } catch (err) {
- if (isEsError(err)) {
- return response.customError({ statusCode: err.statusCode, body: err });
- }
- return response.internalError({ body: err });
- }
- };
-
- deps.router.post(
- {
- path: `${API_BASE_PATH}/search`,
- validate: {
- body: schema.arrayOf(
- schema.object({
- index: schema.string(),
- query: schema.any(),
- })
- ),
- },
- },
- licensePreRoutingFactory(legacy, handler)
- );
-}
diff --git a/x-pack/legacy/plugins/rollup/server/types.ts b/x-pack/legacy/plugins/rollup/server/types.ts
deleted file mode 100644
index bcc6770e9b8ee..0000000000000
--- a/x-pack/legacy/plugins/rollup/server/types.ts
+++ /dev/null
@@ -1,21 +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 { IRouter, ElasticsearchServiceSetup, IClusterClient } from 'src/core/server';
-import { XPackMainPlugin } from '../../xpack_main/server/xpack_main';
-
-export interface ServerShim {
- plugins: {
- xpack_main: XPackMainPlugin;
- rollup: any;
- };
-}
-
-export interface RouteDependencies {
- router: IRouter;
- elasticsearchService: ElasticsearchServiceSetup;
- elasticsearch: IClusterClient;
-}
diff --git a/x-pack/legacy/plugins/rollup/tsconfig.json b/x-pack/legacy/plugins/rollup/tsconfig.json
deleted file mode 100644
index 618c6c3e97b57..0000000000000
--- a/x-pack/legacy/plugins/rollup/tsconfig.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "extends": "../../../tsconfig.json"
-}
diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx
index a7272593c2b27..e18f9b0d346ad 100644
--- a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx
@@ -208,6 +208,7 @@ export const EmbeddedMapComponent = ({
notifications={services.notifications}
overlays={services.overlays}
inspector={services.inspector}
+ application={services.application}
SavedObjectFinder={getSavedObjectFinder(services.savedObjects, services.uiSettings)}
/>
) : !isLoading && isIndexError ? (
diff --git a/x-pack/legacy/plugins/task_manager/server/index.ts b/x-pack/legacy/plugins/task_manager/server/index.ts
index ff25d8a1e0e5d..3ea687f7003f4 100644
--- a/x-pack/legacy/plugins/task_manager/server/index.ts
+++ b/x-pack/legacy/plugins/task_manager/server/index.ts
@@ -15,19 +15,26 @@ export { LegacyTaskManagerApi, getTaskManagerSetup, getTaskManagerStart } from '
// Once all plugins are migrated to NP, this can be removed
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { TaskManager } from '../../../../plugins/task_manager/server/task_manager';
+import {
+ LegacyPluginApi,
+ LegacyPluginSpec,
+ ArrayOrItem,
+} from '../../../../../src/legacy/plugin_discovery/types';
const savedObjectSchemas = {
task: {
hidden: true,
isNamespaceAgnostic: true,
convertToAliasScript: `ctx._id = ctx._source.type + ':' + ctx._id`,
+ // legacy config is marked as any in core, no choice here
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
indexPattern(config: any) {
return config.get('xpack.task_manager.index');
},
},
};
-export function taskManager(kibana: any) {
+export function taskManager(kibana: LegacyPluginApi): ArrayOrItem {
return new kibana.Plugin({
id: 'task_manager',
require: ['kibana', 'elasticsearch', 'xpack_main'],
@@ -58,7 +65,11 @@ export function taskManager(kibana: any) {
// instead we will start the internal Task Manager plugin when
// all legacy plugins have finished initializing
// Once all plugins are migrated to NP, this can be removed
- this.kbnServer.afterPluginsInit(() => {
+
+ // the typing for the lagcy server isn't quite correct, so
+ // we'll bypase it for now
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ (this as any).kbnServer.afterPluginsInit(() => {
taskManagerPlugin.start();
});
return taskManagerPlugin;
@@ -71,5 +82,5 @@ export function taskManager(kibana: any) {
migrations,
savedObjectSchemas,
},
- });
+ } as Legacy.PluginSpecOptions);
}
diff --git a/x-pack/legacy/plugins/task_manager/server/legacy.ts b/x-pack/legacy/plugins/task_manager/server/legacy.ts
index cd2047b757e61..0d50828004a94 100644
--- a/x-pack/legacy/plugins/task_manager/server/legacy.ts
+++ b/x-pack/legacy/plugins/task_manager/server/legacy.ts
@@ -49,10 +49,10 @@ export function createLegacyApi(legacyTaskManager: Promise): Legacy
fetch: (opts: SearchOpts) => legacyTaskManager.then((tm: TaskManager) => tm.fetch(opts)),
get: (id: string) => legacyTaskManager.then((tm: TaskManager) => tm.get(id)),
remove: (id: string) => legacyTaskManager.then((tm: TaskManager) => tm.remove(id)),
- schedule: (taskInstance: TaskInstanceWithDeprecatedFields, options?: any) =>
+ schedule: (taskInstance: TaskInstanceWithDeprecatedFields, options?: object) =>
legacyTaskManager.then((tm: TaskManager) => tm.schedule(taskInstance, options)),
runNow: (taskId: string) => legacyTaskManager.then((tm: TaskManager) => tm.runNow(taskId)),
- ensureScheduled: (taskInstance: TaskInstanceWithId, options?: any) =>
+ ensureScheduled: (taskInstance: TaskInstanceWithId, options?: object) =>
legacyTaskManager.then((tm: TaskManager) => tm.ensureScheduled(taskInstance, options)),
};
}
diff --git a/x-pack/legacy/plugins/task_manager/server/migrations.ts b/x-pack/legacy/plugins/task_manager/server/migrations.ts
index 97c4f97f59c58..1c2cf73d0fe13 100644
--- a/x-pack/legacy/plugins/task_manager/server/migrations.ts
+++ b/x-pack/legacy/plugins/task_manager/server/migrations.ts
@@ -7,7 +7,7 @@ import { SavedObject } from '../../../../../src/core/server';
export const migrations = {
task: {
- '7.4.0': (doc: SavedObject>) => ({
+ '7.4.0': (doc: SavedObject>) => ({
...doc,
updated_at: new Date().toISOString(),
}),
@@ -18,7 +18,7 @@ export const migrations = {
function moveIntervalIntoSchedule({
attributes: { interval, ...attributes },
...doc
-}: SavedObject>) {
+}: SavedObject>) {
return {
...doc,
attributes: {
diff --git a/x-pack/legacy/plugins/uptime/common/constants/index.ts b/x-pack/legacy/plugins/uptime/common/constants/index.ts
index 74783cf46550f..72d498056d6b3 100644
--- a/x-pack/legacy/plugins/uptime/common/constants/index.ts
+++ b/x-pack/legacy/plugins/uptime/common/constants/index.ts
@@ -9,6 +9,7 @@ export { CHART_FORMAT_LIMITS } from './chart_format_limits';
export { CLIENT_DEFAULTS } from './client_defaults';
export { CONTEXT_DEFAULTS } from './context_defaults';
export * from './capabilities';
+export * from './settings_defaults';
export { PLUGIN } from './plugin';
export { QUERY, STATES } from './query';
export * from './ui';
diff --git a/x-pack/legacy/plugins/uptime/common/constants/settings_defaults.ts b/x-pack/legacy/plugins/uptime/common/constants/settings_defaults.ts
new file mode 100644
index 0000000000000..b7986679a09ca
--- /dev/null
+++ b/x-pack/legacy/plugins/uptime/common/constants/settings_defaults.ts
@@ -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.
+ */
+
+import { DynamicSettings } from '../runtime_types';
+
+export const DYNAMIC_SETTINGS_DEFAULTS: DynamicSettings = {
+ heartbeatIndices: 'heartbeat-8*',
+ certThresholds: {
+ expiration: 30,
+ age: 365,
+ },
+};
diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/dynamic_settings.ts b/x-pack/legacy/plugins/uptime/common/runtime_types/dynamic_settings.ts
index 985b51891da99..da887cc5055c1 100644
--- a/x-pack/legacy/plugins/uptime/common/runtime_types/dynamic_settings.ts
+++ b/x-pack/legacy/plugins/uptime/common/runtime_types/dynamic_settings.ts
@@ -6,19 +6,15 @@
import * as t from 'io-ts';
-export const CertificatesStatesThresholdType = t.interface({
- warningState: t.number,
- errorState: t.number,
+export const CertStateThresholdsType = t.type({
+ age: t.number,
+ expiration: t.number,
});
-export const DynamicSettingsType = t.intersection([
- t.type({
- heartbeatIndices: t.string,
- }),
- t.partial({
- certificatesThresholds: CertificatesStatesThresholdType,
- }),
-]);
+export const DynamicSettingsType = t.type({
+ heartbeatIndices: t.string,
+ certThresholds: CertStateThresholdsType,
+});
export const DynamicSettingsSaveType = t.intersection([
t.type({
@@ -31,12 +27,4 @@ export const DynamicSettingsSaveType = t.intersection([
export type DynamicSettings = t.TypeOf;
export type DynamicSettingsSaveResponse = t.TypeOf;
-export type CertificatesStatesThreshold = t.TypeOf;
-
-export const defaultDynamicSettings: DynamicSettings = {
- heartbeatIndices: 'heartbeat-8*',
- certificatesThresholds: {
- errorState: 7,
- warningState: 30,
- },
-};
+export type CertStateThresholds = t.TypeOf;
diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/empty_state.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/empty_state.test.tsx
index acfe2ada5b68d..6328789d03f29 100644
--- a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/empty_state.test.tsx
+++ b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/empty_state.test.tsx
@@ -7,8 +7,7 @@
import React from 'react';
import { EmptyStateComponent } from '../empty_state';
import { StatesIndexStatus } from '../../../../../common/runtime_types';
-import { IHttpFetchError } from '../../../../../../../../../target/types/core/public/http';
-import { HttpFetchError } from '../../../../../../../../../src/core/public/http/http_fetch_error';
+import { HttpFetchError, IHttpFetchError } from 'src/core/public';
import { mountWithRouter, shallowWithRouter } from '../../../../lib';
describe('EmptyState component', () => {
diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/certificate_form.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/certificate_form.test.tsx.snap
index 36bc9bb860211..96d472c91680d 100644
--- a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/certificate_form.test.tsx.snap
+++ b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/certificate_form.test.tsx.snap
@@ -52,17 +52,18 @@ exports[`CertificateForm shallow renders expected elements for valid props 1`] =
}
>
diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/indices_form.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/indices_form.test.tsx.snap
index 93151198c0f49..3b0c6d99fd9f8 100644
--- a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/indices_form.test.tsx.snap
+++ b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/indices_form.test.tsx.snap
@@ -52,17 +52,18 @@ exports[`CertificateForm shallow renders expected elements for valid props 1`] =
}
>
diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/certificate_form.test.tsx b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/certificate_form.test.tsx
index a3158f3d72445..3d4bd58aabe0f 100644
--- a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/certificate_form.test.tsx
+++ b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/certificate_form.test.tsx
@@ -13,12 +13,13 @@ describe('CertificateForm', () => {
expect(
shallowWithRouter(
)
diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/indices_form.test.tsx b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/indices_form.test.tsx
index 654d51019d4e5..07a3bf81e39d8 100644
--- a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/indices_form.test.tsx
+++ b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/indices_form.test.tsx
@@ -13,12 +13,13 @@ describe('CertificateForm', () => {
expect(
shallowWithRouter(
)
diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/certificate_form.tsx b/x-pack/legacy/plugins/uptime/public/components/settings/certificate_form.tsx
index 5103caee1e1c0..209e38785e165 100644
--- a/x-pack/legacy/plugins/uptime/public/components/settings/certificate_form.tsx
+++ b/x-pack/legacy/plugins/uptime/public/components/settings/certificate_form.tsx
@@ -6,155 +6,157 @@
import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
-import { useSelector } from 'react-redux';
import {
EuiDescribedFormGroup,
EuiFormRow,
EuiCode,
EuiFieldNumber,
+ EuiText,
EuiTitle,
EuiSpacer,
- EuiSelect,
EuiFlexGroup,
EuiFlexItem,
} from '@elastic/eui';
-import { defaultDynamicSettings, DynamicSettings } from '../../../common/runtime_types';
-import { selectDynamicSettings } from '../../state/selectors';
+import { CertStateThresholds } from '../../../common/runtime_types';
+import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../common/constants';
+import { SettingsFormProps } from '../../pages/settings';
-type NumStr = string | number;
-
-export type OnFieldChangeType = (field: string, value?: NumStr) => void;
-
-export interface SettingsFormProps {
- onChange: OnFieldChangeType;
- formFields: DynamicSettings | null;
- fieldErrors: any;
- isDisabled: boolean;
+interface ChangedValues {
+ heartbeatIndices?: string;
+ certThresholds?: Partial;
}
+export type OnFieldChangeType = (changedValues: ChangedValues) => void;
+
export const CertificateExpirationForm: React.FC = ({
+ loading,
onChange,
formFields,
fieldErrors,
isDisabled,
-}) => {
- const dss = useSelector(selectDynamicSettings);
-
- return (
- <>
-
-
+}) => (
+ <>
+
+
+
+
+
+
+
+
+ }
+ description={
+
+ }
+ >
+ {DYNAMIC_SETTINGS_DEFAULTS.certThresholds.expiration}
+ ),
+ }}
/>
-
-
-
-
-
-
}
- description={
+ isInvalid={!!fieldErrors?.certificatesThresholds?.expirationThresholdError}
+ label={
}
>
- {defaultDynamicSettings?.certificatesThresholds?.errorState}
- ),
- }}
- />
- }
- isInvalid={!!fieldErrors?.certificatesThresholds?.errorState}
- label={
-
+
+
+ onChange({
+ certThresholds: {
+ expiration: Number(e.target.value),
+ },
+ })
+ }
/>
- }
- >
-
-
-
- onChange(
- 'certificatesThresholds.errorState',
- value === '' ? undefined : Number(value)
- )
- }
+
+
+
+
-
-
-
-
-
-
- {defaultDynamicSettings?.certificatesThresholds?.warningState}
- ),
- }}
- />
- }
- isInvalid={!!fieldErrors?.certificatesThresholds?.warningState}
- label={
-
+
+
+
+ {DYNAMIC_SETTINGS_DEFAULTS.certThresholds.age},
+ }}
+ />
+ }
+ isInvalid={!!fieldErrors?.certificatesThresholds?.ageThresholdError}
+ label={
+
+ }
+ >
+
+
+
+ onChange({
+ certThresholds: { age: Number(e.currentTarget.value) },
+ })
+ }
/>
- }
- >
-
-
-
- onChange('certificatesThresholds.warningState', Number(event.currentTarget.value))
- }
+
+
+
+
-
-
-
-
-
-
-
- >
- );
-};
+
+
+
+
+
+ >
+);
diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/indices_form.tsx b/x-pack/legacy/plugins/uptime/public/components/settings/indices_form.tsx
index c28eca2ea229e..b9a5ca0e730de 100644
--- a/x-pack/legacy/plugins/uptime/public/components/settings/indices_form.tsx
+++ b/x-pack/legacy/plugins/uptime/public/components/settings/indices_form.tsx
@@ -6,7 +6,6 @@
import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
-import { useSelector } from 'react-redux';
import {
EuiDescribedFormGroup,
EuiFormRow,
@@ -15,76 +14,72 @@ import {
EuiTitle,
EuiSpacer,
} from '@elastic/eui';
-import { defaultDynamicSettings } from '../../../common/runtime_types';
-import { selectDynamicSettings } from '../../state/selectors';
-import { SettingsFormProps } from './certificate_form';
+import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../common/constants';
+import { SettingsFormProps } from '../../pages/settings';
export const IndicesForm: React.FC = ({
onChange,
+ loading,
formFields,
fieldErrors,
isDisabled,
-}) => {
- const dss = useSelector(selectDynamicSettings);
-
- return (
- <>
-
-
+}) => (
+ <>
+
+
+
+
+
+
+
+
+
+ }
+ description={
+
+ }
+ >
+ {DYNAMIC_SETTINGS_DEFAULTS.heartbeatIndices},
+ }}
/>
-
-
-
-
-
-
}
- description={
+ isInvalid={!!fieldErrors?.heartbeatIndices}
+ label={
}
>
- {defaultDynamicSettings.heartbeatIndices},
- }}
- />
- }
- isInvalid={!!fieldErrors?.heartbeatIndices}
- label={
-
- }
- >
- onChange('heartbeatIndices', event.currentTarget.value)}
- />
-
-
- >
- );
-};
+ disabled={isDisabled}
+ isLoading={loading}
+ value={formFields?.heartbeatIndices || ''}
+ onChange={(event: any) => onChange({ heartbeatIndices: event.currentTarget.value })}
+ />
+
+
+ >
+);
diff --git a/x-pack/legacy/plugins/uptime/public/pages/settings.tsx b/x-pack/legacy/plugins/uptime/public/pages/settings.tsx
index 6defb96e0da3d..d8c2a78092854 100644
--- a/x-pack/legacy/plugins/uptime/public/pages/settings.tsx
+++ b/x-pack/legacy/plugins/uptime/public/pages/settings.tsx
@@ -17,8 +17,7 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { useDispatch, useSelector } from 'react-redux';
-import { cloneDeep, isEqual, set } from 'lodash';
-import { i18n } from '@kbn/i18n';
+import { isEqual } from 'lodash';
import { Link } from 'react-router-dom';
import { selectDynamicSettings } from '../state/selectors';
import { getDynamicSettings, setDynamicSettings } from '../state/actions/dynamic_settings';
@@ -32,21 +31,38 @@ import {
CertificateExpirationForm,
OnFieldChangeType,
} from '../components/settings/certificate_form';
-
-const getFieldErrors = (formFields: DynamicSettings | null) => {
+import * as Translations from './translations';
+
+interface SettingsPageFieldErrors {
+ heartbeatIndices: 'May not be blank' | '';
+ certificatesThresholds: {
+ expirationThresholdError: string | null;
+ ageThresholdError: string | null;
+ } | null;
+}
+
+export interface SettingsFormProps {
+ loading: boolean;
+ onChange: OnFieldChangeType;
+ formFields: DynamicSettings | null;
+ fieldErrors: SettingsPageFieldErrors | null;
+ isDisabled: boolean;
+}
+
+const getFieldErrors = (formFields: DynamicSettings | null): SettingsPageFieldErrors | null => {
if (formFields) {
const blankStr = 'May not be blank';
- const { certificatesThresholds, heartbeatIndices } = formFields;
+ const { certThresholds: certificatesThresholds, heartbeatIndices } = formFields;
const heartbeatIndErr = heartbeatIndices.match(/^\S+$/) ? '' : blankStr;
- const errorStateErr = certificatesThresholds?.errorState ? null : blankStr;
- const warningStateErr = certificatesThresholds?.warningState ? null : blankStr;
+ const expirationThresholdError = certificatesThresholds?.expiration ? null : blankStr;
+ const ageThresholdError = certificatesThresholds?.age ? null : blankStr;
return {
heartbeatIndices: heartbeatIndErr,
certificatesThresholds:
- errorStateErr || warningStateErr
+ expirationThresholdError || ageThresholdError
? {
- errorState: errorStateErr,
- warningState: warningStateErr,
+ expirationThresholdError,
+ ageThresholdError,
}
: null,
};
@@ -57,10 +73,7 @@ const getFieldErrors = (formFields: DynamicSettings | null) => {
export const SettingsPage = () => {
const dss = useSelector(selectDynamicSettings);
- const settingsBreadcrumbText = i18n.translate('xpack.uptime.settingsBreadcrumbText', {
- defaultMessage: 'Settings',
- });
- useBreadcrumbs([{ text: settingsBreadcrumbText }]);
+ useBreadcrumbs([{ text: Translations.settings.breadcrumbText }]);
useUptimeTelemetry(UptimePage.Settings);
@@ -70,21 +83,28 @@ export const SettingsPage = () => {
dispatch(getDynamicSettings());
}, [dispatch]);
- const [formFields, setFormFields] = useState(dss.settings || null);
+ const [formFields, setFormFields] = useState(
+ dss.settings ? { ...dss.settings } : null
+ );
- if (!dss.loadError && formFields == null && dss.settings) {
- setFormFields({ ...dss.settings });
+ if (!dss.loadError && formFields === null && dss.settings) {
+ setFormFields(Object.assign({}, { ...dss.settings }));
}
const fieldErrors = getFieldErrors(formFields);
const isFormValid = !(fieldErrors && Object.values(fieldErrors).find(v => !!v));
- const onChangeFormField: OnFieldChangeType = (field, value) => {
+ const onChangeFormField: OnFieldChangeType = changedField => {
if (formFields) {
- const newFormFields = cloneDeep(formFields);
- set(newFormFields, field, value);
- setFormFields(cloneDeep(newFormFields));
+ setFormFields({
+ heartbeatIndices: changedField.heartbeatIndices ?? formFields.heartbeatIndices,
+ certThresholds: Object.assign(
+ {},
+ formFields.certThresholds,
+ changedField?.certThresholds ?? null
+ ),
+ });
}
};
@@ -95,27 +115,18 @@ export const SettingsPage = () => {
}
};
- const resetForm = () => {
- if (formFields && dss.settings) {
- setFormFields({ ...dss.settings });
- }
- };
+ const resetForm = () => setFormFields(dss.settings ? { ...dss.settings } : null);
- const isFormDirty = dss.settings ? !isEqual(dss.settings, formFields) : true;
+ const isFormDirty = !isEqual(dss.settings, formFields);
const canEdit: boolean =
!!useKibana().services?.application?.capabilities.uptime.configureSettings || false;
const isFormDisabled = dss.loading || !canEdit;
- const editNoticeTitle = i18n.translate('xpack.uptime.settings.cannotEditTitle', {
- defaultMessage: 'You do not have permission to edit settings.',
- });
- const editNoticeText = i18n.translate('xpack.uptime.settings.cannotEditText', {
- defaultMessage:
- "Your user currently has 'Read' permissions for the Uptime app. Enable a permissions-level of 'All' to edit these settings.",
- });
const cannotEditNotice = canEdit ? null : (
<>
- {editNoticeText}
+
+ {Translations.settings.editNoticeText}
+
>
);
@@ -124,9 +135,7 @@ export const SettingsPage = () => {
<>
- {i18n.translate('xpack.uptime.settings.returnToOverviewLinkLabel', {
- defaultMessage: 'Return to overview',
- })}
+ {Translations.settings.returnToOverviewLinkLabel}
@@ -139,12 +148,14 @@ export const SettingsPage = () => {