From e7c28fda290cd956409b12eb3aecdad5497f9df8 Mon Sep 17 00:00:00 2001
From: Brandon Kobel
Date: Wed, 23 Jan 2019 05:55:27 -0800
Subject: [PATCH 01/29] throw config error based on the joi validation error
(#29137)
---
src/server/config/config.js | 5 ++++-
src/server/config/config.test.js | 8 ++++++--
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/server/config/config.js b/src/server/config/config.js
index b5b89ec579184..5587794c74f8a 100644
--- a/src/server/config/config.js
+++ b/src/server/config/config.js
@@ -124,7 +124,10 @@ export class Config {
});
if (results.error) {
- throw results.error;
+ const error = new Error(results.error.message);
+ error.name = results.error.name;
+ error.stack = results.error.stack;
+ throw error;
}
this[vals] = results.value;
diff --git a/src/server/config/config.test.js b/src/server/config/config.test.js
index 1887548cf7275..3b64f943b85f6 100644
--- a/src/server/config/config.test.js
+++ b/src/server/config/config.test.js
@@ -174,7 +174,7 @@ describe('lib/config/config', function () {
});
it('should thow an exception when setting a value with the wrong type', function (done) {
- expect.assertions(2);
+ expect.assertions(4);
const run = function () {
config.set('test.enable', 'something');
@@ -184,7 +184,11 @@ describe('lib/config/config', function () {
run();
} catch (err) {
expect(err).toHaveProperty('name', 'ValidationError');
- expect(err.details[0].message).toBe('"enable" must be a boolean');
+ expect(err).toHaveProperty('message',
+ 'child \"test\" fails because [child \"enable\" fails because [\"enable\" must be a boolean]]'
+ );
+ expect(err).not.toHaveProperty('details');
+ expect(err).not.toHaveProperty('_object');
}
done();
From ece86f60023746700b58b5d60e6a2577dee7525c Mon Sep 17 00:00:00 2001
From: Brandon Kobel
Date: Wed, 23 Jan 2019 06:25:31 -0800
Subject: [PATCH 02/29] Switch implicit server.log behavior with tmpl to
logWithMetadata (#29002)
* Changing the optimizer's use to logWithMetadata
* Switching ensureEsVersion to logWithMetadata
* Changing pid logging to use logWithMetadata
* Changing server/plugins to use logWithMetadata
* Changing saved objects onBeforeWrite to logWithMetata
* Changing server/status to server.logWithMetadata
* Changing ui settings to use logWithMetadata
* Removing _.template's usage from within log_format
* Fixing initializing plugin log message
* Fixing ensureEsVersion tests
* Fixing health check tests
* Fixing a few more forgotten tests
---
.../lib/__tests__/ensure_es_version.js | 35 ++++++++++---------
.../lib/__tests__/health_check.js | 2 +-
.../elasticsearch/lib/ensure_es_version.js | 17 +++++----
src/optimize/base_optimizer.js | 4 +--
.../dynamic_dll_plugin/dll_compiler.js | 10 +++---
.../dynamic_dll_plugin/dynamic_dll_plugin.js | 12 +++----
src/optimize/index.js | 2 +-
src/optimize/watch/optmzr_role.js | 6 ++--
src/optimize/watch/watch_cache.ts | 10 +++---
src/optimize/watch/watch_optimizer.js | 11 +++---
src/server/logging/log_format.js | 5 ---
src/server/pid/index.js | 11 +++---
src/server/plugins/lib/plugin.js | 3 +-
src/server/plugins/scan_mixin.js | 12 +++----
.../service/create_saved_objects_service.js | 25 +++++++------
src/server/status/server_status.test.js | 2 +-
src/server/status/status.js | 16 +++++----
src/server/status/status.test.js | 2 +-
.../create_or_upgrade_integration.js | 10 +++---
.../create_or_upgrade_saved_config.js | 18 +++++-----
.../create_or_upgrade_saved_config.js | 5 ++-
src/ui/ui_settings/ui_settings_service.js | 10 +++---
.../ui_settings_service_factory.js | 4 +--
23 files changed, 112 insertions(+), 120 deletions(-)
diff --git a/src/legacy/core_plugins/elasticsearch/lib/__tests__/ensure_es_version.js b/src/legacy/core_plugins/elasticsearch/lib/__tests__/ensure_es_version.js
index 07a4c5373d17f..24df2f9c5f893 100644
--- a/src/legacy/core_plugins/elasticsearch/lib/__tests__/ensure_es_version.js
+++ b/src/legacy/core_plugins/elasticsearch/lib/__tests__/ensure_es_version.js
@@ -34,6 +34,7 @@ describe('plugins/elasticsearch', () => {
beforeEach(function () {
server = {
log: sinon.stub(),
+ logWithMetadata: sinon.stub(),
plugins: {
elasticsearch: {
getCluster: sinon.stub().withArgs('admin').returns({ callWithInternalUser: sinon.stub() }),
@@ -120,17 +121,17 @@ describe('plugins/elasticsearch', () => {
it('warns if a node is only off by a patch version', async () => {
setNodes('5.1.1');
await ensureEsVersion(server, KIBANA_VERSION);
- sinon.assert.callCount(server.log, 2);
- expect(server.log.getCall(0).args[0]).to.contain('debug');
- expect(server.log.getCall(1).args[0]).to.contain('warning');
+ sinon.assert.callCount(server.logWithMetadata, 2);
+ expect(server.logWithMetadata.getCall(0).args[0]).to.contain('debug');
+ expect(server.logWithMetadata.getCall(1).args[0]).to.contain('warning');
});
it('warns if a node is off by a patch version and without http publish address', async () => {
setNodeWithoutHTTP('5.1.1');
await ensureEsVersion(server, KIBANA_VERSION);
- sinon.assert.callCount(server.log, 2);
- expect(server.log.getCall(0).args[0]).to.contain('debug');
- expect(server.log.getCall(1).args[0]).to.contain('warning');
+ sinon.assert.callCount(server.logWithMetadata, 2);
+ expect(server.logWithMetadata.getCall(0).args[0]).to.contain('debug');
+ expect(server.logWithMetadata.getCall(1).args[0]).to.contain('warning');
});
it('errors if a node incompatible and without http publish address', async () => {
@@ -147,28 +148,28 @@ describe('plugins/elasticsearch', () => {
setNodes('5.1.1');
await ensureEsVersion(server, KIBANA_VERSION);
- sinon.assert.callCount(server.log, 2);
- expect(server.log.getCall(0).args[0]).to.contain('debug');
- expect(server.log.getCall(1).args[0]).to.contain('warning');
+ sinon.assert.callCount(server.logWithMetadata, 2);
+ expect(server.logWithMetadata.getCall(0).args[0]).to.contain('debug');
+ expect(server.logWithMetadata.getCall(1).args[0]).to.contain('warning');
await ensureEsVersion(server, KIBANA_VERSION);
- sinon.assert.callCount(server.log, 3);
- expect(server.log.getCall(2).args[0]).to.contain('debug');
+ sinon.assert.callCount(server.logWithMetadata, 3);
+ expect(server.logWithMetadata.getCall(2).args[0]).to.contain('debug');
});
it('warns again if the node list changes', async () => {
setNodes('5.1.1');
await ensureEsVersion(server, KIBANA_VERSION);
- sinon.assert.callCount(server.log, 2);
- expect(server.log.getCall(0).args[0]).to.contain('debug');
- expect(server.log.getCall(1).args[0]).to.contain('warning');
+ sinon.assert.callCount(server.logWithMetadata, 2);
+ expect(server.logWithMetadata.getCall(0).args[0]).to.contain('debug');
+ expect(server.logWithMetadata.getCall(1).args[0]).to.contain('warning');
setNodes('5.1.2');
await ensureEsVersion(server, KIBANA_VERSION);
- sinon.assert.callCount(server.log, 4);
- expect(server.log.getCall(2).args[0]).to.contain('debug');
- expect(server.log.getCall(3).args[0]).to.contain('warning');
+ sinon.assert.callCount(server.logWithMetadata, 4);
+ expect(server.logWithMetadata.getCall(2).args[0]).to.contain('debug');
+ expect(server.logWithMetadata.getCall(3).args[0]).to.contain('warning');
});
});
});
diff --git a/src/legacy/core_plugins/elasticsearch/lib/__tests__/health_check.js b/src/legacy/core_plugins/elasticsearch/lib/__tests__/health_check.js
index 0f736e61b76be..1a334083fb7b5 100644
--- a/src/legacy/core_plugins/elasticsearch/lib/__tests__/health_check.js
+++ b/src/legacy/core_plugins/elasticsearch/lib/__tests__/health_check.js
@@ -85,7 +85,7 @@ describe('plugins/elasticsearch', () => {
// Setup the server mock
server = {
- log: sinon.stub(),
+ logWithMetadata: sinon.stub(),
info: { port: 5601 },
config: function () { return { get, set }; },
plugins: {
diff --git a/src/legacy/core_plugins/elasticsearch/lib/ensure_es_version.js b/src/legacy/core_plugins/elasticsearch/lib/ensure_es_version.js
index 85ad2adfab5b9..5c34bd073500b 100644
--- a/src/legacy/core_plugins/elasticsearch/lib/ensure_es_version.js
+++ b/src/legacy/core_plugins/elasticsearch/lib/ensure_es_version.js
@@ -40,7 +40,7 @@ export function ensureEsVersion(server, kibanaVersion) {
const { callWithInternalUser } = server.plugins.elasticsearch.getCluster('admin');
const isProd = server.config().get('env.prod');
- server.log(['plugin', 'debug'], 'Checking Elasticsearch version');
+ server.logWithMetadata(['plugin', 'debug'], 'Checking Elasticsearch version');
return callWithInternalUser('nodes.info', {
filterPath: [
'nodes.*.version',
@@ -92,15 +92,14 @@ export function ensureEsVersion(server, kibanaVersion) {
const warningNodeNames = getHumanizedNodeNames(simplifiedNodes).join(', ');
if (lastWarnedNodesForServer.get(server) !== warningNodeNames) {
lastWarnedNodesForServer.set(server, warningNodeNames);
- server.log(['warning'], {
- tmpl: (
- `You're running Kibana ${kibanaVersion} with some different versions of ` +
+ server.logWithMetadata(['warning'],
+ `You're running Kibana ${kibanaVersion} with some different versions of ` +
'Elasticsearch. Update Kibana or Elasticsearch to the same ' +
- `version to prevent compatibility issues: ${warningNodeNames}`
- ),
- kibanaVersion,
- nodes: simplifiedNodes,
- });
+ `version to prevent compatibility issues: ${warningNodeNames}`,
+ {
+ kibanaVersion,
+ nodes: simplifiedNodes,
+ });
}
}
diff --git a/src/optimize/base_optimizer.js b/src/optimize/base_optimizer.js
index 21f41e342bf9c..ea6ef1e5fe29c 100644
--- a/src/optimize/base_optimizer.js
+++ b/src/optimize/base_optimizer.js
@@ -46,7 +46,7 @@ const STATS_WARNINGS_FILTER = new RegExp([
export default class BaseOptimizer {
constructor(opts) {
- this.log = opts.log || (() => null);
+ this.logWithMetadata = opts.logWithMetadata || (() => null);
this.uiBundles = opts.uiBundles;
this.profile = opts.profile || false;
@@ -270,7 +270,7 @@ export default class BaseOptimizer {
new DynamicDllPlugin({
uiBundles: this.uiBundles,
threadLoaderPoolConfig: this.getThreadLoaderPoolConfig(),
- log: this.log
+ logWithMetadata: this.logWithMetadata
}),
new MiniCssExtractPlugin({
diff --git a/src/optimize/dynamic_dll_plugin/dll_compiler.js b/src/optimize/dynamic_dll_plugin/dll_compiler.js
index 26065c90d345a..5853dcf86dc81 100644
--- a/src/optimize/dynamic_dll_plugin/dll_compiler.js
+++ b/src/optimize/dynamic_dll_plugin/dll_compiler.js
@@ -51,13 +51,13 @@ export class DllCompiler {
};
}
- constructor(uiBundles, threadLoaderPoolConfig, log) {
+ constructor(uiBundles, threadLoaderPoolConfig, logWithMetadata) {
this.rawDllConfig = DllCompiler.getRawDllConfig(
uiBundles,
uiBundles.getCacheDirectory('babel'),
threadLoaderPoolConfig
);
- this.log = log || (() => null);
+ this.logWithMetadata = logWithMetadata || (() => null);
}
async init() {
@@ -182,7 +182,7 @@ export class DllCompiler {
async runWebpack(config) {
return new Promise((resolve, reject) => {
- this.log(['info', 'optimize:dynamic_dll_plugin'], 'Client vendors dll compilation started');
+ this.logWithMetadata(['info', 'optimize:dynamic_dll_plugin'], 'Client vendors dll compilation started');
webpack(config, (err, stats) => {
// If a critical error occurs or we have
@@ -197,7 +197,7 @@ export class DllCompiler {
}));
if (webpackErrors) {
- this.log(
+ this.logWithMetadata(
['fatal', 'optimize:dynamic_dll_plugin'],
`Client vendors dll compilation failed`
);
@@ -205,7 +205,7 @@ export class DllCompiler {
}
// Otherwise let it proceed
- this.log(
+ this.logWithMetadata(
['info', 'optimize:dynamic_dll_plugin'],
`Client vendors dll compilation finished with success`
);
diff --git a/src/optimize/dynamic_dll_plugin/dynamic_dll_plugin.js b/src/optimize/dynamic_dll_plugin/dynamic_dll_plugin.js
index c1d20606a49a3..480905fb234c0 100644
--- a/src/optimize/dynamic_dll_plugin/dynamic_dll_plugin.js
+++ b/src/optimize/dynamic_dll_plugin/dynamic_dll_plugin.js
@@ -40,9 +40,9 @@ function inPluginNodeModules(checkPath) {
}
export class DynamicDllPlugin {
- constructor({ uiBundles, threadLoaderPoolConfig, log, maxCompilations = 1 }) {
- this.log = log || (() => null);
- this.dllCompiler = new DllCompiler(uiBundles, threadLoaderPoolConfig, log);
+ constructor({ uiBundles, threadLoaderPoolConfig, logWithMetadata, maxCompilations = 1 }) {
+ this.logWithMetadata = logWithMetadata || (() => null);
+ this.dllCompiler = new DllCompiler(uiBundles, threadLoaderPoolConfig, logWithMetadata);
this.entryPaths = '';
this.afterCompilationEntryPaths = '';
this.maxCompilations = maxCompilations;
@@ -92,7 +92,7 @@ export class DynamicDllPlugin {
}
registerTasksHooks(compiler) {
- this.log(['info', 'optimize:dynamic_dll_plugin'], 'Started dynamic dll plugin tasks');
+ this.logWithMetadata(['info', 'optimize:dynamic_dll_plugin'], 'Started dynamic dll plugin tasks');
this.registerBeforeCompileHook(compiler);
this.registerCompilationHook(compiler);
this.registerDoneHook(compiler);
@@ -231,7 +231,7 @@ export class DynamicDllPlugin {
// Only run this info log in the first performed dll compilation
// per each execution run
if (this.performedCompilations === 0) {
- this.log(
+ this.logWithMetadata(
['info', 'optimize:dynamic_dll_plugin'],
compilation.needsDLLCompilation
? 'Need to compile the client vendors dll'
@@ -269,7 +269,7 @@ export class DynamicDllPlugin {
if (this.forceDLLCreationFlag) {
this.forceDLLCreationFlag = false;
}
- this.log(['info', 'optimize:dynamic_dll_plugin'], 'Finished all dynamic dll plugin tasks');
+ this.logWithMetadata(['info', 'optimize:dynamic_dll_plugin'], 'Finished all dynamic dll plugin tasks');
});
}
diff --git a/src/optimize/index.js b/src/optimize/index.js
index b6ba806573e52..2820fe1a76457 100644
--- a/src/optimize/index.js
+++ b/src/optimize/index.js
@@ -62,7 +62,7 @@ export default async (kbnServer, server, config) => {
// only require the FsOptimizer when we need to
const optimizer = new FsOptimizer({
- log: (tags, data) => server.log(tags, data),
+ logWithMetadata: (tags, message, metadata) => server.logWithMetadata(tags, message, metadata),
uiBundles,
profile: config.get('optimize.profile'),
sourceMaps: config.get('optimize.sourceMaps'),
diff --git a/src/optimize/watch/optmzr_role.js b/src/optimize/watch/optmzr_role.js
index 6c45774f4cdbc..d6b12f8c944b6 100644
--- a/src/optimize/watch/optmzr_role.js
+++ b/src/optimize/watch/optmzr_role.js
@@ -25,16 +25,16 @@ import { DllCompiler } from '../dynamic_dll_plugin';
import { WatchCache } from './watch_cache';
export default async (kbnServer, kibanaHapiServer, config) => {
- const log = (tags, data) => kibanaHapiServer.log(tags, data);
+ const logWithMetadata = (tags, message, metadata) => kibanaHapiServer.logWithMetadata(tags, message, metadata);
const watchOptimizer = new WatchOptimizer({
- log,
+ logWithMetadata,
uiBundles: kbnServer.uiBundles,
profile: config.get('optimize.profile'),
sourceMaps: config.get('optimize.sourceMaps'),
prebuild: config.get('optimize.watchPrebuild'),
watchCache: new WatchCache({
- log,
+ logWithMetadata,
outputPath: config.get('path.data'),
dllsPath: DllCompiler.getRawDllConfig().outputPath,
cachePath: resolve(kbnServer.uiBundles.getCacheDirectory(), '../'),
diff --git a/src/optimize/watch/watch_cache.ts b/src/optimize/watch/watch_cache.ts
index f744900c21e8c..5b594b30e9f8f 100644
--- a/src/optimize/watch/watch_cache.ts
+++ b/src/optimize/watch/watch_cache.ts
@@ -31,7 +31,7 @@ const readAsync = promisify(readFile);
const writeAsync = promisify(writeFile);
interface Params {
- log: (tags: string[], data: string) => void;
+ logWithMetadata: (tags: string[], message: string, metadata?: { [key: string]: any }) => void;
outputPath: string;
dllsPath: string;
cachePath: string;
@@ -43,7 +43,7 @@ interface WatchCacheStateContent {
}
export class WatchCache {
- private readonly log: Params['log'];
+ private readonly logWithMetadata: Params['logWithMetadata'];
private readonly outputPath: Params['outputPath'];
private readonly dllsPath: Params['dllsPath'];
private readonly cachePath: Params['cachePath'];
@@ -53,7 +53,7 @@ export class WatchCache {
private isInitialized: boolean;
constructor(params: Params) {
- this.log = params.log;
+ this.logWithMetadata = params.logWithMetadata;
this.outputPath = params.outputPath;
this.dllsPath = params.dllsPath;
this.cachePath = params.cachePath;
@@ -87,7 +87,7 @@ export class WatchCache {
}
public async reset() {
- this.log(['info', 'optimize:watch_cache'], 'The optimizer watch cache will reset');
+ this.logWithMetadata(['info', 'optimize:watch_cache'], 'The optimizer watch cache will reset');
// start by deleting the state file to lower the
// amount of time that another process might be able to
@@ -116,7 +116,7 @@ export class WatchCache {
// re-write new cache state file
await this.write();
- this.log(['info', 'optimize:watch_cache'], 'The optimizer watch cache has reset');
+ this.logWithMetadata(['info', 'optimize:watch_cache'], 'The optimizer watch cache has reset');
}
private async buildShaWithMultipleFiles(filePaths: string[]) {
diff --git a/src/optimize/watch/watch_optimizer.js b/src/optimize/watch/watch_optimizer.js
index 82e77f8bc22d3..93e467740a6c6 100644
--- a/src/optimize/watch/watch_optimizer.js
+++ b/src/optimize/watch/watch_optimizer.js
@@ -156,16 +156,14 @@ export default class WatchOptimizer extends BaseOptimizer {
switch (type) {
case STATUS.RUNNING:
if (!this.initialBuildComplete) {
- this.log(['info', 'optimize'], {
- tmpl: 'Optimization started',
+ this.logWithMetadata(['info', 'optimize'], `Optimization started`, {
bundles: this.uiBundles.getIds()
});
}
break;
case STATUS.SUCCESS:
- this.log(['info', 'optimize'], {
- tmpl: 'Optimization <%= status %> in <%= seconds %> seconds',
+ this.logWithMetadata(['info', 'optimize'], `Optimization success in ${seconds} seconds`, {
bundles: this.uiBundles.getIds(),
status: 'success',
seconds
@@ -176,8 +174,7 @@ export default class WatchOptimizer extends BaseOptimizer {
// errors during initialization to the server, unlike the rest of the
// errors produced here. Lets not muddy the console with extra errors
if (!this.initializing) {
- this.log(['fatal', 'optimize'], {
- tmpl: 'Optimization <%= status %> in <%= seconds %> seconds<%= err %>',
+ this.logWithMetadata(['fatal', 'optimize'], `Optimization failed in ${seconds} seconds${error}`, {
bundles: this.uiBundles.getIds(),
status: 'failed',
seconds,
@@ -187,7 +184,7 @@ export default class WatchOptimizer extends BaseOptimizer {
break;
case STATUS.FATAL:
- this.log('fatal', error);
+ this.logWithMetadata('fatal', error);
process.exit(1);
break;
}
diff --git a/src/server/logging/log_format.js b/src/server/logging/log_format.js
index ab7fb8264c9d5..8caae11e2e499 100644
--- a/src/server/logging/log_format.js
+++ b/src/server/logging/log_format.js
@@ -162,11 +162,6 @@ export default class TransformObjStream extends Stream.Transform {
else if (logWithMetadata.isLogEvent(event.data)) {
_.assign(data, logWithMetadata.getLogEventData(event.data));
}
- else if (_.isPlainObject(event.data) && event.data.tmpl) {
- _.assign(data, event.data);
- data.tmpl = undefined;
- data.message = _.template(event.data.tmpl)(event.data);
- }
else {
data.message = _.isString(event.data) ? event.data : inspect(event.data);
}
diff --git a/src/server/pid/index.js b/src/server/pid/index.js
index 30592c525390c..cc53b8bd97f3d 100644
--- a/src/server/pid/index.js
+++ b/src/server/pid/index.js
@@ -33,24 +33,23 @@ export default Promise.method(function (kbnServer, server, config) {
.catch(function (err) {
if (err.code !== 'EEXIST') throw err;
- const log = {
- tmpl: 'pid file already exists at <%= path %>',
+ const message = `pid file already exists at ${path}`;
+ const metadata = {
path: path,
pid: pid
};
if (config.get('pid.exclusive')) {
- throw Boom.internal(_.template(log.tmpl)(log), log);
+ throw Boom.internal(message, { message, ...metadata });
} else {
- server.log(['pid', 'warning'], log);
+ server.log(['pid', 'warning'], message, metadata);
}
return writeFile(path, pid);
})
.then(function () {
- server.log(['pid', 'debug'], {
- tmpl: 'wrote pid file to <%= path %>',
+ server.logWithMetadata(['pid', 'debug'], `wrote pid file to ${path}`, {
path: path,
pid: pid
});
diff --git a/src/server/plugins/lib/plugin.js b/src/server/plugins/lib/plugin.js
index 7399804c818fe..46dd047a657cc 100644
--- a/src/server/plugins/lib/plugin.js
+++ b/src/server/plugins/lib/plugin.js
@@ -66,8 +66,7 @@ export class Plugin {
this._server = server;
this._options = options;
- server.log(['plugins', 'debug'], {
- tmpl: 'Initializing plugin <%= plugin.toString() %>',
+ server.logWithMetadata(['plugins', 'debug'], `Initializing plugin ${this.toString()}`, {
plugin: this
});
diff --git a/src/server/plugins/scan_mixin.js b/src/server/plugins/scan_mixin.js
index 8a25ad231593a..5e21207482e9d 100644
--- a/src/server/plugins/scan_mixin.js
+++ b/src/server/plugins/scan_mixin.js
@@ -38,17 +38,16 @@ export async function scanMixin(kbnServer, server, config) {
const logging$ = Rx.merge(
pack$.pipe(
tap(definition => {
- server.log(['plugin', 'debug'], {
- tmpl: 'Found plugin at <%= path %>',
- path: definition.getPath()
+ const path = definition.getPath();
+ server.logWithMetadata(['plugin', 'debug'], `Found plugin at ${path}`, {
+ path
});
})
),
invalidDirectoryError$.pipe(
tap(error => {
- server.log(['plugin', 'warning'], {
- tmpl: '<%= err.code %>: Unable to scan directory for plugins "<%= dir %>"',
+ server.logWithMetadata(['plugin', 'warning'], `${error.code}: Unable to scan directory for plugins "${error.path}"`, {
err: error,
dir: error.path
});
@@ -57,8 +56,7 @@ export async function scanMixin(kbnServer, server, config) {
invalidPackError$.pipe(
tap(error => {
- server.log(['plugin', 'warning'], {
- tmpl: 'Skipping non-plugin directory at <%= path %>',
+ server.logWithMetadata(['plugin', 'warning'], `Skipping non-plugin directory at ${error.path}`, {
path: error.path
});
})
diff --git a/src/server/saved_objects/service/create_saved_objects_service.js b/src/server/saved_objects/service/create_saved_objects_service.js
index 7432c92d52f44..8b56daa1a3398 100644
--- a/src/server/saved_objects/service/create_saved_objects_service.js
+++ b/src/server/saved_objects/service/create_saved_objects_service.js
@@ -49,17 +49,20 @@ export function createSavedObjectsService(server, schema, serializer, migrator)
},
});
} catch (error) {
- server.log(['debug', 'savedObjects'], {
- tmpl: 'Attempt to write indexTemplate for SavedObjects index failed: <%= err.message %>',
- es: {
- resp: error.body,
- status: error.status,
- },
- err: {
- message: error.message,
- stack: error.stack,
- },
- });
+ server.logWithMetadata(
+ ['debug', 'savedObjects'],
+ `Attempt to write indexTemplate for SavedObjects index failed: ${error.message}`,
+ {
+ es: {
+ resp: error.body,
+ status: error.status,
+ },
+ err: {
+ message: error.message,
+ stack: error.stack,
+ },
+ }
+ );
// We reject with `es.ServiceUnavailable` because writing an index
// template is a very simple operation so if we get an error here
diff --git a/src/server/status/server_status.test.js b/src/server/status/server_status.test.js
index 78ed017755aeb..c6e6721c0f926 100644
--- a/src/server/status/server_status.test.js
+++ b/src/server/status/server_status.test.js
@@ -31,7 +31,7 @@ describe('ServerStatus class', function () {
let serverStatus;
beforeEach(function () {
- server = { expose: sinon.stub(), log: sinon.stub() };
+ server = { expose: sinon.stub(), logWithMetadata: sinon.stub() };
serverStatus = new ServerStatus(server);
});
diff --git a/src/server/status/status.js b/src/server/status/status.js
index 54924fc88b53b..4255eb3531b0a 100644
--- a/src/server/status/status.js
+++ b/src/server/status/status.js
@@ -42,13 +42,15 @@ export default class Status extends EventEmitter {
this.state === 'red' ? 'error' : 'info'
];
- server.log(tags, {
- tmpl: 'Status changed from <%= prevState %> to <%= state %><%= message ? " - " + message : "" %>',
- state: this.state,
- message: this.message,
- prevState: previous,
- prevMsg: previousMsg
- });
+ server.logWithMetadata(tags,
+ `Status changed from ${ previous } to ${this.state}${ this.message ? ' - ' + this.message : '' }`,
+ {
+ state: this.state,
+ message: this.message,
+ prevState: previous,
+ prevMsg: previousMsg
+ }
+ );
});
}
diff --git a/src/server/status/status.test.js b/src/server/status/status.test.js
index c6bc967ca0766..48fdaeedbe5af 100644
--- a/src/server/status/status.test.js
+++ b/src/server/status/status.test.js
@@ -27,7 +27,7 @@ describe('Status class', function () {
let serverStatus;
beforeEach(function () {
- server = { expose: sinon.stub(), log: sinon.stub() };
+ server = { expose: sinon.stub(), logWithMetadata: sinon.stub() };
serverStatus = new ServerStatus(server);
});
diff --git a/src/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_integration.js b/src/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_integration.js
index 1c8ade94456d0..b407f5b327c7b 100644
--- a/src/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_integration.js
+++ b/src/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_integration.js
@@ -78,7 +78,7 @@ describe('createOrUpgradeSavedConfig()', () => {
savedObjectsClient,
version: '5.4.0',
buildNum: 54099,
- log: sinon.stub(),
+ logWithMetadata: sinon.stub(),
});
const config540 = await savedObjectsClient.get('config', '5.4.0');
@@ -104,7 +104,7 @@ describe('createOrUpgradeSavedConfig()', () => {
savedObjectsClient,
version: '5.4.1',
buildNum: 54199,
- log: sinon.stub(),
+ logWithMetadata: sinon.stub(),
});
const config541 = await savedObjectsClient.get('config', '5.4.1');
@@ -130,7 +130,7 @@ describe('createOrUpgradeSavedConfig()', () => {
savedObjectsClient,
version: '7.0.0-rc1',
buildNum: 70010,
- log: sinon.stub(),
+ logWithMetadata: sinon.stub(),
});
const config700rc1 = await savedObjectsClient.get('config', '7.0.0-rc1');
@@ -157,7 +157,7 @@ describe('createOrUpgradeSavedConfig()', () => {
savedObjectsClient,
version: '7.0.0',
buildNum: 70099,
- log: sinon.stub(),
+ logWithMetadata: sinon.stub(),
});
const config700 = await savedObjectsClient.get('config', '7.0.0');
@@ -185,7 +185,7 @@ describe('createOrUpgradeSavedConfig()', () => {
savedObjectsClient,
version: '6.2.3-rc1',
buildNum: 62310,
- log: sinon.stub(),
+ logWithMetadata: sinon.stub(),
});
const config623rc1 = await savedObjectsClient.get('config', '6.2.3-rc1');
diff --git a/src/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_saved_config.js b/src/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_saved_config.js
index 14b7013a4f625..9c36233d0d1f9 100644
--- a/src/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_saved_config.js
+++ b/src/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_saved_config.js
@@ -35,7 +35,7 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () {
const buildNum = chance.integer({ min: 1000, max: 5000 });
function setup() {
- const log = sinon.stub();
+ const logWithMetadata = sinon.stub();
const getUpgradeableConfig = sandbox.stub(getUpgradeableConfigNS, 'getUpgradeableConfig');
const savedObjectsClient = {
create: sinon.stub().callsFake(async (type, attributes, options = {}) => ({
@@ -50,7 +50,7 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () {
savedObjectsClient,
version,
buildNum,
- log,
+ logWithMetadata,
...options
});
@@ -62,7 +62,7 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () {
return {
buildNum,
- log,
+ logWithMetadata,
run,
version,
savedObjectsClient,
@@ -120,17 +120,17 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () {
});
it('should log a message for upgrades', async () => {
- const { getUpgradeableConfig, log, run } = setup();
+ const { getUpgradeableConfig, logWithMetadata, run } = setup();
getUpgradeableConfig
.returns({ id: prevVersion, attributes: { buildNum: buildNum - 100 } });
await run();
- sinon.assert.calledOnce(log);
- sinon.assert.calledWithExactly(log,
+ sinon.assert.calledOnce(logWithMetadata);
+ sinon.assert.calledWithExactly(logWithMetadata,
['plugin', 'elasticsearch'],
+ sinon.match('Upgrade'),
sinon.match({
- tmpl: sinon.match('Upgrade'),
prevVersion,
newVersion: version,
})
@@ -138,7 +138,7 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () {
});
it('does not log when upgrade fails', async () => {
- const { getUpgradeableConfig, log, run, savedObjectsClient } = setup();
+ const { getUpgradeableConfig, logWithMetadata, run, savedObjectsClient } = setup();
getUpgradeableConfig
.returns({ id: prevVersion, attributes: { buildNum: buildNum - 100 } });
@@ -154,7 +154,7 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () {
expect(error.message).to.be('foo');
}
- sinon.assert.notCalled(log);
+ sinon.assert.notCalled(logWithMetadata);
});
});
diff --git a/src/ui/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.js b/src/ui/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.js
index 184e2ca9794a2..c175e583ee916 100644
--- a/src/ui/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.js
+++ b/src/ui/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.js
@@ -26,7 +26,7 @@ export async function createOrUpgradeSavedConfig(options) {
savedObjectsClient,
version,
buildNum,
- log,
+ logWithMetadata,
onWriteError,
} = options;
@@ -58,8 +58,7 @@ export async function createOrUpgradeSavedConfig(options) {
}
if (upgradeableConfig) {
- log(['plugin', 'elasticsearch'], {
- tmpl: 'Upgrade config from <%= prevVersion %> to <%= newVersion %>',
+ logWithMetadata(['plugin', 'elasticsearch'], `Upgrade config from ${upgradeableConfig.id} to ${version}`, {
prevVersion: upgradeableConfig.id,
newVersion: version
});
diff --git a/src/ui/ui_settings/ui_settings_service.js b/src/ui/ui_settings/ui_settings_service.js
index c755b0b6932bd..0451dc588c923 100644
--- a/src/ui/ui_settings/ui_settings_service.js
+++ b/src/ui/ui_settings/ui_settings_service.js
@@ -46,8 +46,8 @@ export class UiSettingsService {
// we use a function for getDefaults() so that defaults can be different in
// different scenarios, and so they can change over time
getDefaults = () => ({}),
- // function that accepts log messages in the same format as server.log
- log = () => {},
+ // function that accepts log messages in the same format as server.logWithMetadata
+ logWithMetadata = () => {},
overrides = {},
} = options;
@@ -57,7 +57,7 @@ export class UiSettingsService {
this._savedObjectsClient = savedObjectsClient;
this._getDefaults = getDefaults;
this._overrides = overrides;
- this._log = log;
+ this._logWithMetadata = logWithMetadata;
}
async getDefaults() {
@@ -157,7 +157,7 @@ export class UiSettingsService {
savedObjectsClient: this._savedObjectsClient,
version: this._id,
buildNum: this._buildNum,
- log: this._log,
+ logWithMetadata: this._logWithMetadata,
});
await this._write({
@@ -195,7 +195,7 @@ export class UiSettingsService {
savedObjectsClient: this._savedObjectsClient,
version: this._id,
buildNum: this._buildNum,
- log: this._log,
+ logWithMetadata: this._logWithMetadata,
onWriteError(error, attributes) {
if (isNotAuthorizedError(error) || isForbiddenError(error)) {
return attributes;
diff --git a/src/ui/ui_settings/ui_settings_service_factory.js b/src/ui/ui_settings/ui_settings_service_factory.js
index 7112ddf7374e4..f83a0d9825557 100644
--- a/src/ui/ui_settings/ui_settings_service_factory.js
+++ b/src/ui/ui_settings/ui_settings_service_factory.js
@@ -47,6 +47,6 @@ export function uiSettingsServiceFactory(server, options) {
savedObjectsClient,
getDefaults,
overrides,
- log: (...args) => server.log(...args),
+ logWithMetadata: (...args) => server.logWithMetadata(...args),
});
-}
\ No newline at end of file
+}
From f56ed2c99975724f58642ac63c440d132ca9fe19 Mon Sep 17 00:00:00 2001
From: Nox911
Date: Wed, 23 Jan 2019 17:54:57 +0300
Subject: [PATCH 03/29] Fix template (#28922)
---
.../watch_edit_execute_detail/watch_edit_execute_detail.html | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/x-pack/plugins/watcher/public/sections/watch_edit/components/watch_edit_execute_detail/watch_edit_execute_detail.html b/x-pack/plugins/watcher/public/sections/watch_edit/components/watch_edit_execute_detail/watch_edit_execute_detail.html
index 684d5ac5de59b..69e7a282f5ec9 100644
--- a/x-pack/plugins/watcher/public/sections/watch_edit/components/watch_edit_execute_detail/watch_edit_execute_detail.html
+++ b/x-pack/plugins/watcher/public/sections/watch_edit/components/watch_edit_execute_detail/watch_edit_execute_detail.html
@@ -94,9 +94,12 @@
type="checkbox"
ng-model="watchEditExecuteDetail.executeDetails.ignoreCondition"
class="kuiCheckBox"
+ />
+
+ >
+
From 80a193341ea341f17ba4f422d52d7b935039feb7 Mon Sep 17 00:00:00 2001
From: Andrew Cholakian
Date: Wed, 23 Jan 2019 07:16:57 -0800
Subject: [PATCH 04/29] [Uptime] Remove broken stacked chart in monitor detail
page. (#29019)
This chart had no legend and the sum of it was incorrect. We can bring this back later in a form that actually functions.
---
.../queries/monitor_charts/monitor_charts.tsx | 119 +++++-------------
1 file changed, 30 insertions(+), 89 deletions(-)
diff --git a/x-pack/plugins/uptime/public/components/queries/monitor_charts/monitor_charts.tsx b/x-pack/plugins/uptime/public/components/queries/monitor_charts/monitor_charts.tsx
index a7dfc0938d66c..b7957f578b20c 100644
--- a/x-pack/plugins/uptime/public/components/queries/monitor_charts/monitor_charts.tsx
+++ b/x-pack/plugins/uptime/public/components/queries/monitor_charts/monitor_charts.tsx
@@ -112,9 +112,6 @@ export const MonitorCharts = ({
const durationDomain = avgDurationSeries.concat(areaRttSeries);
const durationLimits = [0, Math.max(...durationDomain.map(({ y }) => y))];
- // find the greatest y-value for rtt chart
- const rttLimits = [0, Math.max(...maxRtt.map(({ y }) => y))];
-
return (
@@ -122,58 +119,38 @@ export const MonitorCharts = ({
-
+
-
-
-
-
@@ -182,80 +159,44 @@ export const MonitorCharts = ({
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
);
}}
From 8f54a6fc43c94eae18e85000d673e25b801a1852 Mon Sep 17 00:00:00 2001
From: Justin Kambic
Date: Wed, 23 Jan 2019 10:36:03 -0500
Subject: [PATCH 05/29] [Uptime] Disable update button for SDP (#29150)
* Disable update button for SDP.
* Update SDP style.
---
x-pack/plugins/uptime/public/uptime_app.tsx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/x-pack/plugins/uptime/public/uptime_app.tsx b/x-pack/plugins/uptime/public/uptime_app.tsx
index 1f181970c8b0a..f0a4daa6fc5ea 100644
--- a/x-pack/plugins/uptime/public/uptime_app.tsx
+++ b/x-pack/plugins/uptime/public/uptime_app.tsx
@@ -148,7 +148,7 @@ class Application extends React.Component {
{
this.persistState
);
}}
+ showUpdateButton={false}
/>
From e7069089db89d1e1f3e3d5bba17d82e9517d344a Mon Sep 17 00:00:00 2001
From: Paul Sanwald
Date: Wed, 23 Jan 2019 11:56:30 -0500
Subject: [PATCH 06/29] Small improvements to add cluster page (#29142)
Improve text around what port should be entered, and add a tooltip that explains the "Not Connected" error message.
---
.../remote_cluster_form.js | 2 +-
.../connection_status/connection_status.js | 26 +++++++++++++++----
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/x-pack/plugins/remote_clusters/public/sections/components/remote_cluster_form/remote_cluster_form.js b/x-pack/plugins/remote_clusters/public/sections/components/remote_cluster_form/remote_cluster_form.js
index 791c5ea43f218..dee024944d33a 100644
--- a/x-pack/plugins/remote_clusters/public/sections/components/remote_cluster_form/remote_cluster_form.js
+++ b/x-pack/plugins/remote_clusters/public/sections/components/remote_cluster_form/remote_cluster_form.js
@@ -327,7 +327,7 @@ export const RemoteClusterForm = injectI18n(
helpText={(
)}
isInvalid={showErrors}
diff --git a/x-pack/plugins/remote_clusters/public/sections/remote_cluster_list/components/connection_status/connection_status.js b/x-pack/plugins/remote_clusters/public/sections/remote_cluster_list/components/connection_status/connection_status.js
index c60d6f9c74a11..d316267f435e0 100644
--- a/x-pack/plugins/remote_clusters/public/sections/remote_cluster_list/components/connection_status/connection_status.js
+++ b/x-pack/plugins/remote_clusters/public/sections/remote_cluster_list/components/connection_status/connection_status.js
@@ -12,6 +12,7 @@ import {
EuiFlexGroup,
EuiFlexItem,
EuiIcon,
+ EuiIconTip,
EuiText,
} from '@elastic/eui';
@@ -43,16 +44,31 @@ export function ConnectionStatus({ isConnected }) {
});
}
+ const seedNodeTooltip = i18n.translate('xpack.remoteClusters.connectedStatus.notConnectedToolTip', {
+ defaultMessage: "Ensure the seed nodes are configured with the remote cluster's transport port, not the http port.",
+ });
+
return (
- {icon}
+
+
+ {icon}
+
+
+
+
+ {message}
+
+
+
-
-
- {message}
-
+
+
);
From 09f890483f7fc300a33b0a7b52833afa2bdb0868 Mon Sep 17 00:00:00 2001
From: Nathan Reese
Date: Wed, 23 Jan 2019 10:21:41 -0700
Subject: [PATCH 07/29] [Maps] Move alpha from style descriptor to layer
descriptor (#29059)
* default alpha
* update heatmap descriptor to use constant
* clean-up
* use ValidatedRange to ensure alphaValue can not be set to invalid value
* fix jest test expect
* move alpha to layer property
* ensure defaults are set when Layer object is instantiated
---
.../gis/public/actions/store_actions.js | 8 +--
.../public/angular/get_initial_layers.test.js | 6 +-
.../public/components/layer_panel/index.js | 15 +----
.../layer_panel/settings_panel/index.js | 8 +--
.../settings_panel/settings_panel.js | 13 ++--
.../shared/components/validated_range.js | 19 ++++--
.../gis/public/shared/layers/heatmap_layer.js | 7 +-
.../plugins/gis/public/shared/layers/layer.js | 17 +++--
.../es_geohashgrid_source.js | 65 +++++++------------
.../vector/size/size_range_selector.js | 4 ++
.../vector/size/static_size_selection.js | 2 +
.../shared/layers/styles/heatmap_style.js | 30 ++++-----
.../public/shared/layers/styles/tile_style.js | 20 +++---
.../shared/layers/styles/vector_style.js | 28 +++-----
.../layers/styles/vector_style_defaults.js | 4 +-
.../gis/public/shared/layers/tile_layer.js | 16 +++--
.../gis/public/shared/layers/vector_layer.js | 17 +++--
x-pack/plugins/gis/public/store/map.js | 8 ---
.../sample_data/web_logs_saved_objects.json | 2 +-
19 files changed, 133 insertions(+), 156 deletions(-)
diff --git a/x-pack/plugins/gis/public/actions/store_actions.js b/x-pack/plugins/gis/public/actions/store_actions.js
index 6eb5a12883d65..dc6a170b6f470 100644
--- a/x-pack/plugins/gis/public/actions/store_actions.js
+++ b/x-pack/plugins/gis/public/actions/store_actions.js
@@ -42,7 +42,6 @@ export const UPDATE_LAYER_STYLE_FOR_SELECTED_LAYER = 'UPDATE_LAYER_STYLE';
export const PROMOTE_TEMPORARY_STYLES = 'PROMOTE_TEMPORARY_STYLES';
export const CLEAR_TEMPORARY_STYLES = 'CLEAR_TEMPORARY_STYLES';
export const TOUCH_LAYER = 'TOUCH_LAYER';
-export const UPDATE_LAYER_ALPHA_VALUE = 'UPDATE_LAYER_ALPHA_VALUE';
export const UPDATE_SOURCE_PROP = 'UPDATE_SOURCE_PROP';
export const SET_REFRESH_CONFIG = 'SET_REFRESH_CONFIG';
export const SET_MOUSE_COORDINATES = 'SET_MOUSE_COORDINATES';
@@ -352,11 +351,12 @@ export function updateLayerMaxZoom(id, maxZoom) {
};
}
-export function updateLayerAlphaValue(id, newAlphaValue) {
+export function updateLayerAlpha(id, alpha) {
return {
- type: UPDATE_LAYER_ALPHA_VALUE,
+ type: UPDATE_LAYER_PROP,
id,
- newAlphaValue
+ propName: 'alpha',
+ newValue: alpha,
};
}
diff --git a/x-pack/plugins/gis/public/angular/get_initial_layers.test.js b/x-pack/plugins/gis/public/angular/get_initial_layers.test.js
index 8cf99b2201482..47f610d8cf8db 100644
--- a/x-pack/plugins/gis/public/angular/get_initial_layers.test.js
+++ b/x-pack/plugins/gis/public/angular/get_initial_layers.test.js
@@ -45,6 +45,7 @@ describe('Saved object does not have layer list', () => {
const layers = getInitialLayers(null, dataSources);
expect(layers).toEqual([{
+ "alpha": 1,
dataRequests: [],
id: layers[0].id,
label: null,
@@ -56,7 +57,7 @@ describe('Saved object does not have layer list', () => {
url: 'myTileUrl',
},
style: {
- properties: undefined,
+ properties: {},
type: 'TILE',
},
temporary: false,
@@ -72,6 +73,7 @@ describe('Saved object does not have layer list', () => {
const layers = getInitialLayers(null, dataSources);
expect(layers).toEqual([{
+ "alpha": 1,
dataRequests: [],
id: layers[0].id,
label: null,
@@ -83,7 +85,7 @@ describe('Saved object does not have layer list', () => {
type: 'EMS_TMS'
},
style: {
- properties: undefined,
+ properties: {},
type: 'TILE',
},
temporary: false,
diff --git a/x-pack/plugins/gis/public/components/layer_panel/index.js b/x-pack/plugins/gis/public/components/layer_panel/index.js
index 158a0b1a6f105..cd14860b7ccf3 100644
--- a/x-pack/plugins/gis/public/components/layer_panel/index.js
+++ b/x-pack/plugins/gis/public/components/layer_panel/index.js
@@ -7,12 +7,6 @@
import { connect } from 'react-redux';
import { LayerPanel } from './view';
import { getSelectedLayer } from '../../selectors/map_selectors';
-import {
- updateLayerLabel,
- updateLayerMaxZoom,
- updateLayerMinZoom,
- updateLayerAlphaValue
-} from '../../actions/store_actions';
function mapStateToProps(state = {}) {
return {
@@ -20,13 +14,8 @@ function mapStateToProps(state = {}) {
};
}
-function mapDispatchToProps(dispatch) {
- return {
- updateLabel: (id, label) => dispatch(updateLayerLabel(id, label)),
- updateMinZoom: (id, minZoom) => dispatch(updateLayerMinZoom(id, minZoom)),
- updateMaxZoom: (id, maxZoom) => dispatch(updateLayerMaxZoom(id, maxZoom)),
- updateAlphaValue: (id, alphaValue) => dispatch(updateLayerAlphaValue(id, alphaValue))
- };
+function mapDispatchToProps(/* dispatch */) {
+ return {};
}
const connectedLayerPanel = connect(mapStateToProps, mapDispatchToProps)(LayerPanel);
diff --git a/x-pack/plugins/gis/public/components/layer_panel/settings_panel/index.js b/x-pack/plugins/gis/public/components/layer_panel/settings_panel/index.js
index b943c2ffc2a64..2bbcbe3273e01 100644
--- a/x-pack/plugins/gis/public/components/layer_panel/settings_panel/index.js
+++ b/x-pack/plugins/gis/public/components/layer_panel/settings_panel/index.js
@@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import _ from 'lodash';
import { connect } from 'react-redux';
import { SettingsPanel } from './settings_panel';
import { getSelectedLayer } from '../../../selectors/map_selectors';
@@ -12,19 +11,18 @@ import {
updateLayerLabel,
updateLayerMaxZoom,
updateLayerMinZoom,
- updateLayerAlphaValue,
+ updateLayerAlpha,
updateSourceProp,
} from '../../../actions/store_actions';
function mapStateToProps(state = {}) {
const selectedLayer = getSelectedLayer(state);
return {
- alphaValue: _.get(selectedLayer.getCurrentStyle(), '_descriptor.properties.alphaValue', 1),
+ alpha: selectedLayer.getAlpha(),
label: selectedLayer.getLabel(),
layerId: selectedLayer.getId(),
maxZoom: selectedLayer.getMaxZoom(),
minZoom: selectedLayer.getMinZoom(),
- alphaValue: _.get(selectedLayer.getCurrentStyle(), '_descriptor.properties.alphaValue', 1),
renderSourceDetails: selectedLayer.renderSourceDetails,
renderSourceSettingsEditor: selectedLayer.renderSourceSettingsEditor,
};
@@ -35,7 +33,7 @@ function mapDispatchToProps(dispatch) {
updateLabel: (id, label) => dispatch(updateLayerLabel(id, label)),
updateMinZoom: (id, minZoom) => dispatch(updateLayerMinZoom(id, minZoom)),
updateMaxZoom: (id, maxZoom) => dispatch(updateLayerMaxZoom(id, maxZoom)),
- updateAlphaValue: (id, alphaValue) => dispatch(updateLayerAlphaValue(id, alphaValue)),
+ updateAlpha: (id, alpha) => dispatch(updateLayerAlpha(id, alpha)),
updateSourceProp: (id, propName, value) => dispatch(updateSourceProp(id, propName, value)),
};
}
diff --git a/x-pack/plugins/gis/public/components/layer_panel/settings_panel/settings_panel.js b/x-pack/plugins/gis/public/components/layer_panel/settings_panel/settings_panel.js
index 7884497a3a410..8efb06622f0bc 100644
--- a/x-pack/plugins/gis/public/components/layer_panel/settings_panel/settings_panel.js
+++ b/x-pack/plugins/gis/public/components/layer_panel/settings_panel/settings_panel.js
@@ -17,6 +17,7 @@ import {
EuiSpacer,
EuiLink,
} from '@elastic/eui';
+import { ValidatedRange } from '../../../shared/components/validated_range';
export class SettingsPanel extends Component {
@@ -45,10 +46,8 @@ export class SettingsPanel extends Component {
this.props.updateMaxZoom(this.props.layerId, zoom);
}
- onAlphaValueChange = (event) => {
- const sanitizedValue = parseFloat(event.target.value);
- const alphaValue = isNaN(sanitizedValue) ? '' : sanitizedValue;
- this.props.updateAlphaValue(this.props.layerId, alphaValue);
+ onAlphaChange = (alpha) => {
+ this.props.updateAlpha(this.props.layerId, alpha);
}
onSourceChange = ({ propName, value }) => {
@@ -113,12 +112,12 @@ export class SettingsPanel extends Component {
label="Layer transparency"
>
-
{
- const sanitizedValue = parseInt(e.target.value, 10);
+ const sanitizedValue = parseFloat(e.target.value, 10);
let newValue = isNaN(sanitizedValue) ? '' : sanitizedValue;
// work around for https://github.com/elastic/eui/issues/1458
// TODO remove once above EUI issue is resolved
@@ -56,11 +56,19 @@ export class ValidatedRange extends React.Component {
};
render() {
+ const {
+ max,
+ min,
+ value, // eslint-disable-line no-unused-vars
+ onChange, // eslint-disable-line no-unused-vars
+ ...rest
+ } = this.props;
+
let errorMessage;
if (!this.state.isValid) {
errorMessage = (
- {`Must be between ${this.props.min} and ${this.props.max}`}
+ {`Must be between ${min} and ${max}`}
);
}
@@ -68,12 +76,11 @@ export class ValidatedRange extends React.Component {
return (
{errorMessage}
diff --git a/x-pack/plugins/gis/public/shared/layers/heatmap_layer.js b/x-pack/plugins/gis/public/shared/layers/heatmap_layer.js
index ee0b9651b0fd4..8459dd833f4ce 100644
--- a/x-pack/plugins/gis/public/shared/layers/heatmap_layer.js
+++ b/x-pack/plugins/gis/public/shared/layers/heatmap_layer.js
@@ -88,7 +88,12 @@ export class HeatmapLayer extends ALayer {
}
mbMap.setLayoutProperty(heatmapLayerId, 'visibility', this.isVisible() ? 'visible' : 'none');
- this._style.setMBPaintProperties(mbMap, heatmapLayerId, SCALED_PROPERTY_NAME);
+ this._style.setMBPaintProperties({
+ mbMap,
+ layerId: heatmapLayerId,
+ propertyName: SCALED_PROPERTY_NAME,
+ alpha: this.getAlpha(),
+ });
mbMap.setLayerZoomRange(heatmapLayerId, this._descriptor.minZoom, this._descriptor.maxZoom);
}
diff --git a/x-pack/plugins/gis/public/shared/layers/layer.js b/x-pack/plugins/gis/public/shared/layers/layer.js
index 054219d86e43d..2a9d56f28e0d6 100644
--- a/x-pack/plugins/gis/public/shared/layers/layer.js
+++ b/x-pack/plugins/gis/public/shared/layers/layer.js
@@ -14,7 +14,7 @@ const NO_SOURCE_UPDATE_REQUIRED = false;
export class ALayer {
constructor({ layerDescriptor, source, style }) {
- this._descriptor = layerDescriptor;
+ this._descriptor = ALayer.createDescriptor(layerDescriptor);
this._source = source;
this._style = style;
@@ -30,16 +30,15 @@ export class ALayer {
return mbStyle.sources[sourceId].data;
}
- static createDescriptor(options) {
- const layerDescriptor = {};
+ static createDescriptor(options = {}) {
+ const layerDescriptor = { ...options };
- layerDescriptor.dataRequests = [];
- layerDescriptor.id = Math.random().toString(36).substr(2, 5);
+ layerDescriptor.dataRequests = _.get(options, 'dataRequests', []);
+ layerDescriptor.id = _.get(options, 'id', Math.random().toString(36).substr(2, 5));
layerDescriptor.label = options.label && options.label.length > 0 ? options.label : null;
layerDescriptor.minZoom = _.get(options, 'minZoom', 0);
layerDescriptor.maxZoom = _.get(options, 'maxZoom', 24);
- layerDescriptor.source = options.source;
- layerDescriptor.sourceDescriptor = options.sourceDescriptor;
+ layerDescriptor.alpha = _.get(options, 'alpha', 0.75);
layerDescriptor.visible = options.visible || true;
layerDescriptor.temporary = options.temporary || false;
layerDescriptor.style = options.style || {};
@@ -109,6 +108,10 @@ export class ALayer {
return this._descriptor.maxZoom;
}
+ getAlpha() {
+ return this._descriptor.alpha;
+ }
+
getZoomConfig() {
return {
minZoom: this._descriptor.minZoom,
diff --git a/x-pack/plugins/gis/public/shared/layers/sources/es_geohashgrid_source/es_geohashgrid_source.js b/x-pack/plugins/gis/public/shared/layers/sources/es_geohashgrid_source/es_geohashgrid_source.js
index 7431ff45278f3..a5897ea047576 100644
--- a/x-pack/plugins/gis/public/shared/layers/sources/es_geohashgrid_source/es_geohashgrid_source.js
+++ b/x-pack/plugins/gis/public/shared/layers/sources/es_geohashgrid_source/es_geohashgrid_source.js
@@ -301,48 +301,31 @@ export class ESGeohashGridSource extends VectorSource {
sourceDescriptor: this._descriptor,
...options
});
- descriptor.style = {
- ...descriptor.style,
- type: 'VECTOR',
- properties: {
- fillColor: {
- type: 'DYNAMIC',
- options: {
- field: {
- label: COUNT_PROP_LABEL,
- name: COUNT_PROP_NAME,
- origin: 'source'
- },
- color: 'Blues'
- }
- },
- lineColor: {
- type: 'STATIC',
- options: {
- color: '#cccccc'
- }
- },
- lineWidth: {
- type: 'STATIC',
- options: {
- size: 1
- }
- },
- iconSize: {
- type: 'DYNAMIC',
- options: {
- field: {
- label: COUNT_PROP_LABEL,
- name: COUNT_PROP_NAME,
- origin: 'source'
- },
- minSize: 4,
- maxSize: 32,
- }
- },
- alphaValue: 1
+ descriptor.style = VectorStyle.createDescriptor({
+ fillColor: {
+ type: VectorStyle.STYLE_TYPE.DYNAMIC,
+ options: {
+ field: {
+ label: COUNT_PROP_LABEL,
+ name: COUNT_PROP_NAME,
+ origin: 'source'
+ },
+ color: 'Blues'
+ }
+ },
+ iconSize: {
+ type: VectorStyle.STYLE_TYPE.DYNAMIC,
+ options: {
+ field: {
+ label: COUNT_PROP_LABEL,
+ name: COUNT_PROP_NAME,
+ origin: 'source'
+ },
+ minSize: 4,
+ maxSize: 32,
+ }
}
- };
+ });
return descriptor;
}
diff --git a/x-pack/plugins/gis/public/shared/layers/styles/components/vector/size/size_range_selector.js b/x-pack/plugins/gis/public/shared/layers/styles/components/vector/size/size_range_selector.js
index dda95f336c8d1..88b5926e2cf36 100644
--- a/x-pack/plugins/gis/public/shared/layers/styles/components/vector/size/size_range_selector.js
+++ b/x-pack/plugins/gis/public/shared/layers/styles/components/vector/size/size_range_selector.js
@@ -43,6 +43,8 @@ export function SizeRangeSelector({ minSize, maxSize, onChange }) {
max={DEFAULT_MAX_SIZE}
value={minSize}
onChange={onMinSizeChange}
+ showInput
+ showRange
/>
@@ -56,6 +58,8 @@ export function SizeRangeSelector({ minSize, maxSize, onChange }) {
max={DEFAULT_MAX_SIZE}
value={maxSize}
onChange={onMaxSizeChange}
+ showInput
+ showRange
/>
diff --git a/x-pack/plugins/gis/public/shared/layers/styles/components/vector/size/static_size_selection.js b/x-pack/plugins/gis/public/shared/layers/styles/components/vector/size/static_size_selection.js
index 2a8ba9b6c7dac..0a0c29e28c289 100644
--- a/x-pack/plugins/gis/public/shared/layers/styles/components/vector/size/static_size_selection.js
+++ b/x-pack/plugins/gis/public/shared/layers/styles/components/vector/size/static_size_selection.js
@@ -20,6 +20,8 @@ export function StaticSizeSelection({ onChange, styleOptions }) {
max={100}
value={styleOptions.size}
onChange={onSizeChange}
+ showInput
+ showRange
/>
);
}
diff --git a/x-pack/plugins/gis/public/shared/layers/styles/heatmap_style.js b/x-pack/plugins/gis/public/shared/layers/styles/heatmap_style.js
index c87729dc06620..7d1a80f6918ec 100644
--- a/x-pack/plugins/gis/public/shared/layers/styles/heatmap_style.js
+++ b/x-pack/plugins/gis/public/shared/layers/styles/heatmap_style.js
@@ -14,20 +14,23 @@ export class HeatmapStyle {
static type = 'HEATMAP';
- constructor(styleDescriptor) {
- this._descriptor = styleDescriptor;
+ constructor(styleDescriptor = {}) {
+ this._descriptor = HeatmapStyle.createDescriptor(
+ styleDescriptor.refinement,
+ styleDescriptor.properties
+ );
}
static canEdit(styleInstance) {
return styleInstance.constructor === HeatmapStyle;
}
- static createDescriptor(refinement) {
+ static createDescriptor(refinement, properties = {}) {
return {
type: HeatmapStyle.type,
refinement: refinement || 'coarse',
properties: {
- alphaValue: 1
+ ...properties
}
};
}
@@ -47,15 +50,8 @@ export class HeatmapStyle {
}
- _getMBOpacity() {
- const DEFAULT_OPACITY = 1;
- return typeof this._descriptor.properties.alphaValue === 'number' ? this._descriptor.properties.alphaValue : DEFAULT_OPACITY;
- }
-
- setMBPaintProperties(mbMap, pointLayerID, property) {
-
+ setMBPaintProperties({ alpha, mbMap, layerId, propertyName }) {
let radius;
- const opacity = this._getMBOpacity();
if (this._descriptor.refinement === 'coarse') {
radius = 64;
} else if (this._descriptor.refinement === 'fine') {
@@ -65,12 +61,12 @@ export class HeatmapStyle {
} else {
throw new Error(`Refinement param not recognized: ${this._descriptor.refinement}`);
}
- mbMap.setPaintProperty(pointLayerID, 'heatmap-radius', radius);
- mbMap.setPaintProperty(pointLayerID, 'heatmap-weight', {
- "type": 'identity',
- "property": property
+ mbMap.setPaintProperty(layerId, 'heatmap-radius', radius);
+ mbMap.setPaintProperty(layerId, 'heatmap-weight', {
+ type: 'identity',
+ property: propertyName
});
- mbMap.setPaintProperty(pointLayerID, 'heatmap-opacity', opacity);
+ mbMap.setPaintProperty(layerId, 'heatmap-opacity', alpha);
}
getRefinement() {
diff --git a/x-pack/plugins/gis/public/shared/layers/styles/tile_style.js b/x-pack/plugins/gis/public/shared/layers/styles/tile_style.js
index d0441df57def7..fc07c01aeafcb 100644
--- a/x-pack/plugins/gis/public/shared/layers/styles/tile_style.js
+++ b/x-pack/plugins/gis/public/shared/layers/styles/tile_style.js
@@ -8,18 +8,20 @@ export class TileStyle {
static type = 'TILE';
- constructor(styleDescriptor) {
- this._descriptor = styleDescriptor;
+ constructor(styleDescriptor = {}) {
+ this._descriptor = TileStyle.createDescriptor(styleDescriptor.properties);
}
static canEdit(styleInstance) {
return styleInstance.constructor === TileStyle;
}
- static createDescriptor(properties) {
+ static createDescriptor(properties = {}) {
return {
type: TileStyle.type,
- properties
+ properties: {
+ ...properties,
+ }
};
}
@@ -27,13 +29,7 @@ export class TileStyle {
return 'Tile style';
}
- _getMBOpacity() {
- const DEFAULT_OPACITY = 1;
- return typeof this._descriptor.properties.alphaValue === 'number' ? this._descriptor.properties.alphaValue : DEFAULT_OPACITY;
- }
-
- setMBPaintProperties(mbMap, tileLayerID) {
- const opacity = this._getMBOpacity();
- mbMap.setPaintProperty(tileLayerID, 'raster-opacity', opacity);
+ setMBPaintProperties({ alpha, mbMap, layerId }) {
+ mbMap.setPaintProperty(layerId, 'raster-opacity', alpha);
}
}
diff --git a/x-pack/plugins/gis/public/shared/layers/styles/vector_style.js b/x-pack/plugins/gis/public/shared/layers/styles/vector_style.js
index 03d216ecce6c5..55acb03f64221 100644
--- a/x-pack/plugins/gis/public/shared/layers/styles/vector_style.js
+++ b/x-pack/plugins/gis/public/shared/layers/styles/vector_style.js
@@ -11,7 +11,7 @@ import { FillableCircle, FillableVector } from '../../icons/additional_layer_ico
import { ColorGradient } from '../../icons/color_gradient';
import { getHexColorRangeStrings } from '../../utils/color_utils';
import { VectorStyleEditor } from './components/vector/vector_style_editor';
-import { DEFAULT_ALPHA_VALUE, getDefaultStaticProperties } from './vector_style_defaults';
+import { getDefaultStaticProperties } from './vector_style_defaults';
export class VectorStyle {
@@ -22,7 +22,7 @@ export class VectorStyle {
return `__kbn__scaled(${fieldName})`;
}
- constructor(descriptor) {
+ constructor(descriptor = {}) {
this._descriptor = VectorStyle.createDescriptor(descriptor.properties);
}
@@ -30,11 +30,10 @@ export class VectorStyle {
return styleInstance.constructor === VectorStyle;
}
- static createDescriptor(properties) {
- const defaultStyleProperties = getDefaultStaticProperties();
+ static createDescriptor(properties = {}) {
return {
type: VectorStyle.type,
- properties: { ...defaultStyleProperties, ...properties }
+ properties: { ...getDefaultStaticProperties(), ...properties }
};
}
@@ -259,10 +258,6 @@ export class VectorStyle {
return null;
}
- _getMBOpacity() {
- return _.get(this._descriptor.properties, 'alphaValue', DEFAULT_ALPHA_VALUE);
- }
-
_getMbSize(styleDescriptor) {
if (styleDescriptor.type === VectorStyle.STYLE_TYPE.STATIC) {
return styleDescriptor.options.size;
@@ -282,13 +277,11 @@ export class VectorStyle {
return null;
}
- setMBPaintProperties(mbMap, sourceId, fillLayerId, lineLayerId) {
- const opacity = this._getMBOpacity();
-
+ setMBPaintProperties({ alpha, mbMap, fillLayerId, lineLayerId }) {
if (this._descriptor.properties.fillColor) {
const color = this._getMBColor(this._descriptor.properties.fillColor);
mbMap.setPaintProperty(fillLayerId, 'fill-color', color);
- mbMap.setPaintProperty(fillLayerId, 'fill-opacity', opacity);
+ mbMap.setPaintProperty(fillLayerId, 'fill-opacity', alpha);
} else {
mbMap.setPaintProperty(fillLayerId, 'fill-color', null);
mbMap.setPaintProperty(fillLayerId, 'fill-opacity', 0);
@@ -297,7 +290,7 @@ export class VectorStyle {
if (this._descriptor.properties.lineColor) {
const color = this._getMBColor(this._descriptor.properties.lineColor);
mbMap.setPaintProperty(lineLayerId, 'line-color', color);
- mbMap.setPaintProperty(lineLayerId, 'line-opacity', opacity);
+ mbMap.setPaintProperty(lineLayerId, 'line-opacity', alpha);
} else {
mbMap.setPaintProperty(lineLayerId, 'line-color', null);
@@ -312,12 +305,11 @@ export class VectorStyle {
}
}
- setMBPaintPropertiesForPoints(mbMap, sourceId, pointLayerId) {
- const opacity = this._getMBOpacity();
+ setMBPaintPropertiesForPoints({ alpha, mbMap, pointLayerId }) {
if (this._descriptor.properties.fillColor) {
const color = this._getMBColor(this._descriptor.properties.fillColor);
mbMap.setPaintProperty(pointLayerId, 'circle-color', color);
- mbMap.setPaintProperty(pointLayerId, 'circle-opacity', opacity);
+ mbMap.setPaintProperty(pointLayerId, 'circle-opacity', alpha);
} else {
mbMap.setPaintProperty(pointLayerId, 'circle-color', null);
mbMap.setPaintProperty(pointLayerId, 'circle-opacity', 0);
@@ -325,7 +317,7 @@ export class VectorStyle {
if (this._descriptor.properties.lineColor) {
const color = this._getMBColor(this._descriptor.properties.lineColor);
mbMap.setPaintProperty(pointLayerId, 'circle-stroke-color', color);
- mbMap.setPaintProperty(pointLayerId, 'circle-stroke-opacity', opacity);
+ mbMap.setPaintProperty(pointLayerId, 'circle-stroke-opacity', alpha);
} else {
mbMap.setPaintProperty(pointLayerId, 'circle-stroke-color', null);
diff --git a/x-pack/plugins/gis/public/shared/layers/styles/vector_style_defaults.js b/x-pack/plugins/gis/public/shared/layers/styles/vector_style_defaults.js
index 7e0aa83f887dc..fa45178d66764 100644
--- a/x-pack/plugins/gis/public/shared/layers/styles/vector_style_defaults.js
+++ b/x-pack/plugins/gis/public/shared/layers/styles/vector_style_defaults.js
@@ -8,7 +8,7 @@ import { VectorStyle } from './vector_style';
import { COLOR_GRADIENTS } from './components/vector/color/color_ramp_select';
const DEFAULT_COLORS = ['#e6194b', '#3cb44b', '#ffe119', '#f58231', '#911eb4'];
-export const DEFAULT_ALPHA_VALUE = 1;
+
export const DEFAULT_MIN_SIZE = 1;
export const DEFAULT_MAX_SIZE = 64;
@@ -43,7 +43,6 @@ export function getDefaultStaticProperties(mapColors = []) {
size: 10
}
},
- alphaValue: DEFAULT_ALPHA_VALUE
};
}
@@ -75,6 +74,5 @@ export function getDefaultDynamicProperties() {
maxSize: DEFAULT_MAX_SIZE
}
},
- alphaValue: DEFAULT_ALPHA_VALUE
};
}
diff --git a/x-pack/plugins/gis/public/shared/layers/tile_layer.js b/x-pack/plugins/gis/public/shared/layers/tile_layer.js
index 0519cde0faf5d..5950398a6ff10 100644
--- a/x-pack/plugins/gis/public/shared/layers/tile_layer.js
+++ b/x-pack/plugins/gis/public/shared/layers/tile_layer.js
@@ -4,11 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import _ from 'lodash';
import { ALayer } from './layer';
import React from 'react';
import { EuiIcon } from '@elastic/eui';
import { TileStyle } from '../layers/styles/tile_style';
-import _ from 'lodash';
export class TileLayer extends ALayer {
@@ -16,17 +16,15 @@ export class TileLayer extends ALayer {
constructor({ layerDescriptor, source, style }) {
super({ layerDescriptor, source, style });
- if (!style || !_.get(style, '_descriptor.properties.alphaValue')) {
- const defaultStyle = TileStyle.createDescriptor({
- alphaValue: 1
- });
- this._style = new TileStyle(defaultStyle);
+ if (!style) {
+ this._style = new TileStyle();
}
}
static createDescriptor(options) {
const tileLayerDescriptor = super.createDescriptor(options);
tileLayerDescriptor.type = TileLayer.type;
+ tileLayerDescriptor.alpha = _.get(options, 'alpha', 1);
tileLayerDescriptor.style =
TileStyle.createDescriptor(tileLayerDescriptor.style.properties);
return tileLayerDescriptor;
@@ -57,7 +55,11 @@ export class TileLayer extends ALayer {
mbMap.setLayoutProperty(layerId, 'visibility', this.isVisible() ? 'visible' : 'none');
mbMap.setLayerZoomRange(layerId, this._descriptor.minZoom, this._descriptor.maxZoom);
- this._style && this._style.setMBPaintProperties(mbMap, layerId);
+ this._style && this._style.setMBPaintProperties({
+ alpha: this.getAlpha(),
+ mbMap,
+ layerId,
+ });
}
getIcon() {
diff --git a/x-pack/plugins/gis/public/shared/layers/vector_layer.js b/x-pack/plugins/gis/public/shared/layers/vector_layer.js
index 735546e63c2cc..b81bf0dfff83c 100644
--- a/x-pack/plugins/gis/public/shared/layers/vector_layer.js
+++ b/x-pack/plugins/gis/public/shared/layers/vector_layer.js
@@ -397,13 +397,17 @@ export class VectorLayer extends ALayer {
});
mbMap.setFilter(pointLayerId, ['any', ['==', ['geometry-type'], 'Point'], ['==', ['geometry-type'], 'MultiPoint']]);
}
- this._style.setMBPaintPropertiesForPoints(mbMap, this.getId(), pointLayerId);
+ this._style.setMBPaintPropertiesForPoints({
+ alpha: this.getAlpha(),
+ mbMap,
+ pointLayerId: pointLayerId,
+ });
mbMap.setLayoutProperty(pointLayerId, 'visibility', this.isVisible() ? 'visible' : 'none');
mbMap.setLayerZoomRange(pointLayerId, this._descriptor.minZoom, this._descriptor.maxZoom);
this._addTooltipListeners(mbMap, pointLayerId);
}
- _setMbLinePolygonProeprties(mbMap) {
+ _setMbLinePolygonProperties(mbMap) {
const sourceId = this.getId();
const fillLayerId = this.getId() + '_fill';
const lineLayerId = this.getId() + '_line';
@@ -437,7 +441,12 @@ export class VectorLayer extends ALayer {
['==', ['geometry-type'], 'MultiLineString']
]);
}
- this._style.setMBPaintProperties(mbMap, this.getId(), fillLayerId, lineLayerId, this.isTemporary());
+ this._style.setMBPaintProperties({
+ alpha: this.getAlpha(),
+ mbMap,
+ fillLayerId,
+ lineLayerId,
+ });
mbMap.setLayoutProperty(fillLayerId, 'visibility', this.isVisible() ? 'visible' : 'none');
mbMap.setLayoutProperty(lineLayerId, 'visibility', this.isVisible() ? 'visible' : 'none');
mbMap.setLayerZoomRange(lineLayerId, this._descriptor.minZoom, this._descriptor.maxZoom);
@@ -447,7 +456,7 @@ export class VectorLayer extends ALayer {
_syncStylePropertiesWithMb(mbMap) {
this._setMbPointsProperties(mbMap);
- this._setMbLinePolygonProeprties(mbMap);
+ this._setMbLinePolygonProperties(mbMap);
}
_syncSourceBindingWithMb(mbMap) {
diff --git a/x-pack/plugins/gis/public/store/map.js b/x-pack/plugins/gis/public/store/map.js
index cf32464034a9c..78cc2560ae7e3 100644
--- a/x-pack/plugins/gis/public/store/map.js
+++ b/x-pack/plugins/gis/public/store/map.js
@@ -27,7 +27,6 @@ import {
CLEAR_TEMPORARY_STYLES,
SET_JOINS,
TOUCH_LAYER,
- UPDATE_LAYER_ALPHA_VALUE,
UPDATE_SOURCE_PROP,
SET_REFRESH_CONFIG,
TRIGGER_REFRESH_TIMER,
@@ -192,13 +191,6 @@ export function map(state = INITIAL_STATE, action) {
return { ...state, selectedLayerId: match ? action.selectedLayerId : null };
case UPDATE_LAYER_ORDER:
return { ...state, layerList: action.newLayerOrder.map(layerNumber => state.layerList[layerNumber]) };
- case UPDATE_LAYER_ALPHA_VALUE:
- const alphaLayer = state.layerList.find(layer => layer.id === action.id);
- const preAlphaStyle = alphaLayer.style;
- return updateLayerInList(state, action.id, 'style',
- { ...preAlphaStyle, properties: { ...preAlphaStyle.properties,
- alphaValue: action.newAlphaValue }
- });
case UPDATE_LAYER_PROP:
return updateLayerInList(state, action.id, action.propName, action.newValue);
case UPDATE_SOURCE_PROP:
diff --git a/x-pack/plugins/gis/server/sample_data/web_logs_saved_objects.json b/x-pack/plugins/gis/server/sample_data/web_logs_saved_objects.json
index 07d7ad845fe58..09e9d7f271c60 100644
--- a/x-pack/plugins/gis/server/sample_data/web_logs_saved_objects.json
+++ b/x-pack/plugins/gis/server/sample_data/web_logs_saved_objects.json
@@ -8,7 +8,7 @@
"title" : "[Logs] Web Traffic",
"description" : "",
"mapStateJSON" : "{\"zoom\":3.92,\"center\":{\"lon\":-83.95443,\"lat\":38.02463},\"timeFilters\":{\"from\":\"now-7d\",\"to\":\"now\"}}",
- "layerListJSON" : "[{\"id\":\"0hmz5\",\"sourceDescriptor\":{\"type\":\"EMS_TMS\",\"id\":\"road_map\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"TILE\",\"properties\":{\"alphaValue\":1}},\"type\":\"TILE\",\"minZoom\":0,\"maxZoom\":24},{\"id\":\"ajk2l\",\"label\":\"logs(heatmap)\",\"minZoom\":0,\"maxZoom\":9,\"sourceDescriptor\":{\"type\":\"ES_GEOHASH_GRID\",\"id\":\"60c5dffb-7fca-431c-b1f0-9cc2e6697e8c\",\"indexPatternId\":\"90943e30-9a47-11e8-b64d-95841ca0b247\",\"geoField\":\"geo.coordinates\",\"requestType\":\"heatmap\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"HEATMAP\",\"refinement\":\"coarse\",\"properties\":{\"alphaValue\":0.75},\"previousStyle\":null},\"type\":\"HEATMAP\"},{\"id\":\"6hgh2\",\"label\":\"logs(documents)\",\"minZoom\":7,\"maxZoom\":24,\"sourceDescriptor\":{\"id\":\"541f2ca1-6a0f-4937-8846-a589222b7f28\",\"type\":\"ES_SEARCH\",\"indexPatternId\":\"90943e30-9a47-11e8-b64d-95841ca0b247\",\"geoField\":\"geo.coordinates\",\"limit\":2048,\"filterByMapBounds\":true,\"showTooltip\":true,\"tooltipProperties\":[\"timestamp\",\"clientip\",\"url\"]},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#e6194b\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}},\"alphaValue\":0.75},\"previousStyle\":null},\"type\":\"VECTOR\"}]",
+ "layerListJSON" : "[{\"id\":\"0hmz5\",\"sourceDescriptor\":{\"type\":\"EMS_TMS\",\"id\":\"road_map\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"TILE\",\"properties\":{\"alphaValue\":1}},\"type\":\"TILE\",\"alpha\":1,\"minZoom\":0,\"maxZoom\":24},{\"id\":\"ajk2l\",\"label\":\"logs(heatmap)\",\"alpha\":1,\"minZoom\":0,\"maxZoom\":9,\"sourceDescriptor\":{\"type\":\"ES_GEOHASH_GRID\",\"id\":\"60c5dffb-7fca-431c-b1f0-9cc2e6697e8c\",\"indexPatternId\":\"90943e30-9a47-11e8-b64d-95841ca0b247\",\"geoField\":\"geo.coordinates\",\"requestType\":\"heatmap\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"HEATMAP\",\"refinement\":\"coarse\",\"properties\":{\"alphaValue\":0.75},\"previousStyle\":null},\"type\":\"HEATMAP\"},{\"id\":\"6hgh2\",\"label\":\"logs(documents)\",\"alpha\":1,\"minZoom\":7,\"maxZoom\":24,\"sourceDescriptor\":{\"id\":\"541f2ca1-6a0f-4937-8846-a589222b7f28\",\"type\":\"ES_SEARCH\",\"indexPatternId\":\"90943e30-9a47-11e8-b64d-95841ca0b247\",\"geoField\":\"geo.coordinates\",\"limit\":2048,\"filterByMapBounds\":true,\"showTooltip\":true,\"tooltipProperties\":[\"timestamp\",\"clientip\",\"url\"]},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#e6194b\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}},\"alphaValue\":0.75},\"previousStyle\":null},\"type\":\"VECTOR\"}]",
"uiStateJSON" : "{\"isDarkMode\":false}",
"bounds" : {
"type" : "envelope",
From a11e4714203ffecbac086770fb5267d6813c2fdd Mon Sep 17 00:00:00 2001
From: Jason Rhodes
Date: Wed, 23 Jan 2019 13:46:09 -0500
Subject: [PATCH 08/29] Updates React et al to 16.6 (#24707)
* Updates react to 16.6 (latest)
* Updated fragment-based snapshots for Kibana root unit tests
* Updated fragment-based snapshots for x-pack unit tests
* Removed xpack yarn.lock file bc it is no longer needed, it was reintroduced by accident during a rebase in this branch
* React 16.6 snapshot updates, round 2 (mostly Fragment snapshot diffs)
* Updated last round of React 16.6 snapshots
* Fixes query bar issue with 16.4 gDSFP lifecycle
* Updated yarn lock (arraybuffer.slice updated)
* Updates snapshots where executeQueryOptions prop appears
---
package.json | 11 +-
.../dashboard_listing.test.js.snap | 84 +-
.../__snapshots__/home.test.js.snap | 30 +-
.../recently_accessed.test.js.snap | 126 +-
.../__snapshots__/tutorial.test.js.snap | 150 ++-
.../create_index_pattern_wizard.test.js.snap | 24 +-
.../__snapshots__/header.test.js.snap | 26 +-
.../__jest__/__snapshots__/table.test.js.snap | 38 +-
.../__snapshots__/flyout.test.js.snap | 74 +-
.../__snapshots__/header.test.js.snap | 4 +-
.../__snapshots__/relationships.test.js.snap | 514 ++++----
.../__jest__/__snapshots__/table.test.js.snap | 4 +-
.../form/__snapshots__/form.test.js.snap | 394 +++---
.../search/__snapshots__/search.test.js.snap | 4 +-
.../__snapshots__/new_vis_modal.test.tsx.snap | 1064 ++++++++++-------
.../__snapshots__/field_editor.test.js.snap | 846 +++++++------
.../field_format_editor.test.js.snap | 6 +-
.../bytes/__snapshots__/bytes.test.js.snap | 4 +-
.../color/__snapshots__/color.test.js.snap | 12 +-
.../date/__snapshots__/date.test.js.snap | 4 +-
.../__snapshots__/duration.test.js.snap | 8 +-
.../number/__snapshots__/number.test.js.snap | 4 +-
.../__snapshots__/percent.test.js.snap | 4 +-
.../__snapshots__/static_lookup.test.js.snap | 8 +-
.../string/__snapshots__/string.test.js.snap | 4 +-
.../__snapshots__/truncate.test.js.snap | 4 +-
.../url/__snapshots__/url.test.js.snap | 12 +-
.../disabled_call_out.test.js.snap | 4 +-
.../warning_call_out.test.js.snap | 4 +-
.../public/query_bar/components/query_bar.tsx | 3 +-
.../url_panel_content.test.js.snap | 8 +-
x-pack/package.json | 11 +-
.../TransactionOverview.test.js.snap | 8 +-
.../__snapshots__/HistoryTabs.test.tsx.snap | 4 +-
.../__snapshots__/upload_license.test.js.snap | 478 +++++---
.../__snapshots__/form_label.test.js.snap | 8 +-
.../actions_section.test.js.snap | 12 +-
.../conditions_section.test.js.snap | 16 +-
.../rule_editor_flyout.test.js.snap | 16 +-
.../__snapshots__/scope_section.test.js.snap | 92 +-
.../delete_rule_modal.test.js.snap | 12 +-
.../explorer_chart_label.test.js.snap | 96 +-
.../__snapshots__/editor.test.js.snap | 24 +-
.../__snapshots__/list.test.js.snap | 4 +-
.../__snapshots__/calendar_form.test.js.snap | 96 +-
.../__snapshots__/events_table.test.js.snap | 8 +-
.../__snapshots__/import_modal.test.js.snap | 4 +-
.../imported_events.test.js.snap | 4 +-
.../table/__snapshots__/table.test.js.snap | 4 +-
.../edit/__snapshots__/header.test.js.snap | 128 +-
.../edit/__snapshots__/toolbar.test.js.snap | 8 +-
.../list/__snapshots__/header.test.js.snap | 4 +-
.../list/__snapshots__/table.test.js.snap | 374 +++---
.../__snapshots__/ccr_shard.test.js.snap | 102 +-
.../report_info_button.test.tsx.snap | 20 +-
.../basic_login_form.test.tsx.snap | 4 +-
.../collapsible_panel.test.tsx.snap | 14 +-
.../elasticsearch_privileges.test.tsx.snap | 354 +++---
.../index_privilege_form.test.tsx.snap | 380 +++---
.../index_privileges.test.tsx.snap | 2 +-
.../impacted_spaces_flyout.test.tsx.snap | 4 +-
.../simple_privilege_form.test.tsx.snap | 4 +-
.../space_aware_privilege_form.test.tsx.snap | 260 ++--
.../advanced_settings_subtitle.test.tsx.snap | 4 +-
.../secure_space_message.test.tsx.snap | 4 +-
.../delete_spaces_button.test.tsx.snap | 4 +-
.../space_identifier.test.tsx.snap | 4 +-
.../spaces_grid_pages.test.tsx.snap | 220 ++--
.../space_selector.test.tsx.snap | 30 +-
.../__snapshots__/checkup_tab.test.tsx.snap | 686 ++++++-----
.../__snapshots__/telemetry_form.test.js.snap | 4 +-
yarn.lock | 185 ++-
72 files changed, 3734 insertions(+), 3444 deletions(-)
diff --git a/package.json b/package.json
index 1a4b99a1048b9..fb58309ea7a27 100644
--- a/package.json
+++ b/package.json
@@ -190,11 +190,11 @@
"pug": "^2.0.3",
"querystring-browser": "1.0.4",
"raw-loader": "0.5.1",
- "react": "^16.3.0",
+ "react": "^16.6.0",
"react-addons-shallow-compare": "15.6.2",
"react-anything-sortable": "^1.7.4",
"react-color": "^2.13.8",
- "react-dom": "^16.3.0",
+ "react-dom": "^16.6.0",
"react-grid-layout": "^0.16.2",
"react-input-range": "^1.3.0",
"react-markdown": "^3.1.4",
@@ -324,9 +324,10 @@
"classnames": "2.2.5",
"dedent": "^0.7.0",
"delete-empty": "^2.0.0",
- "enzyme": "3.2.0",
- "enzyme-adapter-react-16": "^1.1.1",
- "enzyme-to-json": "3.3.1",
+ "enzyme": "^3.7.0",
+ "enzyme-adapter-react-16": "^1.6.0",
+ "enzyme-adapter-utils": "^1.8.1",
+ "enzyme-to-json": "^3.3.4",
"eslint": "^5.6.0",
"eslint-config-prettier": "^3.1.0",
"eslint-plugin-babel": "^5.2.0",
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/listing/__snapshots__/dashboard_listing.test.js.snap b/src/legacy/core_plugins/kibana/public/dashboard/listing/__snapshots__/dashboard_listing.test.js.snap
index 7e03ebb675111..acb9ee97a6957 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/listing/__snapshots__/dashboard_listing.test.js.snap
+++ b/src/legacy/core_plugins/kibana/public/dashboard/listing/__snapshots__/dashboard_listing.test.js.snap
@@ -524,50 +524,48 @@ exports[`after fetch renders warning when listingLimit is exceeded 1`] = `
-
-
- }
- >
-
-
-
- ,
- "listingLimitText":
- listingLimit
- ,
- "listingLimitValue": 1,
- "totalDashboards": 2,
- }
+
+ }
+ >
+
+
+
+ ,
+ "listingLimitText":
+ listingLimit
+ ,
+ "listingLimitValue": 1,
+ "totalDashboards": 2,
}
- />
-
-
-
-
+ }
+ />
+
+
+
-
-
-
-
+
+
-
-
+
-
-
- label0
-
-
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
-
-
- label1
-
-
-
-
+ label1
+
+
+
-
-
-
- Home
-
- /
-
-
- Add data
-
- /
-
- jest test tutorial
-
-
-
+
+
+ Home
+
+ /
+
+
+ Add data
+
+ /
+
+ jest test tutorial
+
+
-
-
-
- Home
-
- /
-
-
- Add data
-
- /
-
- jest test tutorial
-
-
-
+
+
+ Home
+
+ /
+
+
+ Add data
+
+ /
+
+ jest test tutorial
+
+
-
-
-
- Home
-
- /
-
-
- Add data
-
- /
-
- jest test tutorial
-
-
-
+
+
+ Home
+
+ /
+
+
+ Add data
+
+ /
+
+ jest test tutorial
+
+
+
-
+
`;
exports[`CreateIndexPatternWizard renders index pattern step when there are indices 1`] = `
-
+
-
+
`;
exports[`CreateIndexPatternWizard renders the empty state when there are no indices 1`] = `
-
+
-
+
`;
exports[`CreateIndexPatternWizard renders time field step when step is set to 2 1`] = `
-
+
-
+
`;
exports[`CreateIndexPatternWizard renders when there are no indices but there are remote clusters 1`] = `
-
+
-
+
`;
exports[`CreateIndexPatternWizard shows system indices even if there are no other indices if the include system indices is toggled 1`] = `
-
+
-
+
`;
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/__jest__/__snapshots__/header.test.js.snap b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/__jest__/__snapshots__/header.test.js.snap
index 02ba1ee8fc730..6d77035e82041 100644
--- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/__jest__/__snapshots__/header.test.js.snap
+++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/__jest__/__snapshots__/header.test.js.snap
@@ -16,13 +16,11 @@ exports[`Header should render a different name, prompt, and beta tag if provided
}
}
/>
-
-
-
-
+
+
-
-
-
- Test prompt
-
-
+
+
+ Test prompt
+
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/__jest__/__snapshots__/table.test.js.snap b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/__jest__/__snapshots__/table.test.js.snap
index 8fc08181be4a1..80f44fbcb5d04 100644
--- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/__jest__/__snapshots__/table.test.js.snap
+++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/__jest__/__snapshots__/table.test.js.snap
@@ -2,26 +2,24 @@
exports[`Table editing should show a save button 1`] = `
-
-
-
-
+
+
`;
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/__jest__/__snapshots__/flyout.test.js.snap b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/__jest__/__snapshots__/flyout.test.js.snap
index 317cf1fc32564..03c36783f4c72 100644
--- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/__jest__/__snapshots__/flyout.test.js.snap
+++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/__jest__/__snapshots__/flyout.test.js.snap
@@ -24,45 +24,43 @@ exports[`Flyout conflicts should allow conflict resolution 1`] = `
/>
-
-
-
- }
- >
-
-
-
- ,
- }
+
+
+ }
+ >
+
+
+
+ ,
}
- />
-
-
-
+ }
+ />
+
+
+
-
+
`;
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/__snapshots__/relationships.test.js.snap b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/__snapshots__/relationships.test.js.snap
index 5f10fa8eb10cf..957b5b3fb534c 100644
--- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/__snapshots__/relationships.test.js.snap
+++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/__snapshots__/relationships.test.js.snap
@@ -40,77 +40,73 @@ exports[`Relationships should render dashboards normally 1`] = `
textStyle="normal"
type="row"
>
-
-
}
>
-
- }
- >
-
-
-
-
-
-
-
+
+
+
+
+
+
@@ -248,142 +244,134 @@ exports[`Relationships should render searches normally 1`] = `
textStyle="normal"
type="row"
>
-
-
}
>
-
- }
- >
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
}
>
-
- }
- >
-
-
-
-
-
-
-
+
+
+
+
+
+
@@ -429,77 +417,73 @@ exports[`Relationships should render visualizations normally 1`] = `
textStyle="normal"
type="row"
>
-
-
}
>
-
- }
- >
-
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/__jest__/__snapshots__/table.test.js.snap b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/__jest__/__snapshots__/table.test.js.snap
index d3ca955a95a54..55a6c904d55f8 100644
--- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/__jest__/__snapshots__/table.test.js.snap
+++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/__jest__/__snapshots__/table.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Table should render normally 1`] = `
-
+
-
+
`;
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/settings/components/form/__snapshots__/form.test.js.snap b/src/legacy/core_plugins/kibana/public/management/sections/settings/components/form/__snapshots__/form.test.js.snap
index 3f5625a19b66c..41455f90a6baf 100644
--- a/src/legacy/core_plugins/kibana/public/management/sections/settings/components/form/__snapshots__/form.test.js.snap
+++ b/src/legacy/core_plugins/kibana/public/management/sections/settings/components/form/__snapshots__/form.test.js.snap
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Form should not render no settings message when instructed not to 1`] = `
`;
+exports[`Form should not render no settings message when instructed not to 1`] = `
`;
exports[`Form should render no settings message when there are no settings 1`] = `
-
+
-
+
`;
exports[`Form should render normally 1`] = `
-
-
+
-
-
-
+
+
-
-
-
- General
-
-
-
-
-
-
+ General
+
+
+
+
+
+
-
+
-
-
-
-
-
+
+
+
+
-
-
-
+
+
-
-
-
- Dashboard
-
-
-
-
-
-
+ Dashboard
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
-
-
-
+
+
-
+
+ X-pack
+
+
+
-
-
- X-pack
-
-
-
-
-
-
-
-
- ,
- "settingsCount": 9,
- }
+
+
+
+
+
+ ,
+ "settingsCount": 9,
}
- />
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+ }
+ />
+
+
+
+
`;
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/settings/components/search/__snapshots__/search.test.js.snap b/src/legacy/core_plugins/kibana/public/management/sections/settings/components/search/__snapshots__/search.test.js.snap
index cdfc62c5134b8..70ad5b3819a88 100644
--- a/src/legacy/core_plugins/kibana/public/management/sections/settings/components/search/__snapshots__/search.test.js.snap
+++ b/src/legacy/core_plugins/kibana/public/management/sections/settings/components/search/__snapshots__/search.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Search should render normally 1`] = `
-
+
-
+
`;
diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap b/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap
index 5caafbdcd6484..84a6749eae4c1 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap
+++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap
@@ -229,66 +229,263 @@ exports[`NewVisModal should render as expected 1`] = `
}
>
-
+
+
+ }
>
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- New Visualization
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
-
-
-
- Vis Type 1
-
- }
- onBlur={[Function]}
- onClick={[Function]}
- onFocus={[Function]}
- onMouseEnter={[Function]}
- onMouseLeave={[Function]}
+
-
+ Vis Type 1
+
+ }
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseEnter={[Function]}
onMouseLeave={[Function]}
- type="button"
>
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
- Vis Type 1
-
-
-
-
-
-
- Vis with search
-
- }
- onBlur={[Function]}
- onClick={[Function]}
- onFocus={[Function]}
- onMouseEnter={[Function]}
- onMouseLeave={[Function]}
- >
-
+ Vis Type 1
+
+
+
+
+
+
+ Vis with search
+
+ }
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseEnter={[Function]}
onMouseLeave={[Function]}
- type="button"
>
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
- Vis with search
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ Vis with search
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
- Select a visualization type
-
-
-
-
-
-
-
-
+ Select a visualization type
+
+
+
+
+
+
+
-
-
- Start creating your visualization by selecting a type for that visualization.
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Start creating your visualization by selecting a type for that visualization.
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
diff --git a/src/ui/public/field_editor/__snapshots__/field_editor.test.js.snap b/src/ui/public/field_editor/__snapshots__/field_editor.test.js.snap
index 38bc79e4bab3f..68255e74fa46f 100644
--- a/src/ui/public/field_editor/__snapshots__/field_editor.test.js.snap
+++ b/src/ui/public/field_editor/__snapshots__/field_editor.test.js.snap
@@ -15,29 +15,27 @@ exports[`FieldEditor should render create new scripted field correctly 1`] = `
size="m"
/>
-
-
-
-
+
+
-
+ }
+ isVisible={false}
+ lang="painless"
+ onClose={[Function]}
+ />
-
-
- }
- label={
-
+ }
+ >
+
+
@@ -153,47 +149,43 @@ exports[`FieldEditor should render create new scripted field correctly 1`] = `
onChange={[Function]}
/>
-
-
+
+
+
+
+
+ doc['some_field'].value
+ ,
+ }
+ }
+ />
+
+
+
-
-
-
-
-
-
- doc['some_field'].value
- ,
- }
- }
- />
-
-
-
-
-
-
-
-
+
+
-
-
-
-
+
+
-
+ }
+ isVisible={false}
+ lang="painless"
+ name="test"
+ onClose={[Function]}
+ script="doc.test.value"
+ />
-
-
- }
- label={
-
+ }
+ >
+
+
@@ -389,48 +377,44 @@ exports[`FieldEditor should render edit scripted field correctly 1`] = `
onChange={[Function]}
/>
-
-
+
+
+
+
+
+ doc['some_field'].value
+ ,
+ }
+ }
+ />
+
+
+
-
-
-
-
-
-
- doc['some_field'].value
- ,
- }
- }
- />
-
-
-
-
-
-
-
-
+
+
-
-
-
-
+
+
-
+ }
+ isVisible={false}
+ lang="painless"
+ name="foobar"
+ onClose={[Function]}
+ />
-
-
- }
- label={
-
+ }
+ >
+
+
@@ -690,47 +670,43 @@ exports[`FieldEditor should show conflict field warning 1`] = `
onChange={[Function]}
/>
-
-
+
+
+
+
+
+ doc['some_field'].value
+ ,
+ }
+ }
+ />
+
+
+
-
-
-
-
-
-
- doc['some_field'].value
- ,
- }
- }
- />
-
-
-
-
-
-
-
-
+
+
-
-
-
-
+
+
-
+ }
+ isVisible={false}
+ lang="testlang"
+ name="test"
+ onClose={[Function]}
+ script="doc.test.value"
+ />
@@ -963,47 +937,45 @@ exports[`FieldEditor should show deprecated lang warning 1`] = `
value="number"
/>
-
-
- }
- label={
-
-
+ }
+ >
+
+
@@ -1012,48 +984,44 @@ exports[`FieldEditor should show deprecated lang warning 1`] = `
onChange={[Function]}
/>
-
-
+
+
+
+
+
+ doc['some_field'].value
+ ,
+ }
+ }
+ />
+
+
+
-
-
-
-
-
-
- doc['some_field'].value
- ,
- }
- }
- />
-
-
-
-
-
-
-
-
+
+
+
-
+
`;
-exports[`FieldFormatEditor should render nothing if there is no editor for the format 1`] = ` `;
+exports[`FieldFormatEditor should render nothing if there is no editor for the format 1`] = ` `;
diff --git a/src/ui/public/field_editor/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.js.snap b/src/ui/public/field_editor/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.js.snap
index 480d65ae01f4a..38b3890005a98 100644
--- a/src/ui/public/field_editor/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.js.snap
+++ b/src/ui/public/field_editor/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`BytesFormatEditor should render normally 1`] = `
-
+
-
+
`;
diff --git a/src/ui/public/field_editor/components/field_format_editor/editors/color/__snapshots__/color.test.js.snap b/src/ui/public/field_editor/components/field_format_editor/editors/color/__snapshots__/color.test.js.snap
index 299a9f91ac705..0a2ba6a12ce43 100644
--- a/src/ui/public/field_editor/components/field_format_editor/editors/color/__snapshots__/color.test.js.snap
+++ b/src/ui/public/field_editor/components/field_format_editor/editors/color/__snapshots__/color.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ColorFormatEditorComponent should render multiple colors 1`] = `
-
+
-
+
`;
exports[`ColorFormatEditorComponent should render other type normally (range field) 1`] = `
-
+
-
+
`;
exports[`ColorFormatEditorComponent should render string type normally (regex field) 1`] = `
-
+
-
+
`;
diff --git a/src/ui/public/field_editor/components/field_format_editor/editors/date/__snapshots__/date.test.js.snap b/src/ui/public/field_editor/components/field_format_editor/editors/date/__snapshots__/date.test.js.snap
index 59481cd6e19a5..7502b03af40c6 100644
--- a/src/ui/public/field_editor/components/field_format_editor/editors/date/__snapshots__/date.test.js.snap
+++ b/src/ui/public/field_editor/components/field_format_editor/editors/date/__snapshots__/date.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`DateFormatEditor should render normally 1`] = `
-
+
-
+
`;
diff --git a/src/ui/public/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.js.snap b/src/ui/public/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.js.snap
index 1381973452a1e..438e3a3c9932b 100644
--- a/src/ui/public/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.js.snap
+++ b/src/ui/public/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`DurationFormatEditor should render human readable output normally 1`] = `
-
+
-
+
`;
exports[`DurationFormatEditor should render non-human readable output normally 1`] = `
-
+
-
+
`;
diff --git a/src/ui/public/field_editor/components/field_format_editor/editors/number/__snapshots__/number.test.js.snap b/src/ui/public/field_editor/components/field_format_editor/editors/number/__snapshots__/number.test.js.snap
index 7f07331c77994..97947f01612c3 100644
--- a/src/ui/public/field_editor/components/field_format_editor/editors/number/__snapshots__/number.test.js.snap
+++ b/src/ui/public/field_editor/components/field_format_editor/editors/number/__snapshots__/number.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`NumberFormatEditor should render normally 1`] = `
-
+
-
+
`;
diff --git a/src/ui/public/field_editor/components/field_format_editor/editors/percent/__snapshots__/percent.test.js.snap b/src/ui/public/field_editor/components/field_format_editor/editors/percent/__snapshots__/percent.test.js.snap
index f0ee8f15d509b..a04f27cacf59e 100644
--- a/src/ui/public/field_editor/components/field_format_editor/editors/percent/__snapshots__/percent.test.js.snap
+++ b/src/ui/public/field_editor/components/field_format_editor/editors/percent/__snapshots__/percent.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PercentFormatEditor should render normally 1`] = `
-
+
-
+
`;
diff --git a/src/ui/public/field_editor/components/field_format_editor/editors/static_lookup/__snapshots__/static_lookup.test.js.snap b/src/ui/public/field_editor/components/field_format_editor/editors/static_lookup/__snapshots__/static_lookup.test.js.snap
index 31ac15c41eb8e..68a7a03e47c10 100644
--- a/src/ui/public/field_editor/components/field_format_editor/editors/static_lookup/__snapshots__/static_lookup.test.js.snap
+++ b/src/ui/public/field_editor/components/field_format_editor/editors/static_lookup/__snapshots__/static_lookup.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`StaticLookupFormatEditorComponent should render multiple lookup entries and unknown key value 1`] = `
-
+
-
+
`;
exports[`StaticLookupFormatEditorComponent should render normally 1`] = `
-
+
-
+
`;
diff --git a/src/ui/public/field_editor/components/field_format_editor/editors/string/__snapshots__/string.test.js.snap b/src/ui/public/field_editor/components/field_format_editor/editors/string/__snapshots__/string.test.js.snap
index 17089261bd2fc..537c31f64d5f0 100644
--- a/src/ui/public/field_editor/components/field_format_editor/editors/string/__snapshots__/string.test.js.snap
+++ b/src/ui/public/field_editor/components/field_format_editor/editors/string/__snapshots__/string.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`StringFormatEditor should render normally 1`] = `
-
+
-
+
`;
diff --git a/src/ui/public/field_editor/components/field_format_editor/editors/truncate/__snapshots__/truncate.test.js.snap b/src/ui/public/field_editor/components/field_format_editor/editors/truncate/__snapshots__/truncate.test.js.snap
index e6aa80cb39dca..d6651e5568d58 100644
--- a/src/ui/public/field_editor/components/field_format_editor/editors/truncate/__snapshots__/truncate.test.js.snap
+++ b/src/ui/public/field_editor/components/field_format_editor/editors/truncate/__snapshots__/truncate.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TruncateFormatEditor should render normally 1`] = `
-
+
-
+
`;
diff --git a/src/ui/public/field_editor/components/field_format_editor/editors/url/__snapshots__/url.test.js.snap b/src/ui/public/field_editor/components/field_format_editor/editors/url/__snapshots__/url.test.js.snap
index 923b92eeaf47a..20d42c19f04bd 100644
--- a/src/ui/public/field_editor/components/field_format_editor/editors/url/__snapshots__/url.test.js.snap
+++ b/src/ui/public/field_editor/components/field_format_editor/editors/url/__snapshots__/url.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`UrlFormatEditor should render label template help 1`] = `
-
+
-
+
`;
exports[`UrlFormatEditor should render normally 1`] = `
-
+
-
+
`;
exports[`UrlFormatEditor should render url template help 1`] = `
-
+
-
+
`;
diff --git a/src/ui/public/field_editor/components/scripting_call_outs/__snapshots__/disabled_call_out.test.js.snap b/src/ui/public/field_editor/components/scripting_call_outs/__snapshots__/disabled_call_out.test.js.snap
index d2e4a89bc9b45..7aeade16748ee 100644
--- a/src/ui/public/field_editor/components/scripting_call_outs/__snapshots__/disabled_call_out.test.js.snap
+++ b/src/ui/public/field_editor/components/scripting_call_outs/__snapshots__/disabled_call_out.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ScriptingDisabledCallOut should render normally 1`] = `
-
+
-
+
`;
exports[`ScriptingDisabledCallOut should render nothing if not visible 1`] = `""`;
diff --git a/src/ui/public/field_editor/components/scripting_call_outs/__snapshots__/warning_call_out.test.js.snap b/src/ui/public/field_editor/components/scripting_call_outs/__snapshots__/warning_call_out.test.js.snap
index e9bbdf801d1fb..790ed21d44cda 100644
--- a/src/ui/public/field_editor/components/scripting_call_outs/__snapshots__/warning_call_out.test.js.snap
+++ b/src/ui/public/field_editor/components/scripting_call_outs/__snapshots__/warning_call_out.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ScriptingWarningCallOut should render normally 1`] = `
-
+
-
+
`;
exports[`ScriptingWarningCallOut should render nothing if not visible 1`] = `""`;
diff --git a/src/ui/public/query_bar/components/query_bar.tsx b/src/ui/public/query_bar/components/query_bar.tsx
index 02f240ffc352b..af91fea37eb43 100644
--- a/src/ui/public/query_bar/components/query_bar.tsx
+++ b/src/ui/public/query_bar/components/query_bar.tsx
@@ -110,7 +110,7 @@ export class QueryBarUI extends Component {
};
}
- return null;
+ return { currentProps: nextProps };
}
/*
@@ -132,6 +132,7 @@ export class QueryBarUI extends Component {
},
inputIsPristine: true,
isSuggestionsVisible: false,
+ currentProps: this.props,
index: null,
suggestions: [],
suggestionLimit: 50,
diff --git a/src/ui/public/share/components/__snapshots__/url_panel_content.test.js.snap b/src/ui/public/share/components/__snapshots__/url_panel_content.test.js.snap
index 05669cf36e2dc..1b0c705db40e3 100644
--- a/src/ui/public/share/components/__snapshots__/url_panel_content.test.js.snap
+++ b/src/ui/public/share/components/__snapshots__/url_panel_content.test.js.snap
@@ -186,7 +186,9 @@ exports[`render 1`] = `
afterMessage="Copied"
anchorClassName="sharePanel__copyAnchor"
textToCopy="http://localhost/"
- />
+ >
+
+
`;
@@ -365,6 +367,8 @@ exports[`should enable saved object export option when objectId is provided 1`]
afterMessage="Copied"
anchorClassName="sharePanel__copyAnchor"
textToCopy="http://localhost/"
- />
+ >
+
+
`;
diff --git a/x-pack/package.json b/x-pack/package.json
index 2b21a858a6827..30f47b109994f 100644
--- a/x-pack/package.json
+++ b/x-pack/package.json
@@ -73,9 +73,10 @@
"copy-webpack-plugin": "^4.5.2",
"del": "^3.0.0",
"dotenv": "2.0.0",
- "enzyme": "3.2.0",
- "enzyme-adapter-react-16": "^1.1.1",
- "enzyme-to-json": "3.3.1",
+ "enzyme": "^3.7.0",
+ "enzyme-adapter-react-16": "^1.6.0",
+ "enzyme-adapter-utils": "^1.8.1",
+ "enzyme-to-json": "^3.3.4",
"expect.js": "0.3.1",
"fancy-log": "^1.3.2",
"fetch-mock": "7.3.0",
@@ -220,12 +221,12 @@
"puid": "1.0.5",
"puppeteer-core": "^1.7.0",
"raw-loader": "0.5.1",
- "react": "^16.3.0",
+ "react": "^16.6.0",
"react-apollo": "^2.1.4",
"react-beautiful-dnd": "^8.0.7",
"react-clipboard.js": "^1.1.2",
"react-datetime": "^2.14.0",
- "react-dom": "^16.3.0",
+ "react-dom": "^16.6.0",
"react-dropzone": "^4.2.9",
"react-markdown-renderer": "^1.4.0",
"react-portal": "^3.2.0",
diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/__snapshots__/TransactionOverview.test.js.snap b/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/__snapshots__/TransactionOverview.test.js.snap
index d960d846a1da9..cc5c169bbda11 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/__snapshots__/TransactionOverview.test.js.snap
+++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/__snapshots__/TransactionOverview.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TransactionOverviewView should render with type filter controls 1`] = `
-
+
-
+
`;
exports[`TransactionOverviewView should render without type filter controls if there is just a single type 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/apm/public/components/shared/HistoryTabs/__test__/__snapshots__/HistoryTabs.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/HistoryTabs/__test__/__snapshots__/HistoryTabs.test.tsx.snap
index 3e4c0b0656578..f9ed76ec38cd3 100644
--- a/x-pack/plugins/apm/public/components/shared/HistoryTabs/__test__/__snapshots__/HistoryTabs.test.tsx.snap
+++ b/x-pack/plugins/apm/public/components/shared/HistoryTabs/__test__/__snapshots__/HistoryTabs.test.tsx.snap
@@ -21,7 +21,7 @@ exports[`HistoryTabs should change the selected item on tab click 2`] = `
`;
exports[`HistoryTabs should render correctly 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/license_management/__jest__/__snapshots__/upload_license.test.js.snap b/x-pack/plugins/license_management/__jest__/__snapshots__/upload_license.test.js.snap
index 46b1c5be7eef3..b2ea097186891 100644
--- a/x-pack/plugins/license_management/__jest__/__snapshots__/upload_license.test.js.snap
+++ b/x-pack/plugins/license_management/__jest__/__snapshots__/upload_license.test.js.snap
@@ -175,83 +175,180 @@ exports[`UploadLicense should display a modal when license requires acknowledgem
/>
-
- }
- confirmButtonText={
-
- }
- onCancel={[Function]}
- onConfirm={[Function]}
- title={
-
- }
- >
-
-
-
-
+
+
+
+
+
+
+
+
+
+ Some functionality will be lost if you replace your TRIAL license with a BASIC license. Review the list of features below.
+
+
+
+
+ Watcher will be disabled
+
+
+
+
+
+
+
+
+
+
+
+ }
+ >
+
+ }
+ confirmButtonText={
+
+ }
+ onCancel={[Function]}
+ onConfirm={[Function]}
+ title={
+
+ }
+ >
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
- Confirm License Upload
-
-
-
-
-
-
-
-
+ Confirm License Upload
+
+
+
+
+
+
+
-
-
-
-
+
+
- Some functionality will be lost if you replace your TRIAL license with a BASIC license. Review the list of features below.
-
-
-
-
+ Some functionality will be lost if you replace your TRIAL license with a BASIC license. Review the list of features below.
+
+
+
-
-
- Watcher will be disabled
-
-
-
-
+
+
+
+ Watcher will be disabled
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
-
-
-
- Cancel
-
+
+ Cancel
+
+
-
-
-
-
-
+
+
-
-
- Confirm
-
+
+ Confirm
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
+
-
+
`;
exports[`FormLabel Full initialization 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/actions_section.test.js.snap b/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/actions_section.test.js.snap
index 36fe079f33ddc..13dda08db4187 100644
--- a/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/actions_section.test.js.snap
+++ b/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/actions_section.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ActionsSection renders with no actions selected 1`] = `
-
+
-
+
`;
exports[`ActionsSection renders with skip_result and skip_model_update selected 1`] = `
-
+
-
+
`;
exports[`ActionsSection renders with skip_result selected 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/conditions_section.test.js.snap b/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/conditions_section.test.js.snap
index a3c9364d96740..839a18efdb67c 100644
--- a/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/conditions_section.test.js.snap
+++ b/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/conditions_section.test.js.snap
@@ -5,7 +5,7 @@ exports[`ConditionsSectionExpression don't render when not enabled with conditio
exports[`ConditionsSectionExpression don't render when the section is not enabled 1`] = `""`;
exports[`ConditionsSectionExpression renders when enabled with empty conditions supplied 1`] = `
-
+
@@ -21,11 +21,11 @@ exports[`ConditionsSectionExpression renders when enabled with empty conditions
values={Object {}}
/>
-
+
`;
exports[`ConditionsSectionExpression renders when enabled with no conditions supplied 1`] = `
-
+
@@ -41,11 +41,11 @@ exports[`ConditionsSectionExpression renders when enabled with no conditions sup
values={Object {}}
/>
-
+
`;
exports[`ConditionsSectionExpression renders when enabled with one condition 1`] = `
-
+
-
+
`;
exports[`ConditionsSectionExpression renders when enabled with two conditions 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/rule_editor_flyout.test.js.snap b/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/rule_editor_flyout.test.js.snap
index 077b3cb9de824..fe592b0b0f7bc 100644
--- a/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/rule_editor_flyout.test.js.snap
+++ b/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/rule_editor_flyout.test.js.snap
@@ -5,7 +5,7 @@ exports[`RuleEditorFlyout don't render after closing the flyout 1`] = `""`;
exports[`RuleEditorFlyout don't render when not opened 1`] = `""`;
exports[`RuleEditorFlyout renders the flyout after adding a condition to a rule 1`] = `
-
+
-
+
`;
exports[`RuleEditorFlyout renders the flyout after setting the rule to edit 1`] = `
-
+
-
+
`;
exports[`RuleEditorFlyout renders the flyout for creating a rule with conditions only 1`] = `
-
+
-
+
`;
exports[`RuleEditorFlyout renders the select action component for a detector with a rule 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/scope_section.test.js.snap b/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/scope_section.test.js.snap
index 243771b04b05b..89f1898217958 100644
--- a/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/scope_section.test.js.snap
+++ b/x-pack/plugins/ml/public/components/rule_editor/__snapshots__/scope_section.test.js.snap
@@ -3,7 +3,7 @@
exports[`ScopeSection don't render when no partitioning fields 1`] = `""`;
exports[`ScopeSection false canGetFilters privilege show NoPermissionCallOut when no filter list IDs 1`] = `
-
+
-
-
-
+
-
+
`;
exports[`ScopeSection renders when enabled with no scope supplied 1`] = `
-
+
-
-
-
+
-
+
`;
exports[`ScopeSection renders when enabled with scope supplied 1`] = `
-
+
-
-
-
+
-
+
`;
exports[`ScopeSection renders when not enabled 1`] = `
-
+
-
+
`;
exports[`ScopeSection show NoFilterListsCallOut when no filter list IDs 1`] = `
-
+
-
-
-
+
-
+
`;
diff --git a/x-pack/plugins/ml/public/components/rule_editor/select_rule_action/__snapshots__/delete_rule_modal.test.js.snap b/x-pack/plugins/ml/public/components/rule_editor/select_rule_action/__snapshots__/delete_rule_modal.test.js.snap
index 9d9fe4082ec91..37be903bc85b2 100644
--- a/x-pack/plugins/ml/public/components/rule_editor/select_rule_action/__snapshots__/delete_rule_modal.test.js.snap
+++ b/x-pack/plugins/ml/public/components/rule_editor/select_rule_action/__snapshots__/delete_rule_modal.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`DeleteRuleModal renders as delete button after opening and closing modal 1`] = `
-
+
-
+
`;
exports[`DeleteRuleModal renders as delete button when not visible 1`] = `
-
+
-
+
`;
exports[`DeleteRuleModal renders modal after clicking delete rule link 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/components/explorer_chart_label/__snapshots__/explorer_chart_label.test.js.snap b/x-pack/plugins/ml/public/explorer/explorer_charts/components/explorer_chart_label/__snapshots__/explorer_chart_label.test.js.snap
index 05150c9925afc..6b6930fe40ccf 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_charts/components/explorer_chart_label/__snapshots__/explorer_chart_label.test.js.snap
+++ b/x-pack/plugins/ml/public/explorer/explorer_charts/components/explorer_chart_label/__snapshots__/explorer_chart_label.test.js.snap
@@ -1,77 +1,67 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ExplorerChartLabelBadge Render the chart label in one line. 1`] = `
-
+
-
- high_sum(nginx.access.body_sent.bytes) over nginx.access.remote_ip (population-03)
-
-
- –
-
+ high_sum(nginx.access.body_sent.bytes) over nginx.access.remote_ip (population-03)
+ –
-
-
+
+
+
}
- key="nginx.access.remote_ip 72.57.0.53"
+ position="top"
+ size="s"
+ type="questionInCircle"
/>
-
-
-
- }
- position="top"
- size="s"
- type="questionInCircle"
- />
-
-
+
-
+
`;
exports[`ExplorerChartLabelBadge Render the chart label in two lines. 1`] = `
-
+
-
- high_sum(nginx.access.body_sent.bytes) over nginx.access.remote_ip (population-03)
-
-
-
-
+ high_sum(nginx.access.body_sent.bytes) over nginx.access.remote_ip (population-03)
+
-
+
`;
diff --git a/x-pack/plugins/ml/public/jobs/components/custom_url_editor/__snapshots__/editor.test.js.snap b/x-pack/plugins/ml/public/jobs/components/custom_url_editor/__snapshots__/editor.test.js.snap
index 6d2563b8a19c5..91a671f095f55 100644
--- a/x-pack/plugins/ml/public/jobs/components/custom_url_editor/__snapshots__/editor.test.js.snap
+++ b/x-pack/plugins/ml/public/jobs/components/custom_url_editor/__snapshots__/editor.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`CustomUrlEditor renders the editor for a dashboard type URL with a label 1`] = `
-
+
-
+
`;
exports[`CustomUrlEditor renders the editor for a discover type URL with an entity and empty time range interval 1`] = `
-
+
-
+
`;
exports[`CustomUrlEditor renders the editor for a discover type URL with valid time range interval 1`] = `
-
+
-
+
`;
exports[`CustomUrlEditor renders the editor for a new dashboard type URL with no label 1`] = `
-
+
-
+
`;
exports[`CustomUrlEditor renders the editor for other type of URL with duplicate label 1`] = `
-
+
-
+
`;
exports[`CustomUrlEditor renders the editor for other type of URL with unique label 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/ml/public/jobs/components/custom_url_editor/__snapshots__/list.test.js.snap b/x-pack/plugins/ml/public/jobs/components/custom_url_editor/__snapshots__/list.test.js.snap
index dd76563bc7b76..a7cafe60fb63f 100644
--- a/x-pack/plugins/ml/public/jobs/components/custom_url_editor/__snapshots__/list.test.js.snap
+++ b/x-pack/plugins/ml/public/jobs/components/custom_url_editor/__snapshots__/list.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`CustomUrlList renders a list of custom URLs 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/ml/public/settings/calendars/edit/calendar_form/__snapshots__/calendar_form.test.js.snap b/x-pack/plugins/ml/public/settings/calendars/edit/calendar_form/__snapshots__/calendar_form.test.js.snap
index 7814870fa8aae..2e0f8bca89a5a 100644
--- a/x-pack/plugins/ml/public/settings/calendars/edit/calendar_form/__snapshots__/calendar_form.test.js.snap
+++ b/x-pack/plugins/ml/public/settings/calendars/edit/calendar_form/__snapshots__/calendar_form.test.js.snap
@@ -25,58 +25,56 @@ exports[`CalendarForm CalendarId shown as title when editing 1`] = `
exports[`CalendarForm Renders calendar form 1`] = `
-
-
- }
- >
-
-
-
+
- }
- >
-
+
+
-
-
+ }
+ >
+
+
+
@@ -65,11 +65,11 @@ exports[`EventsTable Renders events table with no search bar 1`] = `
}
}
/>
-
+
`;
exports[`EventsTable Renders events table with search bar 1`] = `
-
+
@@ -177,5 +177,5 @@ exports[`EventsTable Renders events table with search bar 1`] = `
}
}
/>
-
+
`;
diff --git a/x-pack/plugins/ml/public/settings/calendars/edit/import_modal/__snapshots__/import_modal.test.js.snap b/x-pack/plugins/ml/public/settings/calendars/edit/import_modal/__snapshots__/import_modal.test.js.snap
index 45c1bfc53b549..0d1bc10a13f92 100644
--- a/x-pack/plugins/ml/public/settings/calendars/edit/import_modal/__snapshots__/import_modal.test.js.snap
+++ b/x-pack/plugins/ml/public/settings/calendars/edit/import_modal/__snapshots__/import_modal.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ImportModal Renders import modal 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/ml/public/settings/calendars/edit/imported_events/__snapshots__/imported_events.test.js.snap b/x-pack/plugins/ml/public/settings/calendars/edit/imported_events/__snapshots__/imported_events.test.js.snap
index 3db746ce38758..d2773bb09c6e1 100644
--- a/x-pack/plugins/ml/public/settings/calendars/edit/imported_events/__snapshots__/imported_events.test.js.snap
+++ b/x-pack/plugins/ml/public/settings/calendars/edit/imported_events/__snapshots__/imported_events.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ImportedEvents Renders imported events 1`] = `
-
+
@@ -68,5 +68,5 @@ exports[`ImportedEvents Renders imported events 1`] = `
onChange={[MockFunction]}
/>
-
+
`;
diff --git a/x-pack/plugins/ml/public/settings/calendars/list/table/__snapshots__/table.test.js.snap b/x-pack/plugins/ml/public/settings/calendars/list/table/__snapshots__/table.test.js.snap
index a2c09dc7f5162..7ac8b56ba9469 100644
--- a/x-pack/plugins/ml/public/settings/calendars/list/table/__snapshots__/table.test.js.snap
+++ b/x-pack/plugins/ml/public/settings/calendars/list/table/__snapshots__/table.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`CalendarsListTable renders the table with all calendars 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/ml/public/settings/filter_lists/edit/__snapshots__/header.test.js.snap b/x-pack/plugins/ml/public/settings/filter_lists/edit/__snapshots__/header.test.js.snap
index 101a65c499856..39e3fcf066362 100644
--- a/x-pack/plugins/ml/public/settings/filter_lists/edit/__snapshots__/header.test.js.snap
+++ b/x-pack/plugins/ml/public/settings/filter_lists/edit/__snapshots__/header.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`EditFilterListHeader renders the header when creating a new filter list with ID, description and items set 1`] = `
-
+
-
+
`;
exports[`EditFilterListHeader renders the header when creating a new filter list with the ID not set 1`] = `
-
+
-
+
`;
exports[`EditFilterListHeader renders the header when editing an existing unused filter list with no description or items 1`] = `
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
`;
exports[`EditFilterListHeader renders the header when editing an existing used filter list with description and items set 1`] = `
-
+
-
-
+
-
-
-
-
-
-
-
-
+
+
+
-
-
+
-
-
+
+
+
`;
diff --git a/x-pack/plugins/ml/public/settings/filter_lists/edit/__snapshots__/toolbar.test.js.snap b/x-pack/plugins/ml/public/settings/filter_lists/edit/__snapshots__/toolbar.test.js.snap
index f286a971aea7a..fd87730372ad3 100644
--- a/x-pack/plugins/ml/public/settings/filter_lists/edit/__snapshots__/toolbar.test.js.snap
+++ b/x-pack/plugins/ml/public/settings/filter_lists/edit/__snapshots__/toolbar.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`EditFilterListToolbar renders the toolbar with no items selected 1`] = `
-
+
-
+
`;
exports[`EditFilterListToolbar renders the toolbar with one item selected 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/ml/public/settings/filter_lists/list/__snapshots__/header.test.js.snap b/x-pack/plugins/ml/public/settings/filter_lists/list/__snapshots__/header.test.js.snap
index 27ac7dafaa27f..08763ad9d5f29 100644
--- a/x-pack/plugins/ml/public/settings/filter_lists/list/__snapshots__/header.test.js.snap
+++ b/x-pack/plugins/ml/public/settings/filter_lists/list/__snapshots__/header.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Filter Lists Header renders header 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/ml/public/settings/filter_lists/list/__snapshots__/table.test.js.snap b/x-pack/plugins/ml/public/settings/filter_lists/list/__snapshots__/table.test.js.snap
index 4f264c00980f2..dfed87f5c1fc7 100644
--- a/x-pack/plugins/ml/public/settings/filter_lists/list/__snapshots__/table.test.js.snap
+++ b/x-pack/plugins/ml/public/settings/filter_lists/list/__snapshots__/table.test.js.snap
@@ -1,205 +1,201 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Filter Lists Table renders with filter lists and selection supplied 1`] = `
-
-
-
+ ,
- ,
+ ,
- ],
- }
+ },
+ ]
+ }
+ />,
+ ],
}
- selection={
- Object {
- "onSelectionChange": [Function],
- "selectable": [Function],
- "selectableMessage": [Function],
- }
+ }
+ selection={
+ Object {
+ "onSelectionChange": [Function],
+ "selectable": [Function],
+ "selectableMessage": [Function],
}
- sorting={
- Object {
- "sort": Object {
- "direction": "asc",
- "field": "filter_id",
- },
- }
+ }
+ sorting={
+ Object {
+ "sort": Object {
+ "direction": "asc",
+ "field": "filter_id",
+ },
}
- />
-
-
+ }
+ />
+
`;
exports[`Filter Lists Table renders with filter lists supplied 1`] = `
-
-
-
+ ,
- ,
- ],
- }
- }
- selection={
+ "field": "filter_id",
+ "name": "ID",
+ "render": [Function],
+ "sortable": true,
+ },
Object {
- "onSelectionChange": [Function],
- "selectable": [Function],
- "selectableMessage": [Function],
- }
- }
- sorting={
+ "field": "description",
+ "name": "Description",
+ "sortable": true,
+ },
Object {
- "sort": Object {
- "direction": "asc",
- "field": "filter_id",
- },
- }
+ "field": "item_count",
+ "name": "Item count",
+ "sortable": true,
+ },
+ Object {
+ "field": "used_by",
+ "name": "In use",
+ "render": [Function],
+ "sortable": true,
+ },
+ ]
+ }
+ executeQueryOptions={Object {}}
+ isSelectable={true}
+ itemId="filter_id"
+ items={
+ Array [
+ Object {
+ "description": "List of known safe domains",
+ "filter_id": "safe_domains",
+ "item_count": 500,
+ "used_by": Object {
+ "jobs": Array [
+ "dns_exfiltration",
+ ],
+ },
+ },
+ Object {
+ "description": "US East AWS instances",
+ "filter_id": "us_east_instances",
+ "item_count": 20,
+ "used_by": Object {
+ "jobs": Array [],
+ },
+ },
+ ]
+ }
+ pagination={true}
+ responsive={true}
+ search={
+ Object {
+ "box": Object {
+ "incremental": true,
+ },
+ "filters": Array [],
+ "toolsRight": Array [
+ ,
+ ,
+ ],
+ }
+ }
+ selection={
+ Object {
+ "onSelectionChange": [Function],
+ "selectable": [Function],
+ "selectableMessage": [Function],
+ }
+ }
+ sorting={
+ Object {
+ "sort": Object {
+ "direction": "asc",
+ "field": "filter_id",
+ },
}
- />
-
-
+ }
+ />
+
`;
diff --git a/x-pack/plugins/monitoring/public/components/elasticsearch/ccr_shard/__snapshots__/ccr_shard.test.js.snap b/x-pack/plugins/monitoring/public/components/elasticsearch/ccr_shard/__snapshots__/ccr_shard.test.js.snap
index 9285aa7226e57..d4b789d4b79da 100644
--- a/x-pack/plugins/monitoring/public/components/elasticsearch/ccr_shard/__snapshots__/ccr_shard.test.js.snap
+++ b/x-pack/plugins/monitoring/public/components/elasticsearch/ccr_shard/__snapshots__/ccr_shard.test.js.snap
@@ -115,44 +115,42 @@ exports[`CcrShard that it renders normally 1`] = `
responsive={true}
wrap={true}
>
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
-
-
-
- September 27, 2018 9:32:09 AM
-
-
-
-
- {
+
+
+ September 27, 2018 9:32:09 AM
+
+
+
+
+ {
"read_exceptions": [],
"follower_global_checkpoint": 3049,
"follower_index": "follower",
@@ -218,8 +215,7 @@ exports[`CcrShard that it renders normally 1`] = `
"total_index_time_millis": 41827,
"total_transferred_bytes": 234156
}
-
-
+
diff --git a/x-pack/plugins/reporting/public/components/__snapshots__/report_info_button.test.tsx.snap b/x-pack/plugins/reporting/public/components/__snapshots__/report_info_button.test.tsx.snap
index 7ee7c00d6837f..0c08e3e69f24a 100644
--- a/x-pack/plugins/reporting/public/components/__snapshots__/report_info_button.test.tsx.snap
+++ b/x-pack/plugins/reporting/public/components/__snapshots__/report_info_button.test.tsx.snap
@@ -63,7 +63,15 @@ Array [
/>
+ >
+
+ }
+ />
+
+ >
+
+ }
+ />
+
+
-
+
`;
diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/__snapshots__/collapsible_panel.test.tsx.snap b/x-pack/plugins/security/public/views/management/edit_role/components/__snapshots__/collapsible_panel.test.tsx.snap
index a940a55b3754b..52bde6ec75879 100644
--- a/x-pack/plugins/security/public/views/management/edit_role/components/__snapshots__/collapsible_panel.test.tsx.snap
+++ b/x-pack/plugins/security/public/views/management/edit_role/components/__snapshots__/collapsible_panel.test.tsx.snap
@@ -51,13 +51,11 @@ exports[`it renders without blowing up 1`] = `
-
-
-
- child
-
-
+
+
+ child
+
`;
diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/elasticsearch_privileges.test.tsx.snap b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/elasticsearch_privileges.test.tsx.snap
index b5040fd5e9756..31f2adabe766a 100644
--- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/elasticsearch_privileges.test.tsx.snap
+++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/elasticsearch_privileges.test.tsx.snap
@@ -6,157 +6,81 @@ exports[`it renders without crashing 1`] = `
iconType="logoElasticsearch"
title="Elasticsearch"
>
-
-
-
-
-
-
-
- }
- fullWidth={false}
- gutterSize="l"
- title={
-
-
-
- }
- titleSize="xs"
- >
-
-
+
-
-
-
-
-
-
-
-
-
- }
- fullWidth={false}
- gutterSize="l"
- title={
-
+
-
- }
- titleSize="xs"
- >
-
-
-
-
-
-
+
+
+ }
+ fullWidth={false}
+ gutterSize="l"
+ title={
-
-
-
+
+
+
+
+
+
@@ -167,54 +91,128 @@ exports[`it renders without crashing 1`] = `
/>
-
-
-
-
+
+
+ }
+ titleSize="xs"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
`;
diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/index_privilege_form.test.tsx.snap b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/index_privilege_form.test.tsx.snap
index 6f5b137c318b6..15820ba7ddb94 100644
--- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/index_privilege_form.test.tsx.snap
+++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/index_privilege_form.test.tsx.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`it renders without crashing 1`] = `
-
+
-
-
+
-
-
- }
- >
-
-
-
-
-
- }
- >
-
+
+
+
+
-
-
-
-
- }
- label={
-
+
-
-
-
-
-
-
-
-
+
+
+
-
+ }
+ label={
+
+ }
>
-
- }
+
-
-
-
+
+
+
+
+
+
+
+ }
+ onChange={[Function]}
+ />
+
+
-
+
`;
diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/index_privileges.test.tsx.snap b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/index_privileges.test.tsx.snap
index 189c4766c29f9..943c3e1518cab 100644
--- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/index_privileges.test.tsx.snap
+++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/index_privileges.test.tsx.snap
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`it renders without crashing 1`] = `Array []`;
+exports[`it renders without crashing 1`] = `null`;
diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/__snapshots__/impacted_spaces_flyout.test.tsx.snap b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/__snapshots__/impacted_spaces_flyout.test.tsx.snap
index c749a49bce110..059ca0f1c0db6 100644
--- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/__snapshots__/impacted_spaces_flyout.test.tsx.snap
+++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/__snapshots__/impacted_spaces_flyout.test.tsx.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[` renders without crashing 1`] = `
-
+
@@ -17,5 +17,5 @@ exports[` renders without crashing 1`] = `
/>
-
+
`;
diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/__snapshots__/simple_privilege_form.test.tsx.snap b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/__snapshots__/simple_privilege_form.test.tsx.snap
index bd7045f14a47a..d74ee2370caf5 100644
--- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/__snapshots__/simple_privilege_form.test.tsx.snap
+++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/__snapshots__/simple_privilege_form.test.tsx.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[` renders without crashing 1`] = `
-
+
@@ -45,5 +45,5 @@ exports[` renders without crashing 1`] = `
/>
-
+
`;
diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/__snapshots__/space_aware_privilege_form.test.tsx.snap b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/__snapshots__/space_aware_privilege_form.test.tsx.snap
index 02b85cfc32545..819bcb4dcf4cd 100644
--- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/__snapshots__/space_aware_privilege_form.test.tsx.snap
+++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/__snapshots__/space_aware_privilege_form.test.tsx.snap
@@ -185,7 +185,7 @@ exports[` hides the space table if there are no existin
`;
exports[` renders without crashing 1`] = `
-
+
@@ -233,66 +233,130 @@ exports[` renders without crashing 1`] = `
-
-
+
+
+
+
+
+
+
+
+
+ ,
+ "read":
+
+ ,
+ }
+ }
+ />
+
+
+
+
+
+
-
+
-
-
-
-
+
+
-
-
-
- ,
- "read":
-
- ,
- }
- }
- />
-
-
-
-
- renders without crashing 1`] = `
"name": "",
}
}
- spacePrivileges={Object {}}
spaces={
Array [
Object {
@@ -323,82 +386,15 @@ exports[` renders without crashing 1`] = `
},
]
}
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
+ }
+ />
+
+
+
`;
exports[` with user profile disabling "manageSpaces" renders a warning message instead of the privilege form 1`] = `
diff --git a/x-pack/plugins/spaces/public/views/management/components/advanced_settings_subtitle/__snapshots__/advanced_settings_subtitle.test.tsx.snap b/x-pack/plugins/spaces/public/views/management/components/advanced_settings_subtitle/__snapshots__/advanced_settings_subtitle.test.tsx.snap
index 1f91e57a3f37e..69d1011de3c55 100644
--- a/x-pack/plugins/spaces/public/views/management/components/advanced_settings_subtitle/__snapshots__/advanced_settings_subtitle.test.tsx.snap
+++ b/x-pack/plugins/spaces/public/views/management/components/advanced_settings_subtitle/__snapshots__/advanced_settings_subtitle.test.tsx.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`AdvancedSettingsSubtitle renders as expected 1`] = `
-
+
@@ -25,5 +25,5 @@ exports[`AdvancedSettingsSubtitle renders as expected 1`] = `
}
/>
-
+
`;
diff --git a/x-pack/plugins/spaces/public/views/management/components/secure_space_message/__snapshots__/secure_space_message.test.tsx.snap b/x-pack/plugins/spaces/public/views/management/components/secure_space_message/__snapshots__/secure_space_message.test.tsx.snap
index a18d45e2d6518..7b46ee41053fd 100644
--- a/x-pack/plugins/spaces/public/views/management/components/secure_space_message/__snapshots__/secure_space_message.test.tsx.snap
+++ b/x-pack/plugins/spaces/public/views/management/components/secure_space_message/__snapshots__/secure_space_message.test.tsx.snap
@@ -3,7 +3,7 @@
exports[`SecureSpaceMessage doesn't render if user profile does not allow security to be managed 1`] = `""`;
exports[`SecureSpaceMessage renders if user profile allows security to be managed 1`] = `
-
+
@@ -34,5 +34,5 @@ exports[`SecureSpaceMessage renders if user profile allows security to be manage
/>
-
+
`;
diff --git a/x-pack/plugins/spaces/public/views/management/edit_space/__snapshots__/delete_spaces_button.test.tsx.snap b/x-pack/plugins/spaces/public/views/management/edit_space/__snapshots__/delete_spaces_button.test.tsx.snap
index 93bb0363ed65a..554bf9a26ef91 100644
--- a/x-pack/plugins/spaces/public/views/management/edit_space/__snapshots__/delete_spaces_button.test.tsx.snap
+++ b/x-pack/plugins/spaces/public/views/management/edit_space/__snapshots__/delete_spaces_button.test.tsx.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`DeleteSpacesButton renders as expected 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/spaces/public/views/management/edit_space/__snapshots__/space_identifier.test.tsx.snap b/x-pack/plugins/spaces/public/views/management/edit_space/__snapshots__/space_identifier.test.tsx.snap
index b22754203b92a..cae15537921b3 100644
--- a/x-pack/plugins/spaces/public/views/management/edit_space/__snapshots__/space_identifier.test.tsx.snap
+++ b/x-pack/plugins/spaces/public/views/management/edit_space/__snapshots__/space_identifier.test.tsx.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders without crashing 1`] = `
-
+
-
+
`;
diff --git a/x-pack/plugins/spaces/public/views/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap b/x-pack/plugins/spaces/public/views/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap
index 1fb27b544fc9b..a95d29b96155a 100644
--- a/x-pack/plugins/spaces/public/views/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap
+++ b/x-pack/plugins/spaces/public/views/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap
@@ -8,128 +8,126 @@ exports[`SpacesGridPage renders as expected 1`] = `
horizontalPosition="center"
panelPaddingSize="l"
>
-
-
+
-
-
-
-
-
-
-
-
- Organize your dashboards and other saved objects into meaningful categories.
-
-
-
-
-
+
-
-
-
-
-
+
+
+
+ Organize your dashboards and other saved objects into meaningful categories.
+
+
+
+
+
- }
- pagination={true}
- responsive={true}
- search={
+
+
+
+
+
+ }
+ pagination={true}
+ responsive={true}
+ search={
+ Object {
+ "box": Object {
+ "placeholder": "Search",
+ },
}
- sorting={false}
- />
-
+ }
+ sorting={false}
+ />
-
-
+
+
-
-
-
-
+
diff --git a/x-pack/plugins/upgrade_assistant/public/components/tabs/checkup/__snapshots__/checkup_tab.test.tsx.snap b/x-pack/plugins/upgrade_assistant/public/components/tabs/checkup/__snapshots__/checkup_tab.test.tsx.snap
index 9bf3c3836b5ad..1bc2f1ea095d3 100644
--- a/x-pack/plugins/upgrade_assistant/public/components/tabs/checkup/__snapshots__/checkup_tab.test.tsx.snap
+++ b/x-pack/plugins/upgrade_assistant/public/components/tabs/checkup/__snapshots__/checkup_tab.test.tsx.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`CheckupTab render with deprecations 1`] = `
-
+
@@ -27,281 +27,277 @@ exports[`CheckupTab render with deprecations 1`] = `
-
-
- }
- >
-
-
-
- ,
- }
+
+ }
+ >
+
+
+
+ ,
}
- />
-
-
-
-
+ }
+ />
+
+
+
-
-
-
-
-
+
+
+
-
+
`;
exports[`CheckupTab render with error 1`] = `
-
+
@@ -327,46 +323,44 @@ exports[`CheckupTab render with error 1`] = `
-
-
- }
- >
-
-
-
- ,
- }
+
+ }
+ >
+
+
+
+ ,
}
- />
-
-
-
-
+ }
+ />
+
+
+
@@ -385,11 +379,11 @@ exports[`CheckupTab render with error 1`] = `
/>
-
+
`;
exports[`CheckupTab render without deprecations 1`] = `
-
+
@@ -415,46 +409,44 @@ exports[`CheckupTab render without deprecations 1`] = `
-
-
- }
- >
-
-
-
- ,
- }
+
+ }
+ >
+
+
+
+ ,
}
- />
-
-
-
-
+ }
+ />
+
+
+
@@ -514,5 +506,5 @@ exports[`CheckupTab render without deprecations 1`] = `
/>
-
+
`;
diff --git a/x-pack/plugins/xpack_main/public/components/telemetry/__snapshots__/telemetry_form.test.js.snap b/x-pack/plugins/xpack_main/public/components/telemetry/__snapshots__/telemetry_form.test.js.snap
index b7c8519b8f640..799aef28eeea3 100644
--- a/x-pack/plugins/xpack_main/public/components/telemetry/__snapshots__/telemetry_form.test.js.snap
+++ b/x-pack/plugins/xpack_main/public/components/telemetry/__snapshots__/telemetry_form.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TelemetryForm renders as expected 1`] = `
-
+
-
+
`;
diff --git a/yarn.lock b/yarn.lock
index d55df4dd541d0..a1d1f2f09667d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2838,6 +2838,15 @@ array-unique@^0.3.2:
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
+array.prototype.flat@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.1.tgz#812db8f02cad24d3fab65dd67eabe3b8903494a4"
+ integrity sha512-rVqIs330nLJvfC7JqYvEWwqVr5QjYF1ib02i3YJtR/fICO6527Tjpc/e4Mvmxh3GIePPreRXMdaGyC99YphWEw==
+ dependencies:
+ define-properties "^1.1.2"
+ es-abstract "^1.10.0"
+ function-bind "^1.1.1"
+
arraybuffer.slice@~0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
@@ -7604,51 +7613,59 @@ env-variable@0.0.x:
resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.5.tgz#913dd830bef11e96a039c038d4130604eba37f88"
integrity sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==
-enzyme-adapter-react-16@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.1.1.tgz#a8f4278b47e082fbca14f5bfb1ee50ee650717b4"
- integrity sha512-kC8pAtU2Jk3OJ0EG8Y2813dg9Ol0TXi7UNxHzHiWs30Jo/hj7alc//G1YpKUsPP1oKl9X+Lkx+WlGJpPYA+nvw==
+enzyme-adapter-react-16@^1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.6.0.tgz#3fca28d3c32f3ff427495380fe2dd51494689073"
+ integrity sha512-ay9eGFpChyUDnjTFMMJHzrb681LF3hPWJLEA7RoLFG9jSWAdAm2V50pGmFV9dYGJgh5HfdiqM+MNvle41Yf/PA==
dependencies:
- enzyme-adapter-utils "^1.3.0"
- lodash "^4.17.4"
- object.assign "^4.0.4"
+ enzyme-adapter-utils "^1.8.0"
+ function.prototype.name "^1.1.0"
+ object.assign "^4.1.0"
object.values "^1.0.4"
- prop-types "^15.6.0"
- react-reconciler "^0.7.0"
+ prop-types "^15.6.2"
+ react-is "^16.5.2"
react-test-renderer "^16.0.0-0"
-enzyme-adapter-utils@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.3.0.tgz#d6c85756826c257a8544d362cc7a67e97ea698c7"
- integrity sha512-vVXSt6uDv230DIv+ebCG66T1Pm36Kv+m74L1TrF4kaE7e1V7Q/LcxO0QRkajk5cA6R3uu9wJf5h13wOTezTbjA==
+enzyme-adapter-utils@^1.8.0, enzyme-adapter-utils@^1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.8.1.tgz#a927d840ce2c14b42892a533aec836809d4e022b"
+ integrity sha512-s3QB3xQAowaDS2sHhmEqrT13GJC4+n5bG015ZkLv60n9k5vhxxHTQRIneZmQ4hmdCZEBrvUJ89PG6fRI5OEeuQ==
dependencies:
- lodash "^4.17.4"
- object.assign "^4.0.4"
- prop-types "^15.6.0"
+ function.prototype.name "^1.1.0"
+ object.assign "^4.1.0"
+ prop-types "^15.6.2"
-enzyme-to-json@3.3.1:
- version "3.3.1"
- resolved "https://registry.yarnpkg.com/enzyme-to-json/-/enzyme-to-json-3.3.1.tgz#64239dcd417e2fb552f4baa6632de4744b9b5b93"
- integrity sha512-PrgRyZAgEwOrh5/8BtBWrwGcv1mC7yNohytIciAX6SUqDaXg1BlU8CepYQ9BgnDP1i1jTB65qJJITMMCph+T6A==
+enzyme-to-json@^3.3.4:
+ version "3.3.4"
+ resolved "https://registry.yarnpkg.com/enzyme-to-json/-/enzyme-to-json-3.3.4.tgz#67c6040e931182f183418af2eb9f4323258aa77f"
+ integrity sha1-Z8YEDpMRgvGDQYry659DIyWKp38=
dependencies:
lodash "^4.17.4"
-enzyme@3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.2.0.tgz#998bdcda0fc71b8764a0017f7cc692c943f54a7a"
- integrity sha512-l0HcjycivXjB4IXkwuRc1K5z8hzWIVZB2b/Y/H2bao9eFTpBz4ACOwAQf44SgG5Nu3d1jF41LasxDgFWZeeysA==
+enzyme@^3.7.0:
+ version "3.7.0"
+ resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.7.0.tgz#9b499e8ca155df44fef64d9f1558961ba1385a46"
+ integrity sha512-QLWx+krGK6iDNyR1KlH5YPZqxZCQaVF6ike1eDJAOg0HvSkSCVImPsdWaNw6v+VrnK92Kg8jIOYhuOSS9sBpyg==
dependencies:
+ array.prototype.flat "^1.2.1"
cheerio "^1.0.0-rc.2"
- function.prototype.name "^1.0.3"
- has "^1.0.1"
+ function.prototype.name "^1.1.0"
+ has "^1.0.3"
+ is-boolean-object "^1.0.0"
+ is-callable "^1.1.4"
+ is-number-object "^1.0.3"
+ is-string "^1.0.4"
is-subset "^0.1.1"
- lodash "^4.17.4"
+ lodash.escape "^4.0.1"
+ lodash.isequal "^4.5.0"
+ object-inspect "^1.6.0"
object-is "^1.0.1"
- object.assign "^4.0.4"
+ object.assign "^4.1.0"
object.entries "^1.0.4"
object.values "^1.0.4"
raf "^3.4.0"
rst-selector-parser "^2.2.3"
+ string.prototype.trim "^1.1.2"
err-code@^0.1.0:
version "0.1.2"
@@ -7677,6 +7694,17 @@ error@^7.0.0, error@^7.0.2:
string-template "~0.2.1"
xtend "~4.0.0"
+es-abstract@^1.10.0, es-abstract@^1.5.0:
+ version "1.12.0"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165"
+ integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==
+ dependencies:
+ es-to-primitive "^1.1.1"
+ function-bind "^1.1.1"
+ has "^1.0.1"
+ is-callable "^1.1.3"
+ is-regex "^1.0.4"
+
es-abstract@^1.5.1, es-abstract@^1.6.1, es-abstract@^1.7.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
@@ -9374,7 +9402,7 @@ function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
-function.prototype.name@^1.0.3:
+function.prototype.name@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327"
integrity sha512-Bs0VRrTz4ghD8pTmbJQD1mZ8A/mN0ur/jGz+A6FBxPDUPkm1tNfF6bhTYPA7i7aF4lZJVr+OXTNNrnnIl58Wfg==
@@ -11642,6 +11670,11 @@ is-binary-path@^2.0.0:
dependencies:
binary-extensions "^1.0.0"
+is-boolean-object@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"
+ integrity sha1-mPiygDBoQhmpXzdc+9iM40Bd/5M=
+
is-buffer@^1.1.4, is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
@@ -11659,6 +11692,11 @@ is-callable@^1.1.1, is-callable@^1.1.3:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
integrity sha1-hut1OSgF3cM69xySoO7fdO52BLI=
+is-callable@^1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
+ integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
+
is-ci@^1.0.10:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5"
@@ -11868,6 +11906,11 @@ is-npm@^1.0.0:
resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ=
+is-number-object@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.3.tgz#f265ab89a9f445034ef6aff15a8f00b00f551799"
+ integrity sha1-8mWrian0RQNO9q/xWo8AsA9VF5k=
+
is-number@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-0.1.1.tgz#69a7af116963d47206ec9bd9b48a14216f1e3806"
@@ -12025,6 +12068,11 @@ is-stream@1.1.0, is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
+is-string@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.4.tgz#cc3a9b69857d621e963725a24caeec873b826e64"
+ integrity sha1-zDqbaYV9Yh6WNyWiTK7shzuCbmQ=
+
is-subset@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6"
@@ -13749,6 +13797,11 @@ lodash.escape@^3.0.0:
dependencies:
lodash._root "^3.0.0"
+lodash.escape@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98"
+ integrity sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=
+
lodash.filter@^4.4.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace"
@@ -15574,6 +15627,11 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
+object-inspect@^1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b"
+ integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==
+
object-inspect@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-0.4.0.tgz#f5157c116c1455b243b06ee97703392c5ad89fec"
@@ -15616,7 +15674,7 @@ object-visit@^1.0.0:
dependencies:
isobject "^3.0.0"
-object.assign@^4.0.4:
+object.assign@^4.0.4, object.assign@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
@@ -17470,14 +17528,24 @@ react-dom@^16.0.0, react-dom@^16.2.0:
prop-types "^15.6.0"
react-dom@^16.3.0:
- version "16.3.1"
- resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.3.1.tgz#6a3c90a4fb62f915bdbcf6204422d93a7d4ca573"
- integrity sha512-2Infg89vzahq8nfVi1GkjPqq0vrBvf0f3T0+dTtyjq4f6HKOqKixAK25Vr593O3QTx4kw/vmUtAJwerlevNWOA==
+ version "16.7.0"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0.tgz#a17b2a7ca89ee7390bc1ed5eb81783c7461748b8"
+ integrity sha512-D0Ufv1ExCAmF38P2Uh1lwpminZFRXEINJe53zRAbm4KPwSyd6DY/uDoS0Blj9jvPpn1+wivKpZYc8aAAN/nAkg==
dependencies:
- fbjs "^0.8.16"
loose-envify "^1.1.0"
object-assign "^4.1.1"
- prop-types "^15.6.0"
+ prop-types "^15.6.2"
+ scheduler "^0.12.0"
+
+react-dom@^16.6.0:
+ version "16.6.0"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.6.0.tgz#6375b8391e019a632a89a0988bce85f0cc87a92f"
+ integrity sha512-Stm2D9dXEUUAQdvpvhvFj/DEXwC2PAL/RwEMhoN4dvvD2ikTlJegEXf97xryg88VIAU22ZAP7n842l+9BTz6+w==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.2"
+ scheduler "^0.10.0"
react-draggable@3.x, "react-draggable@^2.2.6 || ^3.0.3":
version "3.0.5"
@@ -17537,7 +17605,7 @@ react-is@^16.3.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.4.1.tgz#d624c4650d2c65dbd52c72622bbf389435d9776e"
integrity sha512-xpb0PpALlFWNw/q13A+1aHeyJyLYCg0/cCHPUA43zYluZuIPHaHL3k8OBsTgQtxqW0FhyDEMvi8fZ/+7+r4OSQ==
-react-is@^16.4.0:
+react-is@^16.4.0, react-is@^16.5.2:
version "16.6.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.6.0.tgz#456645144581a6e99f6816ae2bd24ee94bdd0c01"
integrity sha512-q8U7k0Fi7oxF1HvQgyBjPwDXeMplEsArnKt2iYhuIF86+GBbgLHdAmokL3XUFjTd7Q363OSNG55FOGUdONVn1g==
@@ -17610,16 +17678,6 @@ react-portal@^3.2.0:
dependencies:
prop-types "^15.5.8"
-react-reconciler@^0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.7.0.tgz#9614894103e5f138deeeb5eabaf3ee80eb1d026d"
- integrity sha512-50JwZ3yNyMS8fchN+jjWEJOH3Oze7UmhxeoJLn2j6f3NjpfCRbcmih83XTWmzqtar/ivd5f7tvQhvvhism2fgg==
- dependencies:
- fbjs "^0.8.16"
- loose-envify "^1.1.0"
- object-assign "^4.1.1"
- prop-types "^15.6.0"
-
react-redux-request@^1.5.6:
version "1.5.6"
resolved "https://registry.yarnpkg.com/react-redux-request/-/react-redux-request-1.5.6.tgz#8c514dc88264d225e113b4b54a265064e8020651"
@@ -17863,6 +17921,16 @@ react@^16.3.0:
object-assign "^4.1.1"
prop-types "^15.6.0"
+react@^16.6.0:
+ version "16.6.0"
+ resolved "https://registry.yarnpkg.com/react/-/react-16.6.0.tgz#b34761cfaf3e30f5508bc732fb4736730b7da246"
+ integrity sha512-zJPnx/jKtuOEXCbQ9BKaxDMxR0001/hzxXwYxG8septeyYGfsgAei6NgfbVgOhbY1WOP2o3VPs/E9HaN+9hV3Q==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.2"
+ scheduler "^0.10.0"
+
reactcss@1.2.3, reactcss@^1.2.0:
version "1.2.3"
resolved "https://registry.yarnpkg.com/reactcss/-/reactcss-1.2.3.tgz#c00013875e557b1cf0dfd9a368a1c3dab3b548dd"
@@ -19028,6 +19096,22 @@ sax@>=0.6.0, sax@^1.2.1, sax@^1.2.4, sax@~1.2.1:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
+scheduler@^0.10.0:
+ version "0.10.0"
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.10.0.tgz#7988de90fe7edccc774ea175a783e69c40c521e1"
+ integrity sha512-+TSTVTCBAA3h8Anei3haDc1IRwMeDmtI/y/o3iBe3Mjl2vwYF9DtPDt929HyRmV/e7au7CLu8sc4C4W0VOs29w==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+
+scheduler@^0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.12.0.tgz#8ab17699939c0aedc5a196a657743c496538647b"
+ integrity sha512-t7MBR28Akcp4Jm+QoR63XgAi9YgCUmgvDHqf5otgAj4QvdoBE4ImCX0ffehefePPG+aitiYHp0g/mW6s4Tp+dw==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+
schema-utils@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf"
@@ -20099,6 +20183,15 @@ string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"
+string.prototype.trim@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea"
+ integrity sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=
+ dependencies:
+ define-properties "^1.1.2"
+ es-abstract "^1.5.0"
+ function-bind "^1.0.2"
+
string_decoder@0.10, string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
From 476a88e309320d0b35aa50cb86ab503e956cf9a0 Mon Sep 17 00:00:00 2001
From: Justin Kambic
Date: Wed, 23 Jan 2019 14:00:38 -0500
Subject: [PATCH 09/29] [Uptime] Add crosshair sync for monitor page charts
(#28631)
* Add crosshair sync for monitor page charts.
* Fix errant prop in chart component.
* Fix checks domain.
---
.../queries/monitor_charts/monitor_charts.tsx | 343 +++++++++++-------
1 file changed, 217 insertions(+), 126 deletions(-)
diff --git a/x-pack/plugins/uptime/public/components/queries/monitor_charts/monitor_charts.tsx b/x-pack/plugins/uptime/public/components/queries/monitor_charts/monitor_charts.tsx
index b7957f578b20c..b209b92ad5b3a 100644
--- a/x-pack/plugins/uptime/public/components/queries/monitor_charts/monitor_charts.tsx
+++ b/x-pack/plugins/uptime/public/components/queries/monitor_charts/monitor_charts.tsx
@@ -32,130 +32,217 @@ interface MonitorChartsProps {
monitorId: string;
}
+interface MonitorChartsState {
+ crosshairLocation: number;
+}
+
type Props = MonitorChartsProps & UptimeCommonProps;
-export const MonitorCharts = ({
- dateRangeStart,
- dateRangeEnd,
- monitorId,
- autorefreshIsPaused,
- autorefreshInterval,
-}: Props) => (
-
- {({ loading, error, data }) => {
- if (loading) {
- return i18n.translate('xpack.uptime.monitorCharts.loadingMessage', {
- defaultMessage: 'Loading…',
- });
- }
- if (error) {
- return i18n.translate('xpack.uptime.monitorCharts.errorMessage', {
- values: { message: error.message },
- defaultMessage: 'Error {message}',
- });
- }
+export class MonitorCharts extends React.Component {
+ constructor(props: Props) {
+ super(props);
+ this.state = { crosshairLocation: 0 };
+ }
- // TODO: this should not exist in the UI, update the GQL resolver/schema to return
- // an object that contains these series already shaped in the way required by the visualizations.
- const { monitorChartsData } = data;
- const rttWriteRequestSeries: any[] = [];
- const rttValidateSeries: any[] = [];
- const rttContentSeries: any[] = [];
- const rttResponseSeries: any[] = [];
- const rttTcpSeries: any[] = [];
- const avgDurationSeries: any[] = [];
- const areaRttSeries: any[] = [];
- const downSeries: any[] = [];
- const upSeries: any[] = [];
- const checksSeries: any[] = [];
- const maxRtt: any[] = [];
- monitorChartsData.forEach(
- ({
- maxWriteRequest,
- maxValidate,
- maxContent,
- maxResponse,
- maxTcpRtt,
- avgDuration,
- maxDuration,
- minDuration,
- status,
- }: any) => {
- // We're summing these values because we need to know what the max value of the RTT
- // fields are in order to provide an accurate domain size for the RTT combination series.
- maxRtt.push({
- x: maxWriteRequest.x,
- y: maxWriteRequest.y + maxValidate.y + maxContent.y + maxResponse.y + maxTcpRtt.y,
- });
- // TODO: these types of computations should take place on the server and be reflected in the GQL schema
- rttWriteRequestSeries.push(maxWriteRequest);
- rttValidateSeries.push(maxValidate);
- rttContentSeries.push(maxContent);
- rttResponseSeries.push(maxResponse);
- rttTcpSeries.push(maxTcpRtt);
- avgDurationSeries.push(avgDuration);
- areaRttSeries.push({ x: minDuration.x, y0: minDuration.y, y: maxDuration.y });
- downSeries.push({ x: status.x, y: status.down });
- upSeries.push({ x: status.x, y: status.up });
- checksSeries.push({ x: status.x, y: status.total });
- }
- );
+ public render() {
+ const {
+ dateRangeStart,
+ dateRangeEnd,
+ monitorId,
+ autorefreshIsPaused,
+ autorefreshInterval,
+ } = this.props;
+ return (
+
+ {({ loading, error, data }) => {
+ if (loading) {
+ return i18n.translate('xpack.uptime.monitorCharts.loadingMessage', {
+ defaultMessage: 'Loading…',
+ });
+ }
+ if (error) {
+ return i18n.translate('xpack.uptime.monitorCharts.errorMessage', {
+ values: { message: error.message },
+ defaultMessage: 'Error {message}',
+ });
+ }
- // As above, we are building a domain size for the chart to use.
- // Without this code the chart could render data outside of the field.
- const checksDomain = upSeries.concat(downSeries).map(({ y }) => y);
- const domainLimits = [Math.min(...checksDomain), Math.max(...checksDomain)];
- const durationDomain = avgDurationSeries.concat(areaRttSeries);
- const durationLimits = [0, Math.max(...durationDomain.map(({ y }) => y))];
+ // TODO: this should not exist in the UI, update the GQL resolver/schema to return
+ // an object that contains these series already shaped in the way required by the visualizations.
+ const { monitorChartsData } = data;
+ const rttWriteRequestSeries: any[] = [];
+ const rttValidateSeries: any[] = [];
+ const rttContentSeries: any[] = [];
+ const rttResponseSeries: any[] = [];
+ const rttTcpSeries: any[] = [];
+ const avgDurationSeries: any[] = [];
+ const areaRttSeries: any[] = [];
+ const downSeries: any[] = [];
+ const upSeries: any[] = [];
+ const checksSeries: any[] = [];
+ const maxRtt: any[] = [];
+ monitorChartsData.forEach(
+ ({
+ maxWriteRequest,
+ maxValidate,
+ maxContent,
+ maxResponse,
+ maxTcpRtt,
+ avgDuration,
+ maxDuration,
+ minDuration,
+ status,
+ }: any) => {
+ // We're summing these values because we need to know what the max value of the RTT
+ // fields are in order to provide an accurate domain size for the RTT combination series.
+ maxRtt.push({
+ x: maxWriteRequest.x,
+ y: maxWriteRequest.y + maxValidate.y + maxContent.y + maxResponse.y + maxTcpRtt.y,
+ });
+ // TODO: these types of computations should take place on the server and be reflected in the GQL schema
+ rttWriteRequestSeries.push(maxWriteRequest);
+ rttValidateSeries.push(maxValidate);
+ rttContentSeries.push(maxContent);
+ rttResponseSeries.push(maxResponse);
+ rttTcpSeries.push(maxTcpRtt);
+ avgDurationSeries.push(avgDuration);
+ areaRttSeries.push({ x: minDuration.x, y0: minDuration.y, y: maxDuration.y });
+ downSeries.push({ x: status.x, y: status.down });
+ upSeries.push({ x: status.x, y: status.up });
+ checksSeries.push({ x: status.x, y: status.total });
+ }
+ );
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ // As above, we are building a domain size for the chart to use.
+ // Without this code the chart could render data outside of the field.
+ const checksDomain = upSeries.concat(downSeries).map(({ y }) => y);
+ const domainLimits = [0, Math.max(...checksDomain)];
+ const durationDomain = avgDurationSeries.concat(areaRttSeries);
+ const durationLimits = [0, Math.max(...durationDomain.map(({ y }) => y))];
+
+ // find the greatest y-value for rtt chart
+ const rttLimits = [0, Math.max(...maxRtt.map(({ y }) => y))];
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
- );
- }}
-
-);
+
+ );
+ }}
+
+ );
+ }
+ private updateCrosshairLocation = (crosshairLocation: number) =>
+ this.setState({ crosshairLocation });
+}
From b21ee115e9933b0cb874f8421ec5010eb8dcd414 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20St=C3=BCrmer?=
Date: Wed, 23 Jan 2019 21:07:10 +0100
Subject: [PATCH 10/29] Fix index presence detection to work in ccs-only setups
(#28926)
---
.../lib/adapters/framework/adapter_types.ts | 6 ++++++
.../elasticsearch_source_status_adapter.ts | 16 +++++++++++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts
index fca78f8f6fbab..031ab62c4a46f 100644
--- a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts
+++ b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts
@@ -104,6 +104,12 @@ export interface InfraDatabaseResponse {
export interface InfraDatabaseSearchResponse
extends InfraDatabaseResponse {
+ _shards: {
+ total: number;
+ successful: number;
+ skipped: number;
+ failed: number;
+ };
aggregations?: Aggregations;
hits: {
total: number;
diff --git a/x-pack/plugins/infra/server/lib/adapters/source_status/elasticsearch_source_status_adapter.ts b/x-pack/plugins/infra/server/lib/adapters/source_status/elasticsearch_source_status_adapter.ts
index 5b5af97880659..a87499697ddcc 100644
--- a/x-pack/plugins/infra/server/lib/adapters/source_status/elasticsearch_source_status_adapter.ts
+++ b/x-pack/plugins/infra/server/lib/adapters/source_status/elasticsearch_source_status_adapter.ts
@@ -43,7 +43,21 @@ export class InfraElasticsearchSourceStatusAdapter implements InfraSourceStatusA
}
public async hasIndices(request: InfraFrameworkRequest, indexNames: string) {
- return (await this.getIndexNames(request, indexNames)).length > 0;
+ return await this.framework
+ .callWithRequest(request, 'search', {
+ index: indexNames,
+ size: 0,
+ terminate_after: 1,
+ })
+ .then(
+ response => response._shards.total > 0,
+ err => {
+ if (err.status === 404) {
+ return false;
+ }
+ throw err;
+ }
+ );
}
}
From c96068c4ab077f5eba6b1b9d79989a50abb8a255 Mon Sep 17 00:00:00 2001
From: Justin Kambic
Date: Wed, 23 Jan 2019 15:10:36 -0500
Subject: [PATCH 11/29] [Uptime] Fix "last updated" field (#28720)
* Update MonitorStatusBar to not reference undefined value.
* Add sort to top_hits aggregation.
* Add default and loading state for status bar.
* Change bool check.
* Add aria-labels for monitor status bar.
---
.../functional/empty_status_bar.tsx | 23 ++++
.../public/components/functional/index.ts | 9 ++
.../components/functional/status_bar.tsx | 77 +++++++++++++
.../__tests__/format_duration.test.ts | 24 ++++
.../monitor_status_bar/format_duration.ts | 13 +++
.../get_monitor_status_bar.ts | 1 +
.../monitor_status_bar/monitor_status_bar.tsx | 108 +++++-------------
.../components/queries/snapshot/snapshot.tsx | 2 +-
.../uptime/server/graphql/pings/schema.gql.ts | 2 +
.../elasticsearch_pings_adapter.test.ts | 3 +
.../pings/elasticsearch_pings_adapter.ts | 18 ++-
11 files changed, 195 insertions(+), 85 deletions(-)
create mode 100644 x-pack/plugins/uptime/public/components/functional/empty_status_bar.tsx
create mode 100644 x-pack/plugins/uptime/public/components/functional/index.ts
create mode 100644 x-pack/plugins/uptime/public/components/functional/status_bar.tsx
create mode 100644 x-pack/plugins/uptime/public/components/queries/monitor_status_bar/__tests__/format_duration.test.ts
create mode 100644 x-pack/plugins/uptime/public/components/queries/monitor_status_bar/format_duration.ts
diff --git a/x-pack/plugins/uptime/public/components/functional/empty_status_bar.tsx b/x-pack/plugins/uptime/public/components/functional/empty_status_bar.tsx
new file mode 100644
index 0000000000000..46bb9ca560a2a
--- /dev/null
+++ b/x-pack/plugins/uptime/public/components/functional/empty_status_bar.tsx
@@ -0,0 +1,23 @@
+/*
+ * 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 { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui';
+import React from 'react';
+
+interface Props {
+ monitorId: string;
+ message?: string;
+}
+
+export const EmptyStatusBar = ({ message, monitorId }: Props) => (
+
+
+
+ {!message ? `No data found for monitor id ${monitorId}` : message}
+
+
+
+);
diff --git a/x-pack/plugins/uptime/public/components/functional/index.ts b/x-pack/plugins/uptime/public/components/functional/index.ts
new file mode 100644
index 0000000000000..913f35d34c982
--- /dev/null
+++ b/x-pack/plugins/uptime/public/components/functional/index.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export { EmptyStatusBar } from './empty_status_bar';
+export { SnapshotHistogram } from './snapshot_histogram';
+export { StatusBar } from './status_bar';
diff --git a/x-pack/plugins/uptime/public/components/functional/status_bar.tsx b/x-pack/plugins/uptime/public/components/functional/status_bar.tsx
new file mode 100644
index 0000000000000..e5ff275a19e1c
--- /dev/null
+++ b/x-pack/plugins/uptime/public/components/functional/status_bar.tsx
@@ -0,0 +1,77 @@
+/*
+ * 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 { EuiFlexGroup, EuiFlexItem, EuiHealth, EuiLink, EuiPanel } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
+import moment from 'moment';
+import React from 'react';
+
+interface Props {
+ duration?: number;
+ url?: string;
+ status?: string;
+ timestamp?: string;
+}
+
+export const StatusBar = ({ timestamp, url, duration, status }: Props) => (
+
+
+
+
+ {status === 'up'
+ ? i18n.translate('xpack.uptime.monitorStatusBar.healthStatusMessage.upLabel', {
+ defaultMessage: 'Up',
+ })
+ : i18n.translate('xpack.uptime.monitorStatusBar.healthStatusMessage.downLabel', {
+ defaultMessage: 'Down',
+ })}
+
+
+
+
+
+ {url}
+
+
+
+
+
+
+
+ {moment(timestamp).fromNow()}
+
+
+
+);
diff --git a/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/__tests__/format_duration.test.ts b/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/__tests__/format_duration.test.ts
new file mode 100644
index 0000000000000..4889909d98b75
--- /dev/null
+++ b/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/__tests__/format_duration.test.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { formatDuration } from '../format_duration';
+
+describe('formatDuration', () => {
+ it('returns 0 for undefined', () => {
+ const result = formatDuration(undefined);
+ expect(result).toEqual(0);
+ });
+
+ it('returns 0 for NaN', () => {
+ const result = formatDuration(NaN);
+ expect(result).toEqual(0);
+ });
+
+ it('returns duration value in ms', () => {
+ const duration = 320000; // microseconds
+ expect(formatDuration(duration)).toEqual(320);
+ });
+});
diff --git a/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/format_duration.ts b/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/format_duration.ts
new file mode 100644
index 0000000000000..955eb81f9a77a
--- /dev/null
+++ b/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/format_duration.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export const formatDuration = (duration: number | undefined): number => {
+ if (duration === undefined) {
+ return 0;
+ }
+ // TODO: formatting should not be performed this way, remove bare number
+ return isNaN(duration) ? 0 : duration / 1000;
+};
diff --git a/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/get_monitor_status_bar.ts b/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/get_monitor_status_bar.ts
index 747e80b0413d3..ba497e668df8f 100644
--- a/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/get_monitor_status_bar.ts
+++ b/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/get_monitor_status_bar.ts
@@ -14,6 +14,7 @@ export const createGetMonitorStatusBarQuery = gql`
monitorId: $monitorId
) {
timestamp
+ millisFromNow
monitor {
status
host
diff --git a/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/monitor_status_bar.tsx b/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/monitor_status_bar.tsx
index 4af44b72dceb3..4b287873bc62b 100644
--- a/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/monitor_status_bar.tsx
+++ b/x-pack/plugins/uptime/public/components/queries/monitor_status_bar/monitor_status_bar.tsx
@@ -4,19 +4,28 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiFlexGroup, EuiFlexItem, EuiHealth, EuiLink, EuiPanel } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { FormattedMessage } from '@kbn/i18n/react';
-import moment from 'moment';
+import { ApolloError } from 'apollo-client';
+import { get } from 'lodash';
import React from 'react';
import { Query } from 'react-apollo';
+import { Ping } from 'x-pack/plugins/uptime/common/graphql/types';
import { UptimeCommonProps } from '../../../uptime_app';
+import { StatusBar } from '../../functional';
+import { EmptyStatusBar } from '../../functional/empty_status_bar';
+import { formatDuration } from './format_duration';
import { createGetMonitorStatusBarQuery } from './get_monitor_status_bar';
interface MonitorStatusBarProps {
monitorId: string;
}
+interface MonitorStatusBarQueryParams {
+ loading: boolean;
+ error?: ApolloError | any;
+ data?: { monitorStatus: Ping[] };
+}
+
type Props = MonitorStatusBarProps & UptimeCommonProps;
export const MonitorStatusBar = ({
@@ -31,11 +40,9 @@ export const MonitorStatusBar = ({
query={createGetMonitorStatusBarQuery}
variables={{ dateRangeStart, dateRangeEnd, monitorId }}
>
- {({ loading, error, data }) => {
+ {({ loading, error, data }: MonitorStatusBarQueryParams) => {
if (loading) {
- return i18n.translate('xpack.uptime.monitorStatusBar.loadingMessage', {
- defaultMessage: 'Loading…',
- });
+ return ;
}
if (error) {
return i18n.translate('xpack.uptime.monitorStatusBar.errorMessage', {
@@ -43,82 +50,23 @@ export const MonitorStatusBar = ({
defaultMessage: 'Error {message}',
});
}
- const { monitorStatus } = data;
- if (!monitorStatus.length) {
- return i18n.translate('xpack.uptime.monitorStatusBar.noDataMessage', {
- values: { monitorId },
- defaultMessage: 'No data found for monitor id {monitorId}',
- });
+
+ const monitorStatus: Ping[] = get(data, 'monitorStatus');
+ if (!monitorStatus || !monitorStatus.length) {
+ return ;
}
- const {
- monitor: {
- status,
- timestamp,
- ip,
- duration: { us },
- },
- url: { full: fullURL },
- } = monitorStatus[0];
+ const { monitor, timestamp, url } = monitorStatus[0];
+ const status = get(monitor, 'status', undefined);
+ const duration = parseInt(get(monitor, 'duration.us'), 10);
+ const full = get(url, 'full', undefined);
return (
-
-
-
-
-
-
-
-
-
- {status === 'up'
- ? i18n.translate(
- 'xpack.uptime.monitorStatusBar.healthStatusMessage.upLabel',
- { defaultMessage: 'Up' }
- )
- : i18n.translate(
- 'xpack.uptime.monitorStatusBar.healthStatusMessage.downLabel',
- { defaultMessage: 'Down' }
- )}
-
-
-
-
-
-
-
-
-
- {fullURL}
-
-
-
-
-
-
-
-
-
-
+
);
}}
diff --git a/x-pack/plugins/uptime/public/components/queries/snapshot/snapshot.tsx b/x-pack/plugins/uptime/public/components/queries/snapshot/snapshot.tsx
index 4b74d5a2e62ff..cdcad14817bcc 100644
--- a/x-pack/plugins/uptime/public/components/queries/snapshot/snapshot.tsx
+++ b/x-pack/plugins/uptime/public/components/queries/snapshot/snapshot.tsx
@@ -27,7 +27,7 @@ import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import { Query } from 'react-apollo';
import { UptimeCommonProps } from '../../../uptime_app';
-import { SnapshotHistogram } from '../../functional/snapshot_histogram';
+import { SnapshotHistogram } from '../../functional';
import { getSnapshotQuery } from './get_snapshot';
interface SnapshotProps {
diff --git a/x-pack/plugins/uptime/server/graphql/pings/schema.gql.ts b/x-pack/plugins/uptime/server/graphql/pings/schema.gql.ts
index f4811986299f3..1a2b2482b11f3 100644
--- a/x-pack/plugins/uptime/server/graphql/pings/schema.gql.ts
+++ b/x-pack/plugins/uptime/server/graphql/pings/schema.gql.ts
@@ -193,6 +193,8 @@ export const pingsSchema = gql`
type Ping {
"The timestamp of the ping's creation"
timestamp: String!
+ "Milliseconds from the timestamp to the current time"
+ millisFromNow: Int
"The agent that recorded the ping"
beat: Beat
docker: Docker
diff --git a/x-pack/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts b/x-pack/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts
index 39f34aec53cf8..595f87565e161 100644
--- a/x-pack/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts
+++ b/x-pack/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts
@@ -182,6 +182,9 @@ describe('ElasticsearchPingsAdapter class', () => {
latest: {
top_hits: {
size: 1,
+ sort: {
+ '@timestamp': { order: 'desc' },
+ },
},
},
},
diff --git a/x-pack/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts b/x-pack/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts
index bb502bfc39d5a..c8c31a41173c2 100644
--- a/x-pack/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts
+++ b/x-pack/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts
@@ -5,6 +5,7 @@
*/
import { get } from 'lodash';
+import moment from 'moment';
import { INDEX_NAMES } from '../../../../common/constants';
import { DocCount, HistogramSeries, Ping, PingResults } from '../../../../common/graphql/types';
import { DatabaseAdapter } from '../database';
@@ -128,6 +129,9 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
latest: {
top_hits: {
size: 1,
+ sort: {
+ '@timestamp': { order: 'desc' },
+ },
},
},
},
@@ -142,10 +146,16 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
} = await this.database.search(request, params);
// @ts-ignore TODO fix destructuring implicit any
- return buckets.map(({ latest: { hits: { hits } } }) => ({
- ...hits[0]._source,
- timestamp: hits[0]._source[`@timestamp`],
- }));
+ return buckets.map(({ latest: { hits: { hits } } }) => {
+ const timestamp = hits[0]._source[`@timestamp`];
+ const momentTs = moment(timestamp);
+ const millisFromNow = moment().diff(momentTs);
+ return {
+ ...hits[0]._source,
+ timestamp,
+ millisFromNow,
+ };
+ });
}
public async getPingHistogram(
From bc86c52ef11396f97d8d7d8d46047d04fe085fb4 Mon Sep 17 00:00:00 2001
From: Joel Griffith
Date: Wed, 23 Jan 2019 12:20:28 -0800
Subject: [PATCH 12/29] Record failed ES queue jobs when saving the result
fails (don't retry) (#28629)
---
.../server/lib/esqueue/__tests__/worker.js | 27 +++++++++++++++++++
.../reporting/server/lib/esqueue/worker.js | 1 +
2 files changed, 28 insertions(+)
diff --git a/x-pack/plugins/reporting/server/lib/esqueue/__tests__/worker.js b/x-pack/plugins/reporting/server/lib/esqueue/__tests__/worker.js
index d86125d6c4c94..15fa81954d7dd 100644
--- a/x-pack/plugins/reporting/server/lib/esqueue/__tests__/worker.js
+++ b/x-pack/plugins/reporting/server/lib/esqueue/__tests__/worker.js
@@ -867,6 +867,33 @@ describe('Worker class', function () {
return sinon.stub(workerWithFailure, '_failJob').returns(Promise.resolve());
}
+ describe('saving output failure', () => {
+ it('should mark the job as failed if saving to ES fails', async () => {
+ const job = {
+ _id: 'shouldSucced',
+ _source: {
+ timeout: 1000,
+ payload: 'test'
+ }
+ };
+
+ sinon.stub(mockQueue.client, 'update').returns(Promise.reject({ statusCode: 413 }));
+
+ const workerFn = function (jobPayload) {
+ return new Promise(function (resolve) {
+ setTimeout(() => resolve(jobPayload), 10);
+ });
+ };
+ const worker = new Worker(mockQueue, 'test', workerFn, defaultWorkerOptions);
+ const failStub = getFailStub(worker);
+
+ await worker._performJob(job);
+ worker.destroy();
+
+ sinon.assert.called(failStub);
+ });
+ });
+
describe('search failure', function () {
it('causes _processPendingJobs to reject the Promise', function () {
sinon.stub(mockQueue.client, 'search').returns(Promise.reject(new Error('test error')));
diff --git a/x-pack/plugins/reporting/server/lib/esqueue/worker.js b/x-pack/plugins/reporting/server/lib/esqueue/worker.js
index 8c6bd5125e676..c5fa020fb76c6 100644
--- a/x-pack/plugins/reporting/server/lib/esqueue/worker.js
+++ b/x-pack/plugins/reporting/server/lib/esqueue/worker.js
@@ -259,6 +259,7 @@ export class Worker extends events.EventEmitter {
if (err.statusCode === 409) return false;
this.warn(`Failure saving job output ${job._id}`, err);
this.emit(constants.EVENT_WORKER_JOB_UPDATE_ERROR, this._formatErrorParams(err, job));
+ return this._failJob(job, (err.message) ? err.message : false);
});
}, (jobErr) => {
if (!jobErr) {
From adbe6bb592a6f411bffe25574daef4b35ad9ca94 Mon Sep 17 00:00:00 2001
From: James Gowdy
Date: Wed, 23 Jan 2019 21:04:08 +0000
Subject: [PATCH 13/29] [ML] Fixing job cloning when it has an unknown
created_by value (#29175)
---
.../ml/public/jobs/new_job/wizard/preconfigured_job_redirect.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/x-pack/plugins/ml/public/jobs/new_job/wizard/preconfigured_job_redirect.js b/x-pack/plugins/ml/public/jobs/new_job/wizard/preconfigured_job_redirect.js
index 4a9ed00e5c423..65e1e196b2d84 100644
--- a/x-pack/plugins/ml/public/jobs/new_job/wizard/preconfigured_job_redirect.js
+++ b/x-pack/plugins/ml/public/jobs/new_job/wizard/preconfigured_job_redirect.js
@@ -88,6 +88,8 @@ function getWizardUrlFromCloningJob(job) {
page = 'multi_metric';
} else if (created === WIZARD_TYPE.POPULATION) {
page = 'population';
+ } else {
+ return null;
}
const indexPatternId = getIndexPatternIdFromName(job.datafeed_config.indices[0]);
From e0992aa4334520283e1acff943cfe76abbd0c59b Mon Sep 17 00:00:00 2001
From: Ahmad Bamieh
Date: Wed, 23 Jan 2019 14:07:13 -0800
Subject: [PATCH 14/29] [i18n] Translate partials (#28653)
localize partials
---
.../directives/paginated_selectable_list.js | 8 ++-
src/ui/public/partials/paginate_controls.html | 11 ++--
.../partials/paginated_selectable_list.html | 43 ++++++++++----
.../public/partials/saved_object_finder.html | 58 ++++++++++++++-----
4 files changed, 88 insertions(+), 32 deletions(-)
diff --git a/src/ui/public/directives/paginated_selectable_list.js b/src/ui/public/directives/paginated_selectable_list.js
index e71c6dc67e286..417273668dae7 100644
--- a/src/ui/public/directives/paginated_selectable_list.js
+++ b/src/ui/public/directives/paginated_selectable_list.js
@@ -40,7 +40,11 @@ module.directive('paginatedSelectableList', function () {
disableAutoFocus: '='
},
template: paginatedSelectableListTemplate,
- controller: function ($scope) {
+ controller: function ($scope, $filter) {
+ function calculateHitsByQuery() {
+ $scope.hitsByQuery = $filter('filter')($scope.hits, $scope.query);
+ }
+
// Should specify either user-make-url or user-on-select
if (!$scope.userMakeUrl && !$scope.userOnSelect) {
throwError('paginatedSelectableList directive expects a makeUrl or onSelect function');
@@ -53,6 +57,8 @@ module.directive('paginatedSelectableList', function () {
$scope.perPage = $scope.perPage || 10;
$scope.hits = $scope.list = _.sortBy($scope.list, $scope.accessor);
+ $scope.$watchGroup(['hits', 'query'], calculateHitsByQuery);
+ calculateHitsByQuery();
$scope.hitCount = $scope.hits.length;
/**
diff --git a/src/ui/public/partials/paginate_controls.html b/src/ui/public/partials/paginate_controls.html
index 727c7e63624c1..c40021507c233 100644
--- a/src/ui/public/partials/paginate_controls.html
+++ b/src/ui/public/partials/paginate_controls.html
@@ -3,9 +3,9 @@
ng-if="linkToTop"
ng-click="paginate.goToTop()"
data-test-subj="paginateControlsLinkToTop"
->
- Scroll to top
-
+ i18n-id="common.ui.paginateControls.scrollTopButtonLabel"
+ i18n-default-message="Scroll to top"
+>
-
- No matches found.
+
+
diff --git a/src/ui/public/partials/saved_object_finder.html b/src/ui/public/partials/saved_object_finder.html
index d1beae5abfce5..3ce944c41f7ad 100644
--- a/src/ui/public/partials/saved_object_finder.html
+++ b/src/ui/public/partials/saved_object_finder.html
@@ -22,27 +22,32 @@
-
- {{ pageFirstItem }}-{{ pageLastItem }} of {{ finder.hitCount }}
-
-
+
- Add new {{ finder.properties.noun }}
-
+ i18n-id="common.ui.savedObjectFinder.addNewItemButtonLabel"
+ i18n-default-message="Add new {item}"
+ i18n-values="{item: finder.properties.noun}"
+ i18n-description="{item} can be a type of object in Kibana, like 'visualization', 'dashboard', etc"
+ >
- Manage {{ finder.properties.nouns }}
-
+ i18n-id="common.ui.savedObjectFinder.manageItemsButtonLabel"
+ i18n-default-message="Manage {items}"
+ i18n-values="{items: finder.properties.nouns}"
+ i18n-description="{items} can be a type of object in Kibana, like 'visualizations', 'dashboards', etc"
+ >
@@ -58,12 +63,28 @@
ng-click="finder.sortHits(finder.hits)"
aria-live="assertive"
>
- Sort by
- Name
+
+
- ({{finder.isAscending ? 'ascending' : 'descending'}})
+ ng-class="finder.isAscending ? 'fa-caret-up' : 'fa-caret-down'"
+ >
+
+
From c05261396237ea29acc643ff6aa4e9dbe7d2d33f Mon Sep 17 00:00:00 2001
From: Spencer
Date: Wed, 23 Jan 2019 14:29:35 -0800
Subject: [PATCH 15/29] [dashboard+gis] remove dark mode options (#29017)
* [dashboard+gis] remove dark mode options
* [reporting/extract] restore fixtures
* remove mentions of old `.theme-dark` class
* import panel styles from panel/_index.scss
---
docs/api/dashboard-import/import.asciidoc | 2 +-
docs/api/url_shortening/shorten_url.asciidoc | 2 +-
docs/management/advanced-options.asciidoc | 1 -
.../kibana/public/dashboard/README.md | 1 -
.../kibana/public/dashboard/_hacks.scss | 188 ------------------
.../kibana/public/dashboard/_index.scss | 35 +---
.../kibana/public/dashboard/dashboard_app.js | 27 ---
.../dashboard/dashboard_state_manager.js | 9 -
.../kibana/public/dashboard/panel/_index.scss | 1 +
.../saved_dashboard/saved_dashboard.js | 1 -
.../public/dashboard/top_nav/options.js | 21 --
.../dashboard/top_nav/show_options_popover.js | 4 -
.../kibana/ui_setting_defaults.js | 10 -
.../metrics/public/components/vis_editor.js | 24 +--
.../visualizations/components/_metric.scss | 1 -
.../public/directives/chart/_chart.scss | 12 --
.../data_sets/ecommerce/saved_objects.js | 2 +-
.../data_sets/flights/saved_objects.js | 2 +-
.../data_sets/logs/saved_objects.js | 2 +-
src/ui/public/agg_table/_agg_table.scss | 11 -
.../doc_table/components/table_row/_cell.scss | 8 -
src/ui/public/filter_bar/filter_bar.less | 46 -----
src/ui/public/markdown/_github_markdown.scss | 62 ------
.../styles/_legacy/components/_config.scss | 11 -
.../styles/_legacy/components/_input.scss | 9 -
.../_legacy/components/_list_group_menu.scss | 24 ---
.../_legacy/components/_pagination.scss | 21 --
.../components/_react_input_range.scss | 21 --
.../styles/_legacy/components/_spinner.scss | 6 -
.../styles/_legacy/components/_table.scss | 14 --
.../apps/dashboard/_bwc_shared_urls.js | 2 +-
test/functional/apps/dashboard/_dark_theme.js | 48 -----
.../apps/dashboard/_dashboard_state.js | 8 -
.../dashboard/exports/timezonetest_6_2_4.json | 2 +-
test/functional/apps/dashboard/index.js | 1 -
.../functional/page_objects/dashboard_page.js | 16 --
.../gis/public/angular/map_controller.js | 36 +---
.../public/angular/services/saved_gis_map.js | 5 +-
.../public/components/top_nav/options_menu.js | 40 ----
.../top_nav/options_menu_container.js | 26 ---
.../top_nav/show_options_popover.js | 53 -----
x-pack/plugins/gis/public/store/ui.js | 11 -
...ache2-Access-Remote-IP-Count-Explorer.json | 18 +-
.../ML-Apache2-Remote-IP-URL-Explorer.json | 18 +-
...l_auditbeat_docker_process_event_rate.json | 2 +-
.../ml_auditbeat_docker_process_explorer.json | 2 +-
...ml_auditbeat_hosts_process_event_rate.json | 2 +-
.../ml_auditbeat_hosts_process_explorer.json | 2 +-
...Nginx-Access-Remote-IP-Count-Explorer.json | 18 +-
.../ML-Nginx-Remote-IP-URL-Explorer.json | 18 +-
x-pack/test/reporting/api/generation_urls.js | 8 +-
.../saved_objects/spaces/data.json | 6 +-
52 files changed, 62 insertions(+), 858 deletions(-)
delete mode 100644 test/functional/apps/dashboard/_dark_theme.js
delete mode 100644 x-pack/plugins/gis/public/components/top_nav/options_menu.js
delete mode 100644 x-pack/plugins/gis/public/components/top_nav/options_menu_container.js
delete mode 100644 x-pack/plugins/gis/public/components/top_nav/show_options_popover.js
diff --git a/docs/api/dashboard-import/import.asciidoc b/docs/api/dashboard-import/import.asciidoc
index 3e9584bafbddd..9e6752a8ee41b 100644
--- a/docs/api/dashboard-import/import.asciidoc
+++ b/docs/api/dashboard-import/import.asciidoc
@@ -80,7 +80,7 @@ POST api/kibana/dashboards/import?exclude=index-pattern
"hits": 0,
"description": "",
"panelsJSON": "[{\"gridData\":{\"w\":24,\"h\":15,\"x\":0,\"y\":0,\"i\":\"1\"},\"version\":\"7.0.0-alpha1\",\"panelIndex\":\"1\",\"type\":\"visualization\",\"id\":\"80b956f0-b2cd-11e8-ad8e-85441f0c2e5c\",\"embeddableConfig\":{}}]",
- "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}",
+ "optionsJSON": "{\"useMargins\":true,\"hidePanelTitles\":false}",
"version": 1,
"timeRestore": false,
"kibanaSavedObjectMeta": {
diff --git a/docs/api/url_shortening/shorten_url.asciidoc b/docs/api/url_shortening/shorten_url.asciidoc
index 2f9d9342296b9..c0674da0ca6f2 100644
--- a/docs/api/url_shortening/shorten_url.asciidoc
+++ b/docs/api/url_shortening/shorten_url.asciidoc
@@ -28,7 +28,7 @@ the shortened URL token for the provided request body.
--------------------------------------------------
POST api/shorten_url
{
- "url": "/app/kibana#/dashboard?_g=()&_a=(description:'',filters:!(),fullScreenMode:!f,options:(darkTheme:!f,hidePanelTitles:!f,useMargins:!t),panels:!((embeddableConfig:(),gridData:(h:15,i:'1',w:24,x:0,y:0),id:'8f4d0c00-4c86-11e8-b3d7-01146121b73d',panelIndex:'1',type:visualization,version:'7.0.0-alpha1')),query:(language:lucene,query:''),timeRestore:!f,title:'New%20Dashboard',viewMode:edit)",
+ "url": "/app/kibana#/dashboard?_g=()&_a=(description:'',filters:!(),fullScreenMode:!f,options:(hidePanelTitles:!f,useMargins:!t),panels:!((embeddableConfig:(),gridData:(h:15,i:'1',w:24,x:0,y:0),id:'8f4d0c00-4c86-11e8-b3d7-01146121b73d',panelIndex:'1',type:visualization,version:'7.0.0-alpha1')),query:(language:lucene,query:''),timeRestore:!f,title:'New%20Dashboard',viewMode:edit)",
}
--------------------------------------------------
// KIBANA
diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc
index 20d57d1d2ae0a..e1659c7d46f08 100644
--- a/docs/management/advanced-options.asciidoc
+++ b/docs/management/advanced-options.asciidoc
@@ -77,7 +77,6 @@ mentioned use "_default_".
`timepicker:timeDefaults`:: The default time filter selection.
`timepicker:refreshIntervalDefaults`:: The time filter's default refresh interval.
`timepicker:quickRanges`:: The list of ranges to show in the Quick section of the time picker. This should be an array of objects, with each object containing `from`, `to` (see {ref}/common-options.html#date-math[accepted formats]), `display` (the title to be displayed), and `section` (which column to put the option in).
-`dashboard:defaultDarkTheme`:: Set this property to `true` to make new dashboards use the dark theme by default.
`filters:pinnedByDefault`:: Set this property to `true` to make filters have a global state by default.
`filterEditor:suggestValues`:: Set this property to `false` to prevent the filter editor from suggesting values for fields.
`notifications:banner`:: You can specify a custom banner to display temporary notices to all users. This field supports
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/README.md b/src/legacy/core_plugins/kibana/public/dashboard/README.md
index 0e56bb8fd8852..70735bba7b83b 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/README.md
+++ b/src/legacy/core_plugins/kibana/public/dashboard/README.md
@@ -110,7 +110,6 @@ State communicated to the embeddable.
// TODO:
filters: FilterObject,
timeRange: TimeRangeObject,
- darkTheme: boolean,
}
```
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/_hacks.scss b/src/legacy/core_plugins/kibana/public/dashboard/_hacks.scss
index d13fe9f7f6f15..13d23c1d1948d 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/_hacks.scss
+++ b/src/legacy/core_plugins/kibana/public/dashboard/_hacks.scss
@@ -18,191 +18,3 @@ dashboard-listing {
flex: 1;
}
}
-
-
-// Dark theme bootstrap
-// Yes, this is a hack because bootstrap will be removed and everything must move to EUI theming
-// Can't reliably remove all/any of these because of embeddables
-
-.theme-dark {
- @import '@elastic/eui/src/themes/k6/k6_colors_dark';
-
- // /src/ui/public/styles/bootstrap/scaffolding.less
- a {
- color: $euiColorPrimary;
-
- &:hover,
- &:focus {
- color: darken($euiColorPrimary, 10%);
- }
- }
-
- // /src/ui/public/styles/bootstrap/forms.less
- // Updated to match EUI dark theme
- .form-control {
- color: $euiTextColor;
- background-color: tintOrShade($euiColorLightestShade, 60%, 25%);
- border-color: transparentize($euiColorFullShade, .9);
- &[disabled],
- &[readonly],
- fieldset[disabled] & {
- background-color: darken($euiColorLightestShade, 2%);
- }
- }
-
- // /src/ui/public/styles/bootstrap/tables.less
- // Updated to match EUI dark theme
- .table {
- // Cells
- > thead,
- > tbody,
- > tfoot {
- > tr {
- > th,
- > td {
- border-top-color: $euiColorLightShade;
- }
- }
- }
- // Bottom align for column headings
- > thead > tr > th {
- border-bottom-color: $euiColorLightShade;
- }
- // Account for multiple tbody instances
- > tbody + tbody {
- border-top-color: $euiColorLightShade;
- }
-
- // Nesting
- .table {
- background-color: transparent;
- }
- }
-
- table {
- th {
- i.fa-sort {
- color: $euiColorMediumShade;
- }
-
- button.fa-sort-asc,
- button.fa-sort-down,
- i.fa-sort-asc,
- i.fa-sort-down {
- color: $euiTextColor;
- }
-
- button.fa-sort-desc,
- button.fa-sort-up,
- i.fa-sort-desc,
- i.fa-sort-up {
- color: $euiTextColor;
- }
- }
- }
-
-
- // /src/ui/public/styles/bootstrap/list-group.less
- .list-group-item {
- background-color: $euiColorLightShade;
- border-color: $euiColorDarkShade;
- &:nth-child(even) {
- background-color: $euiColorMediumShade;
- }
- }
-
- a.list-group-item,
- button.list-group-item {
- color: $euiColorMediumShade;
-
- .list-group-item-heading {
- color: $euiColorLightShade;
- }
-
- // Hover state
- &:hover,
- &:focus {
- color: $euiColorMediumShade;
- background-color: $euiColorDarkestShade;
- }
- }
-
- .panel {
- > .panel-body + .table,
- > .panel-body + .table-responsive,
- > .table + .panel-body,
- > .table-responsive + .panel-body {
- border-top-color: $euiColorMediumShade;
- }
- }
-
- .panel-group {
- .panel-heading {
- + .panel-collapse > .panel-body,
- + .panel-collapse > .list-group {
- border-top-color: $euiColorEmptyShade;
- }
- }
-
- .panel-footer {
- border-top: 0;
- + .panel-collapse .panel-body {
- border-bottom-color: $euiColorEmptyShade;
- }
- }
- }
-
- .panel-default {
- & > .panel-heading {
- color: $euiColorPrimary;
- background-color: $euiColorEmptyShade;
- border-color: $euiColorLightShade;
-
- + .panel-collapse > .panel-body {
- border-top-color: $euiColorLightShade;
- }
- .badge {
- color: $euiColorEmptyShade;
- background-color: $euiColorPrimary;
- }
- }
- & > .panel-footer {
- + .panel-collapse > .panel-body {
- border-bottom-color: $euiColorLightShade;
- }
- }
- }
-
- // /src/ui/public/styles/bootstrap/navs.less
- .nav {
- > li {
- > a {
- &:hover,
- &:focus {
- background-color: $euiColorDarkShade;
- }
- }
- }
- }
-
- .nav-tabs {
- border-bottom-color: $euiColorMediumShade;
- > li {
- > a {
- &:hover {
- border-color: $euiColorDarkShade;
- }
- }
-
- &.active > a {
- &,
- &:hover,
- &:focus {
- color: $euiColorFullShade;
- background-color: $euiColorMediumShade;
- border: 0 none transparent;
- }
- }
- }
- }
-}
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/_index.scss b/src/legacy/core_plugins/kibana/public/dashboard/_index.scss
index 98e918e507d92..d2d13c778c50e 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/_index.scss
+++ b/src/legacy/core_plugins/kibana/public/dashboard/_index.scss
@@ -13,35 +13,8 @@
// dshChart__legend--small
// dshChart__legend-isLoading
-/**
- * 1. Don't duplicate styles in dark mode
- */
-.theme-light { /* 1 */
- @import 'dashboard_app';
- @import 'grid/index';
- @import 'panel/index';
- @import 'viewport/index';
-}
-
-// Imports outside of theme selector don't change between light/dark modes
+@import 'dashboard_app';
+@import 'grid/index';
+@import 'panel/index';
+@import 'viewport/index';
@import 'components/index';
-
-// Must be outside of theme selector because it lives in a portal
-@import 'panel/panel_header/panel_options_menu_form';
-
-// DARK THEME
-// EUI global scope -- dark
-@import '@elastic/eui/src/themes/k6/k6_colors_dark';
-
-.theme-dark {
- background-color: $euiColorEmptyShade;
-
- @import 'dashboard_app';
- @import 'grid/index';
- @import 'panel/index';
- @import 'viewport/index';
-
- // Vis imports
- @import 'src/ui/public/vis/index';
- @import 'src/ui/public/vislib/index';
-}
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js
index f71edb1c5e77b..ed3edbe6b69bb 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js
+++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js
@@ -22,7 +22,6 @@ import React from 'react';
import angular from 'angular';
import { uiModules } from 'ui/modules';
import chrome from 'ui/chrome';
-import { applyTheme } from 'ui/theme';
import { toastNotifications } from 'ui/notify';
import 'ui/query_bar';
@@ -230,8 +229,6 @@ app.directive('dashboardApp', function ($injector) {
$scope.refresh();
};
- updateTheme();
-
$scope.indexPatterns = [];
$scope.onPanelRemoved = (panelIndex) => {
@@ -433,11 +430,6 @@ app.directive('dashboardApp', function ($injector) {
navActions[TopNavIds.OPTIONS] = (menuItem, navController, anchorElement) => {
showOptionsPopover({
anchorElement,
- darkTheme: dashboardStateManager.getDarkTheme(),
- onDarkThemeChange: (isChecked) => {
- dashboardStateManager.setDarkTheme(isChecked);
- updateTheme();
- },
useMargins: dashboardStateManager.getUseMargins(),
onUseMarginsChange: (isChecked) => {
dashboardStateManager.setUseMargins(isChecked);
@@ -475,27 +467,8 @@ app.directive('dashboardApp', function ($injector) {
$scope.$on('$destroy', () => {
dashboardStateManager.destroy();
-
- // Remove dark theme to keep it from affecting the appearance of other apps.
- setLightTheme();
});
- function updateTheme() {
- dashboardStateManager.getDarkTheme() ? setDarkTheme() : setLightTheme();
- }
-
- function setDarkTheme() {
- chrome.removeApplicationClass(['theme-light']);
- chrome.addApplicationClass('theme-dark');
- applyTheme('dark');
- }
-
- function setLightTheme() {
- chrome.removeApplicationClass(['theme-dark']);
- chrome.addApplicationClass('theme-light');
- applyTheme('light');
- }
-
if ($route.current.params && $route.current.params[DashboardConstants.NEW_VISUALIZATION_ID_PARAM]) {
dashboardStateManager.addNewPanel($route.current.params[DashboardConstants.NEW_VISUALIZATION_ID_PARAM], 'visualization');
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.js b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.js
index 7002819e5e734..cff4438ce3a5d 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.js
+++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.js
@@ -369,15 +369,6 @@ export class DashboardStateManager {
this.saveState();
}
- getDarkTheme() {
- return this.appState.options.darkTheme;
- }
-
- setDarkTheme(darkTheme) {
- this.appState.options.darkTheme = darkTheme;
- this.saveState();
- }
-
getTimeRestore() {
return this.appState.timeRestore;
}
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/panel/_index.scss b/src/legacy/core_plugins/kibana/public/dashboard/panel/_index.scss
index b899f02b2639a..7fed11fe9db9d 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/panel/_index.scss
+++ b/src/legacy/core_plugins/kibana/public/dashboard/panel/_index.scss
@@ -1 +1,2 @@
@import "./dashboard_panel";
+@import 'panel_header/panel_options_menu_form';
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.js b/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.js
index 04773be6e428b..82cf20d9c25af 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.js
+++ b/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.js
@@ -48,7 +48,6 @@ module.factory('SavedDashboard', function (Private, config, i18n) {
description: '',
panelsJSON: '[]',
optionsJSON: angular.toJson({
- darkTheme: config.get('dashboard:defaultDarkTheme'),
// for BWC reasons we can't default dashboards that already exist without this setting to true.
useMargins: id ? false : true,
hidePanelTitles: false,
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/top_nav/options.js b/src/legacy/core_plugins/kibana/public/dashboard/top_nav/options.js
index 62c3b65374db4..6d30f757d2032 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/top_nav/options.js
+++ b/src/legacy/core_plugins/kibana/public/dashboard/top_nav/options.js
@@ -30,17 +30,10 @@ import {
class OptionsMenuUi extends Component {
state = {
- darkTheme: this.props.darkTheme,
useMargins: this.props.useMargins,
hidePanelTitles: this.props.hidePanelTitles,
}
- handleDarkThemeChange = (evt) => {
- const isChecked = evt.target.checked;
- this.props.onDarkThemeChange(isChecked);
- this.setState({ darkTheme: isChecked });
- }
-
handleUseMarginsChange = (evt) => {
const isChecked = evt.target.checked;
this.props.onUseMarginsChange(isChecked);
@@ -59,18 +52,6 @@ class OptionsMenuUi extends Component {
data-test-subj="dashboardOptionsMenu"
>
-
-
-
-
{
export function showOptionsPopover({
anchorElement,
- darkTheme,
- onDarkThemeChange,
useMargins,
onUseMarginsChange,
hidePanelTitles,
@@ -64,8 +62,6 @@ export function showOptionsPopover({
closePopover={onClose}
>
{
const { params } = this.props.vis;
const { visFields } = this.state;
@@ -134,12 +113,11 @@ class VisEditor extends Component {
if (!this.props.vis.params || !this.props.visData) {
return null;
}
- const reversed = this.state.reversed;
return (
[
defaultMessage: 'Analyze mock eCommerce orders and revenue',
}),
"panelsJSON": "[{\"embeddableConfig\":{\"vis\":{\"colors\":{\"Men's Accessories\":\"#82B5D8\",\"Men's Clothing\":\"#F9BA8F\",\"Men's Shoes\":\"#F29191\",\"Women's Accessories\":\"#F4D598\",\"Women's Clothing\":\"#70DBED\",\"Women's Shoes\":\"#B7DBAB\"}}},\"gridData\":{\"x\":12,\"y\":18,\"w\":36,\"h\":10,\"i\":\"1\"},\"id\":\"37cc8650-b882-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"1\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{\"vis\":{\"colors\":{\"FEMALE\":\"#6ED0E0\",\"MALE\":\"#447EBC\"},\"legendOpen\":false}},\"gridData\":{\"x\":12,\"y\":7,\"w\":12,\"h\":11,\"i\":\"2\"},\"id\":\"ed8436b0-b88b-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"2\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":0,\"w\":18,\"h\":7,\"i\":\"3\"},\"id\":\"09ffee60-b88c-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"3\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":18,\"y\":0,\"w\":30,\"h\":7,\"i\":\"4\"},\"id\":\"1c389590-b88d-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"4\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":28,\"w\":48,\"h\":11,\"i\":\"5\"},\"id\":\"45e07720-b890-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"5\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":18,\"w\":12,\"h\":10,\"i\":\"6\"},\"id\":\"10f1a240-b891-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"6\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":7,\"w\":12,\"h\":11,\"i\":\"7\"},\"id\":\"b80e6540-b891-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"7\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{\"vis\":{\"colors\":{\"0 - 50\":\"#E24D42\",\"50 - 75\":\"#EAB839\",\"75 - 100\":\"#7EB26D\"},\"defaultColors\":{\"0 - 50\":\"rgb(165,0,38)\",\"50 - 75\":\"rgb(255,255,190)\",\"75 - 100\":\"rgb(0,104,55)\"},\"legendOpen\":false}},\"gridData\":{\"x\":24,\"y\":7,\"w\":12,\"h\":11,\"i\":\"8\"},\"id\":\"4b3ec120-b892-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"8\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{\"vis\":{\"colors\":{\"0 - 2\":\"#E24D42\",\"2 - 3\":\"#F2C96D\",\"3 - 4\":\"#9AC48A\"},\"defaultColors\":{\"0 - 2\":\"rgb(165,0,38)\",\"2 - 3\":\"rgb(255,255,190)\",\"3 - 4\":\"rgb(0,104,55)\"},\"legendOpen\":false}},\"gridData\":{\"x\":36,\"y\":7,\"w\":12,\"h\":11,\"i\":\"9\"},\"id\":\"9ca7aa90-b892-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"9\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":54,\"w\":48,\"h\":18,\"i\":\"10\"},\"id\":\"3ba638e0-b894-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"10\",\"type\":\"search\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{\"mapZoom\":2,\"mapCenter\":[28.304380682962783,-22.148437500000004]},\"gridData\":{\"x\":0,\"y\":39,\"w\":24,\"h\":15,\"i\":\"11\"},\"id\":\"9c6f83f0-bb4d-11e8-9c84-77068524bcab\",\"panelIndex\":\"11\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":24,\"y\":39,\"w\":24,\"h\":15,\"i\":\"12\"},\"id\":\"b72dd430-bb4d-11e8-9c84-77068524bcab\",\"panelIndex\":\"12\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"}]",
- "optionsJSON": "{\"darkTheme\":false,\"hidePanelTitles\":false,\"useMargins\":true}",
+ "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}",
"version": 1,
"timeRestore": true,
"timeTo": "now",
diff --git a/src/server/sample_data/data_sets/flights/saved_objects.js b/src/server/sample_data/data_sets/flights/saved_objects.js
index 979031836432e..d647cd2816523 100644
--- a/src/server/sample_data/data_sets/flights/saved_objects.js
+++ b/src/server/sample_data/data_sets/flights/saved_objects.js
@@ -405,7 +405,7 @@ export const getSavedObjects = () => [
defaultMessage: 'Analyze mock flight data for ES-Air, Logstash Airways, Kibana Airlines and JetBeats',
}),
"panelsJSON": "[{\"panelIndex\":\"1\",\"gridData\":{\"x\":0,\"y\":0,\"w\":32,\"h\":7,\"i\":\"1\"},\"embeddableConfig\":{},\"id\":\"aeb212e0-4c84-11e8-b3d7-01146121b73d\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"3\",\"gridData\":{\"x\":17,\"y\":7,\"w\":23,\"h\":12,\"i\":\"3\"},\"embeddableConfig\":{\"vis\":{\"colors\":{\"Average Ticket Price\":\"#0A50A1\",\"Flight Count\":\"#82B5D8\"},\"legendOpen\":false}},\"id\":\"c8fc3d30-4c87-11e8-b3d7-01146121b73d\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"4\",\"gridData\":{\"x\":0,\"y\":85,\"w\":48,\"h\":15,\"i\":\"4\"},\"embeddableConfig\":{},\"id\":\"571aaf70-4c88-11e8-b3d7-01146121b73d\",\"type\":\"search\",\"version\":\"6.3.0\"},{\"panelIndex\":\"5\",\"gridData\":{\"x\":0,\"y\":7,\"w\":17,\"h\":12,\"i\":\"5\"},\"embeddableConfig\":{\"vis\":{\"colors\":{\"ES-Air\":\"#447EBC\",\"JetBeats\":\"#65C5DB\",\"Kibana Airlines\":\"#BA43A9\",\"Logstash Airways\":\"#E5AC0E\"},\"legendOpen\":false}},\"id\":\"8f4d0c00-4c86-11e8-b3d7-01146121b73d\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"6\",\"gridData\":{\"x\":24,\"y\":33,\"w\":24,\"h\":14,\"i\":\"6\"},\"embeddableConfig\":{\"vis\":{\"colors\":{\"Carrier Delay\":\"#5195CE\",\"Late Aircraft Delay\":\"#1F78C1\",\"NAS Delay\":\"#70DBED\",\"No Delay\":\"#BADFF4\",\"Security Delay\":\"#052B51\",\"Weather Delay\":\"#6ED0E0\"}}},\"id\":\"f8290060-4c88-11e8-b3d7-01146121b73d\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"7\",\"gridData\":{\"x\":24,\"y\":19,\"w\":24,\"h\":14,\"i\":\"7\"},\"embeddableConfig\":{},\"id\":\"bcb63b50-4c89-11e8-b3d7-01146121b73d\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"10\",\"gridData\":{\"x\":0,\"y\":35,\"w\":24,\"h\":12,\"i\":\"10\"},\"embeddableConfig\":{\"vis\":{\"colors\":{\"Count\":\"#1F78C1\"},\"legendOpen\":false}},\"id\":\"9886b410-4c8b-11e8-b3d7-01146121b73d\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"13\",\"gridData\":{\"x\":10,\"y\":19,\"w\":14,\"h\":8,\"i\":\"13\"},\"embeddableConfig\":{\"vis\":{\"colors\":{\"Count\":\"#1F78C1\"},\"legendOpen\":false}},\"id\":\"76e3c090-4c8c-11e8-b3d7-01146121b73d\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"14\",\"gridData\":{\"x\":10,\"y\":27,\"w\":14,\"h\":8,\"i\":\"14\"},\"embeddableConfig\":{\"vis\":{\"colors\":{\"Count\":\"#1F78C1\"},\"legendOpen\":false}},\"id\":\"707665a0-4c8c-11e8-b3d7-01146121b73d\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"18\",\"gridData\":{\"x\":24,\"y\":70,\"w\":24,\"h\":15,\"i\":\"18\"},\"embeddableConfig\":{\"mapCenter\":[27.421687059550266,15.371002131141724],\"mapZoom\":1},\"id\":\"79e8ff60-4c8e-11e8-b3d7-01146121b73d\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"21\",\"gridData\":{\"x\":0,\"y\":62,\"w\":48,\"h\":8,\"i\":\"21\"},\"embeddableConfig\":{},\"id\":\"293b5a30-4c8f-11e8-b3d7-01146121b73d\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"22\",\"gridData\":{\"x\":32,\"y\":0,\"w\":16,\"h\":7,\"i\":\"22\"},\"embeddableConfig\":{},\"id\":\"129be430-4c93-11e8-b3d7-01146121b73d\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"23\",\"gridData\":{\"x\":0,\"y\":70,\"w\":24,\"h\":15,\"i\":\"23\"},\"embeddableConfig\":{\"mapCenter\":[42.19556096274418,9.536742995308601e-7],\"mapZoom\":1},\"id\":\"334084f0-52fd-11e8-a160-89cc2ad9e8e2\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"25\",\"gridData\":{\"x\":0,\"y\":19,\"w\":10,\"h\":8,\"i\":\"25\"},\"embeddableConfig\":{\"vis\":{\"defaultColors\":{\"0 - 50\":\"rgb(247,251,255)\",\"100 - 150\":\"rgb(107,174,214)\",\"150 - 200\":\"rgb(33,113,181)\",\"200 - 250\":\"rgb(8,48,107)\",\"50 - 100\":\"rgb(198,219,239)\"},\"legendOpen\":false}},\"id\":\"f8283bf0-52fd-11e8-a160-89cc2ad9e8e2\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"27\",\"gridData\":{\"x\":0,\"y\":27,\"w\":10,\"h\":8,\"i\":\"27\"},\"embeddableConfig\":{\"vis\":{\"defaultColors\":{\"0 - 50\":\"rgb(247,251,255)\",\"100 - 150\":\"rgb(107,174,214)\",\"150 - 200\":\"rgb(33,113,181)\",\"200 - 250\":\"rgb(8,48,107)\",\"50 - 100\":\"rgb(198,219,239)\"},\"legendOpen\":false}},\"id\":\"08884800-52fe-11e8-a160-89cc2ad9e8e2\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"28\",\"gridData\":{\"x\":0,\"y\":47,\"w\":24,\"h\":15,\"i\":\"28\"},\"embeddableConfig\":{\"vis\":{\"defaultColors\":{\"0 - 11\":\"rgb(247,251,255)\",\"11 - 22\":\"rgb(208,225,242)\",\"22 - 33\":\"rgb(148,196,223)\",\"33 - 44\":\"rgb(74,152,201)\",\"44 - 55\":\"rgb(23,100,171)\"},\"legendOpen\":false}},\"id\":\"e6944e50-52fe-11e8-a160-89cc2ad9e8e2\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"29\",\"gridData\":{\"x\":40,\"y\":7,\"w\":8,\"h\":6,\"i\":\"29\"},\"embeddableConfig\":{},\"id\":\"01c413e0-5395-11e8-99bf-1ba7b1bdaa61\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"30\",\"gridData\":{\"x\":40,\"y\":13,\"w\":8,\"h\":6,\"i\":\"30\"},\"embeddableConfig\":{},\"id\":\"2edf78b0-5395-11e8-99bf-1ba7b1bdaa61\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"panelIndex\":\"31\",\"gridData\":{\"x\":24,\"y\":47,\"w\":24,\"h\":15,\"i\":\"31\"},\"embeddableConfig\":{},\"id\":\"ed78a660-53a0-11e8-acbd-0be0ad9d822b\",\"type\":\"visualization\",\"version\":\"6.3.0\"}]",
- "optionsJSON": "{\"darkTheme\":false,\"hidePanelTitles\":false,\"useMargins\":true}",
+ "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}",
"version": 1,
"timeRestore": true,
"timeTo": "now",
diff --git a/src/server/sample_data/data_sets/logs/saved_objects.js b/src/server/sample_data/data_sets/logs/saved_objects.js
index 72ffddc6febec..9bdd16ff42bb9 100644
--- a/src/server/sample_data/data_sets/logs/saved_objects.js
+++ b/src/server/sample_data/data_sets/logs/saved_objects.js
@@ -247,7 +247,7 @@ export const getSavedObjects = () => [
defaultMessage: 'Analyze mock web traffic log data for Elastic\'s website',
}),
"panelsJSON": "[{\"embeddableConfig\":{\"vis\":{\"colors\":{\"Avg. Bytes\":\"#6ED0E0\",\"Unique Visitors\":\"#0A437C\"},\"legendOpen\":false}},\"gridData\":{\"x\":27,\"y\":11,\"w\":21,\"h\":13,\"i\":\"2\"},\"id\":\"e1d0f010-9ee7-11e7-8711-e7a007dcef99\",\"panelIndex\":\"2\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"gridData\":{\"x\":0,\"y\":49,\"w\":24,\"h\":18,\"i\":\"4\"},\"id\":\"06cf9c40-9ee8-11e7-8711-e7a007dcef99\",\"panelIndex\":\"4\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{\"vis\":{\"defaultColors\":{\"0 - 22\":\"rgb(247,251,255)\",\"22 - 44\":\"rgb(208,225,242)\",\"44 - 66\":\"rgb(148,196,223)\",\"66 - 88\":\"rgb(74,152,201)\",\"88 - 110\":\"rgb(23,100,171)\"},\"legendOpen\":false}},\"gridData\":{\"x\":0,\"y\":36,\"w\":24,\"h\":13,\"i\":\"7\"},\"id\":\"935afa20-e0cd-11e7-9d07-1398ccfcefa3\",\"panelIndex\":\"7\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"embeddableConfig\":{\"mapCenter\":[36.8092847020594,-96.94335937500001],\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"gridData\":{\"x\":27,\"y\":24,\"w\":21,\"h\":12,\"i\":\"9\"},\"id\":\"4eb6e500-e1c7-11e7-b6d5-4dc382ef7f5b\",\"panelIndex\":\"9\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"embeddableConfig\":{\"vis\":{\"colors\":{\"0 - 500\":\"#BF1B00\",\"1000 - 1500\":\"#7EB26D\",\"500 - 1000\":\"#F2C96D\"},\"defaultColors\":{\"0 - 500\":\"rgb(165,0,38)\",\"1000 - 1500\":\"rgb(0,104,55)\",\"500 - 1000\":\"rgb(255,255,190)\"},\"legendOpen\":false}},\"gridData\":{\"x\":10,\"y\":0,\"w\":9,\"h\":11,\"i\":\"11\"},\"id\":\"69a34b00-9ee8-11e7-8711-e7a007dcef99\",\"panelIndex\":\"11\",\"title\":\"\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"gridData\":{\"x\":0,\"y\":24,\"w\":27,\"h\":12,\"i\":\"13\"},\"id\":\"42b997f0-0c26-11e8-b0ec-3bb475f6b6ff\",\"panelIndex\":\"13\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"gridData\":{\"x\":24,\"y\":36,\"w\":24,\"h\":31,\"i\":\"14\"},\"id\":\"7cbd2350-2223-11e8-b802-5bcf64c2cfb4\",\"panelIndex\":\"14\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"gridData\":{\"x\":0,\"y\":11,\"w\":27,\"h\":13,\"i\":\"15\"},\"id\":\"314c6f60-2224-11e8-b802-5bcf64c2cfb4\",\"panelIndex\":\"15\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"gridData\":{\"x\":19,\"y\":0,\"w\":15,\"h\":11,\"i\":\"16\"},\"id\":\"24a3e970-4257-11e8-b3aa-73fdaf54bfc9\",\"panelIndex\":\"16\",\"title\":\"\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"embeddableConfig\":{\"vis\":{\"legendOpen\":false}},\"gridData\":{\"x\":34,\"y\":0,\"w\":14,\"h\":11,\"i\":\"17\"},\"id\":\"14e2e710-4258-11e8-b3aa-73fdaf54bfc9\",\"panelIndex\":\"17\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":0,\"w\":10,\"h\":11,\"i\":\"18\"},\"id\":\"47f2c680-a6e3-11e8-94b4-c30c0228351b\",\"panelIndex\":\"18\",\"title\":\"\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"}]",
- "optionsJSON": "{\"darkTheme\":false,\"hidePanelTitles\":false,\"useMargins\":true}",
+ "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}",
"version": 1,
"timeRestore": true,
"timeTo": "now",
diff --git a/src/ui/public/agg_table/_agg_table.scss b/src/ui/public/agg_table/_agg_table.scss
index 494ff49343f88..0fffb21eab0fb 100644
--- a/src/ui/public/agg_table/_agg_table.scss
+++ b/src/ui/public/agg_table/_agg_table.scss
@@ -36,14 +36,3 @@ kbn-agg-table-group {
padding: 0;
}
}
-
-.theme-dark {
- @import '@elastic/eui/src/themes/k6/k6_colors_dark';
-
- .kbnAggTable__paginated {
- tr:hover td,
- .kbnTableCellFilter {
- background-color: $euiColorLightestShade;
- }
- }
-}
diff --git a/src/ui/public/doc_table/components/table_row/_cell.scss b/src/ui/public/doc_table/components/table_row/_cell.scss
index 301a275787093..3927e07a1cc84 100644
--- a/src/ui/public/doc_table/components/table_row/_cell.scss
+++ b/src/ui/public/doc_table/components/table_row/_cell.scss
@@ -28,11 +28,3 @@
opacity: 1; /* 3 */
}
}
-
-.theme-dark {
- @import '@elastic/eui/src/themes/k6/k6_colors_dark';
-
- .kbnDocTableRowFilterButton {
- background-color: $euiColorEmptyShade;
- }
-}
diff --git a/src/ui/public/filter_bar/filter_bar.less b/src/ui/public/filter_bar/filter_bar.less
index aecd058a64908..979ca42ea5dc1 100644
--- a/src/ui/public/filter_bar/filter_bar.less
+++ b/src/ui/public/filter_bar/filter_bar.less
@@ -224,49 +224,3 @@ filter-bar {
font-size: 0.9em;
background: @filter-bar-bar-condensed-bg;
}
-
-// SASSTODO: Make sure these colors convert to theme variables
-.tab-dashboard.theme-dark {
- @filter-bar-confirm-bg: @brand-primary;
- @filter-bar-confirm-filter-color: @brand-primary;
- @filter-bar-confirm-border: @gray-base;
- @filter-bar-confirm-filter-bg: @gray-lightest;
- @filter-bar-bar-bg: @brand-primary;
- @filter-bar-bar-border: @gray-base;
- @filter-bar-bar-condensed-bg: darken(@filter-bar-bar-bg, 5%);
- @filter-bar-bar-filter-bg: desaturate(@brand-success, 30%);
- @filter-bar-bar-filter-color: @white;
- @filter-bar-bar-filter-negate-bg: desaturate(@brand-success, 30%);
-
- .filter-bar-confirm {
- background: @filter-bar-confirm-bg;
- border-bottom-color: @filter-bar-confirm-border;
-
- .filter {
- background-color: @filter-bar-confirm-filter-bg;
- color: @filter-bar-confirm-filter-color;
- }
- }
-
- .filter-bar {
- background: @filter-bar-bar-bg;
- border-bottom-color: @filter-bar-bar-border;
-
- .filter {
- background-color: @filter-bar-bar-filter-bg;
- color: @filter-bar-bar-filter-color;
-
- &.negate {
- background-color: @filter-bar-bar-filter-negate-bg;
- }
-
- a {
- color: @filter-bar-bar-filter-color;
- }
- }
- }
-
- .filter-bar-condensed {
- background: @filter-bar-bar-condensed-bg;
- }
-}
diff --git a/src/ui/public/markdown/_github_markdown.scss b/src/ui/public/markdown/_github_markdown.scss
index c0599a3c6baf6..ec397b0834e7b 100644
--- a/src/ui/public/markdown/_github_markdown.scss
+++ b/src/ui/public/markdown/_github_markdown.scss
@@ -398,65 +398,3 @@
padding-left: $euiSizeXXL !important;
}
}
-
-.theme-dark {
- @import '@elastic/eui/src/themes/k6/k6_colors_dark';
-
- .kbnMarkdown__body {
- color: $euiTextColor;
-
- a {
- -webkit-text-decoration-skip: objects;
- color: $euiColorPrimary;
-
- &:active,
- &:hover {
- color: darken($euiColorPrimary, 10%);
- }
- }
-
- img {
- background-color: $euiColorEmptyShade;
- }
-
- hr {
- background-color: $euiColorLightShade;
- }
-
- table {
- &,
- td,
- th,
- tr {
- border-color: $euiColorLightShade;
- }
- }
-
- h1,
- h2 {
- border-color: $euiColorLightShade;
- }
-
- blockquote {
- color: $euiColorDarkShade;
- border-color: $euiColorLightShade;
- }
-
- code,
- kbd,
- pre {
- background-color: $euiCodeBlockBackgroundColor;
- color: $euiCodeBlockColor;
- }
-
- kbd {
- border-color: $euiColorLightShade;
- border-bottom-color: shadeOrTint($euiColorLightShade, 10%, 10%);
- box-shadow: inset 0 -1px 0 $euiColorLightShade;
- }
-
- :checked + .radio-label {
- border-color: $euiColorPrimary;
- }
- }
-}
diff --git a/src/ui/public/styles/_legacy/components/_config.scss b/src/ui/public/styles/_legacy/components/_config.scss
index a936f99b851df..8412f2d8dc7b6 100644
--- a/src/ui/public/styles/_legacy/components/_config.scss
+++ b/src/ui/public/styles/_legacy/components/_config.scss
@@ -9,14 +9,3 @@
padding: $euiSizeS;
}
}
-
-// SASSTODO: Make sure these colors convert to theme variables
-.theme-dark {
- @import '@elastic/eui/src/themes/k6/k6_colors_dark';
-
- .config {
- .container-fluid {
- background-color: $euiColorLightestShade;
- }
- }
-}
diff --git a/src/ui/public/styles/_legacy/components/_input.scss b/src/ui/public/styles/_legacy/components/_input.scss
index c96b72b7ef015..13efc9646e820 100644
--- a/src/ui/public/styles/_legacy/components/_input.scss
+++ b/src/ui/public/styles/_legacy/components/_input.scss
@@ -10,12 +10,3 @@ select {
color: $euiTextColor;
background-color: $euiColorEmptyShade;
}
-
-.theme-dark {
- @import '@elastic/eui/src/themes/k6/k6_colors_dark';
-
- select {
- color: $euiTextColor;
- background-color: $euiColorEmptyShade;
- }
-}
diff --git a/src/ui/public/styles/_legacy/components/_list_group_menu.scss b/src/ui/public/styles/_legacy/components/_list_group_menu.scss
index efee85b079053..678dfdf32a74b 100644
--- a/src/ui/public/styles/_legacy/components/_list_group_menu.scss
+++ b/src/ui/public/styles/_legacy/components/_list_group_menu.scss
@@ -21,27 +21,3 @@
}
}
}
-
-.theme-dark {
- @import '@elastic/eui/src/themes/k6/k6_colors_dark';
-
- .list-group-menu {
- &.select-mode a{
- color: shade($euiColorPrimary, 10%);
- }
-
- .list-group-menu-item {
- color: shade($euiColorPrimary, 10%);
-
- &.active {
- background-color: $euiColorLightShade;
- }
- &:hover {
- background-color: shade($euiColorPrimary, 90%);
- }
- li {
- color: shade($euiColorPrimary, 10%);
- }
- }
- }
-}
diff --git a/src/ui/public/styles/_legacy/components/_pagination.scss b/src/ui/public/styles/_legacy/components/_pagination.scss
index b70a6dea1361b..cf68f2ac8253f 100644
--- a/src/ui/public/styles/_legacy/components/_pagination.scss
+++ b/src/ui/public/styles/_legacy/components/_pagination.scss
@@ -54,24 +54,3 @@ paginate {
}
}
}
-
-// SASSTODO: Make sure these colors convert to theme variables
-.theme-dark {
- @import '@elastic/eui/src/themes/k6/k6_colors_dark';
-
- paginate {
- paginate-controls {
- .pagination-other-pages-list {
- > li {
- a {
- background-color: $euiColorLightestShade;
- color: $euiTextColor;
- }
- &.active a {
- color: $euiColorDarkShade;
- }
- }
- }
- }
- }
-}
diff --git a/src/ui/public/styles/_legacy/components/_react_input_range.scss b/src/ui/public/styles/_legacy/components/_react_input_range.scss
index a91915e8b2528..5460834f00457 100644
--- a/src/ui/public/styles/_legacy/components/_react_input_range.scss
+++ b/src/ui/public/styles/_legacy/components/_react_input_range.scss
@@ -102,24 +102,3 @@
position: relative;
width: calc(100% - #{$euiSize});
}
-
-.theme-dark {
- @import '@elastic/eui/src/themes/k6/k6_colors_dark';
-
- .input-range__track {
- background: $euiColorLightShade;
- }
-
- .input-range__slider {
- background: $euiColorPrimary;
- border-color: $euiColorPrimary;
- }
-
- .input-range__track--active {
- background: $euiColorPrimary;
- }
-
- .input-range__label {
- color: $euiColorDarkShade;
- }
-}
diff --git a/src/ui/public/styles/_legacy/components/_spinner.scss b/src/ui/public/styles/_legacy/components/_spinner.scss
index 8e21e62850e60..7b3b1bd615ae0 100644
--- a/src/ui/public/styles/_legacy/components/_spinner.scss
+++ b/src/ui/public/styles/_legacy/components/_spinner.scss
@@ -4,9 +4,3 @@
opacity: 0;
transition-delay: 0.25s;
}
-
-.theme-dark {
- .spinner > div {
- background-color: $euiColorEmptyShade;
- }
-}
diff --git a/src/ui/public/styles/_legacy/components/_table.scss b/src/ui/public/styles/_legacy/components/_table.scss
index 8832aaec8e37c..3d27f7bf6f946 100644
--- a/src/ui/public/styles/_legacy/components/_table.scss
+++ b/src/ui/public/styles/_legacy/components/_table.scss
@@ -67,17 +67,3 @@ table {
}
}
}
-
-
-.theme-dark {
- @import '@elastic/eui/src/themes/k6/k6_colors_dark';
-
- kbn-table, .kbn-table, tbody[kbn-rows] {
- dl.source {
- dt {
- background-color: transparentize(tint($euiColorPrimary, 60%), .8);
- color: $euiTextColor;
- }
- }
- }
-}
diff --git a/test/functional/apps/dashboard/_bwc_shared_urls.js b/test/functional/apps/dashboard/_bwc_shared_urls.js
index d761dd3d338a9..7c3acfba906a3 100644
--- a/test/functional/apps/dashboard/_bwc_shared_urls.js
+++ b/test/functional/apps/dashboard/_bwc_shared_urls.js
@@ -34,7 +34,7 @@ export default function ({ getService, getPageObjects }) {
`time:(from:'2012-11-17T00:00:00.000Z',mode:absolute,to:'2015-11-17T18:01:36.621Z'))&` +
`_a=(description:'',filters:!(),` +
`fullScreenMode:!f,` +
- `options:(darkTheme:!f),` +
+ `options:(),` +
`panels:!((col:1,id:Visualization-MetricChart,panelIndex:1,row:1,size_x:6,size_y:3,type:visualization),` +
`(col:7,id:Visualization-PieChart,panelIndex:2,row:1,size_x:6,size_y:3,type:visualization)),` +
`query:(language:lucene,query:'memory:%3E220000'),` +
diff --git a/test/functional/apps/dashboard/_dark_theme.js b/test/functional/apps/dashboard/_dark_theme.js
deleted file mode 100644
index ea47784601ad2..0000000000000
--- a/test/functional/apps/dashboard/_dark_theme.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from 'expect.js';
-
-export default function ({ getService, getPageObjects }) {
- const testSubjects = getService('testSubjects');
- const dashboardAddPanel = getService('dashboardAddPanel');
- const PageObjects = getPageObjects(['dashboard']);
-
- describe('dark theme', async () => {
- before(async () => {
- await PageObjects.dashboard.clickNewDashboard();
- });
-
- after(async () => {
- await dashboardAddPanel.closeAddPanel();
- await PageObjects.dashboard.gotoDashboardLandingPage();
- });
-
- // Visual builder applies dark theme by investigating appState for 'options.darkTheme'
- // This test ensures everything is properly wired together and Visual Builder adds dark theme classes
- it('should display Visual Builder timeseries with reversed class', async () => {
- await dashboardAddPanel.addVisualization('Rendering Test: tsvb-ts');
- await PageObjects.dashboard.useDarkTheme(true);
- const classNames = await testSubjects.getAttribute('timeseriesChart', 'class');
- expect(classNames.includes('reversed')).to.be(true);
- });
-
- });
-}
-
diff --git a/test/functional/apps/dashboard/_dashboard_state.js b/test/functional/apps/dashboard/_dashboard_state.js
index b31ba59945199..ed8999eb5977e 100644
--- a/test/functional/apps/dashboard/_dashboard_state.js
+++ b/test/functional/apps/dashboard/_dashboard_state.js
@@ -164,14 +164,6 @@ export default function ({ getService, getPageObjects }) {
expect(changedTileMapData.length).to.not.equal(tileMapData.length);
});
- it('retains dark theme', async function () {
- await PageObjects.dashboard.useDarkTheme(true);
- await PageObjects.header.clickVisualize();
- await PageObjects.header.clickDashboard();
- const isDarkThemeOn = await PageObjects.dashboard.isDarkThemeOn();
- expect(isDarkThemeOn).to.equal(true);
- });
-
describe('Directly modifying url updates dashboard state', () => {
it('for query parameter', async function () {
await PageObjects.dashboard.gotoDashboardLandingPage();
diff --git a/test/functional/apps/dashboard/exports/timezonetest_6_2_4.json b/test/functional/apps/dashboard/exports/timezonetest_6_2_4.json
index c18b460aae632..8be2108f685cc 100644
--- a/test/functional/apps/dashboard/exports/timezonetest_6_2_4.json
+++ b/test/functional/apps/dashboard/exports/timezonetest_6_2_4.json
@@ -7,7 +7,7 @@
"hits": 0,
"description": "",
"panelsJSON": "[{\"gridData\":{\"h\":3,\"i\":\"1\",\"w\":6,\"x\":0,\"y\":0},\"id\":\"3fe22200-3dcb-11e8-8660-4d65aa086b3c\",\"panelIndex\":\"1\",\"type\":\"visualization\",\"version\":\"6.2.4\"}]",
- "optionsJSON": "{\"darkTheme\":false,\"hidePanelTitles\":false,\"useMargins\":true}",
+ "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}",
"version": 1,
"timeRestore": true,
"timeTo": "Tue Apr 09 2018 23:00:00 GMT-0500",
diff --git a/test/functional/apps/dashboard/index.js b/test/functional/apps/dashboard/index.js
index a7c137c2d962f..6919ffc75eb06 100644
--- a/test/functional/apps/dashboard/index.js
+++ b/test/functional/apps/dashboard/index.js
@@ -47,7 +47,6 @@ export default function ({ getService, loadTestFile, getPageObjects }) {
after(unloadCurrentData);
loadTestFile(require.resolve('./_empty_dashboard'));
- loadTestFile(require.resolve('./_dark_theme'));
loadTestFile(require.resolve('./_embeddable_rendering'));
loadTestFile(require.resolve('./_create_and_add_embeddables'));
loadTestFile(require.resolve('./_time_zones'));
diff --git a/test/functional/page_objects/dashboard_page.js b/test/functional/page_objects/dashboard_page.js
index 570f79c30b915..b9d3b53aae893 100644
--- a/test/functional/page_objects/dashboard_page.js
+++ b/test/functional/page_objects/dashboard_page.js
@@ -277,22 +277,6 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
await this.gotoDashboardLandingPage();
}
- async isDarkThemeOn() {
- log.debug('isDarkThemeOn');
- await this.openOptions();
- const darkThemeCheckbox = await testSubjects.find('dashboardDarkThemeCheckbox');
- return await darkThemeCheckbox.getProperty('checked');
- }
-
- async useDarkTheme(on) {
- log.debug(`useDarkTheme: on ${on}`);
- await this.openOptions();
- const isDarkThemeOn = await this.isDarkThemeOn();
- if (isDarkThemeOn !== on) {
- return await testSubjects.click('dashboardDarkThemeCheckbox');
- }
- }
-
async isMarginsOn() {
log.debug('isMarginsOn');
await this.openOptions();
diff --git a/x-pack/plugins/gis/public/angular/map_controller.js b/x-pack/plugins/gis/public/angular/map_controller.js
index f6128b429bd0f..64b171701c3a2 100644
--- a/x-pack/plugins/gis/public/angular/map_controller.js
+++ b/x-pack/plugins/gis/public/angular/map_controller.js
@@ -8,7 +8,6 @@ import chrome from 'ui/chrome';
import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { uiModules } from 'ui/modules';
-import { applyTheme } from 'ui/theme';
import { timefilter } from 'ui/timefilter';
import { Provider } from 'react-redux';
import { getStore } from '../store/store';
@@ -21,13 +20,12 @@ import {
replaceLayerList,
setQuery,
} from '../actions/store_actions';
-import { getIsDarkTheme, updateFlyout, FLYOUT_STATE } from '../store/ui';
+import { updateFlyout, FLYOUT_STATE } from '../store/ui';
import { getDataSources, getUniqueIndexPatternIds } from '../selectors/map_selectors';
import { Inspector } from 'ui/inspector';
import { inspectorAdapters, indexPatternService } from '../kibana_services';
import { SavedObjectSaveModal } from 'ui/saved_objects/components/saved_object_save_modal';
import { showSaveModal } from 'ui/saved_objects/show_saved_object_save_modal';
-import { showOptionsPopover } from '../components/top_nav/show_options_popover';
import { toastNotifications } from 'ui/notify';
import { getInitialLayers } from './get_initial_layers';
@@ -39,7 +37,6 @@ const app = uiModules.get('app/gis', []);
app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage, AppState) => {
const savedMap = $scope.map = $route.current.locals.map;
- let isDarkTheme;
let unsubscribe;
inspectorAdapters.requests.reset();
@@ -141,12 +138,6 @@ app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage
function handleStoreChanges(store) {
const state = store.getState();
- // theme changes must triggered in digest cycle because top nav is still angular
- if (isDarkTheme !== getIsDarkTheme(state)) {
- isDarkTheme = getIsDarkTheme(state);
- updateTheme();
- }
-
const nextIndexPatternIds = getUniqueIndexPatternIds(state);
if (nextIndexPatternIds !== prevIndexPatternIds) {
prevIndexPatternIds = nextIndexPatternIds;
@@ -213,13 +204,6 @@ app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage
run() {
Inspector.open(inspectorAdapters, {});
}
- }, {
- key: 'options',
- description: 'Options',
- testId: 'optionsButton',
- run: async (menuItem, navController, anchorElement) => {
- showOptionsPopover(anchorElement);
- }
}, {
key: 'save',
description: 'Save map',
@@ -256,22 +240,4 @@ app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage
}];
timefilter.enableTimeRangeSelector();
timefilter.enableAutoRefreshSelector();
-
- function updateTheme() {
- $scope.$evalAsync(() => {
- isDarkTheme ? setDarkTheme() : setLightTheme();
- });
- }
-
- function setDarkTheme() {
- chrome.removeApplicationClass(['theme-light']);
- chrome.addApplicationClass('theme-dark');
- applyTheme('dark');
- }
-
- function setLightTheme() {
- chrome.removeApplicationClass(['theme-dark']);
- chrome.addApplicationClass('theme-light');
- applyTheme('light');
- }
});
diff --git a/x-pack/plugins/gis/public/angular/services/saved_gis_map.js b/x-pack/plugins/gis/public/angular/services/saved_gis_map.js
index 29bdacc32afd1..6d18fda8fb933 100644
--- a/x-pack/plugins/gis/public/angular/services/saved_gis_map.js
+++ b/x-pack/plugins/gis/public/angular/services/saved_gis_map.js
@@ -17,7 +17,6 @@ import {
getRefreshConfig,
getQuery,
} from '../../selectors/map_selectors';
-import { getIsDarkTheme } from '../../store/ui';
import { convertMapExtentToPolygon } from '../../elasticsearch_geo_utils';
const module = uiModules.get('app/gis');
@@ -84,9 +83,7 @@ module.factory('SavedGisMap', function (Private) {
query: _.omit(getQuery(state), 'queryLastTriggeredAt'),
});
- this.uiStateJSON = JSON.stringify({
- isDarkMode: getIsDarkTheme(state),
- });
+ this.uiStateJSON = JSON.stringify({});
this.bounds = convertMapExtentToPolygon(getMapExtent(state));
};
diff --git a/x-pack/plugins/gis/public/components/top_nav/options_menu.js b/x-pack/plugins/gis/public/components/top_nav/options_menu.js
deleted file mode 100644
index c7925cd669d71..0000000000000
--- a/x-pack/plugins/gis/public/components/top_nav/options_menu.js
+++ /dev/null
@@ -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 React from 'react';
-import PropTypes from 'prop-types';
-
-import {
- EuiForm,
- EuiFormRow,
- EuiSwitch,
-} from '@elastic/eui';
-
-export function OptionsMenu({ isDarkTheme, onDarkThemeChange }) {
-
- const handleDarkThemeChange = (evt) => {
- onDarkThemeChange(evt.target.checked);
- };
-
- return (
-
-
-
-
-
- );
-}
-
-OptionsMenu.propTypes = {
- isDarkTheme: PropTypes.bool.isRequired,
- onDarkThemeChange: PropTypes.func.isRequired,
-};
diff --git a/x-pack/plugins/gis/public/components/top_nav/options_menu_container.js b/x-pack/plugins/gis/public/components/top_nav/options_menu_container.js
deleted file mode 100644
index ff97eb4a7e681..0000000000000
--- a/x-pack/plugins/gis/public/components/top_nav/options_menu_container.js
+++ /dev/null
@@ -1,26 +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 { connect } from 'react-redux';
-import { getIsDarkTheme, updateIsDarkTheme } from '../../store/ui';
-import { OptionsMenu } from './options_menu';
-
-function mapStateToProps(state = {}) {
- return {
- isDarkTheme: getIsDarkTheme(state),
- };
-}
-
-function mapDispatchToProps(dispatch) {
- return {
- onDarkThemeChange: (isDarkTheme) => {
- dispatch(updateIsDarkTheme(isDarkTheme));
- },
- };
-}
-
-const connectedOptionsMenu = connect(mapStateToProps, mapDispatchToProps)(OptionsMenu);
-export { connectedOptionsMenu as OptionsMenu };
diff --git a/x-pack/plugins/gis/public/components/top_nav/show_options_popover.js b/x-pack/plugins/gis/public/components/top_nav/show_options_popover.js
deleted file mode 100644
index 5f2411a577edf..0000000000000
--- a/x-pack/plugins/gis/public/components/top_nav/show_options_popover.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import React from 'react';
-import ReactDOM from 'react-dom';
-import { Provider } from 'react-redux';
-
-import { OptionsMenu } from './options_menu_container';
-
-import { getStore } from '../../store/store';
-
-import {
- EuiWrappingPopover,
-} from '@elastic/eui';
-
-let isOpen = false;
-
-const container = document.createElement('div');
-
-const onClose = () => {
- ReactDOM.unmountComponentAtNode(container);
- isOpen = false;
-};
-
-export async function showOptionsPopover(anchorElement) {
- if (isOpen) {
- onClose();
- return;
- }
-
- isOpen = true;
-
- const store = await getStore();
-
- document.body.appendChild(container);
- const element = (
-
-
-
-
-
- );
- ReactDOM.render(element, container);
-}
diff --git a/x-pack/plugins/gis/public/store/ui.js b/x-pack/plugins/gis/public/store/ui.js
index e278baf46e1e8..965f289078485 100644
--- a/x-pack/plugins/gis/public/store/ui.js
+++ b/x-pack/plugins/gis/public/store/ui.js
@@ -11,7 +11,6 @@ import { RESET_LAYER_LOAD } from '../actions/ui_actions';
export const UPDATE_FLYOUT = 'UPDATE_FLYOUT';
export const CLOSE_SET_VIEW = 'CLOSE_SET_VIEW';
export const OPEN_SET_VIEW = 'OPEN_SET_VIEW';
-export const UPDATE_IS_DARK_THEME = 'UPDATE_IS_DARK_THEME';
export const FLYOUT_STATE = {
NONE: 'NONE',
LAYER_PANEL: 'LAYER_PANEL',
@@ -25,7 +24,6 @@ export const LAYER_LOAD_STATE = {
const INITIAL_STATE = {
flyoutDisplay: FLYOUT_STATE.NONE,
- isDarkTheme: false,
layerLoad: {
status: LAYER_LOAD_STATE.inactive,
time: Date()
@@ -46,8 +44,6 @@ function ui(state = INITIAL_STATE, action) {
time: Date() } };
case UPDATE_FLYOUT:
return { ...state, flyoutDisplay: action.display };
- case UPDATE_IS_DARK_THEME:
- return { ...state, isDarkTheme: action.isDarkTheme };
case CLOSE_SET_VIEW:
return { ...state, isSetViewOpen: false };
case OPEN_SET_VIEW:
@@ -74,17 +70,10 @@ export function openSetView() {
type: OPEN_SET_VIEW,
};
}
-export function updateIsDarkTheme(isDarkTheme) {
- return {
- type: UPDATE_IS_DARK_THEME,
- isDarkTheme
- };
-}
// Selectors
export const getFlyoutDisplay = ({ ui }) => ui && ui.flyoutDisplay
|| INITIAL_STATE.flyoutDisplay;
-export const getIsDarkTheme = ({ ui }) => _.get(ui, 'isDarkTheme', INITIAL_STATE.isDarkTheme);
export const getIsSetViewOpen = ({ ui }) => _.get(ui, 'isSetViewOpen', false);
export default ui;
diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Access-Remote-IP-Count-Explorer.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Access-Remote-IP-Count-Explorer.json
index 1442d7025ebb4..5fc696c6c702d 100644
--- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Access-Remote-IP-Count-Explorer.json
+++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Access-Remote-IP-Count-Explorer.json
@@ -1,13 +1,13 @@
{
- "hits": 0,
- "timeRestore": false,
- "description": "",
- "title": "ML Apache2 Access Remote IP Count Explorer",
- "uiStateJSON": "{\"P-3\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-5\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}",
- "panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Remote-IP-Timechart\",\"col\":1,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":2,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Response-Code-Timechart\",\"col\":7,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":3,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Top-Remote-IPs-Table\",\"col\":1,\"row\":4},{\"size_x\":6,\"size_y\":3,\"panelIndex\":4,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Map\",\"col\":7,\"row\":4},{\"size_x\":12,\"size_y\":9,\"panelIndex\":5,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Top-URLs-Table\",\"col\":1,\"row\":7}]",
- "optionsJSON": "{\"darkTheme\":false}",
- "version": 1,
+ "hits": 0,
+ "timeRestore": false,
+ "description": "",
+ "title": "ML Apache2 Access Remote IP Count Explorer",
+ "uiStateJSON": "{\"P-3\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-5\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}",
+ "panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Remote-IP-Timechart\",\"col\":1,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":2,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Response-Code-Timechart\",\"col\":7,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":3,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Top-Remote-IPs-Table\",\"col\":1,\"row\":4},{\"size_x\":6,\"size_y\":3,\"panelIndex\":4,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Map\",\"col\":7,\"row\":4},{\"size_x\":12,\"size_y\":9,\"panelIndex\":5,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Top-URLs-Table\",\"col\":1,\"row\":7}]",
+ "optionsJSON": "{}",
+ "version": 1,
"kibanaSavedObjectMeta": {
"searchSourceJSON": "{\"filter\":[{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}}}],\"highlightAll\":true,\"version\":true}"
}
-}
\ No newline at end of file
+}
diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Remote-IP-URL-Explorer.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Remote-IP-URL-Explorer.json
index 668741a2159f1..b04050ceb6e19 100644
--- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Remote-IP-URL-Explorer.json
+++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Remote-IP-URL-Explorer.json
@@ -1,13 +1,13 @@
{
- "hits": 0,
- "timeRestore": false,
- "description": "",
- "title": "ML Apache2 Access Remote IP URL Explorer",
- "uiStateJSON": "{\"P-2\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-3\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-5\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}",
- "panelsJSON": "[{\"col\":1,\"id\":\"ML-Apache2-Access-Unique-Count-URL-Timechart\",\"panelIndex\":1,\"row\":1,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"ML-Apache2-Access-Response-Code-Timechart\",\"panelIndex\":2,\"row\":1,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"ML-Apache2-Access-Top-Remote-IPs-Table\",\"panelIndex\":3,\"row\":4,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"ML-Apache2-Access-Map\",\"panelIndex\":4,\"row\":4,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"size_x\":12,\"size_y\":8,\"panelIndex\":5,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Top-URLs-Table\",\"col\":1,\"row\":7}]",
- "optionsJSON": "{\"darkTheme\":false}",
- "version": 1,
+ "hits": 0,
+ "timeRestore": false,
+ "description": "",
+ "title": "ML Apache2 Access Remote IP URL Explorer",
+ "uiStateJSON": "{\"P-2\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-3\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-5\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}",
+ "panelsJSON": "[{\"col\":1,\"id\":\"ML-Apache2-Access-Unique-Count-URL-Timechart\",\"panelIndex\":1,\"row\":1,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"ML-Apache2-Access-Response-Code-Timechart\",\"panelIndex\":2,\"row\":1,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"ML-Apache2-Access-Top-Remote-IPs-Table\",\"panelIndex\":3,\"row\":4,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"ML-Apache2-Access-Map\",\"panelIndex\":4,\"row\":4,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"size_x\":12,\"size_y\":8,\"panelIndex\":5,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Top-URLs-Table\",\"col\":1,\"row\":7}]",
+ "optionsJSON": "{}",
+ "version": 1,
"kibanaSavedObjectMeta": {
"searchSourceJSON": "{\"filter\":[{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}}}],\"highlightAll\":true,\"version\":true}"
}
-}
\ No newline at end of file
+}
diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker/kibana/dashboard/ml_auditbeat_docker_process_event_rate.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker/kibana/dashboard/ml_auditbeat_docker_process_event_rate.json
index 8089a9ee49884..680b329b29cf7 100644
--- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker/kibana/dashboard/ml_auditbeat_docker_process_event_rate.json
+++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker/kibana/dashboard/ml_auditbeat_docker_process_event_rate.json
@@ -3,7 +3,7 @@
"hits": 0,
"description": "Dashboard to investigate unusual process event rates in a Docker container",
"panelsJSON": "[{\"embeddableConfig\":{\"vis\":{\"legendOpen\":true}},\"gridData\":{\"x\":0,\"y\":0,\"w\":48,\"h\":14,\"i\":\"1\"},\"id\":\"ml_auditbeat_docker_process_event_rate_vis\",\"panelIndex\":\"1\",\"type\":\"visualization\",\"version\":\"6.6.0\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":14,\"w\":48,\"h\":15,\"i\":\"2\"},\"id\":\"ml_auditbeat_docker_process_event_rate_by_process\",\"panelIndex\":\"2\",\"type\":\"visualization\",\"version\":\"6.6.0\"},{\"gridData\":{\"x\":0,\"y\":29,\"w\":48,\"h\":20,\"i\":\"3\"},\"version\":\"6.6.0\",\"panelIndex\":\"3\",\"type\":\"search\",\"id\":\"ml_auditbeat_docker_process_events\",\"embeddableConfig\":{}}]",
- "optionsJSON": "{\"darkTheme\":false,\"hidePanelTitles\":false,\"useMargins\":true}",
+ "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}",
"version": 1,
"timeRestore": false,
"kibanaSavedObjectMeta": {
diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker/kibana/dashboard/ml_auditbeat_docker_process_explorer.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker/kibana/dashboard/ml_auditbeat_docker_process_explorer.json
index 3be2c6e20adf3..a5e13014b9fdd 100644
--- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker/kibana/dashboard/ml_auditbeat_docker_process_explorer.json
+++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker/kibana/dashboard/ml_auditbeat_docker_process_explorer.json
@@ -3,7 +3,7 @@
"hits": 0,
"description": "Dashboard to explore processes for a Docker container",
"panelsJSON": "[{\"embeddableConfig\": {},\"gridData\": {\"x\": 0,\"y\": 0,\"w\": 25,\"h\": 22,\"i\": \"1\"},\"id\": \"ml_auditbeat_docker_process_occurrence\",\"panelIndex\": \"1\",\"type\": \"visualization\",\"version\": \"6.6.0\"},{\"gridData\": {\"x\": 0,\"y\": 22,\"w\": 48,\"h\": 35,\"i\": \"2\"},\"version\": \"6.6.0\",\"panelIndex\": \"2\",\"type\": \"search\",\"id\": \"ml_auditbeat_docker_process_events\",\"embeddableConfig\": {}},{\"gridData\": {\"x\": 25,\"y\": 0,\"w\": 23,\"h\": 22,\"i\": \"3\"},\"version\": \"6.6.0\",\"panelIndex\": \"3\",\"type\": \"visualization\",\"id\": \"ml_auditbeat_docker_process_event_rate_by_process\",\"embeddableConfig\": {\"vis\": {\"legendOpen\": true}}}\n]",
-"optionsJSON": "{\"darkTheme\": false,\"hidePanelTitles\": false,\"useMargins\": true\n}",
+"optionsJSON": "{\"hidePanelTitles\": false,\"useMargins\": true\n}",
"version": 1,
"timeRestore": false,
"kibanaSavedObjectMeta": {
diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts/kibana/dashboard/ml_auditbeat_hosts_process_event_rate.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts/kibana/dashboard/ml_auditbeat_hosts_process_event_rate.json
index 8cc052e12940b..c964b99032c74 100644
--- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts/kibana/dashboard/ml_auditbeat_hosts_process_event_rate.json
+++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts/kibana/dashboard/ml_auditbeat_hosts_process_event_rate.json
@@ -3,7 +3,7 @@
"hits": 0,
"description": "Dashboard to investigate unusual process event rates on a host.",
"panelsJSON": "[{\"embeddableConfig\":{\"vis\":{\"legendOpen\":true}},\"gridData\":{\"x\":0,\"y\":0,\"w\":48,\"h\":14,\"i\":\"1\"},\"id\":\"ml_auditbeat_hosts_process_event_rate_vis\",\"panelIndex\":\"1\",\"type\":\"visualization\",\"version\":\"6.6.0\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":14,\"w\":48,\"h\":15,\"i\":\"2\"},\"id\":\"ml_auditbeat_hosts_process_event_rate_by_process\",\"panelIndex\":\"2\",\"type\":\"visualization\",\"version\":\"6.6.0\"},{\"gridData\":{\"x\":0,\"y\":29,\"w\":48,\"h\":20,\"i\":\"3\"},\"version\":\"6.6.0\",\"panelIndex\":\"3\",\"type\":\"search\",\"id\":\"ml_auditbeat_hosts_process_events\",\"embeddableConfig\":{}}]",
- "optionsJSON": "{\"darkTheme\":false,\"hidePanelTitles\":false,\"useMargins\":true}",
+ "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}",
"version": 1,
"timeRestore": false,
"kibanaSavedObjectMeta": {
diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts/kibana/dashboard/ml_auditbeat_hosts_process_explorer.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts/kibana/dashboard/ml_auditbeat_hosts_process_explorer.json
index 323c772850c99..22f50ca7ea751 100644
--- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts/kibana/dashboard/ml_auditbeat_hosts_process_explorer.json
+++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts/kibana/dashboard/ml_auditbeat_hosts_process_explorer.json
@@ -3,7 +3,7 @@
"hits": 0,
"description": "Dashboard to explore processes for a host",
"panelsJSON": "[{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":0,\"w\":25,\"h\":22,\"i\":\"1\"},\"id\":\"ml_auditbeat_hosts_process_occurrence\",\"panelIndex\":\"1\",\"type\":\"visualization\",\"version\":\"6.6.0\"},{\"gridData\":{\"x\":0,\"y\":22,\"w\":48,\"h\":35,\"i\":\"2\"},\"version\":\"6.6.0\",\"panelIndex\":\"2\",\"type\":\"search\",\"id\":\"ml_auditbeat_hosts_process_events\",\"embeddableConfig\":{}},{\"gridData\":{\"x\":25,\"y\":0,\"w\":23,\"h\":22,\"i\":\"3\"},\"version\":\"6.6.0\",\"panelIndex\":\"3\",\"type\":\"visualization\",\"id\":\"ml_auditbeat_hosts_process_event_rate_by_process\",\"embeddableConfig\":{\"vis\":{\"legendOpen\":true}}}\n]",
- "optionsJSON": "{\"darkTheme\": false,\"hidePanelTitles\": false,\"useMargins\": true\n}",
+ "optionsJSON": "{\"hidePanelTitles\": false,\"useMargins\": true\n}",
"version": 1,
"timeRestore": false,
"kibanaSavedObjectMeta": {
diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx/kibana/dashboard/ML-Nginx-Access-Remote-IP-Count-Explorer.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx/kibana/dashboard/ML-Nginx-Access-Remote-IP-Count-Explorer.json
index 28683287eb503..dd8f285fcbbdc 100644
--- a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx/kibana/dashboard/ML-Nginx-Access-Remote-IP-Count-Explorer.json
+++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx/kibana/dashboard/ML-Nginx-Access-Remote-IP-Count-Explorer.json
@@ -1,13 +1,13 @@
{
- "hits": 0,
- "timeRestore": false,
- "description": "",
- "title": "ML Nginx Access Remote IP Count Explorer",
- "uiStateJSON": "{\"P-3\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-5\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}",
- "panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"ML-Nginx-Access-Remote-IP-Timechart\",\"col\":1,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":2,\"type\":\"visualization\",\"id\":\"ML-Nginx-Access-Response-Code-Timechart\",\"col\":7,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":3,\"type\":\"visualization\",\"id\":\"ML-Nginx-Access-Top-Remote-IPs-Table\",\"col\":1,\"row\":4},{\"size_x\":6,\"size_y\":3,\"panelIndex\":4,\"type\":\"visualization\",\"id\":\"ML-Nginx-Access-Map\",\"col\":7,\"row\":4},{\"size_x\":12,\"size_y\":9,\"panelIndex\":5,\"type\":\"visualization\",\"id\":\"ML-Nginx-Access-Top-URLs-Table\",\"col\":1,\"row\":7}]",
- "optionsJSON": "{\"darkTheme\":false}",
- "version": 1,
+ "hits": 0,
+ "timeRestore": false,
+ "description": "",
+ "title": "ML Nginx Access Remote IP Count Explorer",
+ "uiStateJSON": "{\"P-3\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-5\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}",
+ "panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"ML-Nginx-Access-Remote-IP-Timechart\",\"col\":1,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":2,\"type\":\"visualization\",\"id\":\"ML-Nginx-Access-Response-Code-Timechart\",\"col\":7,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":3,\"type\":\"visualization\",\"id\":\"ML-Nginx-Access-Top-Remote-IPs-Table\",\"col\":1,\"row\":4},{\"size_x\":6,\"size_y\":3,\"panelIndex\":4,\"type\":\"visualization\",\"id\":\"ML-Nginx-Access-Map\",\"col\":7,\"row\":4},{\"size_x\":12,\"size_y\":9,\"panelIndex\":5,\"type\":\"visualization\",\"id\":\"ML-Nginx-Access-Top-URLs-Table\",\"col\":1,\"row\":7}]",
+ "optionsJSON": "{}",
+ "version": 1,
"kibanaSavedObjectMeta": {
"searchSourceJSON": "{\"filter\":[{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}}}],\"highlightAll\":true,\"version\":true}"
}
-}
\ No newline at end of file
+}
diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx/kibana/dashboard/ML-Nginx-Remote-IP-URL-Explorer.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx/kibana/dashboard/ML-Nginx-Remote-IP-URL-Explorer.json
index 24a4a33fd910b..5057502a1ee8e 100644
--- a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx/kibana/dashboard/ML-Nginx-Remote-IP-URL-Explorer.json
+++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx/kibana/dashboard/ML-Nginx-Remote-IP-URL-Explorer.json
@@ -1,13 +1,13 @@
{
- "hits": 0,
- "timeRestore": false,
- "description": "",
- "title": "ML Nginx Access Remote IP URL Explorer",
- "uiStateJSON": "{\"P-2\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-3\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-5\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}",
- "panelsJSON": "[{\"col\":1,\"id\":\"ML-Nginx-Access-Unique-Count-URL-Timechart\",\"panelIndex\":1,\"row\":1,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"ML-Nginx-Access-Response-Code-Timechart\",\"panelIndex\":2,\"row\":1,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"ML-Nginx-Access-Top-Remote-IPs-Table\",\"panelIndex\":3,\"row\":4,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"ML-Nginx-Access-Map\",\"panelIndex\":4,\"row\":4,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"size_x\":12,\"size_y\":8,\"panelIndex\":5,\"type\":\"visualization\",\"id\":\"ML-Nginx-Access-Top-URLs-Table\",\"col\":1,\"row\":7}]",
- "optionsJSON": "{\"darkTheme\":false}",
- "version": 1,
+ "hits": 0,
+ "timeRestore": false,
+ "description": "",
+ "title": "ML Nginx Access Remote IP URL Explorer",
+ "uiStateJSON": "{\"P-2\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-3\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-5\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}",
+ "panelsJSON": "[{\"col\":1,\"id\":\"ML-Nginx-Access-Unique-Count-URL-Timechart\",\"panelIndex\":1,\"row\":1,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"ML-Nginx-Access-Response-Code-Timechart\",\"panelIndex\":2,\"row\":1,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"ML-Nginx-Access-Top-Remote-IPs-Table\",\"panelIndex\":3,\"row\":4,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"ML-Nginx-Access-Map\",\"panelIndex\":4,\"row\":4,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"size_x\":12,\"size_y\":8,\"panelIndex\":5,\"type\":\"visualization\",\"id\":\"ML-Nginx-Access-Top-URLs-Table\",\"col\":1,\"row\":7}]",
+ "optionsJSON": "{}",
+ "version": 1,
"kibanaSavedObjectMeta": {
"searchSourceJSON": "{\"filter\":[{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}}}],\"highlightAll\":true,\"version\":true}"
}
-}
\ No newline at end of file
+}
diff --git a/x-pack/test/reporting/api/generation_urls.js b/x-pack/test/reporting/api/generation_urls.js
index 4f3bc2b43bef8..47dd9227e2439 100644
--- a/x-pack/test/reporting/api/generation_urls.js
+++ b/x-pack/test/reporting/api/generation_urls.js
@@ -10,14 +10,14 @@
// The URL below was captured from release 6.4 and then the layout section was removed to test structure before
// preserve_layout was introduced. See https://github.com/elastic/kibana/issues/23414
-export const PDF_PRINT_DASHBOARD_PRE_6_2 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,objectType:dashboard,relativeUrls:!(%27%2Fapp%2Fkibana%23%2Fdashboard%2F2ae34a60-3dd4-11e8-b2b9-5d5dc1715159%3F_g%3D(refreshInterval:(pause:!!t,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(description:!%27!%27,filters:!!(),fullScreenMode:!!f,options:(darkTheme:!!f,hidePanelTitles:!!f,useMargins:!!t),panels:!!((embeddableConfig:(),gridData:(h:15,i:!%271!%27,w:24,x:0,y:0),id:!%27145ced90-3dcb-11e8-8660-4d65aa086b3c!%27,panelIndex:!%271!%27,type:visualization,version:!%276.3.0!%27),(embeddableConfig:(),gridData:(h:15,i:!%272!%27,w:24,x:24,y:0),id:e2023110-3dcb-11e8-8660-4d65aa086b3c,panelIndex:!%272!%27,type:visualization,version:!%276.3.0!%27)),query:(language:lucene,query:!%27!%27),timeRestore:!!f,title:!%27couple%2Bpanels!%27,viewMode:view)%27),title:%27couple%20panels%27)';
+export const PDF_PRINT_DASHBOARD_PRE_6_2 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,objectType:dashboard,relativeUrls:!(%27%2Fapp%2Fkibana%23%2Fdashboard%2F2ae34a60-3dd4-11e8-b2b9-5d5dc1715159%3F_g%3D(refreshInterval:(pause:!!t,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(description:!%27!%27,filters:!!(),fullScreenMode:!!f,options:(hidePanelTitles:!!f,useMargins:!!t),panels:!!((embeddableConfig:(),gridData:(h:15,i:!%271!%27,w:24,x:0,y:0),id:!%27145ced90-3dcb-11e8-8660-4d65aa086b3c!%27,panelIndex:!%271!%27,type:visualization,version:!%276.3.0!%27),(embeddableConfig:(),gridData:(h:15,i:!%272!%27,w:24,x:24,y:0),id:e2023110-3dcb-11e8-8660-4d65aa086b3c,panelIndex:!%272!%27,type:visualization,version:!%276.3.0!%27)),query:(language:lucene,query:!%27!%27),timeRestore:!!f,title:!%27couple%2Bpanels!%27,viewMode:view)%27),title:%27couple%20panels%27)';
-export const PDF_PRINT_DASHBOARD_6_3 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(id:print),objectType:dashboard,relativeUrls:!(%27%2Fapp%2Fkibana%23%2Fdashboard%2F2ae34a60-3dd4-11e8-b2b9-5d5dc1715159%3F_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(description:!%27!%27,filters:!!(),fullScreenMode:!!f,options:(darkTheme:!!f,hidePanelTitles:!!f,useMargins:!!t),panels:!!((embeddableConfig:(),gridData:(h:15,i:!%271!%27,w:24,x:0,y:0),id:!%27145ced90-3dcb-11e8-8660-4d65aa086b3c!%27,panelIndex:!%271!%27,type:visualization,version:!%276.3.0!%27),(embeddableConfig:(),gridData:(h:15,i:!%272!%27,w:24,x:24,y:0),id:e2023110-3dcb-11e8-8660-4d65aa086b3c,panelIndex:!%272!%27,type:visualization,version:!%276.3.0!%27)),query:(language:lucene,query:!%27!%27),timeRestore:!!f,title:!%27couple%2Bpanels!%27,viewMode:view)%27),title:%27couple%20panels%27)';
-export const PDF_PRESERVE_DASHBOARD_FILTER_6_3 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(dimensions:(height:439,width:1362),id:preserve_layout),objectType:dashboard,relativeUrls:!(%27%2Fapp%2Fkibana%23%2Fdashboard%2F61c58ad0-3dd3-11e8-b2b9-5d5dc1715159%3F_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(description:!%27!%27,filters:!!((!%27$state!%27:(store:appState),meta:(alias:!!n,disabled:!!f,index:a0f483a0-3dc9-11e8-8660-4d65aa086b3c,key:animal,negate:!!f,params:(query:dog,type:phrase),type:phrase,value:dog),query:(match:(animal:(query:dog,type:phrase))))),fullScreenMode:!!f,options:(darkTheme:!!f,hidePanelTitles:!!f,useMargins:!!t),panels:!!((embeddableConfig:(),gridData:(h:15,i:!%271!%27,w:24,x:0,y:0),id:!%2750643b60-3dd3-11e8-b2b9-5d5dc1715159!%27,panelIndex:!%271!%27,type:visualization,version:!%276.3.0!%27),(embeddableConfig:(),gridData:(h:15,i:!%272!%27,w:24,x:24,y:0),id:a16d1990-3dca-11e8-8660-4d65aa086b3c,panelIndex:!%272!%27,type:search,version:!%276.3.0!%27)),query:(language:lucene,query:!%27!%27),timeRestore:!!t,title:!%27dashboard%2Bwith%2Bfilter!%27,viewMode:view)%27),title:%27dashboard%20with%20filter%27)';
+export const PDF_PRINT_DASHBOARD_6_3 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(id:print),objectType:dashboard,relativeUrls:!(%27%2Fapp%2Fkibana%23%2Fdashboard%2F2ae34a60-3dd4-11e8-b2b9-5d5dc1715159%3F_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(description:!%27!%27,filters:!!(),fullScreenMode:!!f,options:(hidePanelTitles:!!f,useMargins:!!t),panels:!!((embeddableConfig:(),gridData:(h:15,i:!%271!%27,w:24,x:0,y:0),id:!%27145ced90-3dcb-11e8-8660-4d65aa086b3c!%27,panelIndex:!%271!%27,type:visualization,version:!%276.3.0!%27),(embeddableConfig:(),gridData:(h:15,i:!%272!%27,w:24,x:24,y:0),id:e2023110-3dcb-11e8-8660-4d65aa086b3c,panelIndex:!%272!%27,type:visualization,version:!%276.3.0!%27)),query:(language:lucene,query:!%27!%27),timeRestore:!!f,title:!%27couple%2Bpanels!%27,viewMode:view)%27),title:%27couple%20panels%27)';
+export const PDF_PRESERVE_DASHBOARD_FILTER_6_3 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(dimensions:(height:439,width:1362),id:preserve_layout),objectType:dashboard,relativeUrls:!(%27%2Fapp%2Fkibana%23%2Fdashboard%2F61c58ad0-3dd3-11e8-b2b9-5d5dc1715159%3F_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(description:!%27!%27,filters:!!((!%27$state!%27:(store:appState),meta:(alias:!!n,disabled:!!f,index:a0f483a0-3dc9-11e8-8660-4d65aa086b3c,key:animal,negate:!!f,params:(query:dog,type:phrase),type:phrase,value:dog),query:(match:(animal:(query:dog,type:phrase))))),fullScreenMode:!!f,options:(hidePanelTitles:!!f,useMargins:!!t),panels:!!((embeddableConfig:(),gridData:(h:15,i:!%271!%27,w:24,x:0,y:0),id:!%2750643b60-3dd3-11e8-b2b9-5d5dc1715159!%27,panelIndex:!%271!%27,type:visualization,version:!%276.3.0!%27),(embeddableConfig:(),gridData:(h:15,i:!%272!%27,w:24,x:24,y:0),id:a16d1990-3dca-11e8-8660-4d65aa086b3c,panelIndex:!%272!%27,type:search,version:!%276.3.0!%27)),query:(language:lucene,query:!%27!%27),timeRestore:!!t,title:!%27dashboard%2Bwith%2Bfilter!%27,viewMode:view)%27),title:%27dashboard%20with%20filter%27)';
export const PDF_PRESERVE_PIE_VISUALIZATION_6_3 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(dimensions:(height:441,width:1002),id:preserve_layout),objectType:visualization,relativeUrls:!(%27%2Fapp%2Fkibana%23%2Fvisualize%2Fedit%2F3fe22200-3dcb-11e8-8660-4d65aa086b3c%3F_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(filters:!!(),linked:!!f,query:(language:lucene,query:!%27!%27),uiState:(),vis:(aggs:!!((enabled:!!t,id:!%271!%27,params:(),schema:metric,type:count),(enabled:!!t,id:!%272!%27,params:(field:bytes,missingBucket:!!f,missingBucketLabel:Missing,order:desc,orderBy:!%271!%27,otherBucket:!!f,otherBucketLabel:Other,size:5),schema:segment,type:terms)),params:(addLegend:!!t,addTooltip:!!t,isDonut:!!t,labels:(last_level:!!t,show:!!f,truncate:100,values:!!t),legendPosition:right,type:pie),title:!%27Rendering%2BTest:%2Bpie!%27,type:pie))%27),title:%27Rendering%20Test:%20pie%27)';
export const PDF_PRINT_PIE_VISUALIZATION_FILTER_AND_SAVED_SEARCH_6_3 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(id:print),objectType:visualization,relativeUrls:!(%27%2Fapp%2Fkibana%23%2Fvisualize%2Fedit%2Fbefdb6b0-3e59-11e8-9fc3-39e49624228e%3F_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(filters:!!((!%27$state!%27:(store:appState),meta:(alias:!!n,disabled:!!f,index:a0f483a0-3dc9-11e8-8660-4d65aa086b3c,key:animal.keyword,negate:!!f,params:(query:dog,type:phrase),type:phrase,value:dog),query:(match:(animal.keyword:(query:dog,type:phrase))))),linked:!!t,query:(language:lucene,query:!%27!%27),uiState:(),vis:(aggs:!!((enabled:!!t,id:!%271!%27,params:(),schema:metric,type:count),(enabled:!!t,id:!%272!%27,params:(field:name.keyword,missingBucket:!!f,missingBucketLabel:Missing,order:desc,orderBy:!%271!%27,otherBucket:!!f,otherBucketLabel:Other,size:5),schema:segment,type:terms)),params:(addLegend:!!t,addTooltip:!!t,isDonut:!!t,labels:(last_level:!!t,show:!!f,truncate:100,values:!!t),legendPosition:right,type:pie),title:!%27Filter%2BTest:%2Banimals:%2Blinked%2Bto%2Bsearch%2Bwith%2Bfilter!%27,type:pie))%27),title:%27Filter%20Test:%20animals:%20linked%20to%20search%20with%20filter%27)';
export const CSV_DISCOVER_KUERY_AND_FILTER_6_3 = '/api/reporting/generate/csv?jobParams=(conflictedTypesFields:!(),fields:!(%27@timestamp%27,agent,bytes,clientip),indexPatternId:%270bf35f60-3dc9-11e8-8660-4d65aa086b3c%27,metaFields:!(_source,_id,_type,_index,_score),searchRequest:(body:(_source:(excludes:!(),includes:!(%27@timestamp%27,agent,bytes,clientip)),docvalue_fields:!(%27@timestamp%27),query:(bool:(filter:!((bool:(minimum_should_match:1,should:!((match:(clientip:%2773.14.212.83%27)))))),must:!((range:(bytes:(gte:100,lt:1000))),(range:(%27@timestamp%27:(format:epoch_millis,gte:1369165215770,lte:1526931615770)))),must_not:!(),should:!())),script_fields:(),sort:!((%27@timestamp%27:(order:desc,unmapped_type:boolean))),stored_fields:!(%27@timestamp%27,agent,bytes,clientip),version:!t),index:%27logstash-*%27),title:%27Bytes%20and%20kuery%20in%20saved%20search%20with%20filter%27,type:search)';
-export const PDF_PRINT_DASHBOARD_6_2 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(id:print),objectType:dashboard,queryString:%27_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(description:!%27!%27,filters:!!((!%27$state!%27:(store:appState),meta:(alias:!!n,disabled:!!f,field:isDog,index:a0f483a0-3dc9-11e8-8660-4d65aa086b3c,key:isDog,negate:!!f,params:(value:!!t),type:phrase,value:true),script:(script:(inline:!%27boolean%2Bcompare(Supplier%2Bs,%2Bdef%2Bv)%2B%257Breturn%2Bs.get()%2B%253D%253D%2Bv%3B%257Dcompare(()%2B-%253E%2B%257B%2Breturn%2Bdoc%255B!!!%27animal.keyword!!!%27%255D.value%2B%253D%253D%2B!!!%27dog!!!%27%2B%257D,%2Bparams.value)%3B!%27,lang:painless,params:(value:!!t))))),fullScreenMode:!!f,options:(darkTheme:!!f,hidePanelTitles:!!f,useMargins:!!t),panels:!!((gridData:(h:3,i:!%274!%27,w:6,x:6,y:0),id:edb65990-53ca-11e8-b481-c9426d020fcd,panelIndex:!%274!%27,type:visualization,version:!%276.2.4!%27),(gridData:(h:3,i:!%275!%27,w:6,x:0,y:0),id:!%270644f890-53cb-11e8-b481-c9426d020fcd!%27,panelIndex:!%275!%27,type:visualization,version:!%276.2.4!%27)),query:(language:lucene,query:!%27weightLbs:%253E15!%27),timeRestore:!!t,title:!%27Animal%2BWeights%2B(created%2Bin%2B6.2)!%27,viewMode:view)%27,savedObjectId:%271b2f47b0-53cb-11e8-b481-c9426d020fcd%27)';
+export const PDF_PRINT_DASHBOARD_6_2 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(id:print),objectType:dashboard,queryString:%27_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(description:!%27!%27,filters:!!((!%27$state!%27:(store:appState),meta:(alias:!!n,disabled:!!f,field:isDog,index:a0f483a0-3dc9-11e8-8660-4d65aa086b3c,key:isDog,negate:!!f,params:(value:!!t),type:phrase,value:true),script:(script:(inline:!%27boolean%2Bcompare(Supplier%2Bs,%2Bdef%2Bv)%2B%257Breturn%2Bs.get()%2B%253D%253D%2Bv%3B%257Dcompare(()%2B-%253E%2B%257B%2Breturn%2Bdoc%255B!!!%27animal.keyword!!!%27%255D.value%2B%253D%253D%2B!!!%27dog!!!%27%2B%257D,%2Bparams.value)%3B!%27,lang:painless,params:(value:!!t))))),fullScreenMode:!!f,options:(hidePanelTitles:!!f,useMargins:!!t),panels:!!((gridData:(h:3,i:!%274!%27,w:6,x:6,y:0),id:edb65990-53ca-11e8-b481-c9426d020fcd,panelIndex:!%274!%27,type:visualization,version:!%276.2.4!%27),(gridData:(h:3,i:!%275!%27,w:6,x:0,y:0),id:!%270644f890-53cb-11e8-b481-c9426d020fcd!%27,panelIndex:!%275!%27,type:visualization,version:!%276.2.4!%27)),query:(language:lucene,query:!%27weightLbs:%253E15!%27),timeRestore:!!t,title:!%27Animal%2BWeights%2B(created%2Bin%2B6.2)!%27,viewMode:view)%27,savedObjectId:%271b2f47b0-53cb-11e8-b481-c9426d020fcd%27)';
export const PDF_PRESERVE_VISUALIZATION_6_2 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(dimensions:(height:441,width:1002),id:preserve_layout),objectType:visualization,queryString:%27_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(filters:!!(),linked:!!f,query:(language:lucene,query:!%27weightLbs:%253E10!%27),uiState:(),vis:(aggs:!!((enabled:!!t,id:!%271!%27,params:(),schema:metric,type:count),(enabled:!!t,id:!%272!%27,params:(field:weightLbs,missingBucket:!!f,missingBucketLabel:Missing,order:desc,orderBy:!%271!%27,otherBucket:!!f,otherBucketLabel:Other,size:5),schema:segment,type:terms)),params:(addLegend:!!t,addTooltip:!!t,isDonut:!!t,labels:(last_level:!!t,show:!!f,truncate:100,values:!!t),legendPosition:right,type:pie),title:!%27Weight%2Bin%2Blbs%2Bpie%2Bcreated%2Bin%2B6.2!%27,type:pie))%27,savedObjectId:%270644f890-53cb-11e8-b481-c9426d020fcd%27)';
export const CSV_DISCOVER_FILTER_QUERY_6_2 = '/api/reporting/generate/csv?jobParams=(conflictedTypesFields:!(),fields:!(%27@timestamp%27,animal,sound,weightLbs),indexPatternId:a0f483a0-3dc9-11e8-8660-4d65aa086b3c,metaFields:!(_source,_id,_type,_index,_score),searchRequest:(body:(_source:(excludes:!(),includes:!(%27@timestamp%27,animal,sound,weightLbs)),docvalue_fields:!(%27@timestamp%27),query:(bool:(filter:!(),must:!((query_string:(analyze_wildcard:!t,default_field:%27*%27,query:%27weightLbs:%3E10%27)),(match_phrase:(sound.keyword:(query:growl))),(range:(%27@timestamp%27:(format:epoch_millis,gte:1523310968000,lte:1523483768000)))),must_not:!(),should:!())),script_fields:(),sort:!((%27@timestamp%27:(order:desc,unmapped_type:boolean))),stored_fields:!(%27@timestamp%27,animal,sound,weightLbs),version:!t),index:%27animals-*%27),title:%27Search%20created%20in%206.2%27,type:search)';
diff --git a/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json b/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json
index 5da6fb43ff1d4..6bf3413f3797d 100644
--- a/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json
+++ b/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json
@@ -122,7 +122,7 @@
"hits": 0,
"description": "",
"panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"dd7caf20-9efd-11e7-acb3-3dab96693fab\",\"col\":1,\"row\":1}]",
- "optionsJSON": "{\"darkTheme\":false}",
+ "optionsJSON": "{}",
"uiStateJSON": "{}",
"version": 1,
"timeRestore": true,
@@ -217,7 +217,7 @@
"hits": 0,
"description": "",
"panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"dd7caf20-9efd-11e7-acb3-3dab96693fab\",\"col\":1,\"row\":1}]",
- "optionsJSON": "{\"darkTheme\":false}",
+ "optionsJSON": "{}",
"uiStateJSON": "{}",
"version": 1,
"timeRestore": true,
@@ -313,7 +313,7 @@
"hits": 0,
"description": "",
"panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"dd7caf20-9efd-11e7-acb3-3dab96693fab\",\"col\":1,\"row\":1}]",
- "optionsJSON": "{\"darkTheme\":false}",
+ "optionsJSON": "{}",
"uiStateJSON": "{}",
"version": 1,
"timeRestore": true,
From 45a4d3bce0112d11f58f1cac77ebf9ea10fc158d Mon Sep 17 00:00:00 2001
From: Josh Dover
Date: Wed, 23 Jan 2019 16:45:19 -0600
Subject: [PATCH 16/29] [kbn-es] Add support to kbn-es and kbn-test for data
archives (#28723)
* Add support to kbn-es and kbn-test for data archives
* Fix log indent
* Decompress directly to data directory
Co-Authored-By: joshdover
* Improve logs
---
packages/kbn-es/src/cli_commands/snapshot.js | 7 ++++++
packages/kbn-es/src/cli_commands/source.js | 7 ++++++
packages/kbn-es/src/cluster.js | 25 ++++++++++++++++++-
packages/kbn-test/src/es/es_test_cluster.js | 5 ++++
.../functional_tests/lib/run_elasticsearch.js | 1 +
.../lib/config/schema.js | 1 +
6 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/packages/kbn-es/src/cli_commands/snapshot.js b/packages/kbn-es/src/cli_commands/snapshot.js
index c01a4fa08ec59..4cf124f53faf8 100644
--- a/packages/kbn-es/src/cli_commands/snapshot.js
+++ b/packages/kbn-es/src/cli_commands/snapshot.js
@@ -33,6 +33,7 @@ exports.help = (defaults = {}) => {
--version Version of ES to download [default: ${defaults.version}]
--base-path Path containing cache/installations [default: ${basePath}]
--install-path Installation path, defaults to 'source' within base-path
+ --data-archive Path to zip or tarball containing an ES data directory to seed the cluster with.
--password Sets password for elastic user [default: ${password}]
-E Additional key=value settings to pass to Elasticsearch
--download-only Download the snapshot but don't actually start it
@@ -49,6 +50,7 @@ exports.run = async (defaults = {}) => {
alias: {
basePath: 'base-path',
installPath: 'install-path',
+ dataArchive: 'data-archive',
esArgs: 'E',
},
@@ -62,6 +64,11 @@ exports.run = async (defaults = {}) => {
await cluster.downloadSnapshot(options);
} else {
const { installPath } = await cluster.installSnapshot(options);
+
+ if (options.dataArchive) {
+ await cluster.extractDataDirectory(installPath, options.dataArchive);
+ }
+
await cluster.run(installPath, { esArgs: options.esArgs });
}
};
diff --git a/packages/kbn-es/src/cli_commands/source.js b/packages/kbn-es/src/cli_commands/source.js
index 00b40ccd6a4db..7acad33ca80bf 100644
--- a/packages/kbn-es/src/cli_commands/source.js
+++ b/packages/kbn-es/src/cli_commands/source.js
@@ -33,6 +33,7 @@ exports.help = (defaults = {}) => {
--source-path Path to ES source [default: ${defaults['source-path']}]
--base-path Path containing cache/installations [default: ${basePath}]
--install-path Installation path, defaults to 'source' within base-path
+ --data-archive Path to zip or tarball containing an ES data directory to seed the cluster with.
--password Sets password for elastic user [default: ${password}]
-E Additional key=value settings to pass to Elasticsearch
@@ -49,6 +50,7 @@ exports.run = async (defaults = {}) => {
basePath: 'base-path',
installPath: 'install-path',
sourcePath: 'source-path',
+ dataArchive: 'data-archive',
esArgs: 'E',
},
@@ -57,5 +59,10 @@ exports.run = async (defaults = {}) => {
const cluster = new Cluster();
const { installPath } = await cluster.installSource(options);
+
+ if (options.dataArchive) {
+ await cluster.extractDataDirectory(installPath, options.dataArchive);
+ }
+
await cluster.run(installPath, { esArgs: options.esArgs });
};
diff --git a/packages/kbn-es/src/cluster.js b/packages/kbn-es/src/cluster.js
index 50f3c5db2d8ca..4f9e5ba94681f 100644
--- a/packages/kbn-es/src/cluster.js
+++ b/packages/kbn-es/src/cluster.js
@@ -19,9 +19,10 @@
const execa = require('execa');
const chalk = require('chalk');
+const path = require('path');
const { downloadSnapshot, installSnapshot, installSource, installArchive } = require('./install');
const { ES_BIN } = require('./paths');
-const { log: defaultLog, parseEsLog, extractConfigFiles } = require('./utils');
+const { log: defaultLog, parseEsLog, extractConfigFiles, decompress } = require('./utils');
const { createCliError } = require('./errors');
const { promisify } = require('util');
const treeKillAsync = promisify(require('tree-kill'));
@@ -116,6 +117,28 @@ exports.Cluster = class Cluster {
return { installPath };
}
+ /**
+ * Unpakcs a tar or zip file containing the data directory for an
+ * ES cluster.
+ *
+ * @param {String} installPath
+ * @param {String} archivePath
+ */
+ async extractDataDirectory(installPath, archivePath) {
+ this._log.info(chalk.bold(`Extracting data directory`));
+ this._log.indent(4);
+
+ // decompress excludes the root directory as that is how our archives are
+ // structured. This works in our favor as we can explicitly extract into the data dir
+ const extractPath = path.resolve(installPath, 'data');
+ this._log.info(`Data archive: ${archivePath}`);
+ this._log.info(`Extract path: ${extractPath}`);
+
+ await decompress(archivePath, extractPath);
+
+ this._log.indent(-4);
+ }
+
/**
* Starts ES and returns resolved promise once started
*
diff --git a/packages/kbn-test/src/es/es_test_cluster.js b/packages/kbn-test/src/es/es_test_cluster.js
index 474537da17c7a..330a49868b9fb 100644
--- a/packages/kbn-test/src/es/es_test_cluster.js
+++ b/packages/kbn-test/src/es/es_test_cluster.js
@@ -36,6 +36,7 @@ export function createEsTestCluster(options = {}) {
log,
basePath = resolve(KIBANA_ROOT, '.es'),
esFrom = esTestConfig.getBuildFrom(),
+ dataArchive,
} = options;
const randomHash = Math.random()
@@ -74,6 +75,10 @@ export function createEsTestCluster(options = {}) {
throw new Error(`unknown option esFrom "${esFrom}"`);
}
+ if (dataArchive) {
+ await cluster.extractDataDirectory(installPath, dataArchive);
+ }
+
await cluster.start(installPath, {
esArgs: [
`cluster.name=${clusterName}`,
diff --git a/packages/kbn-test/src/functional_tests/lib/run_elasticsearch.js b/packages/kbn-test/src/functional_tests/lib/run_elasticsearch.js
index 41d273b5fa79a..189a609d04461 100644
--- a/packages/kbn-test/src/functional_tests/lib/run_elasticsearch.js
+++ b/packages/kbn-test/src/functional_tests/lib/run_elasticsearch.js
@@ -37,6 +37,7 @@ export async function runElasticsearch({ config, options }) {
log,
basePath: resolve(KIBANA_ROOT, '.es'),
esFrom: esFrom || config.get('esTestCluster.from'),
+ dataArchive: config.get('esTestCluster.dataArchive'),
});
const esArgs = config.get('esTestCluster.serverArgs');
diff --git a/src/functional_test_runner/lib/config/schema.js b/src/functional_test_runner/lib/config/schema.js
index eb842deeafc00..d7d2215f0b0be 100644
--- a/src/functional_test_runner/lib/config/schema.js
+++ b/src/functional_test_runner/lib/config/schema.js
@@ -139,6 +139,7 @@ export const schema = Joi.object().keys({
license: Joi.string().default('oss'),
from: Joi.string().default('snapshot'),
serverArgs: Joi.array(),
+ dataArchive: Joi.string(),
}).default(),
kbnTestServer: Joi.object().keys({
From 76212da43677f38781cf8e0f19dd2b0c57f55646 Mon Sep 17 00:00:00 2001
From: Nathan Reese
Date: Wed, 23 Jan 2019 15:57:26 -0700
Subject: [PATCH 17/29] [Maps] fix panel cuttoff in K7 design (#29209)
---
x-pack/plugins/gis/public/_main.scss | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/x-pack/plugins/gis/public/_main.scss b/x-pack/plugins/gis/public/_main.scss
index 0258a2fabec5c..f673aa9d19fff 100644
--- a/x-pack/plugins/gis/public/_main.scss
+++ b/x-pack/plugins/gis/public/_main.scss
@@ -1,11 +1,19 @@
+@import '@elastic/eui/src/components/header/variables';
+
#gis-plugin {
display: flex;
flex-direction: column;
- height: 100vh;
+ height: calc(100vh - #{$euiHeaderChildSize});
width: 100%;
overflow: hidden;
}
+@include euiBreakpoint('xs') {
+ #gis-plugin {
+ height: calc(100vh - #{$euiHeaderChildSizeMobile});
+ }
+}
+
#react-gis-root {
flex-grow: 1;
display: flex;
From 9bdee51c1b9f38632a7ce5c96c7fb07c0fd897c4 Mon Sep 17 00:00:00 2001
From: Spencer
Date: Wed, 23 Jan 2019 16:20:19 -0800
Subject: [PATCH 18/29] [home/sampleData] add empty migrationVersion to
auto-migration objects (#29226)
The sample data does not currently specify a migration version, which means we have manually update the data sets when updating the saved objects API. This just sets the migration version for all the saved objects to `{}`, which signals to the saved objects API that the object has not been migrated and should have all migrations applied.
---
.../data_sets/ecommerce/saved_objects.js | 14 +++++++++++++
.../data_sets/flights/saved_objects.js | 21 +++++++++++++++++++
.../data_sets/logs/saved_objects.js | 13 ++++++++++++
.../sample_data/ecommerce_saved_objects.json | 1 +
.../sample_data/flights_saved_objects.json | 1 +
.../sample_data/web_logs_saved_objects.json | 1 +
.../sample_data/web_logs_saved_objects.json | 1 +
7 files changed, 52 insertions(+)
diff --git a/src/server/sample_data/data_sets/ecommerce/saved_objects.js b/src/server/sample_data/data_sets/ecommerce/saved_objects.js
index 32c0fc5b92ece..bfca3f575d9de 100644
--- a/src/server/sample_data/data_sets/ecommerce/saved_objects.js
+++ b/src/server/sample_data/data_sets/ecommerce/saved_objects.js
@@ -28,6 +28,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-10-01T15:13:03.270Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.ecommerceSpec.salesByCategoryTitle', {
defaultMessage: '[eCommerce] Sales by Category',
@@ -46,6 +47,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-10-01T15:13:03.270Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.ecommerceSpec.salesByGenderTitle', {
defaultMessage: '[eCommerce] Sales by Gender',
@@ -64,6 +66,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-10-01T15:13:03.270Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.ecommerceSpec.markdownTitle', {
defaultMessage: '[eCommerce] Markdown',
@@ -82,6 +85,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-10-01T15:13:03.270Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.ecommerceSpec.controlsTitle', {
defaultMessage: '[eCommerce] Controls',
@@ -100,6 +104,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-10-01T15:17:30.755Z",
"version": 2,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.ecommerceSpec.promotionTrackingTitle', {
defaultMessage: '[eCommerce] Promotion Tracking',
@@ -118,6 +123,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-10-01T15:13:03.270Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.ecommerceSpec.totalRevenueTitle', {
defaultMessage: '[eCommerce] Total Revenue',
@@ -136,6 +142,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-10-01T15:13:03.270Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.ecommerceSpec.soldProductsPerDayTitle', {
defaultMessage: '[eCommerce] Sold Products per Day',
@@ -154,6 +161,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-10-01T15:13:03.270Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.ecommerceSpec.averageSalesPriceTitle', {
defaultMessage: '[eCommerce] Average Sales Price',
@@ -172,6 +180,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-10-01T15:13:03.270Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.ecommerceSpec.averageSoldQuantityTitle', {
defaultMessage: '[eCommerce] Average Sold Quantity',
@@ -190,6 +199,7 @@ export const getSavedObjects = () => [
"type": "search",
"updated_at": "2018-10-01T15:13:03.270Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.ecommerceSpec.ordersTitle', {
defaultMessage: '[eCommerce] Orders',
@@ -217,6 +227,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-10-01T15:13:03.270Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.ecommerceSpec.averageSalesPerRegionTitle', {
defaultMessage: '[eCommerce] Average Sales Per Region',
@@ -235,6 +246,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-10-01T15:13:03.270Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.ecommerceSpec.topSellingProductsTitle', {
defaultMessage: '[eCommerce] Top Selling Products',
@@ -253,6 +265,7 @@ export const getSavedObjects = () => [
"type": "index-pattern",
"updated_at": "2018-10-01T15:13:03.270Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": "kibana_sample_data_ecommerce",
"timeFieldName": "order_date",
@@ -265,6 +278,7 @@ export const getSavedObjects = () => [
"type": "dashboard",
"updated_at": "2018-10-01T15:13:03.270Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.ecommerceSpec.revenueDashboardTitle', {
defaultMessage: '[eCommerce] Revenue Dashboard',
diff --git a/src/server/sample_data/data_sets/flights/saved_objects.js b/src/server/sample_data/data_sets/flights/saved_objects.js
index d647cd2816523..afb1d5b661cc2 100644
--- a/src/server/sample_data/data_sets/flights/saved_objects.js
+++ b/src/server/sample_data/data_sets/flights/saved_objects.js
@@ -28,6 +28,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.controlsTitle', {
defaultMessage: '[Flights] Controls',
@@ -46,6 +47,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.flightCountAndAverageTicketPriceTitle', {
defaultMessage: '[Flights] Flight Count and Average Ticket Price',
@@ -64,6 +66,7 @@ export const getSavedObjects = () => [
"type": "search",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.flightLogTitle', {
defaultMessage: '[Flights] Flight Log',
@@ -96,6 +99,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.airlineCarrierTitle', {
defaultMessage: '[Flights] Airline Carrier',
@@ -114,6 +118,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.delayTypeTitle', {
defaultMessage: '[Flights] Delay Type',
@@ -132,6 +137,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.delaysAndCancellationsTitle', {
defaultMessage: '[Flights] Delays & Cancellations',
@@ -150,6 +156,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.delayBucketsTitle', {
defaultMessage: '[Flights] Delay Buckets',
@@ -168,6 +175,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.flightDelaysTitle', {
defaultMessage: '[Flights] Flight Delays',
@@ -186,6 +194,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.flightCancellationsTitle', {
defaultMessage: '[Flights] Flight Cancellations',
@@ -204,6 +213,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.destinationAirportTitle', {
defaultMessage: '[Flights] Destination Airport',
@@ -222,6 +232,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.destinationWeatherTitle', {
defaultMessage: '[Flights] Destination Weather',
@@ -240,6 +251,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.markdownInstructionsTitle', {
defaultMessage: '[Flights] Markdown Instructions',
@@ -258,6 +270,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.originCountryTicketPricesTitle', {
defaultMessage: '[Flights] Origin Country Ticket Prices',
@@ -276,6 +289,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.totalFlightDelaysTitle', {
defaultMessage: '[Flights] Total Flight Delays',
@@ -294,6 +308,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.totalFlightCancellationsTitle', {
defaultMessage: '[Flights] Total Flight Cancellations',
@@ -312,6 +327,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.originCountryTitle', {
defaultMessage: '[Flights] Origin Country vs. Destination Country',
@@ -330,6 +346,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.totalFlightsTitle', {
defaultMessage: '[Flights] Total Flights',
@@ -348,6 +365,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.averageTicketPriceTitle', {
defaultMessage: '[Flights] Average Ticket Price',
@@ -366,6 +384,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-05-09T15:55:51.195Z",
"version": 3,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.airportConnectionsTitle', {
defaultMessage: '[Flights] Airport Connections (Hover Over Airport)',
@@ -384,6 +403,7 @@ export const getSavedObjects = () => [
"type": "index-pattern",
"updated_at": "2018-05-09T15:49:03.736Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": "kibana_sample_data_flights",
"timeFieldName": "timestamp",
@@ -396,6 +416,7 @@ export const getSavedObjects = () => [
"type": "dashboard",
"updated_at": "2018-05-09T15:59:04.578Z",
"version": 4,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.flightsSpec.globalFlightDashboardTitle', {
defaultMessage: '[Flights] Global Flight Dashboard',
diff --git a/src/server/sample_data/data_sets/logs/saved_objects.js b/src/server/sample_data/data_sets/logs/saved_objects.js
index 9bdd16ff42bb9..55f4bde7e99d3 100644
--- a/src/server/sample_data/data_sets/logs/saved_objects.js
+++ b/src/server/sample_data/data_sets/logs/saved_objects.js
@@ -28,6 +28,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-08-29T13:22:17.617Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.logsSpec.uniqueVisitorsTitle', {
defaultMessage: '[Logs] Unique Visitors vs. Average Bytes',
@@ -46,6 +47,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-08-29T13:22:17.617Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.logsSpec.uniqueVisitorsByCountryTitle', {
defaultMessage: '[Logs] Unique Visitors by Country',
@@ -64,6 +66,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-08-29T13:22:17.617Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.logsSpec.heatmapTitle', {
defaultMessage: '[Logs] Heatmap',
@@ -82,6 +85,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-08-29T13:23:20.897Z",
"version": 2,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.logsSpec.hostVisitsBytesTableTitle', {
defaultMessage: '[Logs] Host, Visits and Bytes Table',
@@ -100,6 +104,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-08-29T13:24:46.136Z",
"version": 2,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.logsSpec.goalsTitle', {
defaultMessage: '[Logs] Goals',
@@ -118,6 +123,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-08-29T13:22:17.617Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.logsSpec.fileTypeScatterPlotTitle', {
defaultMessage: '[Logs] File Type Scatter Plot',
@@ -136,6 +142,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-08-29T13:22:17.617Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.logsSpec.sourceAndDestinationSankeyChartTitle', {
defaultMessage: '[Logs] Source and Destination Sankey Chart',
@@ -154,6 +161,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-08-29T13:22:17.617Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.logsSpec.responseCodesOverTimeTitle', {
defaultMessage: '[Logs] Response Codes Over Time + Annotations',
@@ -172,6 +180,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-08-29T13:22:17.617Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.logsSpec.inputControlsTitle', {
defaultMessage: '[Logs] Input Controls',
@@ -190,6 +199,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-08-29T13:22:17.617Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.logsSpec.articleTagsTitle', {
defaultMessage: '[Logs] Article Tags',
@@ -208,6 +218,7 @@ export const getSavedObjects = () => [
"type": "visualization",
"updated_at": "2018-08-29T13:22:17.617Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.logsSpec.markdownInstructionsTitle', {
defaultMessage: '[Logs] Markdown Instructions',
@@ -226,6 +237,7 @@ export const getSavedObjects = () => [
"type": "index-pattern",
"updated_at": "2018-08-29T13:22:17.617Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"title": "kibana_sample_data_logs",
"timeFieldName": "timestamp",
@@ -238,6 +250,7 @@ export const getSavedObjects = () => [
"type": "dashboard",
"updated_at": "2018-08-29T13:26:13.463Z",
"version": 3,
+ "migrationVersion": {},
"attributes": {
"title": i18n.translate('server.sampleData.logsSpec.webTrafficTitle', {
defaultMessage: '[Logs] Web Traffic',
diff --git a/x-pack/plugins/canvas/server/sample_data/ecommerce_saved_objects.json b/x-pack/plugins/canvas/server/sample_data/ecommerce_saved_objects.json
index d9e7f51215547..2db6cadee646e 100644
--- a/x-pack/plugins/canvas/server/sample_data/ecommerce_saved_objects.json
+++ b/x-pack/plugins/canvas/server/sample_data/ecommerce_saved_objects.json
@@ -4,6 +4,7 @@
"type": "canvas-workpad",
"updated_at": "2018-10-22T15:19:02.081Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"name": "[eCommerce] Revenue Tracking",
"id": "workpad-e08b9bdb-ec14-4339-94c4-063bddfd610e",
diff --git a/x-pack/plugins/canvas/server/sample_data/flights_saved_objects.json b/x-pack/plugins/canvas/server/sample_data/flights_saved_objects.json
index 532f1f5a4e4c5..69943f3c8bd0a 100644
--- a/x-pack/plugins/canvas/server/sample_data/flights_saved_objects.json
+++ b/x-pack/plugins/canvas/server/sample_data/flights_saved_objects.json
@@ -4,6 +4,7 @@
"type": "canvas-workpad",
"updated_at": "2018-10-22T14:17:04.040Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"name": "[Flights] Overview",
"id": "workpad-a474e74b-aedc-47c3-894a-db77e62c41e0",
diff --git a/x-pack/plugins/canvas/server/sample_data/web_logs_saved_objects.json b/x-pack/plugins/canvas/server/sample_data/web_logs_saved_objects.json
index 5b4dd9c19fdf3..f908c2b7b0a3c 100644
--- a/x-pack/plugins/canvas/server/sample_data/web_logs_saved_objects.json
+++ b/x-pack/plugins/canvas/server/sample_data/web_logs_saved_objects.json
@@ -4,6 +4,7 @@
"type": "canvas-workpad",
"updated_at": "2018-10-22T12:41:57.071Z",
"version": 1,
+ "migrationVersion": {},
"attributes": {
"name": "[Logs] Web Traffic",
"id": "workpad-5563cc40-5760-4afe-bf33-9da72fac53b7",
diff --git a/x-pack/plugins/gis/server/sample_data/web_logs_saved_objects.json b/x-pack/plugins/gis/server/sample_data/web_logs_saved_objects.json
index 09e9d7f271c60..065301766c09f 100644
--- a/x-pack/plugins/gis/server/sample_data/web_logs_saved_objects.json
+++ b/x-pack/plugins/gis/server/sample_data/web_logs_saved_objects.json
@@ -4,6 +4,7 @@
"type": "gis-map",
"updated_at" : "2018-12-19T14:56:22.769Z",
"version": 1,
+ "migrationVersion": {},
"attributes" : {
"title" : "[Logs] Web Traffic",
"description" : "",
From 10e52a0eae78604f6f62eedf85c1f18a4fb05f14 Mon Sep 17 00:00:00 2001
From: Tiago Costa
Date: Thu, 24 Jan 2019 00:29:14 +0000
Subject: [PATCH 19/29] fix(NA): replace process.env.HOME with
require('os').homedir(). (#27557)
---
src/dev/register_git_hook/register_git_hook.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/dev/register_git_hook/register_git_hook.js b/src/dev/register_git_hook/register_git_hook.js
index d50fb4ca39329..82616795c978a 100644
--- a/src/dev/register_git_hook/register_git_hook.js
+++ b/src/dev/register_git_hook/register_git_hook.js
@@ -21,6 +21,7 @@ import chalk from 'chalk';
import { chmod, unlink, writeFile } from 'fs';
import dedent from 'dedent';
import normalizePath from 'normalize-path';
+import os from 'os';
import { resolve } from 'path';
import { promisify } from 'util';
import SimpleGit from 'simple-git';
@@ -128,7 +129,7 @@ export async function registerPrecommitGitHook(log) {
await getPrecommitGitHookScriptPath(REPO_ROOT),
getKbnPrecommitGitHookScript(
REPO_ROOT,
- normalizePath(process.env.HOME.replace(/'/g, '\'')),
+ normalizePath(os.homedir()),
process.platform
)
);
From bfa417c7d61965dbbb8d395914eb567f445048bb Mon Sep 17 00:00:00 2001
From: CJ Cenizal
Date: Wed, 23 Jan 2019 16:36:48 -0800
Subject: [PATCH 20/29] Localize strings in Rollup and ILM apps. (#29034)
* Add ILM to i18nrc.json. Fix validation errors.
* Localize CCR and Rollups checkLicense errors.
* Fix bug in Remote Clusters checkLicense error.
* Use rollupJobs namespace in checkLicense.
---
.i18nrc.json | 1 +
.../server/lib/check_license/check_license.js | 26 +++++++++++++--
.../extend_index_management.test.js.snap | 12 +++----
.../components/add_lifecycle_confirm_modal.js | 8 ++---
.../components/index_lifecycle_summary.js | 24 +++++++-------
.../remove_lifecycle_confirm_modal.js | 6 ++--
.../public/extend_index_management/index.js | 8 ++---
.../components/hot_phase/hot_phase.js | 4 +--
.../sections/edit_policy/edit_policy.js | 9 ++---
.../add_policy_to_template_confirm_modal.js | 24 +++++++-------
.../components/policy_table/policy_table.js | 20 ++++++++---
.../server/lib/check_license/check_license.js | 33 ++++++++++++-------
.../server/lib/check_license/check_license.js | 1 -
.../plugins/rollup/public/crud_app/index.js | 5 ++-
.../server/lib/check_license/check_license.js | 26 +++++++++++++--
15 files changed, 135 insertions(+), 72 deletions(-)
diff --git a/.i18nrc.json b/.i18nrc.json
index bcf9fcc2dd596..6416f9416d106 100644
--- a/.i18nrc.json
+++ b/.i18nrc.json
@@ -24,6 +24,7 @@
"xpack.graph": "x-pack/plugins/graph",
"xpack.grokDebugger": "x-pack/plugins/grokdebugger",
"xpack.idxMgmt": "x-pack/plugins/index_management",
+ "xpack.indexLifecycleMgmt": "x-pack/plugins/index_lifecycle_management",
"xpack.infra": "x-pack/plugins/infra",
"xpack.licenseMgmt": "x-pack/plugins/license_management",
"xpack.ml": "x-pack/plugins/ml",
diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/check_license/check_license.js b/x-pack/plugins/cross_cluster_replication/server/lib/check_license/check_license.js
index 7cb6e4e1db08f..35e5e3783e628 100644
--- a/x-pack/plugins/cross_cluster_replication/server/lib/check_license/check_license.js
+++ b/x-pack/plugins/cross_cluster_replication/server/lib/check_license/check_license.js
@@ -4,6 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { i18n } from '@kbn/i18n';
+
export function checkLicense(xpackLicenseInfo) {
const pluginName = 'Cross Cluster Replication';
@@ -14,7 +16,13 @@ export function checkLicense(xpackLicenseInfo) {
isAvailable: false,
showLinks: true,
enableLinks: false,
- message: `You cannot use ${pluginName} because license information is not available at this time.`,
+ message: i18n.translate(
+ 'xpack.crossClusterReplication.checkLicense.errorUnavailableMessage',
+ {
+ defaultMessage: 'You cannot use {pluginName} because license information is not available at this time.',
+ values: { pluginName },
+ },
+ ),
};
}
@@ -29,7 +37,13 @@ export function checkLicense(xpackLicenseInfo) {
return {
isAvailable: false,
showLinks: false,
- message: `Your ${licenseType} license does not support ${pluginName}. Please upgrade your license.`,
+ message: i18n.translate(
+ 'xpack.crossClusterReplication.checkLicense.errorUnsupportedMessage',
+ {
+ defaultMessage: 'Your {licenseType} license does not support {pluginName}. Please upgrade your license.',
+ values: { licenseType, pluginName },
+ },
+ ),
};
}
@@ -39,7 +53,13 @@ export function checkLicense(xpackLicenseInfo) {
isAvailable: false,
showLinks: true,
enableLinks: false,
- message: `You cannot use ${pluginName} because your ${licenseType} license has expired.`,
+ message: i18n.translate(
+ 'xpack.crossClusterReplication.checkLicense.errorExpiredMessage',
+ {
+ defaultMessage: 'You cannot use {pluginName} because your {licenseType} license has expired',
+ values: { licenseType, pluginName },
+ },
+ ),
};
}
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/__snapshots__/extend_index_management.test.js.snap b/x-pack/plugins/index_lifecycle_management/__jest__/__snapshots__/extend_index_management.test.js.snap
index afecebf3391e1..9ad5eb0b66715 100644
--- a/x-pack/plugins/index_lifecycle_management/__jest__/__snapshots__/extend_index_management.test.js.snap
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/__snapshots__/extend_index_management.test.js.snap
@@ -248,7 +248,7 @@ exports[`ilm summary extension should return extension when index has lifecycle
>
Index lifecycle management
@@ -269,7 +269,7 @@ exports[`ilm summary extension should return extension when index has lifecycle
title={
}
@@ -317,7 +317,7 @@ exports[`ilm summary extension should return extension when index has lifecycle
>
Index lifecycle error
@@ -521,7 +521,7 @@ exports[`ilm summary extension should return extension when index has lifecycle
>
@@ -559,7 +559,7 @@ exports[`ilm summary extension should return extension when index has lifecycle
>
Show phase definition
@@ -720,7 +720,7 @@ exports[`ilm summary extension should return extension when index has lifecycle
>
Index lifecycle management
diff --git a/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/add_lifecycle_confirm_modal.js b/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/add_lifecycle_confirm_modal.js
index 6d62023e6c2ff..baedb0f195d3f 100644
--- a/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/add_lifecycle_confirm_modal.js
+++ b/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/add_lifecycle_confirm_modal.js
@@ -211,7 +211,7 @@ export class AddLifecyclePolicyConfirmModal extends Component {
const title = (
-
+
{title}
-
-
+
+
{
return {
- policy: i18n.translate('xpack.idxMgmt.indexLifecycleMgmtSummary.headers.lifecyclePolicyHeader', {
+ policy: i18n.translate('xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.lifecyclePolicyHeader', {
defaultMessage: 'Lifecycle policy',
}),
- phase: i18n.translate('xpack.idxMgmt.indexLifecycleMgmtSummary.headers.currentPhaseHeader', {
+ phase: i18n.translate('xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.currentPhaseHeader', {
defaultMessage: 'Current phase',
}),
- action: i18n.translate('xpack.idxMgmt.indexLifecycleMgmtSummary.headers.currentActionHeader', {
+ action: i18n.translate('xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.currentActionHeader', {
defaultMessage: 'Current action',
}),
- action_time_millis: i18n.translate('xpack.idxMgmt.indexLifecycleMgmtSummary.headers.currentActionTimeHeader', {
+ action_time_millis: i18n.translate('xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.currentActionTimeHeader', {
defaultMessage: 'Current action time',
}),
- failed_step: i18n.translate('xpack.idxMgmt.indexLifecycleMgmtSummary.headers.failedStepHeader', {
+ failed_step: i18n.translate('xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.failedStepHeader', {
defaultMessage: 'Failed step',
}),
};
@@ -70,7 +70,7 @@ export class IndexLifecycleSummary extends Component {
);
@@ -95,7 +95,7 @@ export class IndexLifecycleSummary extends Component {
);
@@ -111,7 +111,7 @@ export class IndexLifecycleSummary extends Component {
@@ -168,7 +168,7 @@ export class IndexLifecycleSummary extends Component {
@@ -180,7 +180,7 @@ export class IndexLifecycleSummary extends Component {
title={
}
iconType="cross"
@@ -199,7 +199,7 @@ export class IndexLifecycleSummary extends Component {
title={
}
>
@@ -223,4 +223,4 @@ export class IndexLifecycleSummary extends Component {
);
}
-}
\ No newline at end of file
+}
diff --git a/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/remove_lifecycle_confirm_modal.js b/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/remove_lifecycle_confirm_modal.js
index 42795a03a7704..67d9c37e556f2 100644
--- a/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/remove_lifecycle_confirm_modal.js
+++ b/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/remove_lifecycle_confirm_modal.js
@@ -85,7 +85,7 @@ export class RemoveLifecyclePolicyConfirmModal extends Component {
title={
{
requestMethod: retryLifecycleForIndex,
icon: 'play',
indexNames: [indexNames],
- buttonLabel: i18n.translate('xpack.idxMgmt.retryIndexLifecycleActionButtonLabel', {
+ buttonLabel: i18n.translate('xpack.indexLifecycleMgmt.retryIndexLifecycleActionButtonLabel', {
defaultMessage: 'Retry lifecycle step',
}),
successMessage: i18n.translate(
- 'xpack.idxMgmt.retryIndexLifecycleAction.retriedLifecycleMessage',
+ 'xpack.indexLifecycleMgmt.retryIndexLifecycleAction.retriedLifecycleMessage',
{
defaultMessage: 'Called retry lifecycle step for: {indexNames}',
values: { indexNames: indexNames.map(indexName => `"${indexName}"`).join(', ') },
@@ -65,7 +65,7 @@ export const removeLifecyclePolicyActionExtension = (indices, reloadIndices) =>
},
icon: 'stopFilled',
indexNames: [indexNames],
- buttonLabel: i18n.translate('xpack.idxMgmt.removeIndexLifecycleActionButtonLabel', {
+ buttonLabel: i18n.translate('xpack.indexLifecycleMgmt.removeIndexLifecycleActionButtonLabel', {
defaultMessage: 'Remove lifecycle policy',
}),
};
@@ -95,7 +95,7 @@ export const addLifecyclePolicyActionExtension = (indices, reloadIndices) => {
);
},
icon: 'plusInCircle',
- buttonLabel: i18n.translate('xpack.idxMgmt.addLifecyclePolicyActionButtonLabel', {
+ buttonLabel: i18n.translate('xpack.indexLifecycleMgmt.addLifecyclePolicyActionButtonLabel', {
defaultMessage: 'Add lifecycle policy',
}),
};
diff --git a/x-pack/plugins/index_lifecycle_management/public/sections/edit_policy/components/hot_phase/hot_phase.js b/x-pack/plugins/index_lifecycle_management/public/sections/edit_policy/components/hot_phase/hot_phase.js
index d33649dc681d1..ade95f6915410 100644
--- a/x-pack/plugins/index_lifecycle_management/public/sections/edit_policy/components/hot_phase/hot_phase.js
+++ b/x-pack/plugins/index_lifecycle_management/public/sections/edit_policy/components/hot_phase/hot_phase.js
@@ -83,8 +83,8 @@ class HotPhaseUi extends PureComponent {
diff --git a/x-pack/plugins/index_lifecycle_management/public/sections/edit_policy/edit_policy.js b/x-pack/plugins/index_lifecycle_management/public/sections/edit_policy/edit_policy.js
index 9e53183408535..ee334fd5e33ed 100644
--- a/x-pack/plugins/index_lifecycle_management/public/sections/edit_policy/edit_policy.js
+++ b/x-pack/plugins/index_lifecycle_management/public/sections/edit_policy/edit_policy.js
@@ -166,8 +166,8 @@ class EditPolicyUi extends Component {
{' '}
diff --git a/x-pack/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/add_policy_to_template_confirm_modal.js b/x-pack/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/add_policy_to_template_confirm_modal.js
index 106a9887e833d..b4c2c6f29ae3e 100644
--- a/x-pack/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/add_policy_to_template_confirm_modal.js
+++ b/x-pack/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/add_policy_to_template_confirm_modal.js
@@ -37,7 +37,7 @@ export class AddPolicyToTemplateConfirmModalUi extends Component {
const policyName = policy.name;
if (!templateName) {
this.setState({ templateError: i18n.translate(
- 'xpack.indexLifecycleMgmt.policyTable.addLifecyclePolicyConfirmModal.noTemplateSelectedErrorMessage',
+ 'xpack.indexLifecycleMgmt.policyTable.addLifecyclePolicyToTemplateConfirmModal.noTemplateSelectedErrorMessage',
{ defaultMessage: 'You must select an index template.' }) });
return;
}
@@ -48,14 +48,14 @@ export class AddPolicyToTemplateConfirmModalUi extends Component {
aliasName
});
const message = intl.formatMessage({
- id: 'xpack.indexLifecycleMgmt.policyTable.addLifecyclePolicyConfirmModal.successMessage',
+ id: 'xpack.indexLifecycleMgmt.policyTable.addLifecyclePolicyToTemplateConfirmModal.successMessage',
defaultMessage: 'Added policy {policyName} to index template {templateName}',
}, { policyName, templateName });
toastNotifications.addSuccess(message);
onCancel();
} catch (e) {
const title = intl.formatMessage({
- id: 'xpack.indexLifecycleMgmt.policyTable.addLifecyclePolicyConfirmModal.errorMessage',
+ id: 'xpack.indexLifecycleMgmt.policyTable.addLifecyclePolicyToTemplateConfirmModal.errorMessage',
defaultMessage: 'Error adding policy "{policyName}" to index template {templateName}',
}, { policyName, templateName });
showApiError(e, title);
@@ -76,14 +76,14 @@ export class AddPolicyToTemplateConfirmModalUi extends Component {
style={{ maxWidth: 400 }}
title={
}
color="warning"
>
}
@@ -153,7 +153,7 @@ export class AddPolicyToTemplateConfirmModalUi extends Component {
}
@@ -170,7 +170,7 @@ export class AddPolicyToTemplateConfirmModalUi extends Component {
render() {
const { intl, policy, onCancel } = this.props;
const title = intl.formatMessage({
- id: 'xpack.indexLifecycleMgmt.policyTable.addLifecyclePolicyConfirmModal.title',
+ id: 'xpack.indexLifecycleMgmt.policyTable.addLifecyclePolicyToTemplateConfirmModal.title',
defaultMessage: 'Add policy "{name}" to index template',
}, { name: policy.name });
return (
@@ -180,11 +180,11 @@ export class AddPolicyToTemplateConfirmModalUi extends Component {
onCancel={onCancel}
onConfirm={this.addPolicyToTemplate}
cancelButtonText={intl.formatMessage({
- id: 'xpack.indexLifecycleMgmt.policyTable.addLifecyclePolicyConfirmModal.cancelButton',
+ id: 'xpack.indexLifecycleMgmt.policyTable.addLifecyclePolicyToTemplateConfirmModal.cancelButton',
defaultMessage: 'Cancel',
})}
confirmButtonText={intl.formatMessage({
- id: 'xpack.indexLifecycleMgmt.policyTable.addLifecyclePolicyConfirmModal.confirmButton',
+ id: 'xpack.indexLifecycleMgmt.policyTable.addLifecyclePolicyToTemplateConfirmModal.confirmButton',
defaultMessage: 'Add policy',
})}
onClose={onCancel}
@@ -192,7 +192,7 @@ export class AddPolicyToTemplateConfirmModalUi extends Component {
{' '} this.togglePolicyPopover(policy)}
color="primary"
>
@@ -410,8 +409,11 @@ export class PolicyTableUi extends Component {
color="danger"
onClick={() => this.setState({ showDeleteConfirmation: true })}
>
- Delete {numSelected} polic
- {numSelected > 1 ? 'ies' : 'y'}
+
) : null}
@@ -427,7 +429,10 @@ export class PolicyTableUi extends Component {
id: 'xpack.indexLifecycleMgmt.policyTable.systempoliciesSearchInputPlaceholder',
defaultMessage: 'Search',
})}
- aria-label="Search policies"
+ aria-label={intl.formatMessage({
+ id: 'xpack.indexLifecycleMgmt.policyTable.systempoliciesSearchInputAriaLabel',
+ defaultMessage: 'Search policies',
+ })}
/>
@@ -461,7 +466,12 @@ export class PolicyTableUi extends Component {
-
+
diff --git a/x-pack/plugins/index_lifecycle_management/server/lib/check_license/check_license.js b/x-pack/plugins/index_lifecycle_management/server/lib/check_license/check_license.js
index 4dff66dffa8d1..91f781575d25f 100644
--- a/x-pack/plugins/index_lifecycle_management/server/lib/check_license/check_license.js
+++ b/x-pack/plugins/index_lifecycle_management/server/lib/check_license/check_license.js
@@ -14,10 +14,13 @@ export function checkLicense(xpackLicenseInfo) {
isAvailable: false,
showLinks: true,
enableLinks: false,
- message: i18n.translate('xpack.idxMgmt.indexLifecycleMgmtSummary.headers.lifecyclePolicyHeader', {
- defaultMessage: `You cannot use {pluginName} because license information is not available at this time.`,
- values: { pluginName }
- })
+ message: i18n.translate(
+ 'xpack.indexLifecycleMgmt.checkLicense.errorUnavailableMessage',
+ {
+ defaultMessage: 'You cannot use {pluginName} because license information is not available at this time.',
+ values: { pluginName },
+ },
+ ),
};
}
@@ -38,10 +41,13 @@ export function checkLicense(xpackLicenseInfo) {
return {
isAvailable: false,
showLinks: false,
- message: i18n.translate('xpack.idxMgmt.indexLifecycleMgmtSummary.headers.lifecyclePolicyHeader', {
- defaultMessage: `Your {licenseType} license does not support ${pluginName}. Please upgrade your license.`,
- values: { licenseType }
- })
+ message: i18n.translate(
+ 'xpack.indexLifecycleMgmt.checkLicense.errorUnsupportedMessage',
+ {
+ defaultMessage: 'Your {licenseType} license does not support {pluginName}. Please upgrade your license.',
+ values: { licenseType, pluginName },
+ },
+ ),
};
}
@@ -51,10 +57,13 @@ export function checkLicense(xpackLicenseInfo) {
isAvailable: false,
showLinks: true,
enableLinks: false,
- message: i18n.translate('xpack.idxMgmt.indexLifecycleMgmtSummary.headers.lifecyclePolicyHeader', {
- defaultMessage: `You cannot use {pluginName} because your {licenseType} license has expired.`,
- values: { pluginName, licenseType }
- })
+ message: i18n.translate(
+ 'xpack.indexLifecycleMgmt.checkLicense.errorExpiredMessage',
+ {
+ defaultMessage: 'You cannot use {pluginName} because your {licenseType} license has expired.',
+ values: { pluginName, licenseType },
+ },
+ ),
};
}
diff --git a/x-pack/plugins/remote_clusters/server/lib/check_license/check_license.js b/x-pack/plugins/remote_clusters/server/lib/check_license/check_license.js
index 2b872a061c53f..c589cbd0c8965 100644
--- a/x-pack/plugins/remote_clusters/server/lib/check_license/check_license.js
+++ b/x-pack/plugins/remote_clusters/server/lib/check_license/check_license.js
@@ -66,7 +66,6 @@ export function checkLicense(xpackLicenseInfo) {
values: { licenseType, pluginName },
},
),
- message: `.`,
};
}
diff --git a/x-pack/plugins/rollup/public/crud_app/index.js b/x-pack/plugins/rollup/public/crud_app/index.js
index da0aa43643b87..44edfbbdf885a 100644
--- a/x-pack/plugins/rollup/public/crud_app/index.js
+++ b/x-pack/plugins/rollup/public/crud_app/index.js
@@ -9,6 +9,7 @@ import { FeatureCatalogueRegistryProvider, FeatureCatalogueCategory } from 'ui/r
import { render, unmountComponentAtNode } from 'react-dom';
import { Provider } from 'react-redux';
import { HashRouter } from 'react-router-dom';
+import { i18n } from '@kbn/i18n';
import { I18nProvider } from '@kbn/i18n/react';
import { management } from 'ui/management';
import routes from 'ui/routes';
@@ -86,7 +87,9 @@ FeatureCatalogueRegistryProvider.register(() => {
return {
id: 'rollup_jobs',
title: 'Rollups',
- description: 'Summarize and store historical data in a smaller index for future analysis.',
+ description: i18n.translate('xpack.rollupJobs.featureCatalogueDescription', {
+ defaultMessage: 'Summarize and store historical data in a smaller index for future analysis.',
+ }),
icon: 'indexRollupApp',
path: `#${CRUD_APP_BASE_PATH}/job_list`,
showOnHomePage: true,
diff --git a/x-pack/plugins/rollup/server/lib/check_license/check_license.js b/x-pack/plugins/rollup/server/lib/check_license/check_license.js
index ef2bed3449195..eb28ba9f930a1 100644
--- a/x-pack/plugins/rollup/server/lib/check_license/check_license.js
+++ b/x-pack/plugins/rollup/server/lib/check_license/check_license.js
@@ -4,6 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { i18n } from '@kbn/i18n';
+
export function checkLicense(xpackLicenseInfo) {
const pluginName = 'Rollups';
@@ -14,7 +16,13 @@ export function checkLicense(xpackLicenseInfo) {
isAvailable: false,
showLinks: true,
enableLinks: false,
- message: `You cannot use ${pluginName} because license information is not available at this time.`
+ message: i18n.translate(
+ 'xpack.rollupJobs.checkLicense.errorUnavailableMessage',
+ {
+ defaultMessage: 'You cannot use {pluginName} because license information is not available at this time.',
+ values: { pluginName },
+ },
+ ),
};
}
@@ -35,7 +43,13 @@ export function checkLicense(xpackLicenseInfo) {
return {
isAvailable: false,
showLinks: false,
- message: `Your ${licenseType} license does not support ${pluginName}. Please upgrade your license.`
+ message: i18n.translate(
+ 'xpack.rollupJobs.checkLicense.errorUnsupportedMessage',
+ {
+ defaultMessage: 'Your {licenseType} license does not support {pluginName}. Please upgrade your license.',
+ values: { licenseType, pluginName },
+ },
+ ),
};
}
@@ -45,7 +59,13 @@ export function checkLicense(xpackLicenseInfo) {
isAvailable: false,
showLinks: true,
enableLinks: false,
- message: `You cannot use ${pluginName} because your ${licenseType} license has expired.`
+ message: i18n.translate(
+ 'xpack.rollupJobs.checkLicense.errorExpiredMessage',
+ {
+ defaultMessage: 'You cannot use {pluginName} because your {licenseType} license has expired',
+ values: { licenseType, pluginName },
+ },
+ ),
};
}
From a95be511f184dd5ac50dcba54fdb77b2c79a03a2 Mon Sep 17 00:00:00 2001
From: Bill McConaghy
Date: Wed, 23 Jan 2019 19:38:54 -0500
Subject: [PATCH 21/29] add follower badge to index management (#29177)
* add follower badge to index management
* fixing i18n id
---
.../cross_cluster_replication_data.js | 30 +++++++++++++++++++
.../cross_cluster_replication/index.js | 8 ++++-
.../public/extend_index_management/index.js | 24 +++++++++++++++
.../cross_cluster_replication/public/index.js | 1 +
4 files changed, 62 insertions(+), 1 deletion(-)
create mode 100644 x-pack/plugins/cross_cluster_replication/cross_cluster_replication_data.js
create mode 100644 x-pack/plugins/cross_cluster_replication/public/extend_index_management/index.js
diff --git a/x-pack/plugins/cross_cluster_replication/cross_cluster_replication_data.js b/x-pack/plugins/cross_cluster_replication/cross_cluster_replication_data.js
new file mode 100644
index 0000000000000..b9ecc52b09297
--- /dev/null
+++ b/x-pack/plugins/cross_cluster_replication/cross_cluster_replication_data.js
@@ -0,0 +1,30 @@
+/*
+ * 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 ccrDataEnricher = async (indicesList, callWithRequest) => {
+ if (!indicesList || !indicesList.length) {
+ return indicesList;
+ }
+ const params = {
+ path: '/_all/_ccr/info',
+ method: 'GET',
+ };
+ try {
+ const { follower_indices: followerIndices } = await callWithRequest('transport.request', params);
+ return indicesList.map(index => {
+ const isFollowerIndex = !!followerIndices.find((followerIndex) => {
+ return followerIndex.follower_index === index.name;
+ });
+ return {
+ ...index,
+ isFollowerIndex
+ };
+ });
+ } catch (e) {
+ return indicesList;
+ }
+
+};
diff --git a/x-pack/plugins/cross_cluster_replication/index.js b/x-pack/plugins/cross_cluster_replication/index.js
index 1424bd751ea6d..c538ed78a85b6 100644
--- a/x-pack/plugins/cross_cluster_replication/index.js
+++ b/x-pack/plugins/cross_cluster_replication/index.js
@@ -8,7 +8,8 @@ import { resolve } from 'path';
import { PLUGIN } from './common/constants';
import { registerLicenseChecker } from './server/lib/register_license_checker';
import { registerRoutes } from './server/routes/register_routes';
-
+import { ccrDataEnricher } from './cross_cluster_replication_data';
+import { addIndexManagementDataEnricher } from '../index_management/index_management_data';
export function crossClusterReplication(kibana) {
return new kibana.Plugin({
id: PLUGIN.ID,
@@ -41,6 +42,11 @@ export function crossClusterReplication(kibana) {
init: function initCcrPlugin(server) {
registerLicenseChecker(server);
registerRoutes(server);
+ if (
+ server.config().get('xpack.ccr.ui.enabled')
+ ) {
+ addIndexManagementDataEnricher(ccrDataEnricher);
+ }
},
});
}
diff --git a/x-pack/plugins/cross_cluster_replication/public/extend_index_management/index.js b/x-pack/plugins/cross_cluster_replication/public/extend_index_management/index.js
new file mode 100644
index 0000000000000..4ee2e8908b708
--- /dev/null
+++ b/x-pack/plugins/cross_cluster_replication/public/extend_index_management/index.js
@@ -0,0 +1,24 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+import { i18n } from '@kbn/i18n';
+import {
+ addBadgeExtension
+} from '../../../index_management/public/index_management_extensions';
+import { get } from 'lodash';
+
+const propertyPath = 'isFollowerIndex';
+export const followerBadgeExtension = {
+ matchIndex: (index) => {
+ return get(index, propertyPath);
+ },
+ label: i18n.translate('xpack.crossClusterReplication.indexMgmtBadge.followerLabel', {
+ defaultMessage: 'Follower',
+ }),
+ color: 'default'
+};
+
+addBadgeExtension(followerBadgeExtension);
+
diff --git a/x-pack/plugins/cross_cluster_replication/public/index.js b/x-pack/plugins/cross_cluster_replication/public/index.js
index d9e036d2dfbfb..b4bf57ec47f7a 100644
--- a/x-pack/plugins/cross_cluster_replication/public/index.js
+++ b/x-pack/plugins/cross_cluster_replication/public/index.js
@@ -6,3 +6,4 @@
import './register_ccr_section';
import './register_routes';
+import './extend_index_management';
From 78299c08e39cccaa989859854ebb6ca3c23ccac5 Mon Sep 17 00:00:00 2001
From: Spencer
Date: Wed, 23 Jan 2019 18:33:52 -0800
Subject: [PATCH 22/29] [es] when specifying path with vars always use
encodeURIComponent (#29210)
Fixes #29194
In node 10, urls are validated to not include any multi-byte characters, which wouldn't be possible if we were always encoding variables injected into URLs but we missed a couple places.
---
.../elasticsearch/lib/create_proxy.js | 2 +-
.../__snapshots__/status_message.test.js.snap | 6 +++++
.../status_message/status_message.js | 2 +-
.../_index_pattern_create_delete.js | 25 ++++++++++++++++++-
test/functional/page_objects/settings_page.js | 6 ++---
.../api/index/register_get_affected_route.js | 2 +-
.../templates/register_add_policy_route.js | 4 +--
.../api/templates/register_get_route.js | 2 +-
.../api/indices/register_freeze_route.js | 2 +-
.../api/indices/register_unfreeze_route.js | 2 +-
10 files changed, 41 insertions(+), 12 deletions(-)
diff --git a/src/legacy/core_plugins/elasticsearch/lib/create_proxy.js b/src/legacy/core_plugins/elasticsearch/lib/create_proxy.js
index a0e7a2599dc16..d1ad422b5c675 100644
--- a/src/legacy/core_plugins/elasticsearch/lib/create_proxy.js
+++ b/src/legacy/core_plugins/elasticsearch/lib/create_proxy.js
@@ -54,7 +54,7 @@ export function createProxy(server) {
handler(req, h) {
const { query, payload: body } = req;
return callWithRequest(req, 'transport.request', {
- path: `/${req.params.index}/_search`,
+ path: `/${encodeURIComponent(req.params.index)}/_search`,
method: 'POST',
query,
body
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/__jest__/__snapshots__/status_message.test.js.snap b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/__jest__/__snapshots__/status_message.test.js.snap
index 0cdb384b3af22..748eb2d0b9680 100644
--- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/__jest__/__snapshots__/status_message.test.js.snap
+++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/__jest__/__snapshots__/status_message.test.js.snap
@@ -2,6 +2,7 @@
exports[`StatusMessage should render with exact matches 1`] = `
@@ -48,6 +49,7 @@ exports[`StatusMessage should render with exact matches 1`] = `
exports[`StatusMessage should render with no partial matches 1`] = `
@@ -83,6 +85,7 @@ exports[`StatusMessage should render with no partial matches 1`] = `
exports[`StatusMessage should render with partial matches 1`] = `
@@ -118,6 +121,7 @@ exports[`StatusMessage should render with partial matches 1`] = `
exports[`StatusMessage should render without a query 1`] = `
@@ -145,6 +149,7 @@ exports[`StatusMessage should render without a query 1`] = `
exports[`StatusMessage should show that no indices exist 1`] = `
@@ -165,6 +170,7 @@ exports[`StatusMessage should show that no indices exist 1`] = `
exports[`StatusMessage should show that system indices exist 1`] = `
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.js b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.js
index 772d7ec900ec1..035d28bb126a5 100644
--- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.js
+++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.js
@@ -161,7 +161,7 @@ export const StatusMessage = ({
}
return (
-
+
{ statusIcon ? : null }
{statusMessage}
diff --git a/test/functional/apps/management/_index_pattern_create_delete.js b/test/functional/apps/management/_index_pattern_create_delete.js
index 002936f060bbe..102f38d091b3a 100644
--- a/test/functional/apps/management/_index_pattern_create_delete.js
+++ b/test/functional/apps/management/_index_pattern_create_delete.js
@@ -24,7 +24,8 @@ export default function ({ getService, getPageObjects }) {
const browser = getService('browser');
const log = getService('log');
const retry = getService('retry');
- const PageObjects = getPageObjects(['settings', 'common']);
+ const testSubjects = getService('testSubjects');
+ const PageObjects = getPageObjects(['settings', 'common', 'header']);
describe('creating and deleting default index', function describeIndexTests() {
before(function () {
@@ -38,6 +39,28 @@ export default function ({ getService, getPageObjects }) {
});
});
+ describe('special character handling', () => {
+ it('should handle special charaters in template input', async () => {
+ await PageObjects.settings.clickOptionalAddNewButton();
+ await PageObjects.header.waitUntilLoadingHasFinished();
+ await PageObjects.settings.setIndexPatternField({
+ indexPatternName: '❤️',
+ expectWildcard: false
+ });
+ await PageObjects.header.waitUntilLoadingHasFinished();
+
+ await retry.try(async () => {
+ expect(await testSubjects.getVisibleText('createIndexPatternStatusMessage'))
+ .to.contain(`The index pattern you've entered doesn't match any indices`);
+ });
+ });
+
+ after(async () => {
+ await PageObjects.settings.navigateTo();
+ await PageObjects.settings.clickKibanaIndices();
+ });
+ });
+
describe('index pattern creation', function indexPatternCreation() {
let indexPatternId;
diff --git a/test/functional/page_objects/settings_page.js b/test/functional/page_objects/settings_page.js
index d6747f4586a38..ebd4bfd254b7f 100644
--- a/test/functional/page_objects/settings_page.js
+++ b/test/functional/page_objects/settings_page.js
@@ -276,7 +276,7 @@ export function SettingsPageProvider({ getService, getPageObjects }) {
await this.clickOptionalAddNewButton();
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.try(async () => {
- await this.setIndexPatternField(indexPatternName);
+ await this.setIndexPatternField({ indexPatternName });
});
await PageObjects.common.sleep(2000);
await (await this.getCreateIndexPatternGoToStep2Button()).click();
@@ -316,14 +316,14 @@ export function SettingsPageProvider({ getService, getPageObjects }) {
return indexPatternId;
}
- async setIndexPatternField(indexPatternName = 'logstash-') {
+ async setIndexPatternField({ indexPatternName = 'logstash-', expectWildcard = true } = {}) {
log.debug(`setIndexPatternField(${indexPatternName})`);
const field = await this.getIndexPatternField();
await field.clearValue();
await field.type(indexPatternName);
const currentName = await field.getAttribute('value');
log.debug(`setIndexPatternField set to ${currentName}`);
- expect(currentName).to.eql(`${indexPatternName}*`);
+ expect(currentName).to.eql(`${indexPatternName}${expectWildcard ? '*' : ''}`);
}
async getCreateIndexPatternGoToStep2Button() {
diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_get_affected_route.js b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_get_affected_route.js
index ed5b6b09db16b..2de097541db21 100644
--- a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_get_affected_route.js
+++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_get_affected_route.js
@@ -51,7 +51,7 @@ async function getAffectedIndices(
}
const indexParams = {
method: 'GET',
- path: `/${indexPatterns.join(',')}`,
+ path: `/${encodeURIComponent(indexPatterns.join(','))}`,
// we allow 404 in case there are no indices
ignore: [404]
};
diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.js b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.js
index ba6d42e720023..d4197b20abb76 100644
--- a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.js
+++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.js
@@ -34,7 +34,7 @@ async function updateIndexTemplate(callWithRequest, indexTemplatePatch) {
const params = {
method: 'PUT',
- path: `/_template/${indexTemplatePatch.templateName}`,
+ path: `/_template/${encodeURIComponent(indexTemplatePatch.templateName)}`,
ignore: [ 404 ],
body: template,
};
@@ -67,4 +67,4 @@ export function registerAddPolicyRoute(server) {
pre: [ licensePreRouting ]
}
});
-}
\ No newline at end of file
+}
diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_get_route.js b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_get_route.js
index ad24160fe798f..4b234571208dc 100644
--- a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_get_route.js
+++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_get_route.js
@@ -15,7 +15,7 @@ import { licensePreRoutingFactory } from'../../../lib/license_pre_routing_factor
async function fetchTemplate(callWithRequest, templateName) {
const params = {
method: 'GET',
- path: `/_template/${templateName}`,
+ path: `/_template/${encodeURIComponent(templateName)}`,
// we allow 404 incase the user shutdown security in-between the check and now
ignore: [ 404 ]
};
diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_freeze_route.js b/x-pack/plugins/index_management/server/routes/api/indices/register_freeze_route.js
index bc9d097d4bfd3..2c2c4a93703c4 100644
--- a/x-pack/plugins/index_management/server/routes/api/indices/register_freeze_route.js
+++ b/x-pack/plugins/index_management/server/routes/api/indices/register_freeze_route.js
@@ -15,7 +15,7 @@ function getIndexArrayFromPayload(payload) {
async function freezeIndices(callWithRequest, indices) {
const params = {
- path: `/${indices.join(',')}/_freeze`,
+ path: `/${encodeURIComponent(indices.join(','))}/_freeze`,
method: 'POST',
};
diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.js b/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.js
index b421e45f070ca..1068fb2903e4c 100644
--- a/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.js
+++ b/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.js
@@ -15,7 +15,7 @@ function getIndexArrayFromPayload(payload) {
async function unfreezeIndices(callWithRequest, indices) {
const params = {
- path: `/${indices.join(',')}/_unfreeze`,
+ path: `/${encodeURIComponent(indices.join(','))}/_unfreeze`,
method: 'POST',
};
From 15658b7db3fcb3a15dfb7ca322abcf17fc3f490e Mon Sep 17 00:00:00 2001
From: Andrew Cholakian
Date: Wed, 23 Jan 2019 20:27:01 -0800
Subject: [PATCH 23/29] [Uptime] Change add-data link to point to uptime app.
(#29200)
In 7.0 we're removing the heartbeat dashboard and pointing people at the new Uptime app instead.
---
.../tutorials/heartbeat_instructions.js | 8 ++---
.../server/tutorials/uptime_monitors/index.js | 36 +++++++++++--------
2 files changed, 25 insertions(+), 19 deletions(-)
diff --git a/src/legacy/core_plugins/kibana/common/tutorials/heartbeat_instructions.js b/src/legacy/core_plugins/kibana/common/tutorials/heartbeat_instructions.js
index d7bd9c4d46c29..d57fdea9d7f13 100644
--- a/src/legacy/core_plugins/kibana/common/tutorials/heartbeat_instructions.js
+++ b/src/legacy/core_plugins/kibana/common/tutorials/heartbeat_instructions.js
@@ -103,7 +103,7 @@ export const createHeartbeatInstructions = context => ({
defaultMessage: 'Start Heartbeat',
}),
textPre: i18n.translate('kbn.common.tutorials.heartbeatInstructions.start.osxTextPre', {
- defaultMessage: 'The `setup` command loads the Kibana dashboards. If the dashboards are already set up, omit this command.',
+ defaultMessage: 'The `setup` command loads the Kibana index pattern.',
}),
commands: [
'./heartbeat setup',
@@ -115,7 +115,7 @@ export const createHeartbeatInstructions = context => ({
defaultMessage: 'Start Heartbeat',
}),
textPre: i18n.translate('kbn.common.tutorials.heartbeatInstructions.start.debTextPre', {
- defaultMessage: 'The `setup` command loads the Kibana dashboards. If the dashboards are already set up, omit this command.',
+ defaultMessage: 'The `setup` command loads the Kibana index pattern.',
}),
commands: [
'sudo heartbeat setup',
@@ -127,7 +127,7 @@ export const createHeartbeatInstructions = context => ({
defaultMessage: 'Start Heartbeat',
}),
textPre: i18n.translate('kbn.common.tutorials.heartbeatInstructions.start.rpmTextPre', {
- defaultMessage: 'The `setup` command loads the Kibana dashboards. If the dashboards are already set up, omit this command.',
+ defaultMessage: 'The `setup` command loads the Kibana index pattern.',
}),
commands: [
'sudo heartbeat setup',
@@ -139,7 +139,7 @@ export const createHeartbeatInstructions = context => ({
defaultMessage: 'Start Heartbeat',
}),
textPre: i18n.translate('kbn.common.tutorials.heartbeatInstructions.start.windowsTextPre', {
- defaultMessage: 'The `setup` command loads the Kibana dashboards. If the dashboards are already set up, omit this command.',
+ defaultMessage: 'The `setup` command loads the Kibana index pattern.',
}),
commands: [
'.\\heartbeat.exe setup',
diff --git a/src/legacy/core_plugins/kibana/server/tutorials/uptime_monitors/index.js b/src/legacy/core_plugins/kibana/server/tutorials/uptime_monitors/index.js
index 504948a887703..47b0bd4f4d1e5 100644
--- a/src/legacy/core_plugins/kibana/server/tutorials/uptime_monitors/index.js
+++ b/src/legacy/core_plugins/kibana/server/tutorials/uptime_monitors/index.js
@@ -17,9 +17,13 @@
* under the License.
*/
-import { i18n } from '@kbn/i18n';
+import { i18n } from '@kbn/i18n';
import { TUTORIAL_CATEGORY } from '../../../common/tutorials/tutorial_category';
-import { onPremInstructions, cloudInstructions, onPremCloudInstructions } from '../../../common/tutorials/heartbeat_instructions';
+import {
+ onPremInstructions,
+ cloudInstructions,
+ onPremCloudInstructions,
+} from '../../../common/tutorials/heartbeat_instructions';
export function uptimeMonitorsSpecProvider(server, context) {
return {
@@ -32,7 +36,8 @@ export function uptimeMonitorsSpecProvider(server, context) {
defaultMessage: 'Monitor services for their availability',
}),
longDescription: i18n.translate('kbn.server.tutorials.uptimeMonitors.longDescription', {
- defaultMessage: 'Monitor services for their availability with active probing. \
+ defaultMessage:
+ 'Monitor services for their availability with active probing. \
Given a list of URLs, Heartbeat asks the simple question: Are you alive? \
[Learn more]({learnMoreLink}).',
values: {
@@ -41,23 +46,24 @@ export function uptimeMonitorsSpecProvider(server, context) {
}),
euiIconType: 'heartbeatApp',
artifacts: {
- dashboards: [
- {
- id: 'f3e771c0-eb19-11e6-be20-559646f8b9ba',
- linkLabel: i18n.translate('kbn.server.tutorials.uptimeMonitors.artifacts.dashboards.linkLabel', {
- defaultMessage: 'Heartbeat dashboard',
- }),
- isOverview: true
- }
- ],
+ dashboards: [],
+ application: {
+ path: '/app/uptime',
+ label: i18n.translate(
+ 'kbn.server.tutorials.uptimeMonitors.artifacts.dashboards.linkLabel',
+ {
+ defaultMessage: 'Uptime App',
+ }
+ ),
+ },
exportedFields: {
- documentationUrl: '{config.docs.beats.heartbeat}/exported-fields.html'
- }
+ documentationUrl: '{config.docs.beats.heartbeat}/exported-fields.html',
+ },
},
completionTimeMinutes: 10,
previewImagePath: '/plugins/kibana/home/tutorial_resources/uptime_monitors/screenshot.png',
onPrem: onPremInstructions(null, null, null, context),
elasticCloud: cloudInstructions(),
- onPremElasticCloud: onPremCloudInstructions()
+ onPremElasticCloud: onPremCloudInstructions(),
};
}
From 735cc82edd267dab9dcdaff739875ec54cd3c977 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Thu, 24 Jan 2019 09:07:54 +0100
Subject: [PATCH 24/29] [ML] explorer controller refactor (#28750)
Refactores the application logic of Anomaly Explorer to reduce relying on angularjs.
---
.../explorer/__tests__/explorer_controller.js | 5 +-
x-pack/plugins/ml/public/explorer/explorer.js | 877 +++++++++++-
.../explorer_charts_container_service.js | 2 +-
.../explorer_charts_container_service.test.js | 2 +-
.../ml/public/explorer/explorer_constants.js | 21 +
.../ml/public/explorer/explorer_controller.js | 1231 ++---------------
.../explorer/explorer_dashboard_service.js | 4 +-
.../explorer_react_wrapper_directive.js | 69 +-
.../ml/public/explorer/explorer_swimlane.js | 49 +-
.../public/explorer/explorer_swimlane.test.js | 18 +-
.../ml/public/explorer/explorer_utils.js | 532 +++++++
.../{explorer_charts => }/legacy_utils.js | 14 +
12 files changed, 1597 insertions(+), 1227 deletions(-)
create mode 100644 x-pack/plugins/ml/public/explorer/explorer_utils.js
rename x-pack/plugins/ml/public/explorer/{explorer_charts => }/legacy_utils.js (50%)
diff --git a/x-pack/plugins/ml/public/explorer/__tests__/explorer_controller.js b/x-pack/plugins/ml/public/explorer/__tests__/explorer_controller.js
index f220b06c6f4ce..200c26a4694f6 100644
--- a/x-pack/plugins/ml/public/explorer/__tests__/explorer_controller.js
+++ b/x-pack/plugins/ml/public/explorer/__tests__/explorer_controller.js
@@ -19,9 +19,8 @@ describe('ML - Explorer Controller', () => {
const scope = $rootScope.$new();
$controller('MlExplorerController', { $scope: scope });
- expect(Array.isArray(scope.annotationsData)).to.be(true);
- expect(Array.isArray(scope.anomalyChartRecords)).to.be(true);
- expect(scope.loading).to.be(true);
+ expect(Array.isArray(scope.jobs)).to.be(true);
+ expect(Array.isArray(scope.queryFilters)).to.be(true);
});
});
});
diff --git a/x-pack/plugins/ml/public/explorer/explorer.js b/x-pack/plugins/ml/public/explorer/explorer.js
index d1d2f099ae870..e598d41e2f1b7 100644
--- a/x-pack/plugins/ml/public/explorer/explorer.js
+++ b/x-pack/plugins/ml/public/explorer/explorer.js
@@ -8,9 +8,11 @@
* React component for rendering Explorer dashboard swimlanes.
*/
+import _ from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
+import DragSelect from 'dragselect';
import {
EuiFlexGroup,
@@ -22,18 +24,54 @@ import {
} from '@elastic/eui';
import { AnnotationsTable } from '../components/annotations_table';
-import { CheckboxShowCharts } from '../components/controls/checkbox_showcharts/checkbox_showcharts';
import {
ExplorerNoInfluencersFound,
ExplorerNoJobsFound,
ExplorerNoResultsFound,
} from './components';
import { ExplorerSwimlane } from './explorer_swimlane';
+import { formatHumanReadableDateTime } from '../util/date_utils';
+import { getBoundsRoundedToInterval } from 'plugins/ml/util/ml_time_buckets';
import { InfluencersList } from '../components/influencers_list';
+import { mlExplorerDashboardService } from './explorer_dashboard_service';
+import { mlResultsService } from 'plugins/ml/services/results_service';
import { LoadingIndicator } from '../components/loading_indicator/loading_indicator';
-import { SelectInterval } from '../components/controls/select_interval/select_interval';
-import { SelectLimit } from './select_limit/select_limit';
-import { SelectSeverity } from '../components/controls/select_severity/select_severity';
+import { CheckboxShowCharts, mlCheckboxShowChartsService } from '../components/controls/checkbox_showcharts/checkbox_showcharts';
+import { SelectInterval, mlSelectIntervalService } from '../components/controls/select_interval/select_interval';
+import { SelectLimit, mlSelectLimitService } from './select_limit/select_limit';
+import { SelectSeverity, mlSelectSeverityService } from '../components/controls/select_severity/select_severity';
+
+import {
+ getClearedSelectedAnomaliesState,
+ getDefaultViewBySwimlaneData,
+ getFilteredTopInfluencers,
+ getSelectionInfluencers,
+ getSelectionTimeRange,
+ getViewBySwimlaneOptions,
+ loadAnnotationsTableData,
+ loadAnomaliesTableData,
+ loadDataForCharts,
+ loadTopInfluencers,
+ processOverallResults,
+ processViewByResults,
+ selectedJobsHaveInfluencers,
+} from './explorer_utils';
+import {
+ explorerChartsContainerServiceFactory,
+ getDefaultChartsData
+} from './explorer_charts/explorer_charts_container_service';
+import {
+ getSwimlaneContainerWidth
+} from './legacy_utils';
+
+import {
+ DRAG_SELECT_ACTION,
+ APP_STATE_ACTION,
+ EXPLORER_ACTION,
+ SWIMLANE_DEFAULT_LIMIT,
+ SWIMLANE_TYPE,
+ VIEW_BY_JOB_LABEL,
+} from './explorer_constants';
// Explorer Charts
import { ExplorerChartsContainer } from './explorer_charts/explorer_charts_container';
@@ -42,6 +80,28 @@ import { ExplorerChartsContainer } from './explorer_charts/explorer_charts_conta
import { AnomaliesTable } from '../components/anomalies_table/anomalies_table';
import { timefilter } from 'ui/timefilter';
+function getExplorerDefaultState() {
+ return {
+ annotationsData: [],
+ anomalyChartRecords: [],
+ chartsData: getDefaultChartsData(),
+ hasResults: false,
+ influencers: {},
+ loading: true,
+ noInfluencersConfigured: true,
+ noJobsFound: true,
+ overallSwimlaneData: [],
+ selectedCells: null,
+ selectedJobs: null,
+ swimlaneViewByFieldName: undefined,
+ tableData: {},
+ viewByLoadedForTimeFormatted: null,
+ viewBySwimlaneData: getDefaultViewBySwimlaneData(),
+ viewBySwimlaneDataLoading: false,
+ viewBySwimlaneOptions: [],
+ };
+}
+
function mapSwimlaneOptionsToEuiOptions(options) {
return options.map(option => ({
value: option,
@@ -52,48 +112,775 @@ function mapSwimlaneOptionsToEuiOptions(options) {
export const Explorer = injectI18n(
class Explorer extends React.Component {
static propTypes = {
- annotationsData: PropTypes.array,
- anomalyChartRecords: PropTypes.array,
- hasResults: PropTypes.bool,
- influencers: PropTypes.object,
- jobs: PropTypes.array,
- loading: PropTypes.bool,
- noInfluencersConfigured: PropTypes.bool,
- setSwimlaneSelectActive: PropTypes.func,
- setSwimlaneViewBy: PropTypes.func,
- showViewBySwimlane: PropTypes.bool,
- swimlaneOverall: PropTypes.object,
- swimlaneViewByFieldName: PropTypes.string,
- tableData: PropTypes.object,
- viewByLoadedForTimeFormatted: PropTypes.any,
- viewBySwimlaneOptions: PropTypes.array,
+ appStateHandler: PropTypes.func.isRequired,
+ dateFormatTz: PropTypes.string.isRequired,
+ mlJobSelectService: PropTypes.object.isRequired,
+ MlTimeBuckets: PropTypes.func.isRequired,
+ };
+
+ state = getExplorerDefaultState();
+
+ // helper to avoid calling `setState()` in the listener for chart updates.
+ _isMounted = false;
+
+ // make sure dragSelect is only available if the mouse pointer is actually over a swimlane
+ disableDragSelectOnMouseLeave = true;
+ // skip listening to clicks on swimlanes while they are loading to avoid race conditions
+ skipCellClicks = true;
+
+ updateCharts = explorerChartsContainerServiceFactory((data) => {
+ if (this._isMounted) {
+ this.setState({
+ chartsData: {
+ ...getDefaultChartsData(),
+ chartsPerRow: data.chartsPerRow,
+ seriesToPlot: data.seriesToPlot,
+ // convert truthy/falsy value to Boolean
+ tooManyBuckets: !!data.tooManyBuckets,
+ }
+ });
+ }
+ });
+
+ ALLOW_CELL_RANGE_SELECTION = mlExplorerDashboardService.allowCellRangeSelection;
+
+ dragSelect = new DragSelect({
+ selectables: document.getElementsByClassName('sl-cell'),
+ callback(elements) {
+ if (elements.length > 1 && !this.ALLOW_CELL_RANGE_SELECTION) {
+ elements = [elements[0]];
+ }
+
+ if (elements.length > 0) {
+ mlExplorerDashboardService.dragSelect.changed({
+ action: DRAG_SELECT_ACTION.NEW_SELECTION,
+ elements
+ });
+ }
+
+ this.disableDragSelectOnMouseLeave = true;
+ },
+ onDragStart() {
+ if (this.ALLOW_CELL_RANGE_SELECTION) {
+ mlExplorerDashboardService.dragSelect.changed({
+ action: DRAG_SELECT_ACTION.DRAG_START
+ });
+ this.disableDragSelectOnMouseLeave = false;
+ }
+ },
+ onElementSelect() {
+ if (this.ALLOW_CELL_RANGE_SELECTION) {
+ mlExplorerDashboardService.dragSelect.changed({
+ action: DRAG_SELECT_ACTION.ELEMENT_SELECT
+ });
+ }
+ }
+ });
+
+ dashboardListener = ((action, payload = {}) => {
+ // Listen to the initial loading of jobs
+ if (action === EXPLORER_ACTION.INITIALIZE) {
+ const { noJobsFound, selectedCells, selectedJobs, swimlaneViewByFieldName } = payload;
+ let currentSelectedCells = this.state.selectedCells;
+ let currentSwimlaneViewByFieldName = this.state.swimlaneViewByFieldName;
+
+ if (selectedCells !== undefined && currentSelectedCells === null) {
+ currentSelectedCells = selectedCells;
+ currentSwimlaneViewByFieldName = swimlaneViewByFieldName;
+ }
+
+ const stateUpdate = {
+ noInfluencersConfigured: !selectedJobsHaveInfluencers(selectedJobs),
+ noJobsFound,
+ selectedCells: currentSelectedCells,
+ selectedJobs,
+ swimlaneViewByFieldName: currentSwimlaneViewByFieldName
+ };
+
+ this.updateExplorer(stateUpdate, true);
+ }
+
+ // Listen for changes to job selection.
+ if (action === EXPLORER_ACTION.JOB_SELECTION_CHANGE) {
+ const { selectedJobs } = payload;
+ const stateUpdate = {
+ noInfluencersConfigured: !selectedJobsHaveInfluencers(selectedJobs),
+ selectedJobs,
+ };
+
+ this.props.appStateHandler(APP_STATE_ACTION.CLEAR_SELECTION);
+ Object.assign(stateUpdate, getClearedSelectedAnomaliesState());
+
+ if (selectedJobs.length > 1) {
+ this.props.appStateHandler(
+ APP_STATE_ACTION.SAVE_SWIMLANE_VIEW_BY_FIELD_NAME,
+ { swimlaneViewByFieldName: VIEW_BY_JOB_LABEL },
+ );
+ stateUpdate.swimlaneViewByFieldName = VIEW_BY_JOB_LABEL;
+ // enforce a state update for swimlaneViewByFieldName
+ this.setState({ swimlaneViewByFieldName: VIEW_BY_JOB_LABEL }, () => {
+ this.updateExplorer(stateUpdate, true);
+ });
+ return;
+ }
+
+ this.updateExplorer(stateUpdate, true);
+ }
+
+ // RELOAD reloads full Anomaly Explorer and clears the selection.
+ if (action === EXPLORER_ACTION.RELOAD) {
+ this.props.appStateHandler(APP_STATE_ACTION.CLEAR_SELECTION);
+ this.updateExplorer({ ...payload, ...getClearedSelectedAnomaliesState() }, true);
+ }
+
+ // REDRAW reloads Anomaly Explorer and tries to retain the selection.
+ if (action === EXPLORER_ACTION.REDRAW) {
+ this.updateExplorer({}, false);
+ }
+ });
+
+ checkboxShowChartsListener = () => {
+ const showCharts = mlCheckboxShowChartsService.state.get('showCharts');
+ const { selectedCells, selectedJobs } = this.state;
+
+ const timerange = getSelectionTimeRange(
+ selectedCells,
+ this.getSwimlaneBucketInterval(selectedJobs).asSeconds()
+ );
+
+ if (showCharts && selectedCells !== null) {
+ this.updateCharts(
+ this.state.anomalyChartRecords, timerange.earliestMs, timerange.latestMs
+ );
+ } else {
+ this.updateCharts(
+ [], timerange.earliestMs, timerange.latestMs
+ );
+ }
+ };
+
+ anomalyChartsSeverityListener = () => {
+ const showCharts = mlCheckboxShowChartsService.state.get('showCharts');
+ const { anomalyChartRecords, selectedCells, selectedJobs } = this.state;
+ if (showCharts && selectedCells !== null) {
+ const timerange = getSelectionTimeRange(
+ selectedCells,
+ this.getSwimlaneBucketInterval(selectedJobs).asSeconds()
+ );
+ this.updateCharts(
+ anomalyChartRecords, timerange.earliestMs, timerange.latestMs
+ );
+ }
};
- viewByChangeHandler = e => this.props.setSwimlaneViewBy(e.target.value);
+ tableControlsListener = async () => {
+ const { dateFormatTz } = this.props;
+ const { selectedCells, swimlaneViewByFieldName, selectedJobs } = this.state;
+ this.setState({
+ tableData: await loadAnomaliesTableData(
+ selectedCells,
+ selectedJobs,
+ dateFormatTz,
+ this.getSwimlaneBucketInterval(selectedJobs).asSeconds(),
+ swimlaneViewByFieldName
+ )
+ });
+ };
+
+ swimlaneLimitListener = () => {
+ this.props.appStateHandler(APP_STATE_ACTION.CLEAR_SELECTION);
+ this.updateExplorer(getClearedSelectedAnomaliesState(), false);
+ };
+
+ // Listens to render updates of the swimlanes to update dragSelect
+ swimlaneRenderDoneListener = () => {
+ this.dragSelect.clearSelection();
+ this.dragSelect.setSelectables(document.getElementsByClassName('sl-cell'));
+ };
+
+ componentDidMount() {
+ this._isMounted = true;
+ mlExplorerDashboardService.explorer.watch(this.dashboardListener);
+ mlCheckboxShowChartsService.state.watch(this.checkboxShowChartsListener);
+ mlSelectLimitService.state.watch(this.swimlaneLimitListener);
+ mlSelectSeverityService.state.watch(this.anomalyChartsSeverityListener);
+ mlSelectIntervalService.state.watch(this.tableControlsListener);
+ mlSelectSeverityService.state.watch(this.tableControlsListener);
+ }
+
+ componentWillUnmount() {
+ this._isMounted = false;
+ mlExplorerDashboardService.explorer.unwatch(this.dashboardListener);
+ mlCheckboxShowChartsService.state.unwatch(this.checkboxShowChartsListener);
+ mlSelectLimitService.state.unwatch(this.swimlaneLimitListener);
+ mlSelectSeverityService.state.unwatch(this.anomalyChartsSeverityListener);
+ mlSelectIntervalService.state.unwatch(this.tableControlsListener);
+ mlSelectSeverityService.state.unwatch(this.tableControlsListener);
+ }
+
+ getSwimlaneBucketInterval(selectedJobs) {
+ const { MlTimeBuckets } = this.props;
+
+ const swimlaneWidth = getSwimlaneContainerWidth(this.state.noInfluencersConfigured);
+ // Bucketing interval should be the maximum of the chart related interval (i.e. time range related)
+ // and the max bucket span for the jobs shown in the chart.
+ const bounds = timefilter.getActiveBounds();
+ const buckets = new MlTimeBuckets();
+ buckets.setInterval('auto');
+ buckets.setBounds(bounds);
+
+ const intervalSeconds = buckets.getInterval().asSeconds();
+
+ // if the swimlane cell widths are too small they will not be visible
+ // calculate how many buckets will be drawn before the swimlanes are actually rendered
+ // and increase the interval to widen the cells if they're going to be smaller than 8px
+ // this has to be done at this stage so all searches use the same interval
+ const timerangeSeconds = (bounds.max.valueOf() - bounds.min.valueOf()) / 1000;
+ const numBuckets = parseInt(timerangeSeconds / intervalSeconds);
+ const cellWidth = Math.floor(swimlaneWidth / numBuckets * 100) / 100;
+
+ // if the cell width is going to be less than 8px, double the interval
+ if (cellWidth < 8) {
+ buckets.setInterval((intervalSeconds * 2) + 's');
+ }
+
+ const maxBucketSpanSeconds = selectedJobs.reduce((memo, job) => Math.max(memo, job.bucketSpanSeconds), 0);
+ if (maxBucketSpanSeconds > intervalSeconds) {
+ buckets.setInterval(maxBucketSpanSeconds + 's');
+ buckets.setBounds(bounds);
+ }
+
+ return buckets.getInterval();
+ }
+
+ loadOverallDataPreviousArgs = null;
+ loadOverallDataPreviousData = null;
+ loadOverallData(selectedJobs, interval, showLoadingIndicator = true) {
+ return new Promise((resolve) => {
+ // Loads the overall data components i.e. the overall swimlane and influencers list.
+ if (selectedJobs === null) {
+ resolve({
+ loading: false,
+ hasResuts: false
+ });
+ return;
+ }
+
+ // check if we can just return existing cached data
+ const compareArgs = {
+ selectedJobs,
+ intervalAsSeconds: interval.asSeconds()
+ };
+
+ if (_.isEqual(compareArgs, this.loadOverallDataPreviousArgs)) {
+ const overallSwimlaneData = this.loadOverallDataPreviousData;
+ const hasResults = (overallSwimlaneData.points && overallSwimlaneData.points.length > 0);
+ resolve({
+ hasResults,
+ loading: false,
+ overallSwimlaneData,
+ });
+ return;
+ }
+
+ this.loadOverallDataPreviousArgs = compareArgs;
+
+ if (showLoadingIndicator) {
+ this.setState({ hasResults: false, loading: true });
+ }
+
+ // Ensure the search bounds align to the bucketing interval used in the swimlane so
+ // that the first and last buckets are complete.
+ const bounds = timefilter.getActiveBounds();
+ const searchBounds = getBoundsRoundedToInterval(
+ bounds,
+ interval,
+ false
+ );
+ const selectedJobIds = selectedJobs.map(d => d.id);
+
+ // Load the overall bucket scores by time.
+ // Pass the interval in seconds as the swimlane relies on a fixed number of seconds between buckets
+ // which wouldn't be the case if e.g. '1M' was used.
+ // Pass 'true' when obtaining bucket bounds due to the way the overall_buckets endpoint works
+ // to ensure the search is inclusive of end time.
+ const overallBucketsBounds = getBoundsRoundedToInterval(
+ bounds,
+ interval,
+ true
+ );
+ mlResultsService.getOverallBucketScores(
+ selectedJobIds,
+ // Note there is an optimization for when top_n == 1.
+ // If top_n > 1, we should test what happens when the request takes long
+ // and refactor the loading calls, if necessary, to avoid delays in loading other components.
+ 1,
+ overallBucketsBounds.min.valueOf(),
+ overallBucketsBounds.max.valueOf(),
+ interval.asSeconds() + 's'
+ ).then((resp) => {
+ this.skipCellClicks = false;
+ const overallSwimlaneData = processOverallResults(
+ resp.results,
+ searchBounds,
+ interval.asSeconds(),
+ );
+ this.loadOverallDataPreviousData = overallSwimlaneData;
+
+ console.log('Explorer overall swimlane data set:', overallSwimlaneData);
+ const hasResults = (overallSwimlaneData.points && overallSwimlaneData.points.length > 0);
+ resolve({
+ hasResults,
+ loading: false,
+ overallSwimlaneData,
+ });
+ });
+ });
+ }
+
+ loadViewBySwimlanePreviousArgs = null;
+ loadViewBySwimlanePreviousData = null;
+ loadViewBySwimlane(fieldValues, overallSwimlaneData, selectedJobs, swimlaneViewByFieldName) {
+ const limit = mlSelectLimitService.state.get('limit');
+ const swimlaneLimit = (limit === undefined) ? SWIMLANE_DEFAULT_LIMIT : limit.val;
+
+ const compareArgs = {
+ fieldValues,
+ overallSwimlaneData,
+ selectedJobs,
+ swimlaneLimit,
+ swimlaneViewByFieldName,
+ interval: this.getSwimlaneBucketInterval(selectedJobs).asSeconds()
+ };
+
+ return new Promise((resolve) => {
+ this.skipCellClicks = true;
+
+ // check if we can just return existing cached data
+ if (_.isEqual(compareArgs, this.loadViewBySwimlanePreviousArgs)) {
+ this.skipCellClicks = false;
+
+ resolve({
+ viewBySwimlaneData: this.loadViewBySwimlanePreviousData,
+ viewBySwimlaneDataLoading: false
+ });
+ return;
+ }
+
+ this.setState({
+ viewBySwimlaneData: getDefaultViewBySwimlaneData(),
+ viewBySwimlaneDataLoading: true
+ });
+
+ const finish = (resp) => {
+ this.skipCellClicks = false;
+ if (resp !== undefined) {
+ const viewBySwimlaneData = processViewByResults(
+ resp.results,
+ fieldValues,
+ overallSwimlaneData,
+ swimlaneViewByFieldName,
+ this.getSwimlaneBucketInterval(selectedJobs).asSeconds(),
+ );
+ this.loadViewBySwimlanePreviousArgs = compareArgs;
+ this.loadViewBySwimlanePreviousData = viewBySwimlaneData;
+ console.log('Explorer view by swimlane data set:', viewBySwimlaneData);
+
+ resolve({
+ viewBySwimlaneData,
+ viewBySwimlaneDataLoading: false
+ });
+ } else {
+ resolve({ viewBySwimlaneDataLoading: false });
+ }
+ };
- onSwimlaneEnterHandler = () => this.props.setSwimlaneSelectActive(true);
- onSwimlaneLeaveHandler = () => this.props.setSwimlaneSelectActive(false);
+ if (
+ selectedJobs === undefined ||
+ swimlaneViewByFieldName === undefined
+ ) {
+ finish();
+ return;
+ } else {
+ // Ensure the search bounds align to the bucketing interval used in the swimlane so
+ // that the first and last buckets are complete.
+ const bounds = timefilter.getActiveBounds();
+ const searchBounds = getBoundsRoundedToInterval(
+ bounds,
+ this.getSwimlaneBucketInterval(selectedJobs),
+ false,
+ );
+ const selectedJobIds = selectedJobs.map(d => d.id);
+
+ // load scores by influencer/jobId value and time.
+ // Pass the interval in seconds as the swimlane relies on a fixed number of seconds between buckets
+ // which wouldn't be the case if e.g. '1M' was used.
+ const interval = `${this.getSwimlaneBucketInterval(selectedJobs).asSeconds()}s`;
+ if (swimlaneViewByFieldName !== VIEW_BY_JOB_LABEL) {
+ mlResultsService.getInfluencerValueMaxScoreByTime(
+ selectedJobIds,
+ swimlaneViewByFieldName,
+ fieldValues,
+ searchBounds.min.valueOf(),
+ searchBounds.max.valueOf(),
+ interval,
+ swimlaneLimit
+ ).then(finish);
+ } else {
+ const jobIds = (fieldValues !== undefined && fieldValues.length > 0) ? fieldValues : selectedJobIds;
+ mlResultsService.getScoresByBucket(
+ jobIds,
+ searchBounds.min.valueOf(),
+ searchBounds.max.valueOf(),
+ interval,
+ swimlaneLimit
+ ).then(finish);
+ }
+ }
+ });
+ }
+
+ topFieldsPreviousArgs = null;
+ topFieldsPreviousData = null;
+ loadViewByTopFieldValuesForSelectedTime(earliestMs, latestMs, selectedJobs, swimlaneViewByFieldName) {
+ const selectedJobIds = selectedJobs.map(d => d.id);
+ const limit = mlSelectLimitService.state.get('limit');
+ const swimlaneLimit = (limit === undefined) ? SWIMLANE_DEFAULT_LIMIT : limit.val;
+
+ const compareArgs = {
+ earliestMs, latestMs, selectedJobIds, swimlaneLimit, swimlaneViewByFieldName,
+ interval: this.getSwimlaneBucketInterval(selectedJobs).asSeconds()
+ };
+
+ // Find the top field values for the selected time, and then load the 'view by'
+ // swimlane over the full time range for those specific field values.
+ return new Promise((resolve) => {
+ if (_.isEqual(compareArgs, this.topFieldsPreviousArgs)) {
+ resolve(this.topFieldsPreviousData);
+ return;
+ }
+ this.topFieldsPreviousArgs = compareArgs;
+
+ if (swimlaneViewByFieldName !== VIEW_BY_JOB_LABEL) {
+ mlResultsService.getTopInfluencers(
+ selectedJobIds,
+ earliestMs,
+ latestMs,
+ swimlaneLimit
+ ).then((resp) => {
+ if (resp.influencers[swimlaneViewByFieldName] === undefined) {
+ this.topFieldsPreviousData = [];
+ resolve([]);
+ }
+
+ const topFieldValues = [];
+ const topInfluencers = resp.influencers[swimlaneViewByFieldName];
+ topInfluencers.forEach((influencerData) => {
+ if (influencerData.maxAnomalyScore > 0) {
+ topFieldValues.push(influencerData.influencerFieldValue);
+ }
+ });
+ this.topFieldsPreviousData = topFieldValues;
+ resolve(topFieldValues);
+ });
+ } else {
+ mlResultsService.getScoresByBucket(
+ selectedJobIds,
+ earliestMs,
+ latestMs,
+ this.getSwimlaneBucketInterval(selectedJobs).asSeconds() + 's',
+ swimlaneLimit
+ ).then((resp) => {
+ const topFieldValues = Object.keys(resp.results);
+ this.topFieldsPreviousData = topFieldValues;
+ resolve(topFieldValues);
+ });
+ }
+ });
+ }
+
+ anomaliesTablePreviousArgs = null;
+ anomaliesTablePreviousData = null;
+ annotationsTablePreviousArgs = null;
+ annotationsTablePreviousData = null;
+ async updateExplorer(stateUpdate, showOverallLoadingIndicator = true) {
+ const {
+ noInfluencersConfigured,
+ noJobsFound,
+ selectedCells,
+ selectedJobs,
+ } = {
+ ...this.state,
+ ...stateUpdate
+ };
+
+ this.skipCellClicks = false;
+
+ if (noJobsFound) {
+ this.setState(stateUpdate);
+ return;
+ }
+
+ if (this.swimlaneCellClickQueue.length > 0) {
+ this.setState(stateUpdate);
+
+ const latestSelectedCells = this.swimlaneCellClickQueue.pop();
+ this.swimlaneCellClickQueue.length = 0;
+ this.swimlaneCellClick(latestSelectedCells);
+ return;
+ }
+
+ const { dateFormatTz } = this.props;
+
+ const jobIds = (selectedCells !== null && selectedCells.viewByFieldName === VIEW_BY_JOB_LABEL)
+ ? selectedCells.lanes
+ : selectedJobs.map(d => d.id);
+
+ const timerange = getSelectionTimeRange(
+ selectedCells,
+ this.getSwimlaneBucketInterval(selectedJobs).asSeconds()
+ );
+
+ // Load the overall data - if the FieldFormats failed to populate
+ // the default formatting will be used for metric values.
+ Object.assign(
+ stateUpdate,
+ await this.loadOverallData(
+ selectedJobs,
+ this.getSwimlaneBucketInterval(selectedJobs),
+ showOverallLoadingIndicator,
+ )
+ );
+
+ const { overallSwimlaneData } = stateUpdate;
+
+ const annotationsTableCompareArgs = {
+ selectedCells,
+ selectedJobs,
+ interval: this.getSwimlaneBucketInterval(selectedJobs).asSeconds()
+ };
+
+ if (_.isEqual(annotationsTableCompareArgs, this.annotationsTablePreviousArgs)) {
+ stateUpdate.annotationsData = this.annotationsTablePreviousData;
+ } else {
+ this.annotationsTablePreviousArgs = annotationsTableCompareArgs;
+ stateUpdate.annotationsData = this.annotationsTablePreviousData = await loadAnnotationsTableData(
+ selectedCells,
+ selectedJobs,
+ this.getSwimlaneBucketInterval(selectedJobs).asSeconds()
+ );
+ }
+
+ const viewBySwimlaneOptions = getViewBySwimlaneOptions(selectedJobs, this.state.swimlaneViewByFieldName);
+ Object.assign(stateUpdate, viewBySwimlaneOptions);
+ if (selectedCells !== null && selectedCells.showTopFieldValues === true) {
+ // this.setState({ viewBySwimlaneData: getDefaultViewBySwimlaneData(), viewBySwimlaneDataLoading: true });
+ // Click is in one of the cells in the Overall swimlane - reload the 'view by' swimlane
+ // to show the top 'view by' values for the selected time.
+ const topFieldValues = await this.loadViewByTopFieldValuesForSelectedTime(
+ timerange.earliestMs,
+ timerange.latestMs,
+ selectedJobs,
+ viewBySwimlaneOptions.swimlaneViewByFieldName
+ );
+ Object.assign(
+ stateUpdate,
+ await this.loadViewBySwimlane(
+ topFieldValues,
+ overallSwimlaneData,
+ selectedJobs,
+ viewBySwimlaneOptions.swimlaneViewByFieldName
+ ),
+ { viewByLoadedForTimeFormatted: formatHumanReadableDateTime(timerange.earliestMs) }
+ );
+ } else {
+ Object.assign(
+ stateUpdate,
+ viewBySwimlaneOptions,
+ await this.loadViewBySwimlane(
+ [],
+ overallSwimlaneData,
+ selectedJobs,
+ viewBySwimlaneOptions.swimlaneViewByFieldName
+ ),
+ );
+ }
+
+ const { viewBySwimlaneData } = stateUpdate;
+
+ // do a sanity check against selectedCells. It can happen that a previously
+ // selected lane loaded via URL/AppState is not available anymore.
+ let clearSelection = false;
+ if (
+ selectedCells !== null &&
+ selectedCells.type === SWIMLANE_TYPE.VIEW_BY
+ ) {
+ clearSelection = !selectedCells.lanes.some((lane) => {
+ return viewBySwimlaneData.points.some((point) => {
+ return (
+ point.laneLabel === lane &&
+ point.time === selectedCells.times[0]
+ );
+ });
+ });
+ }
+
+ if (clearSelection === true) {
+ this.props.appStateHandler(APP_STATE_ACTION.CLEAR_SELECTION);
+ Object.assign(stateUpdate, getClearedSelectedAnomaliesState());
+ }
+
+ const selectionInfluencers = getSelectionInfluencers(selectedCells, viewBySwimlaneOptions.swimlaneViewByFieldName);
+
+ if (selectionInfluencers.length === 0) {
+ stateUpdate.influencers = await loadTopInfluencers(jobIds, timerange.earliestMs, timerange.latestMs, noInfluencersConfigured);
+ }
+
+ const updatedAnomalyChartRecords = await loadDataForCharts(
+ jobIds, timerange.earliestMs, timerange.latestMs, selectionInfluencers, selectedCells
+ );
+
+ if (selectionInfluencers.length > 0 && updatedAnomalyChartRecords !== undefined) {
+ stateUpdate.influencers = await getFilteredTopInfluencers(
+ jobIds,
+ timerange.earliestMs,
+ timerange.latestMs,
+ updatedAnomalyChartRecords,
+ selectionInfluencers,
+ noInfluencersConfigured,
+ );
+ }
+
+ stateUpdate.anomalyChartRecords = updatedAnomalyChartRecords || [];
+
+ this.setState(stateUpdate);
+
+ if (mlCheckboxShowChartsService.state.get('showCharts') && selectedCells !== null) {
+ this.updateCharts(
+ stateUpdate.anomalyChartRecords, timerange.earliestMs, timerange.latestMs
+ );
+ } else {
+ this.updateCharts(
+ [], timerange.earliestMs, timerange.latestMs
+ );
+ }
+
+ const anomaliesTableCompareArgs = {
+ selectedCells,
+ selectedJobs,
+ dateFormatTz,
+ interval: this.getSwimlaneBucketInterval(selectedJobs).asSeconds(),
+ swimlaneViewByFieldName: viewBySwimlaneOptions.swimlaneViewByFieldName,
+ };
+
+ if (_.isEqual(anomaliesTableCompareArgs, this.anomaliesTablePreviousArgs)) {
+ this.setState(this.anomaliesTablePreviousData);
+ } else {
+ this.anomaliesTablePreviousArgs = anomaliesTableCompareArgs;
+ const tableData = this.anomaliesTablePreviousData = await loadAnomaliesTableData(
+ selectedCells,
+ selectedJobs,
+ dateFormatTz,
+ this.getSwimlaneBucketInterval(selectedJobs).asSeconds(),
+ viewBySwimlaneOptions.swimlaneViewByFieldName
+ );
+ this.setState({ tableData });
+ }
+ }
+
+ viewByChangeHandler = e => this.setSwimlaneViewBy(e.target.value);
+ setSwimlaneViewBy = (swimlaneViewByFieldName) => {
+ this.props.appStateHandler(APP_STATE_ACTION.CLEAR_SELECTION);
+ this.props.appStateHandler(APP_STATE_ACTION.SAVE_SWIMLANE_VIEW_BY_FIELD_NAME, { swimlaneViewByFieldName });
+ this.setState({ swimlaneViewByFieldName }, () => {
+ this.updateExplorer({
+ swimlaneViewByFieldName,
+ ...getClearedSelectedAnomaliesState(),
+ }, false);
+ });
+ };
+
+ onSwimlaneEnterHandler = () => this.setSwimlaneSelectActive(true);
+ onSwimlaneLeaveHandler = () => this.setSwimlaneSelectActive(false);
+ setSwimlaneSelectActive = (active) => {
+ if (!active && this.disableDragSelectOnMouseLeave) {
+ this.dragSelect.clearSelection();
+ this.dragSelect.stop();
+ return;
+ }
+ this.dragSelect.start();
+ };
+
+ // This queue tracks click events while the swimlanes are loading.
+ // To avoid race conditions we keep the click events selectedCells in this queue
+ // and trigger another event only after the current loading is done.
+ // The queue is necessary since a click in the overall swimlane triggers
+ // an update of the viewby swimlanes. If we'd just ignored click events
+ // during the loading, we could miss programmatically triggered events like
+ // those coming via AppState when a selection is part of the URL.
+ swimlaneCellClickQueue = [];
+
+ // Listener for click events in the swimlane to load corresponding anomaly data.
+ swimlaneCellClick = (swimlaneSelectedCells) => {
+ if (this.skipCellClicks === true) {
+ this.swimlaneCellClickQueue.push(swimlaneSelectedCells);
+ return;
+ }
+
+ // If selectedCells is an empty object we clear any existing selection,
+ // otherwise we save the new selection in AppState and update the Explorer.
+ if (Object.keys(swimlaneSelectedCells).length === 0) {
+ this.props.appStateHandler(APP_STATE_ACTION.CLEAR_SELECTION);
+
+ const stateUpdate = getClearedSelectedAnomaliesState();
+ this.updateExplorer(stateUpdate, false);
+ } else {
+ swimlaneSelectedCells.showTopFieldValues = false;
+
+ const currentSwimlaneType = _.get(this.state, 'selectedCells.type');
+ const currentShowTopFieldValues = _.get(this.state, 'selectedCells.showTopFieldValues', false);
+ const newSwimlaneType = _.get(swimlaneSelectedCells, 'type');
+
+ if (
+ (currentSwimlaneType === SWIMLANE_TYPE.OVERALL && newSwimlaneType === SWIMLANE_TYPE.VIEW_BY) ||
+ newSwimlaneType === SWIMLANE_TYPE.OVERALL ||
+ currentShowTopFieldValues === true
+ ) {
+ swimlaneSelectedCells.showTopFieldValues = true;
+ }
+
+ this.props.appStateHandler(APP_STATE_ACTION.SAVE_SELECTION, { swimlaneSelectedCells });
+ this.updateExplorer({ selectedCells: swimlaneSelectedCells }, false);
+ }
+ }
render() {
+ const {
+ intl,
+ MlTimeBuckets,
+ } = this.props;
+
const {
annotationsData,
anomalyChartRecords,
chartsData,
influencers,
- intl,
hasResults,
- jobs,
- loading,
noInfluencersConfigured,
- showViewBySwimlane,
- swimlaneOverall,
- swimlaneViewBy,
+ noJobsFound,
+ overallSwimlaneData,
+ selectedCells,
swimlaneViewByFieldName,
tableData,
viewByLoadedForTimeFormatted,
+ viewBySwimlaneData,
viewBySwimlaneDataLoading,
viewBySwimlaneOptions,
- } = this.props;
+ } = this.state;
+
+ const loading = this.props.loading || this.state.loading;
+
+ const swimlaneWidth = getSwimlaneContainerWidth(noInfluencersConfigured);
if (loading === true) {
return (
@@ -106,17 +893,23 @@ export const Explorer = injectI18n(
);
}
- if (jobs.length === 0) {
+ if (noJobsFound) {
return ;
}
- if (jobs.length > 0 && hasResults === false) {
+ if (noJobsFound && hasResults === false) {
return ;
}
const mainColumnWidthClassName = noInfluencersConfigured === true ? 'col-xs-12' : 'col-xs-10';
const mainColumnClasses = `column ${mainColumnWidthClassName}`;
+ const showViewBySwimlane = (
+ viewBySwimlaneData !== null &&
+ viewBySwimlaneData.laneLabels &&
+ viewBySwimlaneData.laneLabels.length > 0
+ );
+
return (
{noInfluencersConfigured && (
@@ -158,7 +951,15 @@ export const Explorer = injectI18n(
onMouseEnter={this.onSwimlaneEnterHandler}
onMouseLeave={this.onSwimlaneLeaveHandler}
>
-
+
{viewBySwimlaneOptions.length > 0 && (
@@ -216,7 +1017,15 @@ export const Explorer = injectI18n(
onMouseEnter={this.onSwimlaneEnterHandler}
onMouseLeave={this.onSwimlaneLeaveHandler}
>
-
+
)}
@@ -224,7 +1033,7 @@ export const Explorer = injectI18n(
)}
- {!showViewBySwimlane && !viewBySwimlaneDataLoading && (
+ {!showViewBySwimlane && !viewBySwimlaneDataLoading && swimlaneViewByFieldName !== null && (
)}
diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_charts_container_service.js b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_charts_container_service.js
index 81172c6ab41bb..b0087754f4254 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_charts_container_service.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_charts_container_service.js
@@ -25,7 +25,7 @@ import {
mlSelectSeverityService,
SEVERITY_OPTIONS,
} from '../../components/controls/select_severity/select_severity';
-import { getChartContainerWidth } from './legacy_utils';
+import { getChartContainerWidth } from '../legacy_utils';
import { CHART_TYPE } from '../explorer_constants';
diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_charts_container_service.test.js b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_charts_container_service.test.js
index 077e339b0fc0c..63b285d41c8d5 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_charts_container_service.test.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_charts_container_service.test.js
@@ -81,7 +81,7 @@ jest.mock('../../util/string_utils', () => ({
mlEscape(d) { return d; }
}));
-jest.mock('./legacy_utils', () => ({
+jest.mock('../legacy_utils', () => ({
getChartContainerWidth() { return 1140; }
}));
diff --git a/x-pack/plugins/ml/public/explorer/explorer_constants.js b/x-pack/plugins/ml/public/explorer/explorer_constants.js
index 0d4a54c6860c4..332f9cf6d8803 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_constants.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_constants.js
@@ -8,12 +8,28 @@
* Contains values for ML anomaly explorer.
*/
+import { i18n } from '@kbn/i18n';
+
export const DRAG_SELECT_ACTION = {
NEW_SELECTION: 'newSelection',
ELEMENT_SELECT: 'elementSelect',
DRAG_START: 'dragStart'
};
+export const EXPLORER_ACTION = {
+ INITIALIZE: 'initialize',
+ JOB_SELECTION_CHANGE: 'jobSelectionChange',
+ LOAD_JOBS: 'loadJobs',
+ REDRAW: 'redraw',
+ RELOAD: 'reload',
+};
+
+export const APP_STATE_ACTION = {
+ CLEAR_SELECTION: 'clearSelection',
+ SAVE_SELECTION: 'saveSelection',
+ SAVE_SWIMLANE_VIEW_BY_FIELD_NAME: 'saveSwimlaneViewByFieldName',
+};
+
export const SWIMLANE_DEFAULT_LIMIT = 10;
export const SWIMLANE_TYPE = {
@@ -26,3 +42,8 @@ export const CHART_TYPE = {
POPULATION_DISTRIBUTION: 'population_distribution',
SINGLE_METRIC: 'single_metric',
};
+
+export const MAX_CATEGORY_EXAMPLES = 10;
+export const MAX_INFLUENCER_FIELD_VALUES = 10;
+
+export const VIEW_BY_JOB_LABEL = i18n.translate('xpack.ml.explorer.jobIdLabel', { defaultMessage: 'job ID' });
diff --git a/x-pack/plugins/ml/public/explorer/explorer_controller.js b/x-pack/plugins/ml/public/explorer/explorer_controller.js
index 5fc45bbe69a58..dd3638f1727e6 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_controller.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_controller.js
@@ -12,49 +12,34 @@
* in the view.
*/
-import _ from 'lodash';
import $ from 'jquery';
-import DragSelect from 'dragselect';
import moment from 'moment-timezone';
-import 'plugins/ml/components/annotations_table';
-import 'plugins/ml/components/anomalies_table';
-import 'plugins/ml/components/controls';
-import 'plugins/ml/components/job_select_list';
+import '../components/annotations_table';
+import '../components/anomalies_table';
+import '../components/controls';
+import '../components/job_select_list';
import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter';
-import { parseInterval } from 'ui/utils/parse_interval';
import template from './explorer.html';
import uiRoutes from 'ui/routes';
+import {
+ createJobs,
+} from './explorer_utils';
import { getAnomalyExplorerBreadcrumbs } from './breadcrumbs';
-import { checkFullLicense } from 'plugins/ml/license/check_license';
-import { checkGetJobsPrivilege } from 'plugins/ml/privilege/check_privilege';
-import { loadIndexPatterns, getIndexPatterns } from 'plugins/ml/util/index_utils';
-import { refreshIntervalWatcher } from 'plugins/ml/util/refresh_interval_watcher';
-import { IntervalHelperProvider, getBoundsRoundedToInterval } from 'plugins/ml/util/ml_time_buckets';
-import { ml } from 'plugins/ml/services/ml_api_service';
+import { checkFullLicense } from '../license/check_license';
+import { checkGetJobsPrivilege } from '../privilege/check_privilege';
+import { getIndexPatterns, loadIndexPatterns } from '../util/index_utils';
+import { IntervalHelperProvider } from 'plugins/ml/util/ml_time_buckets';
+import { JobSelectServiceProvider } from '../components/job_select_list/job_select_service';
import { mlExplorerDashboardService } from './explorer_dashboard_service';
-import { mlResultsService } from 'plugins/ml/services/results_service';
-import { mlJobService } from 'plugins/ml/services/job_service';
import { mlFieldFormatService } from 'plugins/ml/services/field_format_service';
-import { JobSelectServiceProvider } from 'plugins/ml/components/job_select_list/job_select_service';
-import { isTimeSeriesViewDetector } from 'plugins/ml/../common/util/job_utils';
+import { mlJobService } from '../services/job_service';
+import { refreshIntervalWatcher } from '../util/refresh_interval_watcher';
import { timefilter } from 'ui/timefilter';
-import { formatHumanReadableDateTime } from '../util/date_utils';
-import { explorerChartsContainerServiceFactory, getDefaultChartsData } from './explorer_charts/explorer_charts_container_service';
-import {
- DRAG_SELECT_ACTION,
- SWIMLANE_DEFAULT_LIMIT,
- SWIMLANE_TYPE
-} from './explorer_constants';
-import {
- ANNOTATIONS_TABLE_DEFAULT_QUERY_SIZE,
- ANOMALIES_TABLE_DEFAULT_QUERY_SIZE
-} from '../../common/constants/search';
-import chrome from 'ui/chrome';
-const mlAnnotationsEnabled = chrome.getInjected('mlAnnotationsEnabled', false);
+import { APP_STATE_ACTION, EXPLORER_ACTION } from './explorer_constants';
uiRoutes
.when('/explorer/?', {
@@ -70,284 +55,147 @@ uiRoutes
import { uiModules } from 'ui/modules';
const module = uiModules.get('apps/ml');
-function getDefaultViewBySwimlaneData() {
- return {
- fieldName: '',
- laneLabels: [],
- points: [],
- interval: 3600
- };
-}
-
module.controller('MlExplorerController', function (
+ $injector,
$scope,
$timeout,
AppState,
Private,
config,
- mlCheckboxShowChartsService,
- mlSelectLimitService,
- mlSelectIntervalService,
- mlSelectSeverityService,
- i18n) {
-
- $scope.annotationsData = [];
- $scope.anomalyChartRecords = [];
- $scope.chartsData = getDefaultChartsData();
- $scope.timeFieldName = 'timestamp';
- $scope.loading = true;
+) {
+ // Even if they are not used directly anymore in this controller but via imports
+ // in React components, because of the use of AppState and its dependency on angularjs
+ // these services still need to be required here to properly initialize.
+ $injector.get('mlCheckboxShowChartsService');
+ $injector.get('mlSelectIntervalService');
+ $injector.get('mlSelectLimitService');
+ $injector.get('mlSelectSeverityService');
+
+ // $scope should only contain what's actually still necessary for the angular part.
+ // For the moment that's the job selector and the (hidden) filter bar.
+ $scope.jobs = [];
+ $scope.queryFilters = [];
timefilter.enableTimeRangeSelector();
timefilter.enableAutoRefreshSelector();
// Pass the timezone to the server for use when aggregating anomalies (by day / hour) for the table.
const tzConfig = config.get('dateFormat:tz');
- const dateFormatTz = (tzConfig !== 'Browser') ? tzConfig : moment.tz.guess();
+ $scope.dateFormatTz = (tzConfig !== 'Browser') ? tzConfig : moment.tz.guess();
- const TimeBuckets = Private(IntervalHelperProvider);
const queryFilter = Private(FilterBarQueryFilterProvider);
- const mlJobSelectService = Private(JobSelectServiceProvider);
+ $scope.mlJobSelectService = Private(JobSelectServiceProvider);
+ $scope.MlTimeBuckets = Private(IntervalHelperProvider);
let resizeTimeout = null;
- const $mlExplorer = $('.ml-explorer');
- const MAX_INFLUENCER_FIELD_VALUES = 10;
- const MAX_CATEGORY_EXAMPLES = 10;
- const VIEW_BY_JOB_LABEL = i18n('xpack.ml.explorer.jobIdLabel', { defaultMessage: 'job ID' });
-
- const ALLOW_CELL_RANGE_SELECTION = mlExplorerDashboardService.allowCellRangeSelection;
- // make sure dragSelect is only available if the mouse pointer is actually over a swimlane
- let disableDragSelectOnMouseLeave = true;
- // skip listening to clicks on swimlanes while they are loading to avoid race conditions
- let skipCellClicks = true;
- $scope.queryFilters = [];
-
- const anomalyDataChange = explorerChartsContainerServiceFactory((data) => {
- $scope.chartsData = {
- ...getDefaultChartsData(),
- chartsPerRow: data.chartsPerRow,
- seriesToPlot: data.seriesToPlot,
- // convert truthy/falsy value to Boolean
- tooManyBuckets: !!data.tooManyBuckets,
- };
- $scope.$applyAsync();
- });
-
- const dragSelect = new DragSelect({
- selectables: document.getElementsByClassName('sl-cell'),
- callback(elements) {
- if (elements.length > 1 && !ALLOW_CELL_RANGE_SELECTION) {
- elements = [elements[0]];
- }
-
- if (elements.length > 0) {
- mlExplorerDashboardService.dragSelect.changed({
- action: DRAG_SELECT_ACTION.NEW_SELECTION,
- elements
- });
- }
-
- disableDragSelectOnMouseLeave = true;
- },
- onDragStart() {
- if (ALLOW_CELL_RANGE_SELECTION) {
- mlExplorerDashboardService.dragSelect.changed({
- action: DRAG_SELECT_ACTION.DRAG_START
- });
- disableDragSelectOnMouseLeave = false;
- }
- },
- onElementSelect() {
- if (ALLOW_CELL_RANGE_SELECTION) {
- mlExplorerDashboardService.dragSelect.changed({
- action: DRAG_SELECT_ACTION.ELEMENT_SELECT
- });
- }
- }
- });
-
- $scope.selectedJobs = null;
-
- $scope.getSelectedJobIds = function () {
- const selectedJobs = _.filter($scope.jobs, job => job.selected);
- return _.map(selectedJobs, job => job.id);
- };
-
- $scope.viewBySwimlaneOptions = [];
- $scope.viewBySwimlaneData = getDefaultViewBySwimlaneData();
- $scope.viewBySwimlaneDataLoading = false;
-
- $scope.initializeVis = function () {
- // Initialize the AppState in which to store filters.
- const stateDefaults = {
- filters: [],
- mlExplorerSwimlane: {}
- };
- $scope.appState = new AppState(stateDefaults);
- $scope.jobs = [];
-
- // Load the job info needed by the dashboard, then do the first load.
- // Calling loadJobs() ensures the full datafeed config is available for building the charts.
- mlJobService.loadJobs().then((resp) => {
- if (resp.jobs.length > 0) {
- $scope.jobs = createJobs(resp.jobs);
+ mlExplorerDashboardService.init();
- // Select any jobs set in the global state (i.e. passed in the URL).
- const selectedJobIds = mlJobSelectService.getSelectedJobIds(true);
- $scope.setSelectedJobs(selectedJobIds, true);
- } else {
- $scope.loading = false;
- }
-
- $scope.$applyAsync();
- }).catch((resp) => {
- console.log('Explorer - error getting job info from elasticsearch:', resp);
- });
-
- mlExplorerDashboardService.init();
- };
-
- // create new job objects based on standard job config objects
- // new job objects just contain job id, bucket span in seconds and a selected flag.
- function createJobs(jobs) {
- return jobs.map(job => {
- const bucketSpan = parseInterval(job.analysis_config.bucket_span);
- return { id: job.job_id, selected: false, bucketSpanSeconds: bucketSpan.asSeconds() };
+ function jobSelectionUpdate(action, { fullJobs, selectedCells, selectedJobIds }) {
+ const jobs = createJobs(fullJobs).map((job) => {
+ job.selected = selectedJobIds.some((id) => job.id === id);
+ return job;
});
- }
-
- function restoreCellDataFromAppState() {
- // restore cellData from AppState
- if (
- $scope.cellData === undefined &&
- $scope.appState.mlExplorerSwimlane.selectedType !== undefined
- ) {
- $scope.cellData = {
- type: $scope.appState.mlExplorerSwimlane.selectedType,
- lanes: $scope.appState.mlExplorerSwimlane.selectedLanes,
- times: $scope.appState.mlExplorerSwimlane.selectedTimes
- };
- if ($scope.cellData.type === SWIMLANE_TYPE.VIEW_BY) {
- $scope.cellData.fieldName = $scope.appState.mlExplorerSwimlane.viewBy;
- }
- $scope.swimlaneViewByFieldName = $scope.appState.mlExplorerSwimlane.viewBy;
- }
- }
-
- $scope.setSelectedJobs = function (selectedIds, keepSwimlaneSelection = false) {
- let previousSelected = 0;
- if ($scope.selectedJobs !== null) {
- previousSelected = $scope.selectedJobs.length;
- }
-
- // Check for any new jobs created since the page was first loaded,
- // and whether any of the jobs have influencers configured (in which
- // case the Top Influencers section will be hidden).
- let recreateJobs = false;
- let hasInfluencers = false;
- selectedIds.forEach((id) => {
- if (recreateJobs === false && _.find($scope.jobs, { id }) === undefined) {
- recreateJobs = true;
- }
- const job = mlJobService.getJob(id);
- let influencers = [];
- if (job !== undefined) {
- influencers = job.analysis_config.influencers || [];
- }
- hasInfluencers = hasInfluencers || influencers.length > 0;
- });
+ const selectedJobs = jobs.filter(job => job.selected);
- if (recreateJobs === true) {
- $scope.jobs = createJobs(mlJobService.jobs);
- }
- $scope.noInfluencersConfigured = !hasInfluencers;
+ function fieldFormatServiceCallback() {
+ $scope.jobs = jobs;
+ $scope.$applyAsync();
- // update the jobs' selected flag
- $scope.selectedJobs = [];
- _.each($scope.jobs, (job) => {
- job.selected = (_.indexOf(selectedIds, job.id) !== -1);
- if (job.selected) {
- $scope.selectedJobs.push(job);
- }
- });
+ const noJobsFound = ($scope.jobs.length === 0);
- // Clear viewBy from the state if we are moving from single
- // to multi selection, or vice-versa.
- $scope.appState.fetch();
- if ((previousSelected <= 1 && $scope.selectedJobs.length > 1) ||
- ($scope.selectedJobs.length === 1 && previousSelected > 1)) {
- delete $scope.appState.mlExplorerSwimlane.viewBy;
+ mlExplorerDashboardService.explorer.changed(action, {
+ loading: false,
+ noJobsFound,
+ selectedCells,
+ selectedJobs
+ });
}
- $scope.appState.save();
// Populate the map of jobs / detectors / field formatters for the selected IDs.
- mlFieldFormatService.populateFormats(selectedIds, getIndexPatterns())
- .catch((err) => { console.log('Error populating field formats:', err); })
+ mlFieldFormatService.populateFormats(selectedJobIds, getIndexPatterns())
+ .catch((err) => {
+ console.log('Error populating field formats:', err);
+ })
.then(() => {
- // Load the data - if the FieldFormats failed to populate
- // the default formatting will be used for metric values.
- loadOverallData();
- if (keepSwimlaneSelection === false) {
- clearSelectedAnomalies();
- } else {
- restoreCellDataFromAppState();
- updateExplorer();
- }
- $scope.$applyAsync();
+ fieldFormatServiceCallback();
});
- };
-
- $scope.setSwimlaneSelectActive = function (active) {
- if (!active && disableDragSelectOnMouseLeave) {
- dragSelect.clearSelection();
- dragSelect.stop();
- return;
- }
+ }
- dragSelect.start();
- };
+ // Initialize the AppState in which to store filters and swimlane settings.
+ // AppState is used to store state in the URL.
+ $scope.appState = new AppState({
+ filters: [],
+ mlExplorerSwimlane: {},
+ });
- $scope.setSwimlaneViewBy = function (viewByFieldName) {
- $scope.swimlaneViewByFieldName = viewByFieldName;
+ // Load the job info needed by the dashboard, then do the first load.
+ // Calling loadJobs() ensures the full datafeed config is available for building the charts.
+ // Using this listener ensures the jobs will only be loaded and passed on after
+ // and have been initialized.
+ function loadJobsListener(action) {
+ if (action === EXPLORER_ACTION.LOAD_JOBS) {
+ mlJobService.loadJobs()
+ .then((resp) => {
+ if (resp.jobs.length > 0) {
+ // Select any jobs set in the global state (i.e. passed in the URL).
+ const selectedJobIds = $scope.mlJobSelectService.getSelectedJobIds(true);
+ let selectedCells;
+
+ // keep swimlane selection, restore selectedCells from AppState
+ if ($scope.appState.mlExplorerSwimlane.selectedType !== undefined) {
+ selectedCells = {
+ type: $scope.appState.mlExplorerSwimlane.selectedType,
+ lanes: $scope.appState.mlExplorerSwimlane.selectedLanes,
+ times: $scope.appState.mlExplorerSwimlane.selectedTimes,
+ showTopFieldValues: $scope.appState.mlExplorerSwimlane.showTopFieldValues,
+ viewByFieldName: $scope.appState.mlExplorerSwimlane.viewByFieldName,
+ };
+ }
- // Save the 'view by' field name to the AppState so that it can restored from the URL.
- $scope.appState.fetch();
- $scope.appState.mlExplorerSwimlane.viewBy = viewByFieldName;
- $scope.appState.save();
+ jobSelectionUpdate(EXPLORER_ACTION.INITIALIZE, {
+ fullJobs: resp.jobs,
+ selectedCells,
+ selectedJobIds,
+ swimlaneViewByFieldName: $scope.appState.mlExplorerSwimlane.viewByFieldName
+ });
+ } else {
+ mlExplorerDashboardService.explorer.changed(EXPLORER_ACTION.RELOAD, {
+ loading: false,
+ noJobsFound: true,
+ });
+ }
+ })
+ .catch((resp) => {
+ console.log('Explorer - error getting job info from elasticsearch:', resp);
+ });
+ }
+ }
+ mlExplorerDashboardService.explorer.watch(loadJobsListener);
- loadViewBySwimlane([]);
- clearSelectedAnomalies();
- };
+ // Listen for changes to job selection.
+ $scope.mlJobSelectService.listenJobSelectionChange($scope, (event, selectedJobIds) => {
+ jobSelectionUpdate(EXPLORER_ACTION.JOB_SELECTION_CHANGE, { fullJobs: mlJobService.jobs, selectedJobIds });
+ });
// Refresh all the data when the time range is altered.
$scope.$listenAndDigestAsync(timefilter, 'fetch', () => {
- loadOverallData();
- clearSelectedAnomalies();
+ mlExplorerDashboardService.explorer.changed(EXPLORER_ACTION.RELOAD);
});
// Add a watcher for auto-refresh of the time filter to refresh all the data.
const refreshWatcher = Private(refreshIntervalWatcher);
- refreshWatcher.init(() => {
- loadOverallData();
- // TODO - would be better to only clear and reload the selected anomalies
- // if the previous selection was no longer applicable.
- clearSelectedAnomalies();
- });
-
- // Listen for changes to job selection.
- mlJobSelectService.listenJobSelectionChange($scope, (event, selections) => {
- clearSwimlaneSelectionFromAppState();
- $scope.setSelectedJobs(selections);
+ refreshWatcher.init(async () => {
+ mlExplorerDashboardService.explorer.changed(EXPLORER_ACTION.RELOAD);
});
// Redraw the swimlane when the window resizes or the global nav is toggled.
function jqueryRedrawOnResize() {
-
if (resizeTimeout !== null) {
$timeout.cancel(resizeTimeout);
}
- // Only redraw 500ms after last resize event.
- resizeTimeout = $timeout(redrawOnResize, 500);
+ // Only redraw 100ms after last resize event.
+ resizeTimeout = $timeout(redrawOnResize, 100);
}
$(window).resize(jqueryRedrawOnResize);
@@ -358,853 +206,50 @@ module.controller('MlExplorerController', function (
}, 300);
});
- function clearSwimlaneSelectionFromAppState() {
- $scope.appState.fetch();
- delete $scope.appState.mlExplorerSwimlane.selectedType;
- delete $scope.appState.mlExplorerSwimlane.selectedLanes;
- delete $scope.appState.mlExplorerSwimlane.selectedTimes;
- $scope.appState.save();
- }
-
function redrawOnResize() {
- $scope.swimlaneWidth = getSwimlaneContainerWidth();
- $scope.$apply();
-
- if (
- mlCheckboxShowChartsService.state.get('showCharts') &&
- $scope.anomalyChartRecords.length > 0
- ) {
- const timerange = getSelectionTimeRange($scope.cellData);
- anomalyDataChange(
- $scope.anomalyChartRecords, timerange.earliestMs, timerange.latestMs
- );
- }
- }
-
- // Refresh the data when the dashboard filters are updated.
- $scope.$listen(queryFilter, 'update', () => {
- // TODO - add in filtering functionality.
- $scope.queryFilters = queryFilter.getFilters();
- console.log('explorer_controller queryFilter update, filters:', $scope.queryFilters);
- });
-
- $scope.initializeVis();
-
- function setShowViewBySwimlane() {
- $scope.showViewBySwimlane = (
- $scope.viewBySwimlaneData !== null &&
- $scope.viewBySwimlaneData.laneLabels &&
- $scope.viewBySwimlaneData.laneLabels.length > 0
- );
- $scope.$applyAsync();
+ mlExplorerDashboardService.explorer.changed(EXPLORER_ACTION.REDRAW);
}
- function getSelectionTimeRange(cellData) {
- // Returns the time range of the cell(s) currently selected in the swimlane.
- // If no cell(s) are currently selected, returns the dashboard time range.
- const bounds = timefilter.getActiveBounds();
- let earliestMs = bounds.min.valueOf();
- let latestMs = bounds.max.valueOf();
-
- if (cellData !== undefined && cellData.times !== undefined) {
- // time property of the cell data is an array, with the elements being
- // the start times of the first and last cell selected.
- earliestMs = (cellData.times[0] !== undefined) ? cellData.times[0] * 1000 : bounds.min.valueOf();
- latestMs = bounds.max.valueOf();
- if (cellData.times[1] !== undefined) {
- // Subtract 1 ms so search does not include start of next bucket.
- const interval = $scope.swimlaneBucketInterval.asSeconds();
- latestMs = ((cellData.times[1] + interval) * 1000) - 1;
- }
- }
-
- return { earliestMs, latestMs };
- }
-
- function getSelectionInfluencers(cellData) {
- const influencers = [];
-
- if (
- cellData !== undefined &&
- cellData.fieldName !== undefined &&
- cellData.fieldName !== VIEW_BY_JOB_LABEL
- ) {
- cellData.lanes.forEach((laneLabel) =>{
- influencers.push({ fieldName: $scope.swimlaneViewByFieldName, fieldValue: laneLabel });
- });
- }
-
- return influencers;
- }
-
- // This queue tracks click events while the swimlanes are loading.
- // To avoid race conditions we keep the click events cellData in this queue
- // and trigger another event only after the current loading is done.
- // The queue is necessary since a click in the overall swimlane triggers
- // an update of the viewby swimlanes. If we'd just ignored click events
- // during the loading, we could miss programmatically triggered events like
- // those coming via AppState when a selection is part of the URL.
- const swimlaneCellClickQueue = [];
+ $scope.appStateHandler = ((action, payload) => {
+ $scope.appState.fetch();
- // Listener for click events in the swimlane to load corresponding anomaly data.
- $scope.swimlaneCellClick = function (cellData) {
- if (skipCellClicks === true) {
- swimlaneCellClickQueue.push(cellData);
- return;
+ if (action === APP_STATE_ACTION.CLEAR_SELECTION) {
+ delete $scope.appState.mlExplorerSwimlane.selectedType;
+ delete $scope.appState.mlExplorerSwimlane.selectedLanes;
+ delete $scope.appState.mlExplorerSwimlane.selectedTimes;
+ delete $scope.appState.mlExplorerSwimlane.showTopFieldValues;
}
- // If cellData is an empty object we clear any existing selection,
- // otherwise we save the new selection in AppState and update the Explorer.
- if (_.keys(cellData).length === 0) {
- if ($scope.viewByLoadedForTimeFormatted) {
- // Reload 'view by' swimlane over full time range.
- loadViewBySwimlane([]);
- }
- clearSelectedAnomalies();
- } else {
- $scope.appState.fetch();
- $scope.appState.mlExplorerSwimlane.selectedType = cellData.type;
- $scope.appState.mlExplorerSwimlane.selectedLanes = cellData.lanes;
- $scope.appState.mlExplorerSwimlane.selectedTimes = cellData.times;
- $scope.appState.save();
- $scope.cellData = cellData;
- updateExplorer();
- }
- };
+ if (action === APP_STATE_ACTION.SAVE_SELECTION) {
+ const swimlaneSelectedCells = payload.swimlaneSelectedCells;
+ $scope.appState.mlExplorerSwimlane.selectedType = swimlaneSelectedCells.type;
+ $scope.appState.mlExplorerSwimlane.selectedLanes = swimlaneSelectedCells.lanes;
+ $scope.appState.mlExplorerSwimlane.selectedTimes = swimlaneSelectedCells.times;
+ $scope.appState.mlExplorerSwimlane.showTopFieldValues = swimlaneSelectedCells.showTopFieldValues;
+ $scope.appState.mlExplorerSwimlane.viewByFieldName = swimlaneSelectedCells.viewByFieldName;
- const checkboxShowChartsListener = function () {
- const showCharts = mlCheckboxShowChartsService.state.get('showCharts');
- if (showCharts && $scope.cellData !== undefined) {
- updateExplorer();
- } else {
- const timerange = getSelectionTimeRange($scope.cellData);
- anomalyDataChange(
- [], timerange.earliestMs, timerange.latestMs
- );
}
- };
- mlCheckboxShowChartsService.state.watch(checkboxShowChartsListener);
- const anomalyChartsSeverityListener = function () {
- const showCharts = mlCheckboxShowChartsService.state.get('showCharts');
- if (showCharts && $scope.cellData !== undefined) {
- const timerange = getSelectionTimeRange($scope.cellData);
- anomalyDataChange(
- $scope.anomalyChartRecords, timerange.earliestMs, timerange.latestMs
- );
+ if (action === APP_STATE_ACTION.SAVE_SWIMLANE_VIEW_BY_FIELD_NAME) {
+ $scope.appState.mlExplorerSwimlane.viewByFieldName = payload.swimlaneViewByFieldName;
}
- };
- mlSelectSeverityService.state.watch(anomalyChartsSeverityListener);
-
- const tableControlsListener = function () {
- loadAnomaliesTableData();
- };
- mlSelectIntervalService.state.watch(tableControlsListener);
- mlSelectSeverityService.state.watch(tableControlsListener);
- const swimlaneLimitListener = function () {
- loadViewBySwimlane([]);
- clearSelectedAnomalies();
- };
- mlSelectLimitService.state.watch(swimlaneLimitListener);
+ $scope.appState.save();
+ $scope.$applyAsync();
+ });
- // Listens to render updates of the swimlanes to update dragSelect
- const swimlaneRenderDoneListener = function () {
- dragSelect.clearSelection();
- dragSelect.setSelectables(document.getElementsByClassName('sl-cell'));
- };
- mlExplorerDashboardService.swimlaneRenderDone.watch(swimlaneRenderDoneListener);
+ // Refresh the data when the dashboard filters are updated.
+ $scope.$listen(queryFilter, 'update', () => {
+ // TODO - add in filtering functionality.
+ $scope.queryFilters = queryFilter.getFilters();
+ console.log('explorer_controller queryFilter update, filters:', $scope.queryFilters);
+ });
$scope.$on('$destroy', () => {
- dragSelect.stop();
- mlCheckboxShowChartsService.state.unwatch(checkboxShowChartsListener);
- mlExplorerDashboardService.swimlaneRenderDone.unwatch(swimlaneRenderDoneListener);
- mlSelectSeverityService.state.unwatch(anomalyChartsSeverityListener);
- mlSelectIntervalService.state.unwatch(tableControlsListener);
- mlSelectSeverityService.state.unwatch(tableControlsListener);
- mlSelectLimitService.state.unwatch(swimlaneLimitListener);
- delete $scope.cellData;
+ mlExplorerDashboardService.explorer.unwatch(loadJobsListener);
refreshWatcher.cancel();
$(window).off('resize', jqueryRedrawOnResize);
// Cancel listening for updates to the global nav state.
navListener();
});
-
- // track the request to be able to ignore out of date requests
- // and avoid race conditions ending up with the wrong charts.
- let requestCount = 0;
- function loadDataForCharts(jobIds, earliestMs, latestMs, influencers = []) {
- // Just skip doing the request when this function
- // is called without the minimum required data.
- if ($scope.cellData === undefined && influencers.length === 0) {
- return;
- }
-
- const newRequestCount = ++requestCount;
- requestCount = newRequestCount;
-
- // Load the top anomalies (by record_score) which will be displayed in the charts.
- mlResultsService.getRecordsForInfluencer(
- jobIds, influencers, 0, earliestMs, latestMs, 500
- )
- .then((resp) => {
- // Ignore this response if it's returned by an out of date promise
- if (newRequestCount < requestCount) {
- return;
- }
-
- if ($scope.cellData !== undefined && _.keys($scope.cellData).length > 0) {
- $scope.anomalyChartRecords = resp.records;
- console.log('Explorer anomaly charts data set:', $scope.anomalyChartRecords);
-
- if (mlCheckboxShowChartsService.state.get('showCharts')) {
- anomalyDataChange(
- $scope.anomalyChartRecords, earliestMs, latestMs
- );
- }
- }
-
- // While the charts were loaded, other events could reset cellData,
- // so check if it's still present. This can happen if a cell selection
- // gets restored from URL/AppState and we find out it's not applicable
- // to the view by swimlanes currently on display.
- if ($scope.cellData === undefined) {
- return;
- }
-
- if (influencers.length > 0) {
- // Filter the Top Influencers list to show just the influencers from
- // the records in the selected time range.
- const recordInfluencersByName = {};
-
- // Add the specified influencer(s) to ensure they are used in the filter
- // even if their influencer score for the selected time range is zero.
- influencers.forEach((influencer) => {
- const fieldName = influencer.fieldName;
- if (recordInfluencersByName[influencer.fieldName] === undefined) {
- recordInfluencersByName[influencer.fieldName] = [];
- }
- recordInfluencersByName[fieldName].push(influencer.fieldValue);
- });
-
- // Add the influencers from the top scoring anomalies.
- resp.records.forEach((record) => {
- const influencersByName = record.influencers || [];
- influencersByName.forEach((influencer) => {
- const fieldName = influencer.influencer_field_name;
- const fieldValues = influencer.influencer_field_values;
- if (recordInfluencersByName[fieldName] === undefined) {
- recordInfluencersByName[fieldName] = [];
- }
- recordInfluencersByName[fieldName].push(...fieldValues);
- });
- });
-
- const uniqValuesByName = {};
- Object.keys(recordInfluencersByName).forEach((fieldName) => {
- const fieldValues = recordInfluencersByName[fieldName];
- uniqValuesByName[fieldName] = _.uniq(fieldValues);
- });
-
- const filterInfluencers = [];
- Object.keys(uniqValuesByName).forEach((fieldName) => {
- // Find record influencers with the same field name as the clicked on cell(s).
- const matchingFieldName = influencers.find((influencer) => {
- return influencer.fieldName === fieldName;
- });
-
- if (matchingFieldName !== undefined) {
- // Filter for the value(s) of the clicked on cell(s).
- filterInfluencers.push(...influencers);
- } else {
- // For other field names, add values from all records.
- uniqValuesByName[fieldName].forEach((fieldValue) => {
- filterInfluencers.push({ fieldName, fieldValue });
- });
- }
- });
-
- loadTopInfluencers(jobIds, earliestMs, latestMs, filterInfluencers);
- }
- $scope.$applyAsync();
- });
- }
-
- function setViewBySwimlaneOptions() {
- // Obtain the list of 'View by' fields per job.
- $scope.swimlaneViewByFieldName = null;
- let viewByOptions = []; // Unique influencers for the selected job(s).
-
- const selectedJobIds = $scope.getSelectedJobIds();
- const fieldsByJob = { '*': [] };
- _.each(mlJobService.jobs, (job) => {
- // Add the list of distinct by, over, partition and influencer fields for each job.
- let fieldsForJob = [];
-
- const analysisConfig = job.analysis_config;
- const detectors = analysisConfig.detectors || [];
- _.each(detectors, (detector) => {
- if (_.has(detector, 'partition_field_name')) {
- fieldsForJob.push(detector.partition_field_name);
- }
- if (_.has(detector, 'over_field_name')) {
- fieldsForJob.push(detector.over_field_name);
- }
- // For jobs with by and over fields, don't add the 'by' field as this
- // field will only be added to the top-level fields for record type results
- // if it also an influencer over the bucket.
- if (_.has(detector, 'by_field_name') && !(_.has(detector, 'over_field_name'))) {
- fieldsForJob.push(detector.by_field_name);
- }
- });
-
- const influencers = analysisConfig.influencers || [];
- fieldsForJob = fieldsForJob.concat(influencers);
- if (selectedJobIds.indexOf(job.job_id) !== -1) {
- viewByOptions = viewByOptions.concat(influencers);
- }
-
- fieldsByJob[job.job_id] = _.uniq(fieldsForJob);
- fieldsByJob['*'] = _.union(fieldsByJob['*'], fieldsByJob[job.job_id]);
- });
-
- $scope.fieldsByJob = fieldsByJob; // Currently unused but may be used if add in view by detector.
- viewByOptions = _.chain(viewByOptions).uniq().sortBy(fieldName => fieldName.toLowerCase()).value();
- viewByOptions.push(VIEW_BY_JOB_LABEL);
- $scope.viewBySwimlaneOptions = viewByOptions;
-
- if ($scope.appState.mlExplorerSwimlane.viewBy !== undefined &&
- $scope.viewBySwimlaneOptions.indexOf($scope.appState.mlExplorerSwimlane.viewBy) !== -1) {
- // Set the swimlane viewBy to that stored in the state (URL) if set.
- $scope.swimlaneViewByFieldName = $scope.appState.mlExplorerSwimlane.viewBy;
- } else {
- if (selectedJobIds.length > 1) {
- // If more than one job selected, default to job ID.
- $scope.swimlaneViewByFieldName = VIEW_BY_JOB_LABEL;
- } else {
- // For a single job, default to the first partition, over,
- // by or influencer field of the first selected job.
- const firstSelectedJob = _.find(mlJobService.jobs, (job) => {
- return job.job_id === selectedJobIds[0];
- });
-
- const firstJobInfluencers = firstSelectedJob.analysis_config.influencers || [];
- _.each(firstSelectedJob.analysis_config.detectors, (detector) => {
-
- if (_.has(detector, 'partition_field_name') &&
- firstJobInfluencers.indexOf(detector.partition_field_name) !== -1) {
- $scope.swimlaneViewByFieldName = detector.partition_field_name;
- return false;
- }
-
- if (_.has(detector, 'over_field_name') &&
- firstJobInfluencers.indexOf(detector.over_field_name) !== -1) {
- $scope.swimlaneViewByFieldName = detector.over_field_name;
- return false;
- }
-
- // For jobs with by and over fields, don't add the 'by' field as this
- // field will only be added to the top-level fields for record type results
- // if it also an influencer over the bucket.
- if (_.has(detector, 'by_field_name') && !(_.has(detector, 'over_field_name')) &&
- firstJobInfluencers.indexOf(detector.by_field_name) !== -1) {
- $scope.swimlaneViewByFieldName = detector.by_field_name;
- return false;
- }
- });
-
- if ($scope.swimlaneViewByFieldName === null) {
- if (firstJobInfluencers.length > 0) {
- $scope.swimlaneViewByFieldName = firstJobInfluencers[0];
- } else {
- // No influencers for first selected job - set to first available option.
- $scope.swimlaneViewByFieldName = $scope.viewBySwimlaneOptions.length > 0 ? $scope.viewBySwimlaneOptions[0] : null;
- }
- }
-
- }
-
- $scope.appState.fetch();
- $scope.appState.mlExplorerSwimlane.viewBy = $scope.swimlaneViewByFieldName;
- $scope.appState.save();
- }
- }
-
- function loadOverallData() {
- // Loads the overall data components i.e. the overall swimlane and influencers list.
-
- if ($scope.selectedJobs === null) {
- return;
- }
-
- $scope.loading = true;
- $scope.hasResults = false;
-
- $scope.swimlaneBucketInterval = calculateSwimlaneBucketInterval();
- console.log('Explorer swimlane bucketInterval:', $scope.swimlaneBucketInterval);
-
- // Ensure the search bounds align to the bucketing interval used in the swimlane so
- // that the first and last buckets are complete.
- const bounds = timefilter.getActiveBounds();
- const searchBounds = getBoundsRoundedToInterval(bounds, $scope.swimlaneBucketInterval, false);
- const selectedJobIds = $scope.getSelectedJobIds();
-
- // Load the overall bucket scores by time.
- // Pass the interval in seconds as the swimlane relies on a fixed number of seconds between buckets
- // which wouldn't be the case if e.g. '1M' was used.
- // Pass 'true' when obtaining bucket bounds due to the way the overall_buckets endpoint works
- // to ensure the search is inclusive of end time.
- const overallBucketsBounds = getBoundsRoundedToInterval(bounds, $scope.swimlaneBucketInterval, true);
- mlResultsService.getOverallBucketScores(
- selectedJobIds,
- // Note there is an optimization for when top_n == 1.
- // If top_n > 1, we should test what happens when the request takes long
- // and refactor the loading calls, if necessary, to avoid delays in loading other components.
- 1,
- overallBucketsBounds.min.valueOf(),
- overallBucketsBounds.max.valueOf(),
- $scope.swimlaneBucketInterval.asSeconds() + 's'
- ).then((resp) => {
- skipCellClicks = false;
- $scope.overallSwimlaneData = processOverallResults(resp.results, searchBounds);
- console.log('Explorer overall swimlane data set:', $scope.overallSwimlaneData);
-
- if ($scope.overallSwimlaneData.points && $scope.overallSwimlaneData.points.length > 0) {
- $scope.hasResults = true;
-
- // Trigger loading of the 'view by' swimlane -
- // only load once the overall swimlane so that we can match the time span.
- setViewBySwimlaneOptions();
- } else {
- $scope.hasResults = false;
- }
- $scope.loading = false;
-
- // Tell the result components directives to render.
- // Need to use $timeout to ensure the broadcast happens after the child scope is updated with the new data.
- $timeout(() => {
- loadViewBySwimlane([]);
- }, 0);
- });
-
- }
-
- function loadTopInfluencers(selectedJobIds, earliestMs, latestMs, influencers = []) {
- if ($scope.noInfluencersConfigured !== true) {
- mlResultsService.getTopInfluencers(
- selectedJobIds,
- earliestMs,
- latestMs,
- MAX_INFLUENCER_FIELD_VALUES,
- influencers
- ).then((resp) => {
- // TODO - sort the influencers keys so that the partition field(s) are first.
- $scope.influencers = resp.influencers;
- $scope.$applyAsync();
- console.log('Explorer top influencers data set:', $scope.influencers);
- });
- } else {
- $scope.influencers = {};
- $scope.$applyAsync();
- }
- }
-
- function loadViewBySwimlane(fieldValues) {
- // reset the swimlane data to avoid flickering where the old dataset would briefly show up.
- $scope.viewBySwimlaneData = getDefaultViewBySwimlaneData();
- $scope.viewBySwimlaneDataLoading = true;
-
- skipCellClicks = true;
- // finish() function, called after each data set has been loaded and processed.
- // The last one to call it will trigger the page render.
- function finish(resp) {
- if (resp !== undefined) {
- $scope.viewBySwimlaneData = processViewByResults(resp.results, fieldValues);
-
- // do a sanity check against cellData. It can happen that a previously
- // selected lane loaded via URL/AppState is not available anymore.
- if (
- $scope.cellData !== undefined &&
- $scope.cellData.type === SWIMLANE_TYPE.VIEW_BY
- ) {
- const selectionExists = $scope.cellData.lanes.some((lane) => {
- return ($scope.viewBySwimlaneData.laneLabels.includes(lane));
- });
- if (selectionExists === false) {
- clearSelectedAnomalies();
- }
- }
- }
-
- $scope.viewBySwimlaneDataLoading = false;
-
- skipCellClicks = false;
- console.log('Explorer view by swimlane data set:', $scope.viewBySwimlaneData);
- if (swimlaneCellClickQueue.length > 0) {
- const cellData = swimlaneCellClickQueue.pop();
- swimlaneCellClickQueue.length = 0;
- $scope.swimlaneCellClick(cellData);
- return;
- }
-
- setShowViewBySwimlane();
- }
-
- if (
- $scope.selectedJobs === undefined ||
- $scope.swimlaneViewByFieldName === undefined ||
- $scope.swimlaneViewByFieldName === null
- ) {
- finish();
- return;
- } else {
- // Ensure the search bounds align to the bucketing interval used in the swimlane so
- // that the first and last buckets are complete.
- const bounds = timefilter.getActiveBounds();
- const searchBounds = getBoundsRoundedToInterval(bounds, $scope.swimlaneBucketInterval, false);
- const selectedJobIds = $scope.getSelectedJobIds();
- const limit = mlSelectLimitService.state.get('limit');
- const swimlaneLimit = (limit === undefined) ? SWIMLANE_DEFAULT_LIMIT : limit.val;
-
- // load scores by influencer/jobId value and time.
- // Pass the interval in seconds as the swimlane relies on a fixed number of seconds between buckets
- // which wouldn't be the case if e.g. '1M' was used.
- const interval = $scope.swimlaneBucketInterval.asSeconds() + 's';
- if ($scope.swimlaneViewByFieldName !== VIEW_BY_JOB_LABEL) {
- mlResultsService.getInfluencerValueMaxScoreByTime(
- selectedJobIds,
- $scope.swimlaneViewByFieldName,
- fieldValues,
- searchBounds.min.valueOf(),
- searchBounds.max.valueOf(),
- interval,
- swimlaneLimit
- ).then(finish);
- } else {
- const jobIds = (fieldValues !== undefined && fieldValues.length > 0) ? fieldValues : selectedJobIds;
- mlResultsService.getScoresByBucket(
- jobIds,
- searchBounds.min.valueOf(),
- searchBounds.max.valueOf(),
- interval,
- swimlaneLimit
- ).then(finish);
- }
- }
- }
-
- function loadViewBySwimlaneForSelectedTime(earliestMs, latestMs) {
- const selectedJobIds = $scope.getSelectedJobIds();
- const limit = mlSelectLimitService.state.get('limit');
- const swimlaneLimit = (limit === undefined) ? SWIMLANE_DEFAULT_LIMIT : limit.val;
-
- // Find the top field values for the selected time, and then load the 'view by'
- // swimlane over the full time range for those specific field values.
- if ($scope.swimlaneViewByFieldName !== VIEW_BY_JOB_LABEL) {
- mlResultsService.getTopInfluencers(
- selectedJobIds,
- earliestMs,
- latestMs,
- swimlaneLimit
- ).then((resp) => {
- const topFieldValues = [];
- const topInfluencers = resp.influencers[$scope.swimlaneViewByFieldName];
- _.each(topInfluencers, (influencerData) => {
- if (influencerData.maxAnomalyScore > 0) {
- topFieldValues.push(influencerData.influencerFieldValue);
- }
- });
- loadViewBySwimlane(topFieldValues);
- });
- } else {
- mlResultsService.getScoresByBucket(
- selectedJobIds,
- earliestMs,
- latestMs,
- $scope.swimlaneBucketInterval.asSeconds() + 's',
- swimlaneLimit
- ).then((resp) => {
- loadViewBySwimlane(_.keys(resp.results));
- });
- }
- }
-
- async function loadAnnotationsTableData() {
- $scope.annotationsData = [];
-
- const cellData = $scope.cellData;
- const jobIds = ($scope.cellData !== undefined && cellData.fieldName === VIEW_BY_JOB_LABEL) ?
- cellData.lanes : $scope.getSelectedJobIds();
- const timeRange = getSelectionTimeRange(cellData);
-
- if (mlAnnotationsEnabled) {
- const resp = await ml.annotations.getAnnotations({
- jobIds,
- earliestMs: timeRange.earliestMs,
- latestMs: timeRange.latestMs,
- maxAnnotations: ANNOTATIONS_TABLE_DEFAULT_QUERY_SIZE
- });
-
- $scope.$evalAsync(() => {
- const annotationsData = [];
- jobIds.forEach((jobId) => {
- const jobAnnotations = resp.annotations[jobId];
- if (jobAnnotations !== undefined) {
- annotationsData.push(...jobAnnotations);
- }
- });
-
- $scope.annotationsData = annotationsData
- .sort((a, b) => {
- return a.timestamp - b.timestamp;
- })
- .map((d, i) => {
- d.key = String.fromCharCode(65 + i);
- return d;
- });
- });
- }
- }
-
- function loadAnomaliesTableData() {
- const cellData = $scope.cellData;
- const jobIds = ($scope.cellData !== undefined && cellData.fieldName === VIEW_BY_JOB_LABEL) ?
- cellData.lanes : $scope.getSelectedJobIds();
- const influencers = getSelectionInfluencers(cellData);
- const timeRange = getSelectionTimeRange(cellData);
-
- ml.results.getAnomaliesTableData(
- jobIds,
- [],
- influencers,
- mlSelectIntervalService.state.get('interval').val,
- mlSelectSeverityService.state.get('threshold').val,
- timeRange.earliestMs,
- timeRange.latestMs,
- dateFormatTz,
- ANOMALIES_TABLE_DEFAULT_QUERY_SIZE,
- MAX_CATEGORY_EXAMPLES
- ).then((resp) => {
- const anomalies = resp.anomalies;
- const detectorsByJob = mlJobService.detectorsByJob;
- anomalies.forEach((anomaly) => {
- // Add a detector property to each anomaly.
- // Default to functionDescription if no description available.
- // TODO - when job_service is moved server_side, move this to server endpoint.
- const jobId = anomaly.jobId;
- const detector = _.get(detectorsByJob, [jobId, anomaly.detectorIndex]);
- anomaly.detector = _.get(detector,
- ['detector_description'],
- anomaly.source.function_description);
-
- // For detectors with rules, add a property with the rule count.
- if (detector !== undefined && detector.custom_rules !== undefined) {
- anomaly.rulesLength = detector.custom_rules.length;
- }
-
- // Add properties used for building the links menu.
- // TODO - when job_service is moved server_side, move this to server endpoint.
- anomaly.isTimeSeriesViewDetector = isTimeSeriesViewDetector(
- mlJobService.getJob(jobId), anomaly.detectorIndex);
- if (_.has(mlJobService.customUrlsByJob, jobId)) {
- anomaly.customUrls = mlJobService.customUrlsByJob[jobId];
- }
- });
-
- $scope.$evalAsync(() => {
- $scope.tableData = {
- anomalies,
- interval: resp.interval,
- examplesByJobId: resp.examplesByJobId,
- showViewSeriesLink: true,
- jobIds
- };
- });
-
- }).catch((resp) => {
- console.log('Explorer - error loading data for anomalies table:', resp);
- });
- }
-
- function updateExplorer() {
- const cellData = $scope.cellData;
-
- const jobIds = (cellData !== undefined && cellData.fieldName === VIEW_BY_JOB_LABEL) ? cellData.lanes : $scope.getSelectedJobIds();
- const timerange = getSelectionTimeRange(cellData);
- const influencers = getSelectionInfluencers(cellData);
-
- // The following is to avoid running into a race condition where loading a swimlane selection from URL/AppState
- // would fail because the Explorer Charts Container's directive wasn't linked yet and not being subscribed
- // to the anomalyDataChange listener used in loadDataForCharts().
- async function finish() {
- setShowViewBySwimlane();
-
- await loadAnnotationsTableData();
-
- $timeout(() => {
- anomalyDataChange($scope.anomalyChartRecords || [], timerange.earliestMs, timerange.latestMs);
-
- if (cellData !== undefined && cellData.fieldName === undefined) {
- // Click is in one of the cells in the Overall swimlane - reload the 'view by' swimlane
- // to show the top 'view by' values for the selected time.
- loadViewBySwimlaneForSelectedTime(timerange.earliestMs, timerange.latestMs);
- $scope.viewByLoadedForTimeFormatted = formatHumanReadableDateTime(timerange.earliestMs);
- }
-
- if (influencers.length === 0) {
- loadTopInfluencers(jobIds, timerange.earliestMs, timerange.latestMs);
- loadDataForCharts(jobIds, timerange.earliestMs, timerange.latestMs);
- } else {
- loadDataForCharts(jobIds, timerange.earliestMs, timerange.latestMs, influencers);
- }
- loadAnomaliesTableData();
- }, 0);
- }
-
- finish();
- }
-
- function clearSelectedAnomalies() {
- $scope.anomalyChartRecords = [];
- $scope.viewByLoadedForTimeFormatted = null;
- delete $scope.cellData;
- clearSwimlaneSelectionFromAppState();
- updateExplorer();
- }
-
- function calculateSwimlaneBucketInterval() {
- // Bucketing interval should be the maximum of the chart related interval (i.e. time range related)
- // and the max bucket span for the jobs shown in the chart.
- const bounds = timefilter.getActiveBounds();
- const buckets = new TimeBuckets();
- buckets.setInterval('auto');
- buckets.setBounds(bounds);
-
- const intervalSeconds = buckets.getInterval().asSeconds();
-
- // if the swimlane cell widths are too small they will not be visible
- // calculate how many buckets will be drawn before the swimlanes are actually rendered
- // and increase the interval to widen the cells if they're going to be smaller than 8px
- // this has to be done at this stage so all searches use the same interval
- const numBuckets = parseInt(((bounds.max.valueOf() - bounds.min.valueOf()) / 1000) / intervalSeconds);
- const swimlaneWidth = getSwimlaneContainerWidth();
- const cellWidth = Math.floor(swimlaneWidth / numBuckets);
- $scope.swimlaneWidth = swimlaneWidth;
-
- // if the cell width is going to be less than 8px, double the interval
- if (cellWidth < 8) {
- buckets.setInterval((intervalSeconds * 2) + 's');
- }
-
- const selectedJobs = _.filter($scope.jobs, job => job.selected);
- const maxBucketSpanSeconds = _.reduce(selectedJobs, (memo, job) => Math.max(memo, job.bucketSpanSeconds), 0);
- if (maxBucketSpanSeconds > intervalSeconds) {
- buckets.setInterval(maxBucketSpanSeconds + 's');
- buckets.setBounds(bounds);
- }
-
- return buckets.getInterval();
- }
-
- function getSwimlaneContainerWidth() {
- if ($scope.noInfluencersConfigured === true) {
- // swimlane is full width, minus 30 for the 'no influencers' info icon,
- // minus 170 for the lane labels, minus 50 padding
- return $mlExplorer.width() - 250;
- } else {
- // swimlane width is 5 sixths of the window,
- // minus 170 for the lane labels, minus 50 padding
- return (($mlExplorer.width() / 6) * 5) - 220;
- }
- }
-
- function processOverallResults(scoresByTime, searchBounds) {
- const overallLabel = i18n('xpack.ml.explorer.overallLabel', { defaultMessage: 'Overall' });
- const dataset = {
- laneLabels: [overallLabel],
- points: [],
- interval: $scope.swimlaneBucketInterval.asSeconds(),
- earliest: searchBounds.min.valueOf() / 1000,
- latest: searchBounds.max.valueOf() / 1000
- };
-
- if (_.keys(scoresByTime).length > 0) {
- // Store the earliest and latest times of the data returned by the ES aggregations,
- // These will be used for calculating the earliest and latest times for the swimlane charts.
- _.each(scoresByTime, (score, timeMs) => {
- const time = timeMs / 1000;
- dataset.points.push({
- laneLabel: overallLabel,
- time,
- value: score
- });
-
- dataset.earliest = Math.min(time, dataset.earliest);
- dataset.latest = Math.max((time + dataset.interval), dataset.latest);
- });
- }
-
- return dataset;
- }
-
- function processViewByResults(scoresByInfluencerAndTime, sortedLaneValues) {
- // Processes the scores for the 'view by' swimlane.
- // Sorts the lanes according to the supplied array of lane
- // values in the order in which they should be displayed,
- // or pass an empty array to sort lanes according to max score over all time.
- const dataset = {
- fieldName: $scope.swimlaneViewByFieldName,
- points: [],
- interval: $scope.swimlaneBucketInterval.asSeconds()
- };
-
- // Set the earliest and latest to be the same as the overall swimlane.
- dataset.earliest = $scope.overallSwimlaneData.earliest;
- dataset.latest = $scope.overallSwimlaneData.latest;
-
- const laneLabels = [];
- const maxScoreByLaneLabel = {};
-
- _.each(scoresByInfluencerAndTime, (influencerData, influencerFieldValue) => {
- laneLabels.push(influencerFieldValue);
- maxScoreByLaneLabel[influencerFieldValue] = 0;
-
- _.each(influencerData, (anomalyScore, timeMs) => {
- const time = timeMs / 1000;
- dataset.points.push({
- laneLabel: influencerFieldValue,
- time,
- value: anomalyScore
- });
- maxScoreByLaneLabel[influencerFieldValue] =
- Math.max(maxScoreByLaneLabel[influencerFieldValue], anomalyScore);
- });
- });
-
- const sortValuesLength = sortedLaneValues.length;
- if (sortValuesLength === 0) {
- // Sort lanes in descending order of max score.
- // Note the keys in scoresByInfluencerAndTime received from the ES request
- // are not guaranteed to be sorted by score if they can be parsed as numbers
- // (e.g. if viewing by HTTP response code).
- dataset.laneLabels = laneLabels.sort((a, b) => {
- return maxScoreByLaneLabel[b] - maxScoreByLaneLabel[a];
- });
- } else {
- // Sort lanes according to supplied order
- // e.g. when a cell in the overall swimlane has been selected.
- // Find the index of each lane label from the actual data set,
- // rather than using sortedLaneValues as-is, just in case they differ.
- dataset.laneLabels = laneLabels.sort((a, b) => {
- let aIndex = sortedLaneValues.indexOf(a);
- let bIndex = sortedLaneValues.indexOf(b);
- aIndex = (aIndex > -1) ? aIndex : sortValuesLength;
- bIndex = (bIndex > -1) ? bIndex : sortValuesLength;
- return aIndex - bIndex;
- });
- }
-
- return dataset;
- }
-
});
diff --git a/x-pack/plugins/ml/public/explorer/explorer_dashboard_service.js b/x-pack/plugins/ml/public/explorer/explorer_dashboard_service.js
index a8958d127d68e..5413400a23f2d 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_dashboard_service.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_dashboard_service.js
@@ -20,12 +20,12 @@ function mlExplorerDashboardServiceFactory() {
const listenerFactory = listenerFactoryProvider();
const dragSelect = service.dragSelect = listenerFactory();
- const swimlaneRenderDone = service.swimlaneRenderDone = listenerFactory();
+ const explorer = service.explorer = listenerFactory();
service.init = function () {
// Clear out any old listeners.
dragSelect.unwatchAll();
- swimlaneRenderDone.unwatchAll();
+ explorer.unwatchAll();
};
return service;
diff --git a/x-pack/plugins/ml/public/explorer/explorer_react_wrapper_directive.js b/x-pack/plugins/ml/public/explorer/explorer_react_wrapper_directive.js
index 930d6bd66190f..b1cbf9bb554d5 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_react_wrapper_directive.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_react_wrapper_directive.js
@@ -8,79 +8,28 @@
* AngularJS directive wrapper for rendering Anomaly Explorer's React component.
*/
-import { pick } from 'lodash';
-
import React from 'react';
import ReactDOM from 'react-dom';
import { Explorer } from './explorer';
-import { IntervalHelperProvider } from 'plugins/ml/util/ml_time_buckets';
-import { SWIMLANE_TYPE } from './explorer_constants';
-
import { uiModules } from 'ui/modules';
const module = uiModules.get('apps/ml');
import { I18nProvider } from '@kbn/i18n/react';
+import { mapScopeToProps } from './explorer_utils';
-module.directive('mlExplorerReactWrapper', function (Private) {
- const TimeBuckets = Private(IntervalHelperProvider);
+import { EXPLORER_ACTION } from './explorer_constants';
+import { mlExplorerDashboardService } from './explorer_dashboard_service';
+module.directive('mlExplorerReactWrapper', function () {
function link(scope, element) {
- function getSwimlaneData(swimlaneType) {
- switch (swimlaneType) {
- case SWIMLANE_TYPE.OVERALL:
- return scope.overallSwimlaneData;
- case SWIMLANE_TYPE.VIEW_BY:
- return scope.viewBySwimlaneData;
- }
- }
-
- function mapScopeToSwimlaneProps(swimlaneType) {
- return {
- chartWidth: scope.swimlaneWidth,
- MlTimeBuckets: TimeBuckets,
- swimlaneCellClick: scope.swimlaneCellClick,
- swimlaneData: getSwimlaneData(swimlaneType),
- swimlaneType,
- selection: scope.appState.mlExplorerSwimlane,
- };
- }
-
- function render() {
- const props = pick(scope, [
- 'annotationsData',
- 'anomalyChartRecords',
- 'chartsData',
- 'hasResults',
- 'influencers',
- 'jobs',
- 'loading',
- 'noInfluencersConfigured',
- 'setSwimlaneSelectActive',
- 'setSwimlaneViewBy',
- 'showViewBySwimlane',
- 'swimlaneViewByFieldName',
- 'tableData',
- 'viewByLoadedForTimeFormatted',
- 'viewBySwimlaneDataLoading',
- 'viewBySwimlaneOptions',
- ]);
+ ReactDOM.render(
+ {React.createElement(Explorer, mapScopeToProps(scope))} ,
+ element[0]
+ );
- props.swimlaneOverall = mapScopeToSwimlaneProps(SWIMLANE_TYPE.OVERALL);
- props.swimlaneViewBy = mapScopeToSwimlaneProps(SWIMLANE_TYPE.VIEW_BY);
-
- ReactDOM.render(
- {React.createElement(Explorer, props)} ,
- element[0]
- );
- }
-
- render();
-
- scope.$watch(() => {
- render();
- });
+ mlExplorerDashboardService.explorer.changed(EXPLORER_ACTION.LOAD_JOBS);
element.on('$destroy', () => {
ReactDOM.unmountComponentAtNode(element[0]);
diff --git a/x-pack/plugins/ml/public/explorer/explorer_swimlane.js b/x-pack/plugins/ml/public/explorer/explorer_swimlane.js
index 0485ad5a1d778..84bedb1932957 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_swimlane.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_swimlane.js
@@ -37,7 +37,8 @@ export const ExplorerSwimlane = injectI18n(class ExplorerSwimlane extends React.
laneLabels: PropTypes.array.isRequired
}).isRequired,
swimlaneType: PropTypes.string.isRequired,
- selection: PropTypes.object
+ selection: PropTypes.object,
+ swimlaneRenderDoneListener: PropTypes.func.isRequired,
}
// Since this component is mostly rendered using d3 and cellMouseoverActive is only
@@ -85,14 +86,14 @@ export const ExplorerSwimlane = injectI18n(class ExplorerSwimlane extends React.
const { swimlaneType } = this.props;
if (action === DRAG_SELECT_ACTION.NEW_SELECTION && elements.length > 0) {
- const firstCellData = d3.select(elements[0]).node().__clickData__;
+ const firstSelectedCell = d3.select(elements[0]).node().__clickData__;
- if (typeof firstCellData !== 'undefined' && swimlaneType === firstCellData.swimlaneType) {
+ if (typeof firstSelectedCell !== 'undefined' && swimlaneType === firstSelectedCell.swimlaneType) {
const selectedData = elements.reduce((d, e) => {
- const cellData = d3.select(e).node().__clickData__;
- d.bucketScore = Math.max(d.bucketScore, cellData.bucketScore);
- d.laneLabels.push(cellData.laneLabel);
- d.times.push(cellData.time);
+ const cell = d3.select(e).node().__clickData__;
+ d.bucketScore = Math.max(d.bucketScore, cell.bucketScore);
+ d.laneLabels.push(cell.laneLabel);
+ d.times.push(cell.time);
return d;
}, {
bucketScore: 0,
@@ -142,9 +143,9 @@ export const ExplorerSwimlane = injectI18n(class ExplorerSwimlane extends React.
// since it also includes the "viewBy" attribute which might differ depending
// on whether the overall or viewby swimlane was selected.
const oldSelection = {
- selectedType: selection.selectedType,
- selectedLanes: selection.selectedLanes,
- selectedTimes: selection.selectedTimes
+ selectedType: selection && selection.type,
+ selectedLanes: selection && selection.lanes,
+ selectedTimes: selection && selection.times
};
const newSelection = {
@@ -162,13 +163,13 @@ export const ExplorerSwimlane = injectI18n(class ExplorerSwimlane extends React.
return;
}
- const cellData = {
- fieldName: swimlaneData.fieldName,
+ const selectedCells = {
+ viewByFieldName: swimlaneData.fieldName,
lanes: laneLabels,
times: d3.extent(times),
type: swimlaneType
};
- swimlaneCellClick(cellData);
+ swimlaneCellClick(selectedCells);
}
highlightSelection(cellsToSelect, laneLabels, times) {
@@ -249,7 +250,7 @@ export const ExplorerSwimlane = injectI18n(class ExplorerSwimlane extends React.
const swimlanes = element.select('.ml-swimlanes');
swimlanes.html('');
- const cellWidth = Math.floor(chartWidth / numBuckets);
+ const cellWidth = Math.floor(chartWidth / numBuckets * 100) / 100;
const xAxisWidth = cellWidth * numBuckets;
const xAxisScale = d3.time.scale()
@@ -309,7 +310,7 @@ export const ExplorerSwimlane = injectI18n(class ExplorerSwimlane extends React.
.style('width', `${laneLabelWidth}px`)
.html(label => mlEscape(label))
.on('click', () => {
- if (typeof selection.selectedLanes !== 'undefined') {
+ if (typeof selection.lanes !== 'undefined') {
swimlaneCellClick({});
}
})
@@ -424,13 +425,11 @@ export const ExplorerSwimlane = injectI18n(class ExplorerSwimlane extends React.
}
});
- mlExplorerDashboardService.swimlaneRenderDone.changed();
-
// Check for selection and reselect the corresponding swimlane cell
// if the time range and lane label are still in view.
const selectionState = selection;
- const selectedType = _.get(selectionState, 'selectedType', undefined);
- const viewBy = _.get(selectionState, 'viewBy', '');
+ const selectedType = _.get(selectionState, 'type', undefined);
+ const selectionViewByFieldName = _.get(selectionState, 'viewByFieldName', '');
// If a selection was done in the other swimlane, add the "masked" classes
// to de-emphasize the swimlane cells.
@@ -439,15 +438,19 @@ export const ExplorerSwimlane = injectI18n(class ExplorerSwimlane extends React.
element.selectAll('.sl-cell-inner').classed('sl-cell-inner-masked', true);
}
- if ((swimlaneType !== selectedType) ||
- (swimlaneData.fieldName !== undefined && swimlaneData.fieldName !== viewBy)) {
+ this.props.swimlaneRenderDoneListener();
+
+ if (
+ (swimlaneType !== selectedType) ||
+ (swimlaneData.fieldName !== undefined && swimlaneData.fieldName !== selectionViewByFieldName)
+ ) {
// Not this swimlane which was selected.
return;
}
const cellsToSelect = [];
- const selectedLanes = _.get(selectionState, 'selectedLanes', []);
- const selectedTimes = _.get(selectionState, 'selectedTimes', []);
+ const selectedLanes = _.get(selectionState, 'lanes', []);
+ const selectedTimes = _.get(selectionState, 'times', []);
const selectedTimeExtent = d3.extent(selectedTimes);
selectedLanes.forEach((selectedLane) => {
diff --git a/x-pack/plugins/ml/public/explorer/explorer_swimlane.test.js b/x-pack/plugins/ml/public/explorer/explorer_swimlane.test.js
index 4f40a5a7a1965..527713d50ad8f 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_swimlane.test.js
+++ b/x-pack/plugins/ml/public/explorer/explorer_swimlane.test.js
@@ -26,12 +26,6 @@ jest.mock('./explorer_dashboard_service', () => ({
dragSelect: {
watch: jest.fn(),
unwatch: jest.fn()
- },
- swimlaneCellClick: {
- changed: jest.fn()
- },
- swimlaneRenderDone: {
- changed: jest.fn()
}
}
}));
@@ -68,12 +62,15 @@ describe('ExplorerSwimlane', () => {
test('Minimal initialization', () => {
const mocks = getExplorerSwimlaneMocks();
+ const swimlaneRenderDoneListener = jest.fn();
const wrapper = mountWithIntl( );
expect(wrapper.html()).toBe(
@@ -82,32 +79,33 @@ describe('ExplorerSwimlane', () => {
);
// test calls to mock functions
- expect(mlExplorerDashboardService.swimlaneRenderDone.changed.mock.calls.length).toBeGreaterThanOrEqual(1);
expect(mlExplorerDashboardService.dragSelect.watch.mock.calls.length).toBeGreaterThanOrEqual(1);
expect(mlExplorerDashboardService.dragSelect.unwatch.mock.calls).toHaveLength(0);
- expect(mlExplorerDashboardService.swimlaneCellClick.changed.mock.calls).toHaveLength(0);
expect(mocks.MlTimeBuckets.mockMethods.setInterval.mock.calls.length).toBeGreaterThanOrEqual(1);
expect(mocks.MlTimeBuckets.mockMethods.getScaledDateFormat.mock.calls.length).toBeGreaterThanOrEqual(1);
+ expect(swimlaneRenderDoneListener.mock.calls.length).toBeGreaterThanOrEqual(1);
});
test('Overall swimlane', () => {
const mocks = getExplorerSwimlaneMocks();
+ const swimlaneRenderDoneListener = jest.fn();
const wrapper = mountWithIntl( );
expect(wrapper.html()).toMatchSnapshot();
// test calls to mock functions
- expect(mlExplorerDashboardService.swimlaneRenderDone.changed.mock.calls.length).toBeGreaterThanOrEqual(1);
expect(mlExplorerDashboardService.dragSelect.watch.mock.calls.length).toBeGreaterThanOrEqual(1);
expect(mlExplorerDashboardService.dragSelect.unwatch.mock.calls).toHaveLength(0);
- expect(mlExplorerDashboardService.swimlaneCellClick.changed.mock.calls).toHaveLength(0);
expect(mocks.MlTimeBuckets.mockMethods.setInterval.mock.calls.length).toBeGreaterThanOrEqual(1);
expect(mocks.MlTimeBuckets.mockMethods.getScaledDateFormat.mock.calls.length).toBeGreaterThanOrEqual(1);
+ expect(swimlaneRenderDoneListener.mock.calls.length).toBeGreaterThanOrEqual(1);
});
});
diff --git a/x-pack/plugins/ml/public/explorer/explorer_utils.js b/x-pack/plugins/ml/public/explorer/explorer_utils.js
new file mode 100644
index 0000000000000..17453a8a69b28
--- /dev/null
+++ b/x-pack/plugins/ml/public/explorer/explorer_utils.js
@@ -0,0 +1,532 @@
+/*
+ * 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.
+ */
+
+/*
+ * utils for Anomaly Explorer.
+ */
+
+import { chain, each, get, union, uniq } from 'lodash';
+import { timefilter } from 'ui/timefilter';
+import { parseInterval } from 'ui/utils/parse_interval';
+
+import { isTimeSeriesViewDetector } from '../../common/util/job_utils';
+import { ml } from '../services/ml_api_service';
+import { mlJobService } from '../services/job_service';
+import { mlResultsService } from 'plugins/ml/services/results_service';
+import { mlSelectIntervalService } from '../components/controls/select_interval/select_interval';
+import { mlSelectSeverityService } from '../components/controls/select_severity/select_severity';
+
+import {
+ MAX_CATEGORY_EXAMPLES,
+ MAX_INFLUENCER_FIELD_VALUES,
+ VIEW_BY_JOB_LABEL,
+} from './explorer_constants';
+import {
+ ANNOTATIONS_TABLE_DEFAULT_QUERY_SIZE,
+ ANOMALIES_TABLE_DEFAULT_QUERY_SIZE
+} from '../../common/constants/search';
+
+import { i18n } from '@kbn/i18n';
+import chrome from 'ui/chrome';
+const mlAnnotationsEnabled = chrome.getInjected('mlAnnotationsEnabled', false);
+
+// create new job objects based on standard job config objects
+// new job objects just contain job id, bucket span in seconds and a selected flag.
+export function createJobs(jobs) {
+ return jobs.map(job => {
+ const bucketSpan = parseInterval(job.analysis_config.bucket_span);
+ return { id: job.job_id, selected: false, bucketSpanSeconds: bucketSpan.asSeconds() };
+ });
+}
+
+export function getClearedSelectedAnomaliesState() {
+ return {
+ anomalyChartRecords: [],
+ selectedCells: null,
+ viewByLoadedForTimeFormatted: null,
+ };
+}
+
+export function getDefaultViewBySwimlaneData() {
+ return {
+ fieldName: '',
+ laneLabels: [],
+ points: [],
+ interval: 3600
+ };
+}
+
+export function mapScopeToProps(scope) {
+ return {
+ appStateHandler: scope.appStateHandler,
+ dateFormatTz: scope.dateFormatTz,
+ mlJobSelectService: scope.mlJobSelectService,
+ MlTimeBuckets: scope.MlTimeBuckets,
+ };
+}
+
+export async function getFilteredTopInfluencers(jobIds, earliestMs, latestMs, records, influencers, noInfluencersConfigured) {
+ // Filter the Top Influencers list to show just the influencers from
+ // the records in the selected time range.
+ const recordInfluencersByName = {};
+
+ // Add the specified influencer(s) to ensure they are used in the filter
+ // even if their influencer score for the selected time range is zero.
+ influencers.forEach((influencer) => {
+ const fieldName = influencer.fieldName;
+ if (recordInfluencersByName[influencer.fieldName] === undefined) {
+ recordInfluencersByName[influencer.fieldName] = [];
+ }
+ recordInfluencersByName[fieldName].push(influencer.fieldValue);
+ });
+
+ // Add the influencers from the top scoring anomalies.
+ records.forEach((record) => {
+ const influencersByName = record.influencers || [];
+ influencersByName.forEach((influencer) => {
+ const fieldName = influencer.influencer_field_name;
+ const fieldValues = influencer.influencer_field_values;
+ if (recordInfluencersByName[fieldName] === undefined) {
+ recordInfluencersByName[fieldName] = [];
+ }
+ recordInfluencersByName[fieldName].push(...fieldValues);
+ });
+ });
+
+ const uniqValuesByName = {};
+ Object.keys(recordInfluencersByName).forEach((fieldName) => {
+ const fieldValues = recordInfluencersByName[fieldName];
+ uniqValuesByName[fieldName] = uniq(fieldValues);
+ });
+
+ const filterInfluencers = [];
+ Object.keys(uniqValuesByName).forEach((fieldName) => {
+ // Find record influencers with the same field name as the clicked on cell(s).
+ const matchingFieldName = influencers.find((influencer) => {
+ return influencer.fieldName === fieldName;
+ });
+
+ if (matchingFieldName !== undefined) {
+ // Filter for the value(s) of the clicked on cell(s).
+ filterInfluencers.push(...influencers);
+ } else {
+ // For other field names, add values from all records.
+ uniqValuesByName[fieldName].forEach((fieldValue) => {
+ filterInfluencers.push({ fieldName, fieldValue });
+ });
+ }
+ });
+
+ return await loadTopInfluencers(jobIds, earliestMs, latestMs, filterInfluencers, noInfluencersConfigured);
+}
+
+export function selectedJobsHaveInfluencers(selectedJobs = []) {
+ let hasInfluencers = false;
+ selectedJobs.forEach((selectedJob) => {
+ const job = mlJobService.getJob(selectedJob.id);
+ let influencers = [];
+ if (job !== undefined) {
+ influencers = job.analysis_config.influencers || [];
+ }
+ hasInfluencers = hasInfluencers || influencers.length > 0;
+ });
+ return hasInfluencers;
+}
+
+export function getFieldsByJob() {
+ return mlJobService.jobs.reduce((reducedFieldsByJob, job) => {
+ // Add the list of distinct by, over, partition and influencer fields for each job.
+ const analysisConfig = job.analysis_config;
+ const influencers = analysisConfig.influencers || [];
+ const fieldsForJob = (analysisConfig.detectors || [])
+ .reduce((reducedfieldsForJob, detector) => {
+ if (detector.partition_field_name !== undefined) {
+ reducedfieldsForJob.push(detector.partition_field_name);
+ }
+ if (detector.over_field_name !== undefined) {
+ reducedfieldsForJob.push(detector.over_field_name);
+ }
+ // For jobs with by and over fields, don't add the 'by' field as this
+ // field will only be added to the top-level fields for record type results
+ // if it also an influencer over the bucket.
+ if (detector.by_field_name !== undefined && detector.over_field_name === undefined) {
+ reducedfieldsForJob.push(detector.by_field_name);
+ }
+ return reducedfieldsForJob;
+ }, [])
+ .concat(influencers);
+
+ reducedFieldsByJob[job.job_id] = uniq(fieldsForJob);
+ reducedFieldsByJob['*'] = union(reducedFieldsByJob['*'], reducedFieldsByJob[job.job_id]);
+ return reducedFieldsByJob;
+ }, { '*': [] });
+}
+
+export function getSelectionTimeRange(selectedCells, interval) {
+ // Returns the time range of the cell(s) currently selected in the swimlane.
+ // If no cell(s) are currently selected, returns the dashboard time range.
+ const bounds = timefilter.getActiveBounds();
+ let earliestMs = bounds.min.valueOf();
+ let latestMs = bounds.max.valueOf();
+
+ if (selectedCells !== null && selectedCells.times !== undefined) {
+ // time property of the cell data is an array, with the elements being
+ // the start times of the first and last cell selected.
+ earliestMs = (selectedCells.times[0] !== undefined) ? selectedCells.times[0] * 1000 : bounds.min.valueOf();
+ latestMs = bounds.max.valueOf();
+ if (selectedCells.times[1] !== undefined) {
+ // Subtract 1 ms so search does not include start of next bucket.
+ latestMs = ((selectedCells.times[1] + interval) * 1000) - 1;
+ }
+ }
+
+ return { earliestMs, latestMs };
+}
+
+export function getSelectionInfluencers(selectedCells, fieldName) {
+ if (
+ selectedCells !== null &&
+ selectedCells.viewByFieldName !== undefined &&
+ selectedCells.viewByFieldName !== VIEW_BY_JOB_LABEL
+ ) {
+ return selectedCells.lanes.map(laneLabel => ({ fieldName, fieldValue: laneLabel }));
+ }
+
+ return [];
+}
+
+// Obtain the list of 'View by' fields per job and swimlaneViewByFieldName
+export function getViewBySwimlaneOptions(selectedJobs, currentSwimlaneViewByFieldName) {
+ const selectedJobIds = selectedJobs.map(d => d.id);
+
+ // Unique influencers for the selected job(s).
+ const viewByOptions = chain(
+ mlJobService.jobs.reduce((reducedViewByOptions, job) => {
+ if (selectedJobIds.some(jobId => jobId === job.job_id)) {
+ return reducedViewByOptions.concat(job.analysis_config.influencers || []);
+ }
+ return reducedViewByOptions;
+ }, []))
+ .uniq()
+ .sortBy(fieldName => fieldName.toLowerCase())
+ .value();
+
+ viewByOptions.push(VIEW_BY_JOB_LABEL);
+ const viewBySwimlaneOptions = viewByOptions;
+
+ let swimlaneViewByFieldName = undefined;
+
+ if (
+ viewBySwimlaneOptions.indexOf(currentSwimlaneViewByFieldName) !== -1
+ ) {
+ // Set the swimlane viewBy to that stored in the state (URL) if set.
+ // This means we reset it to the current state because it was set by the listener
+ // on initialization.
+ swimlaneViewByFieldName = currentSwimlaneViewByFieldName;
+ } else {
+ if (selectedJobIds.length > 1) {
+ // If more than one job selected, default to job ID.
+ swimlaneViewByFieldName = VIEW_BY_JOB_LABEL;
+ } else {
+ // For a single job, default to the first partition, over,
+ // by or influencer field of the first selected job.
+ const firstSelectedJob = mlJobService.jobs.find((job) => {
+ return job.job_id === selectedJobIds[0];
+ });
+
+ const firstJobInfluencers = firstSelectedJob.analysis_config.influencers || [];
+ firstSelectedJob.analysis_config.detectors.forEach((detector) => {
+ if (
+ detector.partition_field_name !== undefined &&
+ firstJobInfluencers.indexOf(detector.partition_field_name) !== -1
+ ) {
+ swimlaneViewByFieldName = detector.partition_field_name;
+ return false;
+ }
+
+ if (
+ detector.over_field_name !== undefined &&
+ firstJobInfluencers.indexOf(detector.over_field_name) !== -1
+ ) {
+ swimlaneViewByFieldName = detector.over_field_name;
+ return false;
+ }
+
+ // For jobs with by and over fields, don't add the 'by' field as this
+ // field will only be added to the top-level fields for record type results
+ // if it also an influencer over the bucket.
+ if (
+ detector.by_field_name !== undefined &&
+ detector.over_field_name === undefined &&
+ firstJobInfluencers.indexOf(detector.by_field_name) !== -1
+ ) {
+ swimlaneViewByFieldName = detector.by_field_name;
+ return false;
+ }
+ });
+
+ if (swimlaneViewByFieldName === undefined) {
+ if (firstJobInfluencers.length > 0) {
+ swimlaneViewByFieldName = firstJobInfluencers[0];
+ } else {
+ // No influencers for first selected job - set to first available option.
+ swimlaneViewByFieldName = viewBySwimlaneOptions.length > 0
+ ? viewBySwimlaneOptions[0]
+ : undefined;
+ }
+ }
+ }
+ }
+
+ return {
+ swimlaneViewByFieldName,
+ viewBySwimlaneOptions,
+ };
+}
+
+
+export function processOverallResults(scoresByTime, searchBounds, interval) {
+ const overallLabel = i18n.translate('xpack.ml.explorer.overallLabel', { defaultMessage: 'Overall' });
+ const dataset = {
+ laneLabels: [overallLabel],
+ points: [],
+ interval,
+ earliest: searchBounds.min.valueOf() / 1000,
+ latest: searchBounds.max.valueOf() / 1000
+ };
+
+ if (Object.keys(scoresByTime).length > 0) {
+ // Store the earliest and latest times of the data returned by the ES aggregations,
+ // These will be used for calculating the earliest and latest times for the swimlane charts.
+ each(scoresByTime, (score, timeMs) => {
+ const time = timeMs / 1000;
+ dataset.points.push({
+ laneLabel: overallLabel,
+ time,
+ value: score
+ });
+
+ dataset.earliest = Math.min(time, dataset.earliest);
+ dataset.latest = Math.max((time + dataset.interval), dataset.latest);
+ });
+ }
+
+ return dataset;
+}
+
+export function processViewByResults(
+ scoresByInfluencerAndTime,
+ sortedLaneValues,
+ overallSwimlaneData,
+ swimlaneViewByFieldName,
+ interval,
+) {
+ // Processes the scores for the 'view by' swimlane.
+ // Sorts the lanes according to the supplied array of lane
+ // values in the order in which they should be displayed,
+ // or pass an empty array to sort lanes according to max score over all time.
+ const dataset = {
+ fieldName: swimlaneViewByFieldName,
+ points: [],
+ interval
+ };
+
+ // Set the earliest and latest to be the same as the overall swimlane.
+ dataset.earliest = overallSwimlaneData.earliest;
+ dataset.latest = overallSwimlaneData.latest;
+
+ const laneLabels = [];
+ const maxScoreByLaneLabel = {};
+
+ each(scoresByInfluencerAndTime, (influencerData, influencerFieldValue) => {
+ laneLabels.push(influencerFieldValue);
+ maxScoreByLaneLabel[influencerFieldValue] = 0;
+
+ each(influencerData, (anomalyScore, timeMs) => {
+ const time = timeMs / 1000;
+ dataset.points.push({
+ laneLabel: influencerFieldValue,
+ time,
+ value: anomalyScore
+ });
+ maxScoreByLaneLabel[influencerFieldValue] =
+ Math.max(maxScoreByLaneLabel[influencerFieldValue], anomalyScore);
+ });
+ });
+
+ const sortValuesLength = sortedLaneValues.length;
+ if (sortValuesLength === 0) {
+ // Sort lanes in descending order of max score.
+ // Note the keys in scoresByInfluencerAndTime received from the ES request
+ // are not guaranteed to be sorted by score if they can be parsed as numbers
+ // (e.g. if viewing by HTTP response code).
+ dataset.laneLabels = laneLabels.sort((a, b) => {
+ return maxScoreByLaneLabel[b] - maxScoreByLaneLabel[a];
+ });
+ } else {
+ // Sort lanes according to supplied order
+ // e.g. when a cell in the overall swimlane has been selected.
+ // Find the index of each lane label from the actual data set,
+ // rather than using sortedLaneValues as-is, just in case they differ.
+ dataset.laneLabels = laneLabels.sort((a, b) => {
+ let aIndex = sortedLaneValues.indexOf(a);
+ let bIndex = sortedLaneValues.indexOf(b);
+ aIndex = (aIndex > -1) ? aIndex : sortValuesLength;
+ bIndex = (bIndex > -1) ? bIndex : sortValuesLength;
+ return aIndex - bIndex;
+ });
+ }
+
+ return dataset;
+}
+
+export async function loadAnnotationsTableData(selectedCells, selectedJobs, interval) {
+ const jobIds = (selectedCells !== null && selectedCells.viewByFieldName === VIEW_BY_JOB_LABEL) ?
+ selectedCells.lanes : selectedJobs.map(d => d.id);
+ const timeRange = getSelectionTimeRange(selectedCells, interval);
+
+ if (mlAnnotationsEnabled === false) {
+ return Promise.resolve([]);
+ }
+
+ const resp = await ml.annotations.getAnnotations({
+ jobIds,
+ earliestMs: timeRange.earliestMs,
+ latestMs: timeRange.latestMs,
+ maxAnnotations: ANNOTATIONS_TABLE_DEFAULT_QUERY_SIZE
+ });
+
+ const annotationsData = [];
+ jobIds.forEach((jobId) => {
+ const jobAnnotations = resp.annotations[jobId];
+ if (jobAnnotations !== undefined) {
+ annotationsData.push(...jobAnnotations);
+ }
+ });
+
+ return Promise.resolve(
+ annotationsData
+ .sort((a, b) => {
+ return a.timestamp - b.timestamp;
+ })
+ .map((d, i) => {
+ d.key = String.fromCharCode(65 + i);
+ return d;
+ })
+ );
+}
+
+export async function loadAnomaliesTableData(selectedCells, selectedJobs, dateFormatTz, interval, fieldName) {
+ const jobIds = (selectedCells !== null && selectedCells.viewByFieldName === VIEW_BY_JOB_LABEL) ?
+ selectedCells.lanes : selectedJobs.map(d => d.id);
+ const influencers = getSelectionInfluencers(selectedCells, fieldName);
+ const timeRange = getSelectionTimeRange(selectedCells, interval);
+
+ return new Promise((resolve, reject) => {
+ ml.results.getAnomaliesTableData(
+ jobIds,
+ [],
+ influencers,
+ mlSelectIntervalService.state.get('interval').val,
+ mlSelectSeverityService.state.get('threshold').val,
+ timeRange.earliestMs,
+ timeRange.latestMs,
+ dateFormatTz,
+ ANOMALIES_TABLE_DEFAULT_QUERY_SIZE,
+ MAX_CATEGORY_EXAMPLES
+ ).then((resp) => {
+ const anomalies = resp.anomalies;
+ const detectorsByJob = mlJobService.detectorsByJob;
+ anomalies.forEach((anomaly) => {
+ // Add a detector property to each anomaly.
+ // Default to functionDescription if no description available.
+ // TODO - when job_service is moved server_side, move this to server endpoint.
+ const jobId = anomaly.jobId;
+ const detector = get(detectorsByJob, [jobId, anomaly.detectorIndex]);
+ anomaly.detector = get(detector,
+ ['detector_description'],
+ anomaly.source.function_description);
+
+ // For detectors with rules, add a property with the rule count.
+ if (detector !== undefined && detector.custom_rules !== undefined) {
+ anomaly.rulesLength = detector.custom_rules.length;
+ }
+
+ // Add properties used for building the links menu.
+ // TODO - when job_service is moved server_side, move this to server endpoint.
+ anomaly.isTimeSeriesViewDetector = isTimeSeriesViewDetector(mlJobService.getJob(jobId), anomaly.detectorIndex);
+ if (mlJobService.customUrlsByJob[jobId] !== undefined) {
+ anomaly.customUrls = mlJobService.customUrlsByJob[jobId];
+ }
+ });
+
+ resolve({
+ anomalies,
+ interval: resp.interval,
+ examplesByJobId: resp.examplesByJobId,
+ showViewSeriesLink: true,
+ jobIds
+ });
+ }).catch((resp) => {
+ console.log('Explorer - error loading data for anomalies table:', resp);
+ reject();
+ });
+ });
+}
+
+// track the request to be able to ignore out of date requests
+// and avoid race conditions ending up with the wrong charts.
+let requestCount = 0;
+export async function loadDataForCharts(jobIds, earliestMs, latestMs, influencers = [], selectedCells) {
+ return new Promise((resolve) => {
+ // Just skip doing the request when this function
+ // is called without the minimum required data.
+ if (selectedCells === null && influencers.length === 0) {
+ resolve([]);
+ }
+
+ const newRequestCount = ++requestCount;
+ requestCount = newRequestCount;
+
+ // Load the top anomalies (by record_score) which will be displayed in the charts.
+ mlResultsService.getRecordsForInfluencer(
+ jobIds, influencers, 0, earliestMs, latestMs, 500
+ )
+ .then((resp) => {
+ // Ignore this response if it's returned by an out of date promise
+ if (newRequestCount < requestCount) {
+ resolve(undefined);
+ }
+
+ if (selectedCells !== null && Object.keys(selectedCells).length > 0) {
+ console.log('Explorer anomaly charts data set:', resp.records);
+ resolve(resp.records);
+ }
+
+ resolve(undefined);
+ });
+ });
+}
+
+export async function loadTopInfluencers(selectedJobIds, earliestMs, latestMs, influencers = [], noInfluencersConfigured) {
+ return new Promise((resolve) => {
+ if (noInfluencersConfigured !== true) {
+ mlResultsService.getTopInfluencers(
+ selectedJobIds,
+ earliestMs,
+ latestMs,
+ MAX_INFLUENCER_FIELD_VALUES,
+ influencers
+ ).then((resp) => {
+ // TODO - sort the influencers keys so that the partition field(s) are first.
+ console.log('Explorer top influencers data set:', resp.influencers);
+ resolve(resp.influencers);
+ });
+ } else {
+ resolve({});
+ }
+ });
+}
diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/legacy_utils.js b/x-pack/plugins/ml/public/explorer/legacy_utils.js
similarity index 50%
rename from x-pack/plugins/ml/public/explorer/explorer_charts/legacy_utils.js
rename to x-pack/plugins/ml/public/explorer/legacy_utils.js
index 3b2ba22082d8d..62feabdf1e141 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_charts/legacy_utils.js
+++ b/x-pack/plugins/ml/public/explorer/legacy_utils.js
@@ -11,3 +11,17 @@ export function getChartContainerWidth() {
const chartContainer = document.querySelector('.explorer-charts');
return Math.floor(chartContainer && chartContainer.clientWidth || 0);
}
+
+export function getSwimlaneContainerWidth(noInfluencersConfigured = true) {
+ const explorerContainer = document.querySelector('.ml-explorer');
+ const explorerContainerWidth = explorerContainer && explorerContainer.clientWidth || 0;
+ if (noInfluencersConfigured === true) {
+ // swimlane is full width, minus 30 for the 'no influencers' info icon,
+ // minus 170 for the lane labels, minus 50 padding
+ return explorerContainerWidth - 250;
+ } else {
+ // swimlane width is 5 sixths of the window,
+ // minus 170 for the lane labels, minus 50 padding
+ return ((explorerContainerWidth / 6) * 5) - 220;
+ }
+}
From ad4884890b99b5ae3c0317d14f4267a661170ad5 Mon Sep 17 00:00:00 2001
From: James Gowdy
Date: Thu, 24 Jan 2019 10:01:15 +0000
Subject: [PATCH 25/29] [ML] Adding missed applyAsync calls (#28814)
* [ML] Adding missed applyAsync calls
* fixing data recognizer results panel
* adding extra applySync calls to job saving in advanced job page
* fix for forcast results display issue
---
.../components/data_recognizer/data_recognizer.js | 3 +++
.../public/datavisualizer/datavisualizer_controller.js | 7 ++++++-
.../public/jobs/new_job/advanced/new_job_controller.js | 10 ++++++++++
.../single_metric/create_job/create_job_controller.js | 1 +
.../timeseries_chart/timeseries_chart_directive.js | 6 ++++--
5 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/x-pack/plugins/ml/public/components/data_recognizer/data_recognizer.js b/x-pack/plugins/ml/public/components/data_recognizer/data_recognizer.js
index cc13feaa4a9cc..80f17042c7578 100644
--- a/x-pack/plugins/ml/public/components/data_recognizer/data_recognizer.js
+++ b/x-pack/plugins/ml/public/components/data_recognizer/data_recognizer.js
@@ -41,6 +41,9 @@ export class DataRecognizer extends Component {
));
if (typeof this.results === 'object') {
this.results.count = results.length;
+ if (typeof this.results.onChange === 'function') {
+ this.results.onChange();
+ }
}
this.setState({
diff --git a/x-pack/plugins/ml/public/datavisualizer/datavisualizer_controller.js b/x-pack/plugins/ml/public/datavisualizer/datavisualizer_controller.js
index 1b21027d9f307..8403d6bf47b04 100644
--- a/x-pack/plugins/ml/public/datavisualizer/datavisualizer_controller.js
+++ b/x-pack/plugins/ml/public/datavisualizer/datavisualizer_controller.js
@@ -95,7 +95,12 @@ module
$scope.metricFieldFilter = '';
$scope.fieldFilterIcon = 0;
$scope.fieldFilter = '';
- $scope.recognizerResults = { count: 0 };
+ $scope.recognizerResults = {
+ count: 0,
+ onChange() {
+ $scope.$applyAsync();
+ }
+ };
$scope.showSidebar = isFullLicense();
diff --git a/x-pack/plugins/ml/public/jobs/new_job/advanced/new_job_controller.js b/x-pack/plugins/ml/public/jobs/new_job/advanced/new_job_controller.js
index 3aedb1b3f11f0..976137a429561 100644
--- a/x-pack/plugins/ml/public/jobs/new_job/advanced/new_job_controller.js
+++ b/x-pack/plugins/ml/public/jobs/new_job/advanced/new_job_controller.js
@@ -595,6 +595,7 @@ module.controller('MlNewJob',
);
// update status
$scope.ui.saveStatus.job = 2;
+ $scope.$applyAsync();
// save successful, attempt to open the job
mlJobService.openJob($scope.job.job_id)
@@ -631,10 +632,14 @@ module.controller('MlNewJob',
resp
);
$scope.saveLock = false;
+ })
+ .then(() => {
+ $scope.$applyAsync();
});
} else {
// no datafeed, so save is complete
$scope.saveLock = false;
+ $scope.$applyAsync();
}
}
@@ -650,6 +655,7 @@ module.controller('MlNewJob',
values: { message: result.resp.message }
})
);
+ $scope.$applyAsync();
}
}).catch((result) => {
$scope.ui.saveStatus.job = -1;
@@ -660,6 +666,7 @@ module.controller('MlNewJob',
values: { message: result.resp.message }
})
);
+ $scope.$applyAsync();
});
}
})
@@ -670,11 +677,13 @@ module.controller('MlNewJob',
})
);
console.log('save(): job validation failed. Jobs list could not be loaded.');
+ $scope.$applyAsync();
});
}
else {
msgs.error(jobValid.message);
console.log('save(): job validation failed');
+ $scope.$applyAsync();
}
};
@@ -689,6 +698,7 @@ module.controller('MlNewJob',
})
.then(() => {
msgs.clear();
+ $scope.$applyAsync();
$location.path('jobs');
});
};
diff --git a/x-pack/plugins/ml/public/jobs/new_job/simple/single_metric/create_job/create_job_controller.js b/x-pack/plugins/ml/public/jobs/new_job/simple/single_metric/create_job/create_job_controller.js
index 9dc6c159dbc9d..f2b75b053d05e 100644
--- a/x-pack/plugins/ml/public/jobs/new_job/simple/single_metric/create_job/create_job_controller.js
+++ b/x-pack/plugins/ml/public/jobs/new_job/simple/single_metric/create_job/create_job_controller.js
@@ -475,6 +475,7 @@ module
msgs.error(i18n('xpack.ml.newJob.simple.singleMetric.saveDatafeedFailedErrorMessage', {
defaultMessage: 'Save datafeed failed: '
}), resp);
+ $scope.$applyAsync();
});
}
};
diff --git a/x-pack/plugins/ml/public/timeseriesexplorer/components/timeseries_chart/timeseries_chart_directive.js b/x-pack/plugins/ml/public/timeseriesexplorer/components/timeseries_chart/timeseries_chart_directive.js
index 9286932bc879d..5f3c8c1fec46b 100644
--- a/x-pack/plugins/ml/public/timeseriesexplorer/components/timeseries_chart/timeseries_chart_directive.js
+++ b/x-pack/plugins/ml/public/timeseriesexplorer/components/timeseries_chart/timeseries_chart_directive.js
@@ -32,7 +32,7 @@ import { I18nProvider } from '@kbn/i18n/react';
import chrome from 'ui/chrome';
const mlAnnotationsEnabled = chrome.getInjected('mlAnnotationsEnabled', false);
-module.directive('mlTimeseriesChart', function () {
+module.directive('mlTimeseriesChart', function ($timeout) {
function link(scope, element) {
// Key dimensions for the viz and constituent charts.
@@ -85,7 +85,9 @@ module.directive('mlTimeseriesChart', function () {
renderReactComponent();
scope.$on('render', () => {
- renderReactComponent();
+ $timeout(() => {
+ renderReactComponent();
+ });
});
function renderFocusChart() {
From 45b8ff99f00d2dc80e3286a8f921727f56f20e51 Mon Sep 17 00:00:00 2001
From: James Gowdy
Date: Thu, 24 Jan 2019 10:03:09 +0000
Subject: [PATCH 26/29] [ML] Adding ability to override number of sample lines
in File Data Visualizer (#29214)
* [ML] Adding ability to override number of sample lines in file data viz
* tiny tweak
* updating tests
---
.../__snapshots__/overrides.test.js.snap | 22 ++++
.../components/edit_flyout/edit_flyout.js | 12 +-
.../components/edit_flyout/overrides.js | 114 ++++++++++++++----
.../components/edit_flyout/overrides.test.js | 4 +-
.../file_datavisualizer_view.js | 3 +-
.../components/utils/overrides.js | 2 +
.../components/utils/utils.js | 11 +-
.../ml/server/client/elasticsearch_ml.js | 5 +-
8 files changed, 140 insertions(+), 33 deletions(-)
diff --git a/x-pack/plugins/ml/public/file_datavisualizer/components/edit_flyout/__snapshots__/overrides.test.js.snap b/x-pack/plugins/ml/public/file_datavisualizer/components/edit_flyout/__snapshots__/overrides.test.js.snap
index eb9a4b8def88d..134593d713243 100644
--- a/x-pack/plugins/ml/public/file_datavisualizer/components/edit_flyout/__snapshots__/overrides.test.js.snap
+++ b/x-pack/plugins/ml/public/file_datavisualizer/components/edit_flyout/__snapshots__/overrides.test.js.snap
@@ -2,6 +2,28 @@
exports[`Overrides render overrides 1`] = `
+
+ }
+ >
+
+
{};
+ this.state = {
+ overridesValid: true
+ };
}
applyAndClose = () => {
@@ -42,10 +45,14 @@ export class EditFlyout extends Component {
unsetApplyOverrides = () => {
this.applyOverrides = () => {};
}
+ setOverridesValid = (overridesValid) => {
+ this.setState({ overridesValid });
+ }
render() {
- const { isFlyoutVisible, closeEditFlyout } = this.props;
const {
+ isFlyoutVisible,
+ closeEditFlyout,
setOverrides,
overrides,
originalSettings,
@@ -78,6 +85,7 @@ export class EditFlyout extends Component {
overrides={overrides}
originalSettings={originalSettings}
setApplyOverrides={this.setApplyOverrides}
+ setOverridesValid={this.setOverridesValid}
fields={fields}
/>
@@ -105,8 +113,8 @@ export class EditFlyout extends Component {
{
- const overrides = { ...this.state };
- overrides.delimiter = convertDelimiterBack(overrides);
- delete overrides.customDelimiter;
- delete overrides.originalColumnNames;
+ const overrides = { ...this.state.overrides };
+ overrides.delimiter = convertDelimiterBack(overrides.delimiter, this.state.customDelimiter);
this.props.setOverrides(overrides);
}
+ setOverride(o) {
+ const overrides = { ...this.state.overrides, ...o };
+ this.setState({ overrides });
+ }
+
onFormatChange = (format) => {
- this.setState({ format });
+ this.setOverride({ format });
}
onTimestampFormatChange = (timestampFormat) => {
- this.setState({ timestampFormat });
+ this.setOverride({ timestampFormat });
}
onTimestampFieldChange = (timestampField) => {
- this.setState({ timestampField });
+ this.setOverride({ timestampField });
}
onDelimiterChange = (delimiter) => {
- this.setState({ delimiter });
+ this.setOverride({ delimiter });
}
onCustomDelimiterChange = (e) => {
@@ -128,54 +150,90 @@ export class Overrides extends Component {
}
onQuoteChange = (quote) => {
- this.setState({ quote });
+ this.setOverride({ quote });
}
onHasHeaderRowChange = (e) => {
- this.setState({ hasHeaderRow: e.target.checked });
+ this.setOverride({ hasHeaderRow: e.target.checked });
}
onShouldTrimFieldsChange = (e) => {
- this.setState({ shouldTrimFields: e.target.checked });
+ this.setOverride({ shouldTrimFields: e.target.checked });
}
onCharsetChange = (charset) => {
- this.setState({ charset });
+ this.setOverride({ charset });
}
onColumnNameChange = (e, i) => {
- const columnNames = this.state.columnNames;
+ const columnNames = this.state.overrides.columnNames;
columnNames[i] = e.target.value;
- this.setState({ columnNames });
+ this.setOverride({ columnNames });
}
grokPatternChange = (e) => {
- this.setState({ grokPattern: e.target.value });
+ this.setOverride({ grokPattern: e.target.value });
+ }
+
+ onLinesToSampleChange = (e) => {
+ const linesToSample = +e.target.value;
+ this.setOverride({ linesToSample });
+
+ // check whether the value is valid and set that to state.
+ const linesToSampleValid = isLinesToSampleValid(linesToSample);
+ this.setState({ linesToSampleValid });
+
+ // set the overrides valid setting in the parent component,
+ // used to disable the Apply button if any of the overrides are invalid
+ this.props.setOverridesValid(linesToSampleValid);
}
render() {
const { fields } = this.props;
+ const {
+ customDelimiter,
+ originalColumnNames,
+ linesToSampleValid,
+ overrides,
+ } = this.state;
+
const {
timestampFormat,
timestampField,
format,
delimiter,
- customDelimiter,
quote,
hasHeaderRow,
shouldTrimFields,
// charset,
columnNames,
- originalColumnNames,
grokPattern,
- } = this.state;
+ linesToSample,
+ } = overrides;
const fieldOptions = fields.map(f => ({ value: f, inputDisplay: f }));
return (
+
+ }
+ >
+
+
+
{
- (this.state.format === 'delimited') &&
+ (format === 'delimited') &&
}
{
- (this.state.format === 'semi_structured_text') &&
+ (format === 'semi_structured_text') &&
*/}
{
- (this.state.format === 'delimited' && originalColumnNames.length > 0) &&
+ (format === 'delimited' && originalColumnNames.length > 0) &&
@@ -398,7 +456,7 @@ function convertDelimiter(d) {
}
// Convert the delimiter textual descriptions back to their real characters.
-function convertDelimiterBack({ delimiter, customDelimiter }) {
+function convertDelimiterBack(delimiter, customDelimiter) {
switch (delimiter) {
case 'comma':
return ',';
@@ -429,3 +487,7 @@ function getColumnNames(columnNames, originalSettings) {
originalColumnNames,
};
}
+
+function isLinesToSampleValid(linesToSample) {
+ return (linesToSample > LINES_TO_SAMPLE_VALUE_MIN && linesToSample <= LINES_TO_SAMPLE_VALUE_MAX);
+}
diff --git a/x-pack/plugins/ml/public/file_datavisualizer/components/edit_flyout/overrides.test.js b/x-pack/plugins/ml/public/file_datavisualizer/components/edit_flyout/overrides.test.js
index 783b175377e9b..3aa71fc148b34 100644
--- a/x-pack/plugins/ml/public/file_datavisualizer/components/edit_flyout/overrides.test.js
+++ b/x-pack/plugins/ml/public/file_datavisualizer/components/edit_flyout/overrides.test.js
@@ -44,11 +44,11 @@ describe('Overrides', () => {
);
- expect(component.state('format')).toEqual(FORMAT_1);
+ expect(component.state('overrides').format).toEqual(FORMAT_1);
component.instance().onFormatChange(FORMAT_2);
- expect(component.state('format')).toEqual(FORMAT_2);
+ expect(component.state('overrides').format).toEqual(FORMAT_2);
});
});
diff --git a/x-pack/plugins/ml/public/file_datavisualizer/components/file_datavisualizer_view/file_datavisualizer_view.js b/x-pack/plugins/ml/public/file_datavisualizer/components/file_datavisualizer_view/file_datavisualizer_view.js
index 74d0a0ad4fd84..6c8f804634273 100644
--- a/x-pack/plugins/ml/public/file_datavisualizer/components/file_datavisualizer_view/file_datavisualizer_view.js
+++ b/x-pack/plugins/ml/public/file_datavisualizer/components/file_datavisualizer_view/file_datavisualizer_view.js
@@ -150,6 +150,7 @@ export class FileDataVisualizerView extends Component {
}
if (serverOverrides === undefined) {
+ // if no overrides were used, store all the settings returned from the endpoint
this.originalSettings = serverSettings;
} else {
Object.keys(serverOverrides).forEach((o) => {
@@ -164,7 +165,7 @@ export class FileDataVisualizerView extends Component {
Object.keys(serverSettings).forEach((o) => {
const value = serverSettings[o];
if (
- this.overrides[o] === undefined &&
+ (this.overrides[o] === undefined) &&
(Array.isArray(value) && (isEqual(value, this.originalSettings[o]) === false) ||
(value !== this.originalSettings[o]))
) {
diff --git a/x-pack/plugins/ml/public/file_datavisualizer/components/utils/overrides.js b/x-pack/plugins/ml/public/file_datavisualizer/components/utils/overrides.js
index 413c2ca7372dc..f8a90c87b9dc8 100644
--- a/x-pack/plugins/ml/public/file_datavisualizer/components/utils/overrides.js
+++ b/x-pack/plugins/ml/public/file_datavisualizer/components/utils/overrides.js
@@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
+export const DEFAULT_LINES_TO_SAMPLE = 1000;
export const overrideDefaults = {
timestampFormat: undefined,
@@ -16,4 +17,5 @@ export const overrideDefaults = {
columnNames: undefined,
shouldTrimFields: undefined,
grokPattern: undefined,
+ linesToSample: undefined,
};
diff --git a/x-pack/plugins/ml/public/file_datavisualizer/components/utils/utils.js b/x-pack/plugins/ml/public/file_datavisualizer/components/utils/utils.js
index af9b24ba6e810..c373db4a4a83f 100644
--- a/x-pack/plugins/ml/public/file_datavisualizer/components/utils/utils.js
+++ b/x-pack/plugins/ml/public/file_datavisualizer/components/utils/utils.js
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { overrideDefaults } from './overrides';
+import { overrideDefaults, DEFAULT_LINES_TO_SAMPLE } from './overrides';
import { isEqual } from 'lodash';
import { ml } from '../../../services/ml_api_service';
@@ -86,6 +86,11 @@ export function createUrlOverrides(overrides, originalSettings) {
if (formattedOverrides.grok_pattern !== '') {
formattedOverrides.grok_pattern = encodeURIComponent(formattedOverrides.grok_pattern);
}
+
+ if (formattedOverrides.lines_to_sample === '') {
+ formattedOverrides.lines_to_sample = overrides.linesToSample;
+ }
+
return formattedOverrides;
}
@@ -93,6 +98,9 @@ export function processResults(results) {
const timestampFormat = (results.joda_timestamp_formats !== undefined && results.joda_timestamp_formats.length) ?
results.joda_timestamp_formats[0] : undefined;
+ const linesToSample = (results.overrides !== undefined && results.overrides.lines_to_sample !== undefined) ?
+ results.overrides.lines_to_sample : DEFAULT_LINES_TO_SAMPLE;
+
return {
format: results.format,
delimiter: results.delimiter,
@@ -104,6 +112,7 @@ export function processResults(results) {
charset: results.charset,
columnNames: results.column_names,
grokPattern: results.grok_pattern,
+ linesToSample,
};
}
diff --git a/x-pack/plugins/ml/server/client/elasticsearch_ml.js b/x-pack/plugins/ml/server/client/elasticsearch_ml.js
index 2342bafd3c5fb..47574fb6576c5 100644
--- a/x-pack/plugins/ml/server/client/elasticsearch_ml.js
+++ b/x-pack/plugins/ml/server/client/elasticsearch_ml.js
@@ -570,7 +570,7 @@ export const elasticsearchJsPlugin = (Client, config, components) => {
urls: [
{
// eslint-disable-next-line max-len
- fmt: '/_ml/find_file_structure?&charset=<%=charset%>&format=<%=format%>&has_header_row=<%=has_header_row%>&column_names=<%=column_names%>&delimiter=<%=delimiter%>"e=<%=quote%>&should_trim_fields=<%=should_trim_fields%>&grok_pattern=<%=grok_pattern%>×tamp_field=<%=timestamp_field%>×tamp_format=<%=timestamp_format%>',
+ fmt: '/_ml/find_file_structure?&charset=<%=charset%>&format=<%=format%>&has_header_row=<%=has_header_row%>&column_names=<%=column_names%>&delimiter=<%=delimiter%>"e=<%=quote%>&should_trim_fields=<%=should_trim_fields%>&grok_pattern=<%=grok_pattern%>×tamp_field=<%=timestamp_field%>×tamp_format=<%=timestamp_format%>&lines_to_sample=<%=lines_to_sample%>',
req: {
charset: {
type: 'string'
@@ -602,6 +602,9 @@ export const elasticsearchJsPlugin = (Client, config, components) => {
timestamp_format: {
type: 'string'
},
+ lines_to_sample: {
+ type: 'string'
+ },
}
},
{
From 5b6ecbc4c9986a71e5dbe3f6843716557534df60 Mon Sep 17 00:00:00 2001
From: Daniil Suleiman <31325372+sulemanof@users.noreply.github.com>
Date: Thu, 24 Jan 2019 13:10:23 +0300
Subject: [PATCH 27/29] Deleted dead code (#28761)
---
.../lib/vis_data/table/get_column_data.js | 57 -------------------
.../lib/vis_data/table/get_request_params.js | 33 -----------
.../vis_data/table/handle_response_body.js | 36 ------------
3 files changed, 126 deletions(-)
delete mode 100644 src/legacy/core_plugins/metrics/server/lib/vis_data/table/get_column_data.js
delete mode 100644 src/legacy/core_plugins/metrics/server/lib/vis_data/table/get_request_params.js
delete mode 100644 src/legacy/core_plugins/metrics/server/lib/vis_data/table/handle_response_body.js
diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/table/get_column_data.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/table/get_column_data.js
deleted file mode 100644
index 687d1ecb420c9..0000000000000
--- a/src/legacy/core_plugins/metrics/server/lib/vis_data/table/get_column_data.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import getRequestParams from './get_request_params';
-import handleResponseBody from './handle_response_body';
-import handleErrorResponse from '../handle_error_response';
-import getLastValue from '../../../../common/get_last_value';
-import _ from 'lodash';
-import regression from 'regression';
-export function getColumnData(req, panel, entities, client) {
- const elasticsearch = _.get(req, 'server.plugins.elasticsearch');
- if (elasticsearch) {
- const { callWithRequest } = elasticsearch.getCluster('data');
- if (!client) {
- client = callWithRequest.bind(null, req);
- }
- }
- const params = {
- rest_total_hits_as_int: true,
- body: getRequestParams(req, panel, entities)
- };
- return client('msearch', params)
- .then(resp => {
- const handler = handleResponseBody(panel);
- return entities.map((entity, index) => {
- entity.data = {};
- handler(resp.responses[index]).forEach(row => {
- const linearRegression = regression('linear', row.data);
- entity.data[row.id] = {
- last: getLastValue(row.data),
- slope: linearRegression.equation[0],
- yIntercept: linearRegression.equation[1],
- label: row.label
- };
- });
- return entity;
- });
- })
- .catch(handleErrorResponse(panel));
-}
-
diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/table/get_request_params.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/table/get_request_params.js
deleted file mode 100644
index d8370edeb26c2..0000000000000
--- a/src/legacy/core_plugins/metrics/server/lib/vis_data/table/get_request_params.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import buildRequestBody from './build_request_body';
-export default (req, panel, entities) => {
- const bodies = [];
- entities.forEach(entity => {
- bodies.push({
- index: panel.index_pattern,
- ignoreUnavailable: true,
- });
- const body = buildRequestBody(req, panel, entity);
- body.timeout = '90s';
- bodies.push(body);
- });
- return bodies;
-};
diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/table/handle_response_body.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/table/handle_response_body.js
deleted file mode 100644
index 106dda20f0e0c..0000000000000
--- a/src/legacy/core_plugins/metrics/server/lib/vis_data/table/handle_response_body.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import buildProcessorFunction from '../build_processor_function';
-import _ from 'lodash';
-import processors from '../response_processors/table';
-
-export default function handleResponseBody(panel) {
- return resp => {
- if (resp.error) {
- const err = new Error(resp.error.type);
- err.response = JSON.stringify(resp);
- throw err;
- }
- return panel.columns.map(column => {
- const processor = buildProcessorFunction(processors, resp, panel, column);
- return _.first(processor([]));
- });
- };
-}
From 9d33143ff97a24352885d27fd1a813870fe713fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?=
Date: Thu, 24 Jan 2019 12:13:14 +0100
Subject: [PATCH 28/29] [APM] Remove v1 and make required ECS changes (#28068)
* [APM] ECS changes
* Remove ambient types for idx
* Update `observer.listening`
* Added type safety to property config
* More ECS updates
* Juan fixes for ECS
---
.../server/tutorials/apm/envs/on_prem.js | 2 +-
x-pack/package.json | 1 -
.../__snapshots__/constants.test.ts.snap | 360 ++++++------------
x-pack/plugins/apm/common/constants.test.ts | 214 ++---------
x-pack/plugins/apm/common/constants.ts | 15 +-
x-pack/plugins/apm/common/idx.ts | 51 +++
.../DetailView/__test__/DetailView.test.tsx | 30 +-
.../__snapshots__/DetailView.test.tsx.snap | 54 +--
.../ErrorGroupDetails/DetailView/index.tsx | 22 +-
.../createErrorGroupWatch.test.js.snap | 2 +-
.../app/TraceOverview/TraceList.tsx | 2 +-
.../StickyTransactionProperties.tsx | 4 +-
.../TransactionPropertiesTable.tsx | 20 +-
.../TransactionPropertiesTableForFlyout.tsx | 13 +-
.../Waterfall/FlyoutTopLevelProperties.tsx | 4 +-
.../Waterfall/SpanFlyout/DatabaseContext.tsx | 4 +-
.../Waterfall/SpanFlyout/HttpContext.tsx | 2 +-
.../Waterfall/SpanFlyout/index.tsx | 23 +-
.../Waterfall/TransactionFlyout/index.tsx | 11 +-
.../Waterfall/WaterfallItem.tsx | 2 +-
.../mock_responses/spans.json | 18 +-
.../mock_responses/transaction.json | 46 ++-
.../waterfall_helpers/waterfall_helpers.ts | 36 +-
.../Links/DiscoverLinks/DiscoverErrorLink.tsx | 2 +-
.../Links/DiscoverLinks/DiscoverSpanLink.tsx | 8 +-
.../DiscoverLinks/DiscoverTransactionLink.tsx | 3 +-
.../__test__/DiscoverErrorButton.test.tsx | 8 +-
.../DiscoverErrorButton.test.tsx.snap | 4 +-
.../__test__/mockTransaction.json | 67 ++--
.../__test__/PropertiesTable.test.tsx | 4 +-
.../shared/PropertiesTable/index.tsx | 11 +-
.../shared/PropertiesTable/propertyConfig.ts | 80 ++--
.../components/shared/Stacktrace/Context.tsx | 2 +-
.../shared/Stacktrace/FrameHeading.tsx | 2 +-
.../shared/Stacktrace/LibraryStackFrames.tsx | 2 +-
.../shared/Stacktrace/Stackframe.tsx | 2 +-
.../shared/Stacktrace/Variables.tsx | 2 +-
.../Stacktrace/__test__/Stackframe.test.tsx | 2 +-
.../shared/Stacktrace/__test__/index.test.ts | 2 +-
.../components/shared/Stacktrace/index.tsx | 2 +-
.../StickyProperties/StickyProperties.test.js | 2 +-
.../StickyProperties.test.js.snap | 6 +-
.../TransactionActionMenu.tsx | 16 +-
.../__test__/TransactionActionMenu.test.tsx | 8 +-
.../TransactionActionMenu.test.tsx.snap | 4 +-
.../__test__/transactionActionMenuProps.json | 124 ------
.../__test__/transactionActionMenuProps.ts | 130 +++++++
.../components/shared/TransactionLink.tsx | 9 +-
.../apm/public/services/rest/apm/apm.ts | 12 -
.../apm/public/services/rest/apm/traces.ts | 13 +-
.../services/rest/apm/transaction_groups.ts | 9 +-
.../public/services/rest/apm/transactions.ts | 30 +-
.../store/reactReduxRequest/waterfall.tsx | 51 ++-
.../store/reactReduxRequest/waterfallV1.tsx | 53 ---
.../store/reactReduxRequest/waterfallV2.tsx | 49 ---
.../__snapshots__/get_buckets.test.ts.snap | 2 +-
.../apm/server/lib/errors/get_error_group.ts | 3 +-
.../__snapshots__/fetcher.test.ts.snap | 2 +-
.../__snapshots__/fetcher.test.ts.snap | 2 +-
.../server/lib/status_check/server_check.js | 4 +-
.../__snapshots__/fetcher.test.ts.snap | 2 +-
.../lib/transactions/spans/get_spans.ts | 51 ---
.../plugins/apm/server/routes/transactions.ts | 17 -
.../plugins/apm/typings/es_schemas/APMDoc.ts | 26 +-
.../plugins/apm/typings/es_schemas/Context.ts | 52 ---
.../plugins/apm/typings/es_schemas/Error.ts | 80 ++--
x-pack/plugins/apm/typings/es_schemas/Span.ts | 80 ++--
.../apm/typings/es_schemas/Transaction.ts | 105 ++---
.../typings/es_schemas/fields/Container.ts | 9 +
.../apm/typings/es_schemas/fields/Context.ts | 10 +
.../apm/typings/es_schemas/fields/Host.ts | 12 +
.../apm/typings/es_schemas/fields/Http.ts | 10 +
.../typings/es_schemas/fields/Kubernetes.ts | 9 +
.../apm/typings/es_schemas/fields/Process.ts | 12 +
.../apm/typings/es_schemas/fields/Service.ts | 21 +
.../es_schemas/{ => fields}/Stackframe.ts | 0
.../apm/typings/es_schemas/fields/Url.ts | 9 +
.../apm/typings/es_schemas/fields/User.ts | 11 +
yarn.lock | 5 -
79 files changed, 802 insertions(+), 1387 deletions(-)
create mode 100644 x-pack/plugins/apm/common/idx.ts
delete mode 100644 x-pack/plugins/apm/public/components/shared/TransactionActionMenu/__test__/transactionActionMenuProps.json
create mode 100644 x-pack/plugins/apm/public/components/shared/TransactionActionMenu/__test__/transactionActionMenuProps.ts
delete mode 100644 x-pack/plugins/apm/public/store/reactReduxRequest/waterfallV1.tsx
delete mode 100644 x-pack/plugins/apm/public/store/reactReduxRequest/waterfallV2.tsx
delete mode 100644 x-pack/plugins/apm/server/lib/transactions/spans/get_spans.ts
delete mode 100644 x-pack/plugins/apm/typings/es_schemas/Context.ts
create mode 100644 x-pack/plugins/apm/typings/es_schemas/fields/Container.ts
create mode 100644 x-pack/plugins/apm/typings/es_schemas/fields/Context.ts
create mode 100644 x-pack/plugins/apm/typings/es_schemas/fields/Host.ts
create mode 100644 x-pack/plugins/apm/typings/es_schemas/fields/Http.ts
create mode 100644 x-pack/plugins/apm/typings/es_schemas/fields/Kubernetes.ts
create mode 100644 x-pack/plugins/apm/typings/es_schemas/fields/Process.ts
create mode 100644 x-pack/plugins/apm/typings/es_schemas/fields/Service.ts
rename x-pack/plugins/apm/typings/es_schemas/{ => fields}/Stackframe.ts (100%)
create mode 100644 x-pack/plugins/apm/typings/es_schemas/fields/Url.ts
create mode 100644 x-pack/plugins/apm/typings/es_schemas/fields/User.ts
diff --git a/src/legacy/core_plugins/kibana/server/tutorials/apm/envs/on_prem.js b/src/legacy/core_plugins/kibana/server/tutorials/apm/envs/on_prem.js
index 9d941d9b4234d..3e7b40bec6e4d 100644
--- a/src/legacy/core_plugins/kibana/server/tutorials/apm/envs/on_prem.js
+++ b/src/legacy/core_plugins/kibana/server/tutorials/apm/envs/on_prem.js
@@ -91,7 +91,7 @@ export function onPremInstructions(apmIndexPattern) {
bool: {
filter: {
exists: {
- field: 'listening',
+ field: 'observer.listening',
},
},
},
diff --git a/x-pack/package.json b/x-pack/package.json
index 30f47b109994f..f411f03a8a778 100644
--- a/x-pack/package.json
+++ b/x-pack/package.json
@@ -182,7 +182,6 @@
"history-extra": "^4.0.2",
"humps": "2.0.1",
"icalendar": "0.7.1",
- "idx": "^2.5.2",
"inline-style": "^2.0.0",
"intl": "^1.2.5",
"io-ts": "^1.4.2",
diff --git a/x-pack/plugins/apm/common/__snapshots__/constants.test.ts.snap b/x-pack/plugins/apm/common/__snapshots__/constants.test.ts.snap
index 4edc200d39350..2da95b190fe38 100644
--- a/x-pack/plugins/apm/common/__snapshots__/constants.test.ts.snap
+++ b/x-pack/plugins/apm/common/__snapshots__/constants.test.ts.snap
@@ -1,361 +1,217 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Error v2 ERROR_CULPRIT 1`] = `"handleOopsie"`;
+exports[`Error ERROR_CULPRIT 1`] = `"handleOopsie"`;
-exports[`Error v2 ERROR_EXC_HANDLED 1`] = `false`;
+exports[`Error ERROR_EXC_HANDLED 1`] = `false`;
-exports[`Error v2 ERROR_EXC_MESSAGE 1`] = `"sonic boom"`;
+exports[`Error ERROR_EXC_MESSAGE 1`] = `"sonic boom"`;
-exports[`Error v2 ERROR_EXC_STACKTRACE 1`] = `undefined`;
+exports[`Error ERROR_EXC_STACKTRACE 1`] = `undefined`;
-exports[`Error v2 ERROR_GROUP_ID 1`] = `"grouping key"`;
+exports[`Error ERROR_GROUP_ID 1`] = `"grouping key"`;
-exports[`Error v2 ERROR_LOG_MESSAGE 1`] = `undefined`;
+exports[`Error ERROR_LOG_MESSAGE 1`] = `undefined`;
-exports[`Error v2 ERROR_LOG_STACKTRACE 1`] = `undefined`;
+exports[`Error ERROR_LOG_STACKTRACE 1`] = `undefined`;
-exports[`Error v2 METRIC_PROCESS_CPU_PERCENT 1`] = `undefined`;
+exports[`Error METRIC_PROCESS_CPU_PERCENT 1`] = `undefined`;
-exports[`Error v2 METRIC_PROCESS_MEMORY_RSS 1`] = `undefined`;
+exports[`Error METRIC_PROCESS_MEMORY_RSS 1`] = `undefined`;
-exports[`Error v2 METRIC_PROCESS_MEMORY_SIZE 1`] = `undefined`;
+exports[`Error METRIC_PROCESS_MEMORY_SIZE 1`] = `undefined`;
-exports[`Error v2 METRIC_SYSTEM_CPU_PERCENT 1`] = `undefined`;
+exports[`Error METRIC_SYSTEM_CPU_PERCENT 1`] = `undefined`;
-exports[`Error v2 METRIC_SYSTEM_FREE_MEMORY 1`] = `undefined`;
+exports[`Error METRIC_SYSTEM_FREE_MEMORY 1`] = `undefined`;
-exports[`Error v2 METRIC_SYSTEM_TOTAL_MEMORY 1`] = `undefined`;
+exports[`Error METRIC_SYSTEM_TOTAL_MEMORY 1`] = `undefined`;
-exports[`Error v2 PARENT_ID 1`] = `"parentId"`;
+exports[`Error OBSERVER_LISTENING 1`] = `undefined`;
-exports[`Error v2 PROCESSOR_EVENT 1`] = `"error"`;
+exports[`Error PARENT_ID 1`] = `"parentId"`;
-exports[`Error v2 PROCESSOR_NAME 1`] = `"error"`;
+exports[`Error PROCESSOR_EVENT 1`] = `"error"`;
-exports[`Error v2 REQUEST_METHOD 1`] = `undefined`;
+exports[`Error PROCESSOR_NAME 1`] = `"error"`;
-exports[`Error v2 REQUEST_URL_FULL 1`] = `undefined`;
+exports[`Error REQUEST_METHOD 1`] = `undefined`;
-exports[`Error v2 SERVICE_AGENT_NAME 1`] = `"agent name"`;
+exports[`Error REQUEST_URL_FULL 1`] = `undefined`;
-exports[`Error v2 SERVICE_LANGUAGE_NAME 1`] = `"nodejs"`;
+exports[`Error SERVICE_AGENT_NAME 1`] = `"agent name"`;
-exports[`Error v2 SERVICE_NAME 1`] = `"service name"`;
+exports[`Error SERVICE_LANGUAGE_NAME 1`] = `"nodejs"`;
-exports[`Error v2 SPAN_DURATION 1`] = `undefined`;
+exports[`Error SERVICE_NAME 1`] = `"service name"`;
-exports[`Error v2 SPAN_HEX_ID 1`] = `undefined`;
+exports[`Error SPAN_DURATION 1`] = `undefined`;
-exports[`Error v2 SPAN_ID 1`] = `undefined`;
+exports[`Error SPAN_ID 1`] = `undefined`;
-exports[`Error v2 SPAN_NAME 1`] = `undefined`;
+exports[`Error SPAN_NAME 1`] = `undefined`;
-exports[`Error v2 SPAN_SQL 1`] = `undefined`;
+exports[`Error SPAN_SQL 1`] = `undefined`;
-exports[`Error v2 SPAN_START 1`] = `undefined`;
+exports[`Error SPAN_START 1`] = `undefined`;
-exports[`Error v2 SPAN_TYPE 1`] = `undefined`;
+exports[`Error SPAN_TYPE 1`] = `undefined`;
-exports[`Error v2 TRACE_ID 1`] = `"trace id"`;
+exports[`Error TRACE_ID 1`] = `"trace id"`;
-exports[`Error v2 TRANSACTION_DURATION 1`] = `undefined`;
+exports[`Error TRANSACTION_DURATION 1`] = `undefined`;
-exports[`Error v2 TRANSACTION_ID 1`] = `"transaction id"`;
+exports[`Error TRANSACTION_ID 1`] = `"transaction id"`;
-exports[`Error v2 TRANSACTION_NAME 1`] = `undefined`;
+exports[`Error TRANSACTION_NAME 1`] = `undefined`;
-exports[`Error v2 TRANSACTION_RESULT 1`] = `undefined`;
+exports[`Error TRANSACTION_RESULT 1`] = `undefined`;
-exports[`Error v2 TRANSACTION_SAMPLED 1`] = `undefined`;
+exports[`Error TRANSACTION_SAMPLED 1`] = `undefined`;
-exports[`Error v2 TRANSACTION_TYPE 1`] = `undefined`;
+exports[`Error TRANSACTION_TYPE 1`] = `undefined`;
-exports[`Error v2 USER_ID 1`] = `undefined`;
+exports[`Error USER_ID 1`] = `undefined`;
-exports[`Span v1 ERROR_CULPRIT 1`] = `undefined`;
+exports[`Span ERROR_CULPRIT 1`] = `undefined`;
-exports[`Span v1 ERROR_EXC_HANDLED 1`] = `undefined`;
+exports[`Span ERROR_EXC_HANDLED 1`] = `undefined`;
-exports[`Span v1 ERROR_EXC_MESSAGE 1`] = `undefined`;
+exports[`Span ERROR_EXC_MESSAGE 1`] = `undefined`;
-exports[`Span v1 ERROR_EXC_STACKTRACE 1`] = `undefined`;
+exports[`Span ERROR_EXC_STACKTRACE 1`] = `undefined`;
-exports[`Span v1 ERROR_GROUP_ID 1`] = `undefined`;
+exports[`Span ERROR_GROUP_ID 1`] = `undefined`;
-exports[`Span v1 ERROR_LOG_MESSAGE 1`] = `undefined`;
+exports[`Span ERROR_LOG_MESSAGE 1`] = `undefined`;
-exports[`Span v1 ERROR_LOG_STACKTRACE 1`] = `undefined`;
+exports[`Span ERROR_LOG_STACKTRACE 1`] = `undefined`;
-exports[`Span v1 METRIC_PROCESS_CPU_PERCENT 1`] = `undefined`;
+exports[`Span METRIC_PROCESS_CPU_PERCENT 1`] = `undefined`;
-exports[`Span v1 METRIC_PROCESS_MEMORY_RSS 1`] = `undefined`;
+exports[`Span METRIC_PROCESS_MEMORY_RSS 1`] = `undefined`;
-exports[`Span v1 METRIC_PROCESS_MEMORY_SIZE 1`] = `undefined`;
+exports[`Span METRIC_PROCESS_MEMORY_SIZE 1`] = `undefined`;
-exports[`Span v1 METRIC_SYSTEM_CPU_PERCENT 1`] = `undefined`;
+exports[`Span METRIC_SYSTEM_CPU_PERCENT 1`] = `undefined`;
-exports[`Span v1 METRIC_SYSTEM_FREE_MEMORY 1`] = `undefined`;
+exports[`Span METRIC_SYSTEM_FREE_MEMORY 1`] = `undefined`;
-exports[`Span v1 METRIC_SYSTEM_TOTAL_MEMORY 1`] = `undefined`;
+exports[`Span METRIC_SYSTEM_TOTAL_MEMORY 1`] = `undefined`;
-exports[`Span v1 PARENT_ID 1`] = `undefined`;
+exports[`Span OBSERVER_LISTENING 1`] = `undefined`;
-exports[`Span v1 PROCESSOR_EVENT 1`] = `"span"`;
+exports[`Span PARENT_ID 1`] = `"parentId"`;
-exports[`Span v1 PROCESSOR_NAME 1`] = `"transaction"`;
+exports[`Span PROCESSOR_EVENT 1`] = `"span"`;
-exports[`Span v1 REQUEST_METHOD 1`] = `undefined`;
+exports[`Span PROCESSOR_NAME 1`] = `"transaction"`;
-exports[`Span v1 REQUEST_URL_FULL 1`] = `undefined`;
+exports[`Span REQUEST_METHOD 1`] = `undefined`;
-exports[`Span v1 SERVICE_AGENT_NAME 1`] = `"agent name"`;
+exports[`Span REQUEST_URL_FULL 1`] = `undefined`;
-exports[`Span v1 SERVICE_LANGUAGE_NAME 1`] = `"nodejs"`;
+exports[`Span SERVICE_AGENT_NAME 1`] = `"agent name"`;
-exports[`Span v1 SERVICE_NAME 1`] = `"service name"`;
+exports[`Span SERVICE_LANGUAGE_NAME 1`] = `undefined`;
-exports[`Span v1 SPAN_DURATION 1`] = `1337`;
+exports[`Span SERVICE_NAME 1`] = `"service name"`;
-exports[`Span v1 SPAN_HEX_ID 1`] = `undefined`;
+exports[`Span SPAN_DURATION 1`] = `1337`;
-exports[`Span v1 SPAN_ID 1`] = `1337`;
+exports[`Span SPAN_ID 1`] = `"span id"`;
-exports[`Span v1 SPAN_NAME 1`] = `"span name"`;
+exports[`Span SPAN_NAME 1`] = `"span name"`;
-exports[`Span v1 SPAN_SQL 1`] = `"db statement"`;
+exports[`Span SPAN_SQL 1`] = `"db statement"`;
-exports[`Span v1 SPAN_START 1`] = `1337`;
+exports[`Span SPAN_START 1`] = `undefined`;
-exports[`Span v1 SPAN_TYPE 1`] = `"span type"`;
+exports[`Span SPAN_TYPE 1`] = `"span type"`;
-exports[`Span v1 TRACE_ID 1`] = `undefined`;
+exports[`Span TRACE_ID 1`] = `"trace id"`;
-exports[`Span v1 TRANSACTION_DURATION 1`] = `undefined`;
+exports[`Span TRANSACTION_DURATION 1`] = `undefined`;
-exports[`Span v1 TRANSACTION_ID 1`] = `"transaction id"`;
+exports[`Span TRANSACTION_ID 1`] = `"transaction id"`;
-exports[`Span v1 TRANSACTION_NAME 1`] = `undefined`;
+exports[`Span TRANSACTION_NAME 1`] = `undefined`;
-exports[`Span v1 TRANSACTION_RESULT 1`] = `undefined`;
+exports[`Span TRANSACTION_RESULT 1`] = `undefined`;
-exports[`Span v1 TRANSACTION_SAMPLED 1`] = `undefined`;
+exports[`Span TRANSACTION_SAMPLED 1`] = `undefined`;
-exports[`Span v1 TRANSACTION_TYPE 1`] = `undefined`;
+exports[`Span TRANSACTION_TYPE 1`] = `undefined`;
-exports[`Span v1 USER_ID 1`] = `undefined`;
+exports[`Span USER_ID 1`] = `undefined`;
-exports[`Span v2 ERROR_CULPRIT 1`] = `undefined`;
+exports[`Transaction ERROR_CULPRIT 1`] = `undefined`;
-exports[`Span v2 ERROR_EXC_HANDLED 1`] = `undefined`;
+exports[`Transaction ERROR_EXC_HANDLED 1`] = `undefined`;
-exports[`Span v2 ERROR_EXC_MESSAGE 1`] = `undefined`;
+exports[`Transaction ERROR_EXC_MESSAGE 1`] = `undefined`;
-exports[`Span v2 ERROR_EXC_STACKTRACE 1`] = `undefined`;
+exports[`Transaction ERROR_EXC_STACKTRACE 1`] = `undefined`;
-exports[`Span v2 ERROR_GROUP_ID 1`] = `undefined`;
+exports[`Transaction ERROR_GROUP_ID 1`] = `undefined`;
-exports[`Span v2 ERROR_LOG_MESSAGE 1`] = `undefined`;
+exports[`Transaction ERROR_LOG_MESSAGE 1`] = `undefined`;
-exports[`Span v2 ERROR_LOG_STACKTRACE 1`] = `undefined`;
+exports[`Transaction ERROR_LOG_STACKTRACE 1`] = `undefined`;
-exports[`Span v2 METRIC_PROCESS_CPU_PERCENT 1`] = `undefined`;
+exports[`Transaction METRIC_PROCESS_CPU_PERCENT 1`] = `undefined`;
-exports[`Span v2 METRIC_PROCESS_MEMORY_RSS 1`] = `undefined`;
+exports[`Transaction METRIC_PROCESS_MEMORY_RSS 1`] = `undefined`;
-exports[`Span v2 METRIC_PROCESS_MEMORY_SIZE 1`] = `undefined`;
+exports[`Transaction METRIC_PROCESS_MEMORY_SIZE 1`] = `undefined`;
-exports[`Span v2 METRIC_SYSTEM_CPU_PERCENT 1`] = `undefined`;
+exports[`Transaction METRIC_SYSTEM_CPU_PERCENT 1`] = `undefined`;
-exports[`Span v2 METRIC_SYSTEM_FREE_MEMORY 1`] = `undefined`;
+exports[`Transaction METRIC_SYSTEM_FREE_MEMORY 1`] = `undefined`;
-exports[`Span v2 METRIC_SYSTEM_TOTAL_MEMORY 1`] = `undefined`;
+exports[`Transaction METRIC_SYSTEM_TOTAL_MEMORY 1`] = `undefined`;
-exports[`Span v2 PARENT_ID 1`] = `"parentId"`;
+exports[`Transaction OBSERVER_LISTENING 1`] = `undefined`;
-exports[`Span v2 PROCESSOR_EVENT 1`] = `"span"`;
+exports[`Transaction PARENT_ID 1`] = `"parentId"`;
-exports[`Span v2 PROCESSOR_NAME 1`] = `"transaction"`;
+exports[`Transaction PROCESSOR_EVENT 1`] = `"transaction"`;
-exports[`Span v2 REQUEST_METHOD 1`] = `undefined`;
+exports[`Transaction PROCESSOR_NAME 1`] = `"transaction"`;
-exports[`Span v2 REQUEST_URL_FULL 1`] = `undefined`;
+exports[`Transaction REQUEST_METHOD 1`] = `"GET"`;
-exports[`Span v2 SERVICE_AGENT_NAME 1`] = `"agent name"`;
+exports[`Transaction REQUEST_URL_FULL 1`] = `"http://www.elastic.co"`;
-exports[`Span v2 SERVICE_LANGUAGE_NAME 1`] = `"nodejs"`;
+exports[`Transaction SERVICE_AGENT_NAME 1`] = `"agent name"`;
-exports[`Span v2 SERVICE_NAME 1`] = `"service name"`;
+exports[`Transaction SERVICE_LANGUAGE_NAME 1`] = `"nodejs"`;
-exports[`Span v2 SPAN_DURATION 1`] = `1337`;
+exports[`Transaction SERVICE_NAME 1`] = `"service name"`;
-exports[`Span v2 SPAN_HEX_ID 1`] = `"hex id"`;
+exports[`Transaction SPAN_DURATION 1`] = `undefined`;
-exports[`Span v2 SPAN_ID 1`] = `1337`;
+exports[`Transaction SPAN_ID 1`] = `undefined`;
-exports[`Span v2 SPAN_NAME 1`] = `"span name"`;
+exports[`Transaction SPAN_NAME 1`] = `undefined`;
-exports[`Span v2 SPAN_SQL 1`] = `"db statement"`;
+exports[`Transaction SPAN_SQL 1`] = `undefined`;
-exports[`Span v2 SPAN_START 1`] = `undefined`;
+exports[`Transaction SPAN_START 1`] = `undefined`;
-exports[`Span v2 SPAN_TYPE 1`] = `"span type"`;
+exports[`Transaction SPAN_TYPE 1`] = `undefined`;
-exports[`Span v2 TRACE_ID 1`] = `"trace id"`;
+exports[`Transaction TRACE_ID 1`] = `"trace id"`;
-exports[`Span v2 TRANSACTION_DURATION 1`] = `undefined`;
+exports[`Transaction TRANSACTION_DURATION 1`] = `1337`;
-exports[`Span v2 TRANSACTION_ID 1`] = `"transaction id"`;
+exports[`Transaction TRANSACTION_ID 1`] = `"transaction id"`;
-exports[`Span v2 TRANSACTION_NAME 1`] = `undefined`;
+exports[`Transaction TRANSACTION_NAME 1`] = `"transaction name"`;
-exports[`Span v2 TRANSACTION_RESULT 1`] = `undefined`;
+exports[`Transaction TRANSACTION_RESULT 1`] = `"transaction result"`;
-exports[`Span v2 TRANSACTION_SAMPLED 1`] = `undefined`;
+exports[`Transaction TRANSACTION_SAMPLED 1`] = `true`;
-exports[`Span v2 TRANSACTION_TYPE 1`] = `undefined`;
+exports[`Transaction TRANSACTION_TYPE 1`] = `"transaction type"`;
-exports[`Span v2 USER_ID 1`] = `undefined`;
-
-exports[`Transaction v1: ERROR_CULPRIT 1`] = `undefined`;
-
-exports[`Transaction v1: ERROR_EXC_HANDLED 1`] = `undefined`;
-
-exports[`Transaction v1: ERROR_EXC_MESSAGE 1`] = `undefined`;
-
-exports[`Transaction v1: ERROR_EXC_STACKTRACE 1`] = `undefined`;
-
-exports[`Transaction v1: ERROR_GROUP_ID 1`] = `undefined`;
-
-exports[`Transaction v1: ERROR_LOG_MESSAGE 1`] = `undefined`;
-
-exports[`Transaction v1: ERROR_LOG_STACKTRACE 1`] = `undefined`;
-
-exports[`Transaction v1: METRIC_PROCESS_CPU_PERCENT 1`] = `undefined`;
-
-exports[`Transaction v1: METRIC_PROCESS_MEMORY_RSS 1`] = `undefined`;
-
-exports[`Transaction v1: METRIC_PROCESS_MEMORY_SIZE 1`] = `undefined`;
-
-exports[`Transaction v1: METRIC_SYSTEM_CPU_PERCENT 1`] = `undefined`;
-
-exports[`Transaction v1: METRIC_SYSTEM_FREE_MEMORY 1`] = `undefined`;
-
-exports[`Transaction v1: METRIC_SYSTEM_TOTAL_MEMORY 1`] = `undefined`;
-
-exports[`Transaction v1: PARENT_ID 1`] = `undefined`;
-
-exports[`Transaction v1: PROCESSOR_EVENT 1`] = `"transaction"`;
-
-exports[`Transaction v1: PROCESSOR_NAME 1`] = `"transaction"`;
-
-exports[`Transaction v1: REQUEST_METHOD 1`] = `"GET"`;
-
-exports[`Transaction v1: REQUEST_URL_FULL 1`] = `"http://www.elastic.co"`;
-
-exports[`Transaction v1: SERVICE_AGENT_NAME 1`] = `"agent name"`;
-
-exports[`Transaction v1: SERVICE_LANGUAGE_NAME 1`] = `"nodejs"`;
-
-exports[`Transaction v1: SERVICE_NAME 1`] = `"service name"`;
-
-exports[`Transaction v1: SPAN_DURATION 1`] = `undefined`;
-
-exports[`Transaction v1: SPAN_HEX_ID 1`] = `undefined`;
-
-exports[`Transaction v1: SPAN_ID 1`] = `undefined`;
-
-exports[`Transaction v1: SPAN_NAME 1`] = `undefined`;
-
-exports[`Transaction v1: SPAN_SQL 1`] = `undefined`;
-
-exports[`Transaction v1: SPAN_START 1`] = `undefined`;
-
-exports[`Transaction v1: SPAN_TYPE 1`] = `undefined`;
-
-exports[`Transaction v1: TRACE_ID 1`] = `undefined`;
-
-exports[`Transaction v1: TRANSACTION_DURATION 1`] = `1337`;
-
-exports[`Transaction v1: TRANSACTION_ID 1`] = `"transaction id"`;
-
-exports[`Transaction v1: TRANSACTION_NAME 1`] = `"transaction name"`;
-
-exports[`Transaction v1: TRANSACTION_RESULT 1`] = `"transaction result"`;
-
-exports[`Transaction v1: TRANSACTION_SAMPLED 1`] = `true`;
-
-exports[`Transaction v1: TRANSACTION_TYPE 1`] = `"transaction type"`;
-
-exports[`Transaction v1: USER_ID 1`] = `"1337"`;
-
-exports[`Transaction v2 ERROR_CULPRIT 1`] = `undefined`;
-
-exports[`Transaction v2 ERROR_EXC_HANDLED 1`] = `undefined`;
-
-exports[`Transaction v2 ERROR_EXC_MESSAGE 1`] = `undefined`;
-
-exports[`Transaction v2 ERROR_EXC_STACKTRACE 1`] = `undefined`;
-
-exports[`Transaction v2 ERROR_GROUP_ID 1`] = `undefined`;
-
-exports[`Transaction v2 ERROR_LOG_MESSAGE 1`] = `undefined`;
-
-exports[`Transaction v2 ERROR_LOG_STACKTRACE 1`] = `undefined`;
-
-exports[`Transaction v2 METRIC_PROCESS_CPU_PERCENT 1`] = `undefined`;
-
-exports[`Transaction v2 METRIC_PROCESS_MEMORY_RSS 1`] = `undefined`;
-
-exports[`Transaction v2 METRIC_PROCESS_MEMORY_SIZE 1`] = `undefined`;
-
-exports[`Transaction v2 METRIC_SYSTEM_CPU_PERCENT 1`] = `undefined`;
-
-exports[`Transaction v2 METRIC_SYSTEM_FREE_MEMORY 1`] = `undefined`;
-
-exports[`Transaction v2 METRIC_SYSTEM_TOTAL_MEMORY 1`] = `undefined`;
-
-exports[`Transaction v2 PARENT_ID 1`] = `"parentId"`;
-
-exports[`Transaction v2 PROCESSOR_EVENT 1`] = `"transaction"`;
-
-exports[`Transaction v2 PROCESSOR_NAME 1`] = `"transaction"`;
-
-exports[`Transaction v2 REQUEST_METHOD 1`] = `"GET"`;
-
-exports[`Transaction v2 REQUEST_URL_FULL 1`] = `"http://www.elastic.co"`;
-
-exports[`Transaction v2 SERVICE_AGENT_NAME 1`] = `"agent name"`;
-
-exports[`Transaction v2 SERVICE_LANGUAGE_NAME 1`] = `"nodejs"`;
-
-exports[`Transaction v2 SERVICE_NAME 1`] = `"service name"`;
-
-exports[`Transaction v2 SPAN_DURATION 1`] = `undefined`;
-
-exports[`Transaction v2 SPAN_HEX_ID 1`] = `undefined`;
-
-exports[`Transaction v2 SPAN_ID 1`] = `undefined`;
-
-exports[`Transaction v2 SPAN_NAME 1`] = `undefined`;
-
-exports[`Transaction v2 SPAN_SQL 1`] = `undefined`;
-
-exports[`Transaction v2 SPAN_START 1`] = `undefined`;
-
-exports[`Transaction v2 SPAN_TYPE 1`] = `undefined`;
-
-exports[`Transaction v2 TRACE_ID 1`] = `"trace id"`;
-
-exports[`Transaction v2 TRANSACTION_DURATION 1`] = `1337`;
-
-exports[`Transaction v2 TRANSACTION_ID 1`] = `"transaction id"`;
-
-exports[`Transaction v2 TRANSACTION_NAME 1`] = `"transaction name"`;
-
-exports[`Transaction v2 TRANSACTION_RESULT 1`] = `"transaction result"`;
-
-exports[`Transaction v2 TRANSACTION_SAMPLED 1`] = `true`;
-
-exports[`Transaction v2 TRANSACTION_TYPE 1`] = `"transaction type"`;
-
-exports[`Transaction v2 USER_ID 1`] = `"1337"`;
+exports[`Transaction USER_ID 1`] = `"1337"`;
diff --git a/x-pack/plugins/apm/common/constants.test.ts b/x-pack/plugins/apm/common/constants.test.ts
index 9527c39b921fe..564f5b7dbec4c 100644
--- a/x-pack/plugins/apm/common/constants.test.ts
+++ b/x-pack/plugins/apm/common/constants.test.ts
@@ -10,93 +10,27 @@ import { Span } from '../typings/es_schemas/Span';
import { Transaction } from '../typings/es_schemas/Transaction';
import * as constants from './constants';
-describe('Transaction v1:', () => {
+describe('Transaction', () => {
const transaction: Transaction = {
- version: 'v1',
'@timestamp': new Date().toString(),
- beat: {
- hostname: 'beat hostname',
- name: 'beat name',
- version: 'beat version'
- },
- host: {
- name: 'my hostname'
+ agent: {
+ name: 'agent name',
+ version: 'agent version'
},
- processor: {
- name: 'transaction',
- event: 'transaction'
+ http: {
+ request: { method: 'GET' },
+ response: { status_code: 200 }
},
- context: {
- system: {
- architecture: 'x86',
- hostname: 'some-host',
- ip: '111.0.2.3',
- platform: 'linux'
- },
- service: {
- name: 'service name',
- agent: {
- name: 'agent name',
- version: 'v1337'
- },
- language: {
- name: 'nodejs',
- version: 'v1337'
- }
- },
- user: {
- id: '1337'
- },
- request: {
- url: {
- full: 'http://www.elastic.co'
- },
- method: 'GET'
- }
- },
- transaction: {
- duration: {
- us: 1337
- },
- id: 'transaction id',
- name: 'transaction name',
- result: 'transaction result',
- sampled: true,
- type: 'transaction type'
- }
- };
-
- matchSnapshot(transaction);
-});
-
-describe('Transaction v2', () => {
- const transaction: Transaction = {
- version: 'v2',
- '@timestamp': new Date().toString(),
- beat: {
- hostname: 'beat hostname',
- name: 'beat name',
- version: 'beat version'
+ url: { full: 'http://www.elastic.co' },
+ service: {
+ name: 'service name',
+ language: { name: 'nodejs', version: 'v1337' }
},
- host: { name: 'my hostname' },
+ host: { hostname: 'my hostname' },
processor: { name: 'transaction', event: 'transaction' },
timestamp: { us: 1337 },
trace: { id: 'trace id' },
- context: {
- system: {
- architecture: 'x86',
- hostname: 'some-host',
- ip: '111.0.2.3',
- platform: 'linux'
- },
- service: {
- name: 'service name',
- agent: { name: 'agent name', version: 'v1337' },
- language: { name: 'nodejs', version: 'v1337' }
- },
- user: { id: '1337' },
- request: { url: { full: 'http://www.elastic.co' }, method: 'GET' }
- },
+ user: { id: '1337' },
parent: {
id: 'parentId'
},
@@ -121,68 +55,12 @@ describe('Transaction v2', () => {
matchSnapshot(transaction);
});
-describe('Span v1', () => {
+describe('Span', () => {
const span: Span = {
- version: 'v1',
'@timestamp': new Date().toString(),
- beat: {
- hostname: 'beat hostname',
- name: 'beat name',
- version: 'beat version'
- },
- host: {
- name: 'my hostname'
- },
- processor: {
- name: 'transaction',
- event: 'span'
- },
- context: {
- db: {
- statement: 'db statement'
- },
- service: {
- name: 'service name',
- agent: {
- name: 'agent name',
- version: 'v1337'
- },
- language: {
- name: 'nodejs',
- version: 'v1337'
- }
- }
- },
- span: {
- duration: {
- us: 1337
- },
- start: {
- us: 1337
- },
- name: 'span name',
- type: 'span type',
- id: 1337
- },
- transaction: {
- id: 'transaction id'
- }
- };
-
- matchSnapshot(span);
-});
-
-describe('Span v2', () => {
- const span: Span = {
- version: 'v2',
- '@timestamp': new Date().toString(),
- beat: {
- hostname: 'beat hostname',
- name: 'beat name',
- version: 'beat version'
- },
- host: {
- name: 'my hostname'
+ agent: {
+ name: 'agent name',
+ version: 'agent version'
},
processor: {
name: 'transaction',
@@ -194,33 +72,25 @@ describe('Span v2', () => {
trace: {
id: 'trace id'
},
+ service: {
+ name: 'service name'
+ },
context: {
db: {
statement: 'db statement'
- },
- service: {
- name: 'service name',
- agent: {
- name: 'agent name',
- version: 'v1337'
- },
- language: {
- name: 'nodejs',
- version: 'v1337'
- }
}
},
parent: {
id: 'parentId'
},
span: {
- duration: {
- us: 1337
- },
+ action: 'my action',
+ duration: { us: 1337 },
+ id: 'span id',
name: 'span name',
- type: 'span type',
- id: 1337,
- hex_id: 'hex id'
+ subtype: 'my subtype',
+ sync: false,
+ type: 'span type'
},
transaction: {
id: 'transaction id'
@@ -230,12 +100,11 @@ describe('Span v2', () => {
matchSnapshot(span);
});
-describe('Error v2', () => {
+describe('Error', () => {
const errorDoc: APMError = {
agent: {
- hostname: 'agent hostname',
- type: 'apm-server',
- version: '7.0.0'
+ name: 'agent name',
+ version: 'agent version'
},
error: {
exception: {
@@ -248,15 +117,9 @@ describe('Error v2', () => {
id: 'error id',
grouping_key: 'grouping key'
},
- version: 'v2',
'@timestamp': new Date().toString(),
- beat: {
- hostname: 'beat hostname',
- name: 'beat name',
- version: 'beat version'
- },
host: {
- name: 'my hostname'
+ hostname: 'my hostname'
},
processor: {
name: 'error',
@@ -268,19 +131,14 @@ describe('Error v2', () => {
trace: {
id: 'trace id'
},
- context: {
- service: {
- name: 'service name',
- agent: {
- name: 'agent name',
- version: 'v1337'
- },
- language: {
- name: 'nodejs',
- version: 'v1337'
- }
+ service: {
+ name: 'service name',
+ language: {
+ name: 'nodejs',
+ version: 'v1337'
}
},
+ context: {},
parent: {
id: 'parentId'
},
diff --git a/x-pack/plugins/apm/common/constants.ts b/x-pack/plugins/apm/common/constants.ts
index 0afe8115e75d7..4ccc01e2300bb 100644
--- a/x-pack/plugins/apm/common/constants.ts
+++ b/x-pack/plugins/apm/common/constants.ts
@@ -3,12 +3,14 @@
* 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 SERVICE_NAME = 'context.service.name';
-export const SERVICE_AGENT_NAME = 'context.service.agent.name';
-export const SERVICE_LANGUAGE_NAME = 'context.service.language.name';
-export const REQUEST_URL_FULL = 'context.request.url.full';
-export const REQUEST_METHOD = 'context.request.method';
-export const USER_ID = 'context.user.id';
+export const SERVICE_NAME = 'service.name';
+export const SERVICE_AGENT_NAME = 'agent.name';
+export const SERVICE_LANGUAGE_NAME = 'service.language.name';
+export const REQUEST_URL_FULL = 'url.full';
+export const REQUEST_METHOD = 'http.request.method';
+export const USER_ID = 'user.id';
+
+export const OBSERVER_LISTENING = 'observer.listening';
export const PROCESSOR_NAME = 'processor.name';
export const PROCESSOR_EVENT = 'processor.event';
@@ -28,7 +30,6 @@ export const SPAN_TYPE = 'span.type';
export const SPAN_NAME = 'span.name';
export const SPAN_ID = 'span.id';
export const SPAN_SQL = 'context.db.statement';
-export const SPAN_HEX_ID = 'span.hex_id';
// Parent ID for a transaction or span
export const PARENT_ID = 'parent.id';
diff --git a/x-pack/plugins/apm/common/idx.ts b/x-pack/plugins/apm/common/idx.ts
new file mode 100644
index 0000000000000..6513f5f86f1df
--- /dev/null
+++ b/x-pack/plugins/apm/common/idx.ts
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+/**
+ * DeepRequiredArray
+ * Nested array condition handler
+ */
+interface DeepRequiredArray extends Array> {}
+
+/**
+ * DeepRequiredObject
+ * Nested object condition handler
+ */
+type DeepRequiredObject = { [P in keyof T]-?: DeepRequired };
+
+/**
+ * Function that has deeply required return type
+ */
+type FunctionWithRequiredReturnType<
+ T extends (...args: any[]) => any
+> = T extends (...args: infer A) => infer R
+ ? (...args: A) => DeepRequired
+ : never;
+
+/**
+ * DeepRequired
+ * Required that works for deeply nested structure
+ */
+type DeepRequired = NonNullable extends never
+ ? T
+ : T extends any[]
+ ? DeepRequiredArray
+ : T extends (...args: any[]) => any
+ ? FunctionWithRequiredReturnType
+ : NonNullable extends object
+ ? DeepRequiredObject>
+ : T;
+
+export function idx(
+ input: T1,
+ accessor: (input: NonNullable>) => T2
+): T2 | undefined {
+ try {
+ return accessor(input as NonNullable>);
+ } catch (error) {
+ return undefined;
+ }
+}
diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/DetailView.test.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/DetailView.test.tsx
index c32919b09a0a3..854de5d203a50 100644
--- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/DetailView.test.tsx
+++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/DetailView.test.tsx
@@ -40,11 +40,10 @@ describe('DetailView', () => {
occurrencesCount: 10,
error: ({
'@timestamp': 'myTimestamp',
- context: {
- service: { name: 'myService' },
- user: { id: 'myUserId' },
- request: { method: 'GET', url: { full: 'myUrl' } }
- },
+ http: { request: { method: 'GET' } },
+ url: { full: 'myUrl' },
+ service: { name: 'myService' },
+ user: { id: 'myUserId' },
error: { exception: { handled: true } },
transaction: { id: 'myTransactionId', sampled: true }
} as unknown) as APMError
@@ -69,25 +68,23 @@ describe('DetailView', () => {
data: {
occurrencesCount: 10,
transaction: ({
+ http: { request: { method: 'GET' } },
+ url: { full: 'myUrl' },
trace: { id: 'traceId' },
transaction: {
type: 'myTransactionType',
name: 'myTransactionName',
id: 'myTransactionName'
},
- context: {
- service: { name: 'myService' },
- user: { id: 'myUserId' },
- request: { method: 'GET', url: { full: 'myUrl' } }
- }
+ service: { name: 'myService' },
+ user: { id: 'myUserId' }
} as unknown) as Transaction,
error: ({
'@timestamp': 'myTimestamp',
- context: {
- service: { name: 'myService' },
- user: { id: 'myUserId' },
- request: { method: 'GET', url: { full: 'myUrl' } }
- },
+ http: { request: { method: 'GET' } },
+ url: { full: 'myUrl' },
+ service: { name: 'myService' },
+ user: { id: 'myUserId' },
error: { exception: { handled: true } },
transaction: { id: 'myTransactionId', sampled: true }
} as unknown) as APMError
@@ -113,7 +110,8 @@ describe('DetailView', () => {
occurrencesCount: 10,
error: ({
'@timestamp': 'myTimestamp',
- context: { service: {}, user: {}, request: {} }
+ service: {},
+ user: {}
} as unknown) as APMError
}
};
diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/__snapshots__/DetailView.test.tsx.snap b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/__snapshots__/DetailView.test.tsx.snap
index 00580027c064d..5b9ce6cfa947f 100644
--- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/__snapshots__/DetailView.test.tsx.snap
+++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/__snapshots__/DetailView.test.tsx.snap
@@ -5,29 +5,29 @@ exports[`DetailView should render Discover button 1`] = `
error={
Object {
"@timestamp": "myTimestamp",
- "context": Object {
- "request": Object {
- "method": "GET",
- "url": Object {
- "full": "myUrl",
- },
- },
- "service": Object {
- "name": "myService",
- },
- "user": Object {
- "id": "myUserId",
- },
- },
"error": Object {
"exception": Object {
"handled": true,
},
},
+ "http": Object {
+ "request": Object {
+ "method": "GET",
+ },
+ },
+ "service": Object {
+ "name": "myService",
+ },
"transaction": Object {
"id": "myTransactionId",
"sampled": true,
},
+ "url": Object {
+ "full": "myUrl",
+ },
+ "user": Object {
+ "id": "myUserId",
+ },
}
}
>
@@ -53,14 +53,14 @@ exports[`DetailView should render StickyProperties 1`] = `
"width": "50%",
},
Object {
- "fieldName": "context.request.url.full",
+ "fieldName": "url.full",
"label": "URL",
"truncated": true,
"val": "myUrl",
"width": "50%",
},
Object {
- "fieldName": "context.request.method",
+ "fieldName": "http.request.method",
"label": "Request method",
"val": "GET",
"width": "25%",
@@ -88,7 +88,7 @@ exports[`DetailView should render StickyProperties 1`] = `
"width": "25%",
},
Object {
- "fieldName": "context.user.id",
+ "fieldName": "user.id",
"label": "User ID",
"val": "myUserId",
"width": "25%",
@@ -128,14 +128,6 @@ exports[`DetailView should render tabs 1`] = `
>
Exception stacktrace
-
- Request
-
- Tags
-
-
- Custom
+ Labels
`;
diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx
index 6b5cfa2d280e1..7b23c58cd81d0 100644
--- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx
@@ -13,7 +13,6 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { Location } from 'history';
-import idx from 'idx';
import { first, get } from 'lodash';
import React from 'react';
import { RRRRenderResponse } from 'react-redux-request';
@@ -22,6 +21,7 @@ import {
ERROR_EXC_STACKTRACE,
ERROR_LOG_STACKTRACE
} from 'x-pack/plugins/apm/common/constants';
+import { idx } from 'x-pack/plugins/apm/common/idx';
import { KibanaLink } from 'x-pack/plugins/apm/public/components/shared/Links/KibanaLink';
import { legacyEncodeURIComponent } from 'x-pack/plugins/apm/public/components/shared/Links/url_helpers';
import {
@@ -33,7 +33,7 @@ import { NOT_AVAILABLE_LABEL } from 'x-pack/plugins/apm/public/constants';
import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams';
import { ErrorGroupAPIResponse } from 'x-pack/plugins/apm/server/lib/errors/get_error_group';
import { APMError } from 'x-pack/plugins/apm/typings/es_schemas/Error';
-import { IStackframe } from 'x-pack/plugins/apm/typings/es_schemas/Stackframe';
+import { IStackframe } from 'x-pack/plugins/apm/typings/es_schemas/fields/Stackframe';
import { Transaction } from 'x-pack/plugins/apm/typings/es_schemas/Transaction';
import {
ERROR_EXC_HANDLED,
@@ -54,9 +54,9 @@ import {
import { DiscoverErrorLink } from '../../../shared/Links/DiscoverLinks/DiscoverErrorLink';
import {
getPropertyTabNames,
- PropertiesTable,
- Tab
+ PropertiesTable
} from '../../../shared/PropertiesTable';
+import { Tab } from '../../../shared/PropertiesTable/propertyConfig';
import { Stacktrace } from '../../../shared/Stacktrace';
import { StickyProperties } from '../../../shared/StickyProperties';
@@ -126,7 +126,7 @@ export function DetailView({ errorGroup, urlParams, location }: Props) {
label: 'URL',
val:
idx(error, _ => _.context.page.url) ||
- idx(transaction, _ => _.context.request.url.full) ||
+ idx(transaction, _ => _.url.full) ||
NOT_AVAILABLE_LABEL,
truncated: true,
width: '50%'
@@ -239,7 +239,7 @@ function getTransactionLink(error: APMError, transaction?: Transaction) {
}
const path = `/${
- transaction.context.service.name
+ transaction.service.name
}/transactions/${legacyEncodeURIComponent(
transaction.transaction.type
)}/${legacyEncodeURIComponent(transaction.transaction.name)}`;
@@ -266,8 +266,8 @@ export function TabContent({
error: APMError;
currentTab: Tab;
}) {
- const codeLanguage = error.context.service.name;
- const agentName = error.context.service.agent.name;
+ const codeLanguage = error.service.name;
+ const agentName = error.agent.name;
const excStackframes: MaybeStackframes = get(error, ERROR_EXC_STACKTRACE);
const logStackframes: MaybeStackframes = get(error, ERROR_LOG_STACKTRACE);
@@ -281,7 +281,7 @@ export function TabContent({
);
default:
- const propData = error.context[currentTab.key] as any;
+ const propData = get(error, currentTab);
return (
0;
- const contextKeys = Object.keys(error.context);
-
return [
...(hasLogStacktrace ? [logStacktraceTab] : []),
exceptionStacktraceTab,
- ...getPropertyTabNames(contextKeys)
+ ...getPropertyTabNames(error)
];
}
diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/__test__/__snapshots__/createErrorGroupWatch.test.js.snap b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/__test__/__snapshots__/createErrorGroupWatch.test.js.snap
index b7b9ddb5c4687..88f254747c686 100644
--- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/__test__/__snapshots__/createErrorGroupWatch.test.js.snap
+++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/__test__/__snapshots__/createErrorGroupWatch.test.js.snap
@@ -120,7 +120,7 @@ Object {
"filter": Array [
Object {
"term": Object {
- "context.service.name": "opbeans-node",
+ "service.name": "opbeans-node",
},
},
Object {
diff --git a/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx b/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx
index d2ae8aca3817d..8a3880156b792 100644
--- a/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx
+++ b/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx
@@ -44,7 +44,7 @@ const traceListColumns: ITableColumn[] = [
)
},
{
- field: 'sample.context.service.name',
+ field: 'sample.service.name',
name: i18n.translate(
'xpack.apm.tracesTable.originatingServiceColumnLabel',
{
diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/StickyTransactionProperties.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/StickyTransactionProperties.tsx
index b8682ff3a8335..f4547a07bbd12 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/StickyTransactionProperties.tsx
+++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/StickyTransactionProperties.tsx
@@ -5,9 +5,9 @@
*/
import { i18n } from '@kbn/i18n';
-import idx from 'idx';
import { get } from 'lodash';
import React from 'react';
+import { idx } from 'x-pack/plugins/apm/common/idx';
import {
REQUEST_URL_FULL,
TRANSACTION_DURATION,
@@ -34,7 +34,7 @@ export function StickyTransactionProperties({
const timestamp = transaction['@timestamp'];
const url =
idx(transaction, _ => _.context.page.url) ||
- idx(transaction, _ => _.context.request.url.full) ||
+ idx(transaction, _ => _.url.full) ||
NOT_AVAILABLE_LABEL;
const duration = transaction.transaction.duration.us;
const stickyProperties: IStickyProperty[] = [
diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/TransactionPropertiesTable.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/TransactionPropertiesTable.tsx
index 901adfd68e789..035749d18cb29 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/TransactionPropertiesTable.tsx
+++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/TransactionPropertiesTable.tsx
@@ -20,9 +20,9 @@ import { IUrlParams } from '../../../../store/urlParams';
import { px, units } from '../../../../style/variables';
import {
getPropertyTabNames,
- PropertiesTable,
- Tab
+ PropertiesTable
} from '../../../shared/PropertiesTable';
+import { Tab } from '../../../shared/PropertiesTable/propertyConfig';
import { WaterfallContainer } from './WaterfallContainer';
import { IWaterfall } from './WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers';
@@ -44,9 +44,8 @@ const timelineTab = {
})
};
-function getTabs(transactionData: Transaction) {
- const dynamicProps = Object.keys(transactionData.context || {});
- return [timelineTab, ...getPropertyTabNames(dynamicProps)];
+function getTabs(transaction: Transaction) {
+ return [timelineTab, ...getPropertyTabNames(transaction)];
}
interface TransactionPropertiesTableProps {
@@ -64,7 +63,8 @@ export function TransactionPropertiesTable({
}: TransactionPropertiesTableProps) {
const tabs = getTabs(transaction);
const currentTab = getCurrentTab(tabs, urlParams.detailTab);
- const agentName = transaction.context.service.agent.name;
+ const agentName = transaction.agent.name;
+ const isTimelineTab = currentTab.key === timelineTab.key;
return (
@@ -92,19 +92,17 @@ export function TransactionPropertiesTable({
- {currentTab.key === timelineTab.key && (
+ {isTimelineTab ? (
- )}
-
- {currentTab.key !== timelineTab.key && (
+ ) : (
diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/TransactionPropertiesTableForFlyout.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/TransactionPropertiesTableForFlyout.tsx
index a0cc5f6a3c898..8fc1918f016a3 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/TransactionPropertiesTableForFlyout.tsx
+++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/TransactionPropertiesTableForFlyout.tsx
@@ -17,9 +17,9 @@ import { Transaction } from '../../../../../typings/es_schemas/Transaction';
import { IUrlParams } from '../../../../store/urlParams';
import {
getPropertyTabNames,
- PropertiesTable,
- Tab
+ PropertiesTable
} from '../../../shared/PropertiesTable';
+import { Tab } from '../../../shared/PropertiesTable/propertyConfig';
// Ensure the selected tab exists or use the first
function getCurrentTab(tabs: Tab[] = [], selectedTabKey?: string) {
@@ -27,9 +27,8 @@ function getCurrentTab(tabs: Tab[] = [], selectedTabKey?: string) {
return selectedTab ? selectedTab : first(tabs) || {};
}
-function getTabs(transactionData: Transaction) {
- const dynamicProps = Object.keys(transactionData.context || {});
- return getPropertyTabNames(dynamicProps);
+function getTabs(transaction: Transaction) {
+ return getPropertyTabNames(transaction);
}
interface Props {
@@ -45,7 +44,7 @@ export const TransactionPropertiesTableForFlyout: React.SFC = ({
}) => {
const tabs = getTabs(transaction);
const currentTab = getCurrentTab(tabs, urlParams.flyoutDetailTab);
- const agentName = transaction.context.service.agent.name;
+ const agentName = transaction.agent.name;
return (
@@ -72,7 +71,7 @@ export const TransactionPropertiesTableForFlyout: React.SFC
= ({
diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/FlyoutTopLevelProperties.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/FlyoutTopLevelProperties.tsx
index 80ead9bf70d7e..8bde28f2fef16 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/FlyoutTopLevelProperties.tsx
+++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/FlyoutTopLevelProperties.tsx
@@ -31,8 +31,8 @@ export function FlyoutTopLevelProperties({ transaction }: Props) {
}),
fieldName: SERVICE_NAME,
val: (
-
- {transaction.context.service.name}
+
+ {transaction.service.name}
),
width: '50%'
diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/DatabaseContext.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/DatabaseContext.tsx
index 891282497fbad..4c9519ce1ced8 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/DatabaseContext.tsx
+++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/DatabaseContext.tsx
@@ -16,7 +16,7 @@ import SyntaxHighlighter, {
// @ts-ignore
import { xcode } from 'react-syntax-highlighter/dist/styles';
import styled from 'styled-components';
-import { DbContext } from '../../../../../../../../typings/es_schemas/Span';
+import { Span } from 'x-pack/plugins/apm/typings/es_schemas/Span';
import {
borderRadius,
colors,
@@ -37,7 +37,7 @@ const DatabaseStatement = styled.div`
`;
interface Props {
- dbContext?: DbContext;
+ dbContext?: NonNullable['db'];
}
export function DatabaseContext({ dbContext }: Props) {
diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/HttpContext.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/HttpContext.tsx
index ae8f1b44c0888..790100d464ee7 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/HttpContext.tsx
+++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/HttpContext.tsx
@@ -27,7 +27,7 @@ const ContextUrl = styled.div`
`;
interface Props {
- httpContext: Span['context']['http'];
+ httpContext: NonNullable['http'];
}
export function HttpContext({ httpContext }: Props) {
diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/index.tsx
index c988540bd290c..c3831a26c3163 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/index.tsx
@@ -22,18 +22,16 @@ import { i18n } from '@kbn/i18n';
import { get, keys } from 'lodash';
import React, { Fragment } from 'react';
import styled from 'styled-components';
-
-import { SERVICE_LANGUAGE_NAME } from '../../../../../../../../common/constants';
-
-import { DatabaseContext } from './DatabaseContext';
-import { HttpContext } from './HttpContext';
-import { StickySpanProperties } from './StickySpanProperties';
-
+import { idx } from 'x-pack/plugins/apm/common/idx';
import { DiscoverSpanLink } from 'x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverSpanLink';
import { Stacktrace } from 'x-pack/plugins/apm/public/components/shared/Stacktrace';
import { Transaction } from 'x-pack/plugins/apm/typings/es_schemas/Transaction';
+import { SERVICE_LANGUAGE_NAME } from '../../../../../../../../common/constants';
import { Span } from '../../../../../../../../typings/es_schemas/Span';
import { FlyoutTopLevelProperties } from '../FlyoutTopLevelProperties';
+import { DatabaseContext } from './DatabaseContext';
+import { HttpContext } from './HttpContext';
+import { StickySpanProperties } from './StickySpanProperties';
const TagName = styled.div`
font-weight: bold;
@@ -55,14 +53,15 @@ export function SpanFlyout({
if (!span) {
return null;
}
+
const stackframes = span.span.stacktrace;
const codeLanguage: string = get(span, SERVICE_LANGUAGE_NAME);
- const dbContext = span.context.db;
- const httpContext = span.context.http;
- const tagContext = span.context.tags;
- const tags = keys(tagContext).map(key => ({
+ const dbContext = idx(span, _ => _.context.db);
+ const httpContext = idx(span, _ => _.context.http);
+ const labels = span.labels;
+ const tags = keys(labels).map(key => ({
key,
- value: get(tagContext, key)
+ value: get(labels, key)
}));
return (
diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/TransactionFlyout/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/TransactionFlyout/index.tsx
index f658c0f906a91..90817b23a69a2 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/TransactionFlyout/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/TransactionFlyout/index.tsx
@@ -18,9 +18,9 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { Location } from 'history';
-import { get } from 'lodash';
import React from 'react';
import styled from 'styled-components';
+import { idx } from 'x-pack/plugins/apm/common/idx';
import { TransactionActionMenu } from 'x-pack/plugins/apm/public/components/shared/TransactionActionMenu/TransactionActionMenu';
import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams';
import { DROPPED_SPANS_DOCS } from 'x-pack/plugins/apm/public/utils/documentation/apm-get-started';
@@ -63,13 +63,8 @@ function DroppedSpansWarning({
}: {
transactionDoc: Transaction;
}) {
- const dropped: number = get(
- transactionDoc,
- 'transaction.span_count.dropped.total',
- 0
- );
-
- if (dropped === 0) {
+ const dropped = idx(transactionDoc, _ => _.transaction.span_count.dropped);
+ if (!dropped) {
return null;
}
diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/WaterfallItem.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/WaterfallItem.tsx
index 9cf10db1f26ba..6649952e135cd 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/WaterfallItem.tsx
+++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/WaterfallItem.tsx
@@ -104,7 +104,7 @@ function PrefixIcon({ item }: { item: IWaterfallItem }) {
}
// icon for RUM agent transactions
- const isRumAgent = item.transaction.context.service.agent.name === 'js-base';
+ const isRumAgent = item.transaction.agent.name === 'js-base';
if (isRumAgent) {
return ;
}
diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/mock_responses/spans.json b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/mock_responses/spans.json
index e12fe757ef1ee..fc16c4ddc9213 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/mock_responses/spans.json
+++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/mock_responses/spans.json
@@ -16,23 +16,23 @@
"duration": {
"us": 1380
},
- "hex_id": "8143a38f3367fd97"
+ "id": "8143a38f3367fd97"
},
"transaction": {
"id": "e070bc3c732087f8"
},
+ "service": {
+ "name": "opbeans-java",
+ "agent": {
+ "version": "0.7.0-SNAPSHOT",
+ "name": "java"
+ }
+ },
"context": {
"db": {
"statement": "select order0_.id as col_0_0_, order0_.created_at as col_1_0_, customer1_.full_name as col_2_0_ from orders order0_ left outer join customers customer1_ on order0_.customer_id=customer1_.id",
"type": "sql",
"user": "SA"
- },
- "service": {
- "name": "opbeans-java",
- "agent": {
- "version": "0.7.0-SNAPSHOT",
- "name": "java"
- }
}
},
"beat": {
@@ -41,7 +41,7 @@
"hostname": "361022bff072"
},
"host": {
- "name": "361022bff072"
+ "hostname": "361022bff072"
}
}
]
diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/mock_responses/transaction.json b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/mock_responses/transaction.json
index 401b8473ec3fc..0e6272d8dfe37 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/mock_responses/transaction.json
+++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/mock_responses/transaction.json
@@ -14,13 +14,31 @@
"sampled": true,
"span_count": {
"started": 1,
- "dropped": {
- "total": 0
- }
+ "dropped": 0
},
"id": "e070bc3c732087f8",
"name": "APIRestController#orders"
},
+ "service": {
+ "language": {
+ "version": "10.0.2",
+ "name": "Java"
+ },
+ "runtime": {
+ "name": "Java",
+ "version": "10.0.2"
+ },
+ "name": "opbeans-java",
+ "agent": {
+ "name": "java",
+ "version": "0.7.0-SNAPSHOT"
+ }
+ },
+ "process": {
+ "ppid": 10060,
+ "title": "/Library/Java/JavaVirtualMachines/jdk-10.0.2.jdk/Contents/Home/bin/java",
+ "pid": 10069
+ },
"context": {
"request": {
"url": {
@@ -60,26 +78,6 @@
"platform": "Srens-MacBook-Pro.local",
"ip": "172.18.0.1",
"hostname": "Mac OS X"
- },
- "process": {
- "ppid": 10060,
- "title": "/Library/Java/JavaVirtualMachines/jdk-10.0.2.jdk/Contents/Home/bin/java",
- "pid": 10069
- },
- "service": {
- "language": {
- "version": "10.0.2",
- "name": "Java"
- },
- "runtime": {
- "name": "Java",
- "version": "10.0.2"
- },
- "name": "opbeans-java",
- "agent": {
- "name": "java",
- "version": "0.7.0-SNAPSHOT"
- }
}
},
"beat": {
@@ -88,6 +86,6 @@
"hostname": "361022bff072"
},
"host": {
- "name": "361022bff072"
+ "hostname": "361022bff072"
}
}
diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.ts b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.ts
index ee4f382f19550..9807787727448 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.ts
+++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.ts
@@ -84,24 +84,10 @@ export type IWaterfallItem = IWaterfallItemSpan | IWaterfallItemTransaction;
function getTransactionItem(
transaction: Transaction
): IWaterfallItemTransaction {
- if (transaction.version === 'v1') {
- return {
- id: transaction.transaction.id,
- serviceName: transaction.context.service.name,
- name: transaction.transaction.name,
- duration: transaction.transaction.duration.us,
- timestamp: new Date(transaction['@timestamp']).getTime() * 1000,
- offset: 0,
- skew: 0,
- docType: 'transaction',
- transaction
- };
- }
-
return {
id: transaction.transaction.id,
parentId: transaction.parent && transaction.parent.id,
- serviceName: transaction.context.service.name,
+ serviceName: transaction.service.name,
name: transaction.transaction.name,
duration: transaction.transaction.duration.us,
timestamp: transaction.timestamp.us,
@@ -113,26 +99,10 @@ function getTransactionItem(
}
function getSpanItem(span: Span): IWaterfallItemSpan {
- if (span.version === 'v1') {
- return {
- id: span.span.id,
- parentId: span.span.parent || span.transaction.id,
- serviceName: span.context.service.name,
- name: span.span.name,
- duration: span.span.duration.us,
- timestamp:
- new Date(span['@timestamp']).getTime() * 1000 + span.span.start.us,
- offset: 0,
- skew: 0,
- docType: 'span',
- span
- };
- }
-
return {
- id: span.span.hex_id,
+ id: span.span.id,
parentId: span.parent && span.parent.id,
- serviceName: span.context.service.name,
+ serviceName: span.service.name,
name: span.span.name,
duration: span.span.duration.us,
timestamp: span.timestamp.us,
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverErrorLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverErrorLink.tsx
index d00fa332d1543..9019df6132149 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverErrorLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverErrorLink.tsx
@@ -13,7 +13,7 @@ import { APMError } from 'x-pack/plugins/apm/typings/es_schemas/Error';
import { DiscoverLink } from './DiscoverLink';
function getDiscoverQuery(error: APMError, kuery?: string) {
- const serviceName = error.context.service.name;
+ const serviceName = error.service.name;
const groupId = error.error.grouping_key;
let query = `${SERVICE_NAME}:"${serviceName}" AND ${ERROR_GROUP_ID}:"${groupId}"`;
if (kuery) {
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverSpanLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverSpanLink.tsx
index f508cfc0e9469..7c094cad230e3 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverSpanLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverSpanLink.tsx
@@ -5,16 +5,12 @@
*/
import React from 'react';
-import { SPAN_HEX_ID, SPAN_ID } from 'x-pack/plugins/apm/common/constants';
+import { SPAN_ID } from 'x-pack/plugins/apm/common/constants';
import { Span } from 'x-pack/plugins/apm/typings/es_schemas/Span';
import { DiscoverLink } from './DiscoverLink';
function getDiscoverQuery(span: Span) {
- const query =
- span.version === 'v2'
- ? `${SPAN_HEX_ID}:"${span.span.hex_id}"`
- : `${SPAN_ID}:"${span.span.id}"`;
-
+ const query = `${SPAN_ID}:"${span.span.id}"`;
return {
_a: {
interval: 'auto',
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverTransactionLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverTransactionLink.tsx
index 4845abe780b95..6539607a0ca87 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverTransactionLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverTransactionLink.tsx
@@ -15,8 +15,7 @@ import { DiscoverLink } from './DiscoverLink';
export function getDiscoverQuery(transaction: Transaction) {
const transactionId = transaction.transaction.id;
- const traceId =
- transaction.version === 'v2' ? transaction.trace.id : undefined;
+ const traceId = transaction.trace.id;
let query = `${PROCESSOR_EVENT}:"transaction" AND ${TRANSACTION_ID}:"${transactionId}"`;
if (traceId) {
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/DiscoverErrorButton.test.tsx b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/DiscoverErrorButton.test.tsx
index 7eee92ee5396e..2d5a3909b8ce3 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/DiscoverErrorButton.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/DiscoverErrorButton.test.tsx
@@ -14,7 +14,7 @@ describe('DiscoverErrorLink without kuery', () => {
let wrapper: ShallowWrapper;
beforeEach(() => {
const error = {
- context: { service: { name: 'myServiceName' } },
+ service: { name: 'myServiceName' },
error: { grouping_key: 'myGroupingKey' }
} as APMError;
@@ -24,7 +24,7 @@ describe('DiscoverErrorLink without kuery', () => {
it('should have correct query', () => {
const queryProp = wrapper.prop('query') as any;
expect(queryProp._a.query.query).toEqual(
- 'context.service.name:"myServiceName" AND error.grouping_key:"myGroupingKey"'
+ 'service.name:"myServiceName" AND error.grouping_key:"myGroupingKey"'
);
});
@@ -37,7 +37,7 @@ describe('DiscoverErrorLink with kuery', () => {
let wrapper: ShallowWrapper;
beforeEach(() => {
const error = {
- context: { service: { name: 'myServiceName' } },
+ service: { name: 'myServiceName' },
error: { grouping_key: 'myGroupingKey' }
} as APMError;
@@ -49,7 +49,7 @@ describe('DiscoverErrorLink with kuery', () => {
it('should have correct query', () => {
const queryProp = wrapper.prop('query') as any;
expect(queryProp._a.query.query).toEqual(
- 'context.service.name:"myServiceName" AND error.grouping_key:"myGroupingKey" AND transaction.sampled: true'
+ 'service.name:"myServiceName" AND error.grouping_key:"myGroupingKey" AND transaction.sampled: true'
);
});
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/__snapshots__/DiscoverErrorButton.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/__snapshots__/DiscoverErrorButton.test.tsx.snap
index 85f5a27f7f3f7..61007f91dcedd 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/__snapshots__/DiscoverErrorButton.test.tsx.snap
+++ b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/__snapshots__/DiscoverErrorButton.test.tsx.snap
@@ -8,7 +8,7 @@ exports[`DiscoverErrorLink with kuery should match snapshot 1`] = `
"interval": "auto",
"query": Object {
"language": "lucene",
- "query": "context.service.name:\\"myServiceName\\" AND error.grouping_key:\\"myGroupingKey\\" AND transaction.sampled: true",
+ "query": "service.name:\\"myServiceName\\" AND error.grouping_key:\\"myGroupingKey\\" AND transaction.sampled: true",
},
"sort": Object {
"@timestamp": "desc",
@@ -27,7 +27,7 @@ exports[`DiscoverErrorLink without kuery should match snapshot 1`] = `
"interval": "auto",
"query": Object {
"language": "lucene",
- "query": "context.service.name:\\"myServiceName\\" AND error.grouping_key:\\"myGroupingKey\\"",
+ "query": "service.name:\\"myServiceName\\" AND error.grouping_key:\\"myGroupingKey\\"",
},
"sort": Object {
"@timestamp": "desc",
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/mockTransaction.json b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/mockTransaction.json
index e70eab1b9e80c..4d038cd7e8397 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/mockTransaction.json
+++ b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/mockTransaction.json
@@ -13,7 +13,38 @@
},
"@timestamp": "2018-12-18T00:14:30.952Z",
"host": {
- "name": "227453131a17"
+ "hostname": "227453131a17"
+ },
+ "service": {
+ "agent": {
+ "name": "go",
+ "version": "1.1.1"
+ },
+ "framework": {
+ "name": "gin",
+ "version": "v1.4.0-dev"
+ },
+ "name": "opbeans-go",
+ "runtime": {
+ "name": "gc",
+ "version": "go1.10.6"
+ },
+ "language": {
+ "name": "go",
+ "version": "go1.10.6"
+ }
+ },
+ "process": {
+ "pid": 1,
+ "title": "opbeans-go",
+ "argv": [
+ "/opbeans-go",
+ "-listen=:3000",
+ "-frontend=/opbeans-frontend",
+ "-db=postgres:",
+ "-cache=redis://redis:6379"
+ ],
+ "ppid": 0
},
"context": {
"request": {
@@ -35,18 +66,6 @@
"pathname": "/api/products/3/customers"
}
},
- "process": {
- "pid": 1,
- "title": "opbeans-go",
- "argv": [
- "/opbeans-go",
- "-listen=:3000",
- "-frontend=/opbeans-frontend",
- "-db=postgres:",
- "-cache=redis://redis:6379"
- ],
- "ppid": 0
- },
"system": {
"hostname": "8acb9c1a71f3",
"ip": "172.18.0.7",
@@ -63,25 +82,6 @@
"Content-Type": "application/json; charset=utf-8"
},
"status_code": 200
- },
- "service": {
- "agent": {
- "name": "go",
- "version": "1.1.1"
- },
- "framework": {
- "name": "gin",
- "version": "v1.4.0-dev"
- },
- "name": "opbeans-go",
- "runtime": {
- "name": "gc",
- "version": "go1.10.6"
- },
- "language": {
- "name": "go",
- "version": "go1.10.6"
- }
}
},
"transaction": {
@@ -110,6 +110,5 @@
},
"timestamp": {
"us": 1545092070952472
- },
- "version": "v2"
+ }
}
diff --git a/x-pack/plugins/apm/public/components/shared/PropertiesTable/__test__/PropertiesTable.test.tsx b/x-pack/plugins/apm/public/components/shared/PropertiesTable/__test__/PropertiesTable.test.tsx
index 61af939f39114..2d350bc8eea6c 100644
--- a/x-pack/plugins/apm/public/components/shared/PropertiesTable/__test__/PropertiesTable.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/PropertiesTable/__test__/PropertiesTable.test.tsx
@@ -100,7 +100,9 @@ describe('PropertiesTable', () => {
label: 'requiredPropertyLabel'
}
];
- expect(getPropertyTabNames(['testProperty'])).toEqual(expectedTabsConfig);
+ expect(getPropertyTabNames({ testProperty: {} } as any)).toEqual(
+ expectedTabsConfig
+ );
});
});
diff --git a/x-pack/plugins/apm/public/components/shared/PropertiesTable/index.tsx b/x-pack/plugins/apm/public/components/shared/PropertiesTable/index.tsx
index bc29d1e20e8f1..520f4a4149e4c 100644
--- a/x-pack/plugins/apm/public/components/shared/PropertiesTable/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/PropertiesTable/index.tsx
@@ -10,6 +10,8 @@ import { i18n } from '@kbn/i18n';
import { get, indexBy, uniq } from 'lodash';
import React from 'react';
import styled from 'styled-components';
+import { APMError } from 'x-pack/plugins/apm/typings/es_schemas/Error';
+import { Transaction } from 'x-pack/plugins/apm/typings/es_schemas/Transaction';
import { StringMap } from '../../../../typings/common';
import {
colors,
@@ -44,14 +46,9 @@ const EuiIconWithSpace = styled(EuiIcon)`
margin-right: ${px(units.half)};
`;
-export interface Tab {
- key: string;
- label: string;
-}
-
-export function getPropertyTabNames(selected: string[]): Tab[] {
+export function getPropertyTabNames(obj: Transaction | APMError) {
return PROPERTY_CONFIG.filter(
- ({ key, required }) => required || selected.includes(key)
+ ({ key, required }) => required || obj.hasOwnProperty(key)
).map(({ key, label }) => ({ key, label }));
}
diff --git a/x-pack/plugins/apm/public/components/shared/PropertiesTable/propertyConfig.ts b/x-pack/plugins/apm/public/components/shared/PropertiesTable/propertyConfig.ts
index 35f76dd8a1ccd..3cb34230b3496 100644
--- a/x-pack/plugins/apm/public/components/shared/PropertiesTable/propertyConfig.ts
+++ b/x-pack/plugins/apm/public/components/shared/PropertiesTable/propertyConfig.ts
@@ -5,39 +5,53 @@
*/
import { i18n } from '@kbn/i18n';
+import { APMError } from 'x-pack/plugins/apm/typings/es_schemas/Error';
+import { Transaction } from 'x-pack/plugins/apm/typings/es_schemas/Transaction';
+
+export interface Tab {
+ key: string;
+ label: string;
+}
+
+type AllKeys = keyof NonNullable | keyof NonNullable;
+interface ConfigItem {
+ key: T;
+ label: string;
+ required: boolean;
+ presortedKeys: Array<
+ T extends keyof Transaction
+ ? keyof NonNullable
+ : T extends keyof APMError
+ ? keyof NonNullable
+ : never
+ >;
+}
export const PROPERTY_CONFIG = [
{
- key: 'request',
- label: i18n.translate('xpack.apm.propertiesTable.tabs.requestLabel', {
- defaultMessage: 'Request'
+ key: 'url',
+ label: i18n.translate('xpack.apm.propertiesTable.tabs.urlLabel', {
+ defaultMessage: 'Url'
}),
required: false,
- presortedKeys: [
- 'http_version',
- 'method',
- 'url',
- 'socket',
- 'headers',
- 'body'
- ]
- },
+ presortedKeys: []
+ } as ConfigItem<'url'>,
{
- key: 'response',
- label: i18n.translate('xpack.apm.propertiesTable.tabs.responseLabel', {
- defaultMessage: 'Response'
+ key: 'http',
+ label: i18n.translate('xpack.apm.propertiesTable.tabs.httpLabel', {
+ defaultMessage: 'HTTP'
}),
required: false,
- presortedKeys: ['status_code', 'headers', 'headers_sent', 'finished']
- },
+ presortedKeys: []
+ } as ConfigItem<'http'>,
{
- key: 'system',
- label: i18n.translate('xpack.apm.propertiesTable.tabs.systemLabel', {
- defaultMessage: 'System'
+ key: 'host',
+ label: i18n.translate('xpack.apm.propertiesTable.tabs.hostLabel', {
+ defaultMessage: 'Host'
}),
required: false,
presortedKeys: ['hostname', 'architecture', 'platform']
- },
+ } as ConfigItem<'host'>,
{
key: 'service',
label: i18n.translate('xpack.apm.propertiesTable.tabs.serviceLabel', {
@@ -45,15 +59,15 @@ export const PROPERTY_CONFIG = [
}),
required: false,
presortedKeys: ['runtime', 'framework', 'agent', 'version']
- },
+ } as ConfigItem<'service'>,
{
key: 'process',
label: i18n.translate('xpack.apm.propertiesTable.tabs.processLabel', {
defaultMessage: 'Process'
}),
required: false,
- presortedKeys: ['pid', 'title', 'argv']
- },
+ presortedKeys: ['pid', 'title', 'args']
+ } as ConfigItem<'process'>,
{
key: 'user',
label: i18n.translate('xpack.apm.propertiesTable.tabs.userLabel', {
@@ -61,21 +75,13 @@ export const PROPERTY_CONFIG = [
}),
required: true,
presortedKeys: ['id', 'username', 'email']
- },
- {
- key: 'tags',
- label: i18n.translate('xpack.apm.propertiesTable.tabs.tagsLabel', {
- defaultMessage: 'Tags'
- }),
- required: true,
- presortedKeys: []
- },
+ } as ConfigItem<'user'>,
{
- key: 'custom',
- label: i18n.translate('xpack.apm.propertiesTable.tabs.customLabel', {
- defaultMessage: 'Custom'
+ key: 'labels',
+ label: i18n.translate('xpack.apm.propertiesTable.tabs.labelsLabel', {
+ defaultMessage: 'Labels'
}),
required: true,
presortedKeys: []
- }
+ } as ConfigItem<'labels'>
];
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/Context.tsx b/x-pack/plugins/apm/public/components/shared/Stacktrace/Context.tsx
index 283bb65dcc6b7..53412b2a9237e 100644
--- a/x-pack/plugins/apm/public/components/shared/Stacktrace/Context.tsx
+++ b/x-pack/plugins/apm/public/components/shared/Stacktrace/Context.tsx
@@ -20,7 +20,7 @@ import { registerLanguage } from 'react-syntax-highlighter/dist/light';
// @ts-ignore
import { xcode } from 'react-syntax-highlighter/dist/styles';
import styled from 'styled-components';
-import { IStackframeWithLineContext } from 'x-pack/plugins/apm/typings/es_schemas/Stackframe';
+import { IStackframeWithLineContext } from 'x-pack/plugins/apm/typings/es_schemas/fields/Stackframe';
import {
borderRadius,
colors,
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/FrameHeading.tsx b/x-pack/plugins/apm/public/components/shared/Stacktrace/FrameHeading.tsx
index fbb532067b7e2..a0a9d4b4fe773 100644
--- a/x-pack/plugins/apm/public/components/shared/Stacktrace/FrameHeading.tsx
+++ b/x-pack/plugins/apm/public/components/shared/Stacktrace/FrameHeading.tsx
@@ -7,7 +7,7 @@
import { get } from 'lodash';
import React, { Fragment } from 'react';
import styled from 'styled-components';
-import { IStackframe } from '../../../../typings/es_schemas/Stackframe';
+import { IStackframe } from '../../../../typings/es_schemas/fields/Stackframe';
import { colors, fontFamilyCode, px, units } from '../../../style/variables';
const FileDetails = styled.div`
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/LibraryStackFrames.tsx b/x-pack/plugins/apm/public/components/shared/Stacktrace/LibraryStackFrames.tsx
index 07e4b59a21910..579273507c521 100644
--- a/x-pack/plugins/apm/public/components/shared/Stacktrace/LibraryStackFrames.tsx
+++ b/x-pack/plugins/apm/public/components/shared/Stacktrace/LibraryStackFrames.tsx
@@ -8,7 +8,7 @@ import { EuiLink, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { Fragment } from 'react';
import styled from 'styled-components';
-import { IStackframe } from 'x-pack/plugins/apm/typings/es_schemas/Stackframe';
+import { IStackframe } from 'x-pack/plugins/apm/typings/es_schemas/fields/Stackframe';
import { units } from '../../../style/variables';
// @ts-ignore
import { Ellipsis } from '../../shared/Icons';
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/Stackframe.tsx b/x-pack/plugins/apm/public/components/shared/Stacktrace/Stackframe.tsx
index 5f6e35066dfb2..e3f4ad5cb0105 100644
--- a/x-pack/plugins/apm/public/components/shared/Stacktrace/Stackframe.tsx
+++ b/x-pack/plugins/apm/public/components/shared/Stacktrace/Stackframe.tsx
@@ -9,7 +9,7 @@ import styled from 'styled-components';
import {
IStackframe,
IStackframeWithLineContext
-} from '../../../../typings/es_schemas/Stackframe';
+} from 'x-pack/plugins/apm/typings/es_schemas/fields/Stackframe';
import { borderRadius, colors, fontFamilyCode } from '../../../style/variables';
import { FrameHeading } from '../Stacktrace/FrameHeading';
import { Context } from './Context';
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/Variables.tsx b/x-pack/plugins/apm/public/components/shared/Stacktrace/Variables.tsx
index 16b38a9b1f21b..6030952ec28c3 100644
--- a/x-pack/plugins/apm/public/components/shared/Stacktrace/Variables.tsx
+++ b/x-pack/plugins/apm/public/components/shared/Stacktrace/Variables.tsx
@@ -7,7 +7,7 @@
import { i18n } from '@kbn/i18n';
import React from 'react';
import styled from 'styled-components';
-import { IStackframe } from 'x-pack/plugins/apm/typings/es_schemas/Stackframe';
+import { IStackframe } from 'x-pack/plugins/apm/typings/es_schemas/fields/Stackframe';
import {
borderRadius,
colors,
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/__test__/Stackframe.test.tsx b/x-pack/plugins/apm/public/components/shared/Stacktrace/__test__/Stackframe.test.tsx
index e85c1c70d25a4..0098c51e6e9a1 100644
--- a/x-pack/plugins/apm/public/components/shared/Stacktrace/__test__/Stackframe.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/Stacktrace/__test__/Stackframe.test.tsx
@@ -7,7 +7,7 @@
import { mount, ReactWrapper, shallow } from 'enzyme';
import 'jest-styled-components';
import React from 'react';
-import { IStackframe } from 'x-pack/plugins/apm/typings/es_schemas/Stackframe';
+import { IStackframe } from 'x-pack/plugins/apm/typings/es_schemas/fields/Stackframe';
import { Stackframe } from '../Stackframe';
import stacktracesMock from './stacktraces.json';
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/__test__/index.test.ts b/x-pack/plugins/apm/public/components/shared/Stacktrace/__test__/index.test.ts
index 65ab2cf72aeff..b85d8b55cfd95 100644
--- a/x-pack/plugins/apm/public/components/shared/Stacktrace/__test__/index.test.ts
+++ b/x-pack/plugins/apm/public/components/shared/Stacktrace/__test__/index.test.ts
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { IStackframe } from '../../../../../typings/es_schemas/Stackframe';
+import { IStackframe } from 'x-pack/plugins/apm/typings/es_schemas/fields/Stackframe';
import { getGroupedStackframes } from '../index';
import stacktracesMock from './stacktraces.json';
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/index.tsx b/x-pack/plugins/apm/public/components/shared/Stacktrace/index.tsx
index 084c545dfcae1..8275a45537e85 100644
--- a/x-pack/plugins/apm/public/components/shared/Stacktrace/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/Stacktrace/index.tsx
@@ -8,7 +8,7 @@ import { EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { isEmpty, last } from 'lodash';
import React, { Fragment } from 'react';
-import { IStackframe } from '../../../../typings/es_schemas/Stackframe';
+import { IStackframe } from '../../../../typings/es_schemas/fields/Stackframe';
import { EmptyMessage } from '../../shared/EmptyMessage';
// @ts-ignore
import { Ellipsis } from '../../shared/Icons';
diff --git a/x-pack/plugins/apm/public/components/shared/StickyProperties/StickyProperties.test.js b/x-pack/plugins/apm/public/components/shared/StickyProperties/StickyProperties.test.js
index 1ec04b7d1b0a0..0085b42afc6aa 100644
--- a/x-pack/plugins/apm/public/components/shared/StickyProperties/StickyProperties.test.js
+++ b/x-pack/plugins/apm/public/components/shared/StickyProperties/StickyProperties.test.js
@@ -28,7 +28,7 @@ describe('StickyProperties', () => {
},
{
label: 'Request method',
- fieldName: 'context.request.method',
+ fieldName: 'http.request.method',
val: 'GET'
},
{
diff --git a/x-pack/plugins/apm/public/components/shared/StickyProperties/__snapshots__/StickyProperties.test.js.snap b/x-pack/plugins/apm/public/components/shared/StickyProperties/__snapshots__/StickyProperties.test.js.snap
index de93fc92bc67c..2b76a435def89 100644
--- a/x-pack/plugins/apm/public/components/shared/StickyProperties/__snapshots__/StickyProperties.test.js.snap
+++ b/x-pack/plugins/apm/public/components/shared/StickyProperties/__snapshots__/StickyProperties.test.js.snap
@@ -61,7 +61,7 @@ exports[`StickyProperties should render entire component 1`] = `
- context.request.url.full
+ url.full
}
delay="regular"
@@ -97,7 +97,7 @@ exports[`StickyProperties should render entire component 1`] = `
- context.request.method
+ http.request.method
}
delay="regular"
@@ -157,7 +157,7 @@ exports[`StickyProperties should render entire component 1`] = `
- context.user.id
+ user.id
}
delay="regular"
diff --git a/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/TransactionActionMenu.tsx b/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/TransactionActionMenu.tsx
index 0aa1f37932b35..2761b97dcfb08 100644
--- a/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/TransactionActionMenu.tsx
+++ b/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/TransactionActionMenu.tsx
@@ -16,14 +16,11 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { Location } from 'history';
-import idx from 'idx';
import React from 'react';
+import { idx } from 'x-pack/plugins/apm/common/idx';
import { getKibanaHref } from 'x-pack/plugins/apm/public/components/shared/Links/url_helpers';
import { StringMap } from 'x-pack/plugins/apm/typings/common';
-import {
- Transaction,
- TransactionV2
-} from 'x-pack/plugins/apm/typings/es_schemas/Transaction';
+import { Transaction } from 'x-pack/plugins/apm/typings/es_schemas/Transaction';
import { getDiscoverQuery } from '../Links/DiscoverLinks/DiscoverTransactionLink';
import { QueryWithIndexPattern } from '../Links/DiscoverLinks/QueryWithIndexPattern';
@@ -74,12 +71,9 @@ export class TransactionActionMenu extends React.Component {
public getInfraActions() {
const { transaction, location } = this.props;
- const hostName = idx(transaction, _ => _.context.system.hostname);
- const podId = idx(transaction as TransactionV2, _ => _.kubernetes.pod.uid);
- const containerId = idx(
- transaction as TransactionV2,
- _ => _.docker.container.id
- );
+ const hostName = idx(transaction, _ => _.host.hostname);
+ const podId = idx(transaction, _ => _.kubernetes.pod.uid);
+ const containerId = idx(transaction, _ => _.container.id);
const pathname = '/app/infra';
const time = new Date(transaction['@timestamp']).getTime();
const infraMetricsQuery = getInfraMetricsQuery(transaction);
diff --git a/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/__test__/TransactionActionMenu.test.tsx b/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/__test__/TransactionActionMenu.test.tsx
index 2ee53948e4400..10b5216544962 100644
--- a/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/__test__/TransactionActionMenu.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/__test__/TransactionActionMenu.test.tsx
@@ -5,17 +5,15 @@
*/
import { shallow } from 'enzyme';
-import { Location } from 'history';
import 'jest-styled-components';
import React from 'react';
-import { Transaction } from 'x-pack/plugins/apm/typings/es_schemas/Transaction';
import { TransactionActionMenu } from '../TransactionActionMenu';
-import transactionActionMenuProps from './transactionActionMenuProps.json';
+import { props } from './transactionActionMenuProps';
describe('TransactionActionMenu component', () => {
it('should render with data', () => {
- const transaction: Transaction = transactionActionMenuProps.transaction;
- const location: Location = transactionActionMenuProps.location;
+ const transaction = props.transaction;
+ const location = props.location;
expect(
shallow(
diff --git a/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/__test__/__snapshots__/TransactionActionMenu.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/__test__/__snapshots__/TransactionActionMenu.test.tsx.snap
index ca865f4a0c94c..51687920de715 100644
--- a/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/__test__/__snapshots__/TransactionActionMenu.test.tsx.snap
+++ b/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/__test__/__snapshots__/TransactionActionMenu.test.tsx.snap
@@ -94,7 +94,7 @@ exports[`TransactionActionMenu component should render with data 1`] = `
,
,
(
- item: T
-): T {
- if (item != null) {
- item.version = item.hasOwnProperty('trace') ? 'v2' : 'v1';
- }
-
- return item;
-}
diff --git a/x-pack/plugins/apm/public/services/rest/apm/traces.ts b/x-pack/plugins/apm/public/services/rest/apm/traces.ts
index fde2a124db945..1a681ecc3ade4 100644
--- a/x-pack/plugins/apm/public/services/rest/apm/traces.ts
+++ b/x-pack/plugins/apm/public/services/rest/apm/traces.ts
@@ -8,22 +8,20 @@ import { TraceListAPIResponse } from 'x-pack/plugins/apm/server/lib/traces/get_t
import { TraceAPIResponse } from 'x-pack/plugins/apm/server/lib/traces/get_trace';
import { IUrlParams } from '../../../store/urlParams';
import { callApi } from '../callApi';
-import { addVersion, getEncodedEsQuery } from './apm';
+import { getEncodedEsQuery } from './apm';
export async function loadTrace({ traceId, start, end }: IUrlParams) {
- const hits = await callApi({
+ return callApi({
pathname: `/api/apm/traces/${traceId}`,
query: {
start,
end
}
});
-
- return hits.map(addVersion);
}
export async function loadTraceList({ start, end, kuery }: IUrlParams) {
- const groups = await callApi({
+ return callApi({
pathname: '/api/apm/traces',
query: {
start,
@@ -31,9 +29,4 @@ export async function loadTraceList({ start, end, kuery }: IUrlParams) {
esFilterQuery: await getEncodedEsQuery(kuery)
}
});
-
- return groups.map(group => {
- group.sample = addVersion(group.sample);
- return group;
- });
}
diff --git a/x-pack/plugins/apm/public/services/rest/apm/transaction_groups.ts b/x-pack/plugins/apm/public/services/rest/apm/transaction_groups.ts
index b6781e1405a99..53025a0daf685 100644
--- a/x-pack/plugins/apm/public/services/rest/apm/transaction_groups.ts
+++ b/x-pack/plugins/apm/public/services/rest/apm/transaction_groups.ts
@@ -9,7 +9,7 @@ import { ITransactionDistributionAPIResponse } from 'x-pack/plugins/apm/server/l
import { TransactionListAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/get_top_transactions';
import { IUrlParams } from '../../../store/urlParams';
import { callApi } from '../callApi';
-import { addVersion, getEncodedEsQuery } from './apm';
+import { getEncodedEsQuery } from './apm';
export async function loadTransactionList({
serviceName,
@@ -18,7 +18,7 @@ export async function loadTransactionList({
kuery,
transactionType = 'request'
}: IUrlParams) {
- const groups = await callApi({
+ return await callApi({
pathname: `/api/apm/services/${serviceName}/transaction_groups/${transactionType}`,
query: {
start,
@@ -26,11 +26,6 @@ export async function loadTransactionList({
esFilterQuery: await getEncodedEsQuery(kuery)
}
});
-
- return groups.map(group => {
- group.sample = addVersion(group.sample);
- return group;
- });
}
export async function loadTransactionDistribution({
diff --git a/x-pack/plugins/apm/public/services/rest/apm/transactions.ts b/x-pack/plugins/apm/public/services/rest/apm/transactions.ts
index 3154af684fa2c..7a3bec3435140 100644
--- a/x-pack/plugins/apm/public/services/rest/apm/transactions.ts
+++ b/x-pack/plugins/apm/public/services/rest/apm/transactions.ts
@@ -6,35 +6,9 @@
import { KFetchError } from 'ui/kfetch/kfetch_error';
import { TransactionAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/get_transaction';
-import { SpanListAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/spans/get_spans';
-import { Span } from 'x-pack/plugins/apm/typings/es_schemas/Span';
import { IUrlParams } from '../../../store/urlParams';
import { callApi } from '../callApi';
-import { addVersion, getEncodedEsQuery } from './apm';
-
-export async function loadSpans({
- serviceName,
- start,
- end,
- transactionId
-}: IUrlParams) {
- const hits = await callApi({
- pathname: `/api/apm/services/${serviceName}/transactions/${transactionId}/spans`,
- query: {
- start,
- end
- }
- });
-
- return hits.map(addVersion).map(addSpanId);
-}
-
-function addSpanId(hit: Span, i: number) {
- if (!hit.span.id) {
- hit.span.id = i;
- }
- return hit;
-}
+import { getEncodedEsQuery } from './apm';
export async function loadTransaction({
serviceName,
@@ -54,7 +28,7 @@ export async function loadTransaction({
esFilterQuery: await getEncodedEsQuery(kuery)
}
});
- return addVersion(result);
+ return result;
} catch (e) {
const err: KFetchError = e;
diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/waterfall.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/waterfall.tsx
index 5029e88ccaf3a..38c10d4d6c015 100644
--- a/x-pack/plugins/apm/public/store/reactReduxRequest/waterfall.tsx
+++ b/x-pack/plugins/apm/public/store/reactReduxRequest/waterfall.tsx
@@ -4,13 +4,22 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { get } from 'lodash';
import React from 'react';
-import { RRRRender } from 'react-redux-request';
+import { Request, RRRRender } from 'react-redux-request';
+import { TRACE_ID } from 'x-pack/plugins/apm/common/constants';
+import { TraceAPIResponse } from 'x-pack/plugins/apm/server/lib/traces/get_trace';
import { Transaction } from 'x-pack/plugins/apm/typings/es_schemas/Transaction';
-import { IWaterfall } from '../../components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers';
+import {
+ getWaterfall,
+ IWaterfall
+} from '../../components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers';
+import { loadTrace } from '../../services/rest/apm/traces';
import { IUrlParams } from '../urlParams';
-import { WaterfallV1Request } from './waterfallV1';
-import { WaterfallV2Request } from './waterfallV2';
+// @ts-ignore
+import { createInitialDataSelector } from './helpers';
+
+export const ID = 'waterfall';
interface Props {
urlParams: IUrlParams;
@@ -19,22 +28,22 @@ interface Props {
}
export function WaterfallRequest({ urlParams, transaction, render }: Props) {
- const hasTrace = transaction.hasOwnProperty('trace');
- if (hasTrace) {
- return (
-
- );
- } else {
- return (
-
- );
+ const { start, end } = urlParams;
+ const traceId: string = get(transaction, TRACE_ID);
+
+ if (!(traceId && start && end)) {
+ return null;
}
+
+ return (
+
+ id={ID}
+ fn={loadTrace}
+ args={[{ traceId, start, end }]}
+ render={({ args, data = [], status }) => {
+ const waterfall = getWaterfall(data, transaction);
+ return render({ args, data: waterfall, status });
+ }}
+ />
+ );
}
diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/waterfallV1.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/waterfallV1.tsx
deleted file mode 100644
index cbcf307267017..0000000000000
--- a/x-pack/plugins/apm/public/store/reactReduxRequest/waterfallV1.tsx
+++ /dev/null
@@ -1,53 +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';
-import React from 'react';
-import { Request, RRRRender } from 'react-redux-request';
-import {
- SERVICE_NAME,
- TRANSACTION_ID
-} from 'x-pack/plugins/apm/common/constants';
-import { Span } from 'x-pack/plugins/apm/typings/es_schemas/Span';
-import { Transaction } from 'x-pack/plugins/apm/typings/es_schemas/Transaction';
-import {
- getWaterfall,
- IWaterfall
-} from '../../components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers';
-import { loadSpans } from '../../services/rest/apm/transactions';
-import { IUrlParams } from '../urlParams';
-// @ts-ignore
-import { createInitialDataSelector } from './helpers';
-
-export const ID = 'waterfallV1';
-
-interface Props {
- urlParams: IUrlParams;
- transaction: Transaction;
- render: RRRRender;
-}
-
-export function WaterfallV1Request({ urlParams, transaction, render }: Props) {
- const { start, end } = urlParams;
- const transactionId: string = get(transaction, TRANSACTION_ID);
- const serviceName: string = get(transaction, SERVICE_NAME);
-
- if (!(serviceName && transactionId && start && end)) {
- return null;
- }
-
- return (
-
- id={ID}
- fn={loadSpans}
- args={[{ serviceName, start, end, transactionId }]}
- render={({ status, data = [], args }) => {
- const waterfall = getWaterfall([transaction, ...data], transaction);
- return render({ status, data: waterfall, args });
- }}
- />
- );
-}
diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/waterfallV2.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/waterfallV2.tsx
deleted file mode 100644
index 0291a9b2012af..0000000000000
--- a/x-pack/plugins/apm/public/store/reactReduxRequest/waterfallV2.tsx
+++ /dev/null
@@ -1,49 +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';
-import React from 'react';
-import { Request, RRRRender } from 'react-redux-request';
-import { TRACE_ID } from 'x-pack/plugins/apm/common/constants';
-import { TraceAPIResponse } from 'x-pack/plugins/apm/server/lib/traces/get_trace';
-import { Transaction } from 'x-pack/plugins/apm/typings/es_schemas/Transaction';
-import {
- getWaterfall,
- IWaterfall
-} from '../../components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers';
-import { loadTrace } from '../../services/rest/apm/traces';
-import { IUrlParams } from '../urlParams';
-// @ts-ignore
-import { createInitialDataSelector } from './helpers';
-
-export const ID = 'waterfallV2';
-
-interface Props {
- urlParams: IUrlParams;
- transaction: Transaction;
- render: RRRRender;
-}
-
-export function WaterfallV2Request({ urlParams, transaction, render }: Props) {
- const { start, end } = urlParams;
- const traceId: string = get(transaction, TRACE_ID);
-
- if (!(traceId && start && end)) {
- return null;
- }
-
- return (
-
- id={ID}
- fn={loadTrace}
- args={[{ traceId, start, end }]}
- render={({ args, data = [], status }) => {
- const waterfall = getWaterfall(data, transaction);
- return render({ args, data: waterfall, status });
- }}
- />
- );
-}
diff --git a/x-pack/plugins/apm/server/lib/errors/distribution/__tests__/__snapshots__/get_buckets.test.ts.snap b/x-pack/plugins/apm/server/lib/errors/distribution/__tests__/__snapshots__/get_buckets.test.ts.snap
index 9ec26216d1dc0..c8063cd5c1ea2 100644
--- a/x-pack/plugins/apm/server/lib/errors/distribution/__tests__/__snapshots__/get_buckets.test.ts.snap
+++ b/x-pack/plugins/apm/server/lib/errors/distribution/__tests__/__snapshots__/get_buckets.test.ts.snap
@@ -29,7 +29,7 @@ Array [
},
Object {
"term": Object {
- "context.service.name": "myServiceName",
+ "service.name": "myServiceName",
},
},
Object {
diff --git a/x-pack/plugins/apm/server/lib/errors/get_error_group.ts b/x-pack/plugins/apm/server/lib/errors/get_error_group.ts
index 607ccb6fccee0..c09213f87ce65 100644
--- a/x-pack/plugins/apm/server/lib/errors/get_error_group.ts
+++ b/x-pack/plugins/apm/server/lib/errors/get_error_group.ts
@@ -5,7 +5,6 @@
*/
import { ESFilter } from 'elasticsearch';
-import { get } from 'lodash';
import { oc } from 'ts-optchain';
import { APMError } from 'x-pack/plugins/apm/typings/es_schemas/Error';
import { Transaction } from 'x-pack/plugins/apm/typings/es_schemas/Transaction';
@@ -72,7 +71,7 @@ export async function getErrorGroup({
const resp = await client('search', params);
const error = oc(resp).hits.hits[0]._source();
const transactionId = oc(error).transaction.id();
- const traceId: string | undefined = get(error, 'trace.id'); // cannot use oc because 'trace' doesn't exist on v1 errors
+ const traceId = oc(error).trace.id();
let transaction;
if (transactionId) {
diff --git a/x-pack/plugins/apm/server/lib/metrics/get_cpu_chart_data/__tests__/__snapshots__/fetcher.test.ts.snap b/x-pack/plugins/apm/server/lib/metrics/get_cpu_chart_data/__tests__/__snapshots__/fetcher.test.ts.snap
index acb2f79c4d8b9..7c23e4eecb454 100644
--- a/x-pack/plugins/apm/server/lib/metrics/get_cpu_chart_data/__tests__/__snapshots__/fetcher.test.ts.snap
+++ b/x-pack/plugins/apm/server/lib/metrics/get_cpu_chart_data/__tests__/__snapshots__/fetcher.test.ts.snap
@@ -66,7 +66,7 @@ Array [
"filter": Array [
Object {
"term": Object {
- "context.service.name": "test-service",
+ "service.name": "test-service",
},
},
Object {
diff --git a/x-pack/plugins/apm/server/lib/metrics/get_memory_chart_data/__tests__/__snapshots__/fetcher.test.ts.snap b/x-pack/plugins/apm/server/lib/metrics/get_memory_chart_data/__tests__/__snapshots__/fetcher.test.ts.snap
index 5536ea3805282..75c403aecfe51 100644
--- a/x-pack/plugins/apm/server/lib/metrics/get_memory_chart_data/__tests__/__snapshots__/fetcher.test.ts.snap
+++ b/x-pack/plugins/apm/server/lib/metrics/get_memory_chart_data/__tests__/__snapshots__/fetcher.test.ts.snap
@@ -58,7 +58,7 @@ Array [
"filter": Array [
Object {
"term": Object {
- "context.service.name": "test-service",
+ "service.name": "test-service",
},
},
Object {
diff --git a/x-pack/plugins/apm/server/lib/status_check/server_check.js b/x-pack/plugins/apm/server/lib/status_check/server_check.js
index d13a63adda61b..bc0c4dea4ceec 100644
--- a/x-pack/plugins/apm/server/lib/status_check/server_check.js
+++ b/x-pack/plugins/apm/server/lib/status_check/server_check.js
@@ -4,6 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { OBSERVER_LISTENING } from '../../../common/constants';
+
// Note: this logic is duplicated in tutorials/apm/envs/on_prem
export async function getServerStatus({ setup }) {
const { client, config } = setup;
@@ -16,7 +18,7 @@ export async function getServerStatus({ setup }) {
bool: {
filter: {
exists: {
- field: 'listening'
+ field: OBSERVER_LISTENING
}
}
}
diff --git a/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/__snapshots__/fetcher.test.ts.snap b/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/__snapshots__/fetcher.test.ts.snap
index b8b881249f072..c7ebc6028f1d0 100644
--- a/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/__snapshots__/fetcher.test.ts.snap
+++ b/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/__snapshots__/fetcher.test.ts.snap
@@ -69,7 +69,7 @@ Array [
},
Object {
"term": Object {
- "context.service.name": "myServiceName",
+ "service.name": "myServiceName",
},
},
Object {
diff --git a/x-pack/plugins/apm/server/lib/transactions/spans/get_spans.ts b/x-pack/plugins/apm/server/lib/transactions/spans/get_spans.ts
deleted file mode 100644
index 983e16ae48672..0000000000000
--- a/x-pack/plugins/apm/server/lib/transactions/spans/get_spans.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { Span } from 'x-pack/plugins/apm/typings/es_schemas/Span';
-import {
- PROCESSOR_EVENT,
- SPAN_START,
- TRANSACTION_ID
-} from '../../../../common/constants';
-import { Setup } from '../../helpers/setup_request';
-
-export type SpanListAPIResponse = Span[];
-
-// Deprecated and will be removed in 7.0. Only needed for backwards compatability pre 6.5 (introducition of v2 API and distributed tracing)
-export async function getSpans(
- transactionId: string,
- setup: Setup
-): Promise {
- const { start, end, client, config } = setup;
-
- const params = {
- index: config.get('apm_oss.spanIndices'),
- body: {
- size: 500,
- query: {
- bool: {
- filter: [
- { term: { [TRANSACTION_ID]: transactionId } },
- { term: { [PROCESSOR_EVENT]: 'span' } },
- {
- range: {
- '@timestamp': {
- gte: start,
- lte: end,
- format: 'epoch_millis'
- }
- }
- }
- ]
- }
- },
- sort: [{ [SPAN_START]: { order: 'asc' } }]
- }
- };
-
- const resp = await client('search', params);
- return resp.hits.hits.map(hit => hit._source);
-}
diff --git a/x-pack/plugins/apm/server/routes/transactions.ts b/x-pack/plugins/apm/server/routes/transactions.ts
index d6bd35e3fb6d4..faf95183132c5 100644
--- a/x-pack/plugins/apm/server/routes/transactions.ts
+++ b/x-pack/plugins/apm/server/routes/transactions.ts
@@ -10,7 +10,6 @@ import Joi from 'joi';
import { withDefaultValidators } from '../lib/helpers/input_validation';
import { setupRequest } from '../lib/helpers/setup_request';
import { getTransaction } from '../lib/transactions/get_transaction';
-import { getSpans } from '../lib/transactions/spans/get_spans';
export function initTransactionsApi(server: Server) {
server.route({
@@ -35,20 +34,4 @@ export function initTransactionsApi(server: Server) {
}
}
});
-
- // TODO: this can be removed by 7.0 when v1 compatability can be dropped
- server.route({
- method: 'GET',
- path: `/api/apm/services/{serviceName}/transactions/{transactionId}/spans`,
- options: {
- validate: {
- query: withDefaultValidators()
- }
- },
- handler: req => {
- const { transactionId } = req.params;
- const setup = setupRequest(req);
- return getSpans(transactionId, setup);
- }
- });
}
diff --git a/x-pack/plugins/apm/typings/es_schemas/APMDoc.ts b/x-pack/plugins/apm/typings/es_schemas/APMDoc.ts
index e4693170e293c..046f6faa177b2 100644
--- a/x-pack/plugins/apm/typings/es_schemas/APMDoc.ts
+++ b/x-pack/plugins/apm/typings/es_schemas/APMDoc.ts
@@ -4,27 +4,17 @@
* you may not use this file except in compliance with the Elastic License.
*/
-export interface APMDocV1 {
+// all documents types extend APMDoc and inherit all properties
+export interface APMDoc {
'@timestamp': string;
- beat: {
- hostname: string;
+ agent: {
name: string;
version: string;
};
- host: {
- name: string;
- };
- agent?: object;
-}
-
-export interface APMDocV2 extends APMDocV1 {
- timestamp: {
- us: number;
- };
- parent?: {
- id: string; // parent ID is not available on the root transaction
- };
- trace: {
- id: string;
+ timestamp: { us: number };
+ parent?: { id: string }; // parent ID is not available on root transactions
+ trace: { id: string };
+ labels?: {
+ [key: string]: string | number | boolean;
};
}
diff --git a/x-pack/plugins/apm/typings/es_schemas/Context.ts b/x-pack/plugins/apm/typings/es_schemas/Context.ts
deleted file mode 100644
index 244181d4d87ea..0000000000000
--- a/x-pack/plugins/apm/typings/es_schemas/Context.ts
+++ /dev/null
@@ -1,52 +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 interface ContextService {
- name: string;
- agent: {
- name: string;
- version: string;
- };
- framework?: {
- name: string;
- version: string;
- };
- runtime?: {
- name: string;
- version: string;
- };
- language?: {
- name: string;
- version?: string;
- };
- [key: string]: unknown;
-}
-
-export interface ContextSystem {
- architecture?: string;
- hostname?: string;
- ip?: string;
- platform?: string;
-}
-
-export interface ContextRequest {
- url: {
- full: string;
- [key: string]: string;
- };
- method: string;
- headers?: {
- [key: string]: unknown;
- };
- [key: string]: unknown;
-}
-
-export interface ContextProcess {
- pid: number;
- title: string;
- argv: string[];
- [key: string]: unknown;
-}
diff --git a/x-pack/plugins/apm/typings/es_schemas/Error.ts b/x-pack/plugins/apm/typings/es_schemas/Error.ts
index fe380cacc8044..f65ee70b41e0f 100644
--- a/x-pack/plugins/apm/typings/es_schemas/Error.ts
+++ b/x-pack/plugins/apm/typings/es_schemas/Error.ts
@@ -4,37 +4,23 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { APMDocV1, APMDocV2 } from './APMDoc';
-import {
- ContextProcess,
- ContextRequest,
- ContextService,
- ContextSystem
-} from './Context';
-import { IStackframe } from './Stackframe';
-
-interface Agent {
- hostname: string;
- type: string;
- version: string;
-}
+import { APMDoc } from './APMDoc';
+import { Container } from './fields/Container';
+import { Context } from './fields/Context';
+import { Host } from './fields/Host';
+import { Http } from './fields/Http';
+import { Kubernetes } from './fields/Kubernetes';
+import { Process } from './fields/Process';
+import { Service } from './fields/Service';
+import { IStackframe } from './fields/Stackframe';
+import { Url } from './fields/Url';
+import { User } from './fields/User';
interface Processor {
name: 'error';
event: 'error';
}
-interface Context {
- process?: ContextProcess;
- service: ContextService;
- system?: ContextSystem;
- request?: ContextRequest;
- page?: {
- url: string;
- };
- [key: string]: unknown;
-}
-
interface Exception {
message?: string; // either message or type are given
type?: string;
@@ -53,43 +39,31 @@ interface Log {
stacktrace?: IStackframe[];
}
-interface ErrorV1 extends APMDocV1 {
- version: 'v1';
- agent: Agent;
- processor: Processor;
- context: Context;
- transaction?: {
- id: string; // transaction ID is not required in v1
- };
- error: {
- id?: string; // ID is not required in v1
- timestamp: string;
- culprit: string;
- grouping_key: string;
- // either exception or log are given
- exception?: Exception;
- log?: Log;
- };
-}
-
-interface ErrorV2 extends APMDocV2 {
- version: 'v2';
- agent: Agent;
+// Not calling it "Error" to avoid clashes with types for native Error
+export interface APMError extends APMDoc {
processor: Processor;
- context: Context;
transaction: {
- id: string; // transaction ID is required in v2
+ id: string;
sampled?: boolean;
+ type?: string;
};
error: {
- id: string; // ID is required in v2
+ id: string;
culprit: string;
grouping_key: string;
// either exception or log are given
exception?: Exception;
log?: Log;
};
-}
-// Not calling it "Error" to avoid clashes with types for native Error
-export type APMError = ErrorV1 | ErrorV2;
+ // Shared by errors and transactions
+ container?: Container;
+ context?: Context;
+ host?: Host;
+ http?: Http;
+ kubernetes?: Kubernetes;
+ process?: Process;
+ service: Service;
+ url?: Url;
+ user?: User;
+}
diff --git a/x-pack/plugins/apm/typings/es_schemas/Span.ts b/x-pack/plugins/apm/typings/es_schemas/Span.ts
index 132c0c036f421..ef5ec78236812 100644
--- a/x-pack/plugins/apm/typings/es_schemas/Span.ts
+++ b/x-pack/plugins/apm/typings/es_schemas/Span.ts
@@ -4,77 +4,41 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { APMDocV1, APMDocV2 } from './APMDoc';
-import { ContextService } from './Context';
-import { IStackframe } from './Stackframe';
-
-export interface DbContext {
- instance?: string;
- statement?: string;
- type?: string;
- user?: string;
-}
+import { APMDoc } from './APMDoc';
+import { IStackframe } from './fields/Stackframe';
interface Processor {
name: 'transaction';
event: 'span';
}
-interface HttpContext {
- url?: string;
-}
-
-interface TagsContext {
- [key: string]: string;
-}
-
-interface Context {
- db?: DbContext;
- http?: HttpContext;
- tags?: TagsContext;
- service: ContextService;
- [key: string]: unknown;
-}
-
-export interface SpanV1 extends APMDocV1 {
- version: 'v1';
- processor: Processor;
- context: Context;
- span: {
- duration: {
- us: number;
- };
- start: {
- us: number; // only v1
- };
- name: string;
- type: string;
- id: number; // we are manually adding span.id
- parent?: string; // only v1
- stacktrace?: IStackframe[];
+interface SpanContext {
+ db?: {
+ instance?: string;
+ statement?: string;
+ type?: string;
+ user?: string;
};
- transaction: {
- id: string;
+ http?: {
+ method?: string;
+ status_code?: number;
+ url?: string;
};
}
-export interface SpanV2 extends APMDocV2 {
- version: 'v2';
+export interface Span extends APMDoc {
processor: Processor;
- context: Context;
+ context?: SpanContext;
+ service: { name: string };
span: {
- duration: {
- us: number;
- };
+ action: string;
+ duration: { us: number };
+ id: string;
name: string;
- type: string;
- id: number; // id will be derived from hex encoded 64 bit hex_id string in v2
- hex_id: string; // only v2
stacktrace?: IStackframe[];
+ subtype: string;
+ sync: boolean;
+ type: string;
};
- transaction: {
- id: string;
- };
+ transaction: { id: string };
}
-
-export type Span = SpanV1 | SpanV2;
diff --git a/x-pack/plugins/apm/typings/es_schemas/Transaction.ts b/x-pack/plugins/apm/typings/es_schemas/Transaction.ts
index 4d071acc157a5..f7ce5c8d79156 100644
--- a/x-pack/plugins/apm/typings/es_schemas/Transaction.ts
+++ b/x-pack/plugins/apm/typings/es_schemas/Transaction.ts
@@ -4,98 +4,51 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { APMDocV1, APMDocV2 } from './APMDoc';
-import {
- ContextProcess,
- ContextRequest,
- ContextService,
- ContextSystem
-} from './Context';
+import { APMDoc } from './APMDoc';
+import { Container } from './fields/Container';
+import { Context } from './fields/Context';
+import { Host } from './fields/Host';
+import { Http } from './fields/Http';
+import { Kubernetes } from './fields/Kubernetes';
+import { Process } from './fields/Process';
+import { Service } from './fields/Service';
+import { Url } from './fields/Url';
+import { User } from './fields/User';
interface Processor {
name: 'transaction';
event: 'transaction';
}
-interface Context {
- process?: ContextProcess;
- service: ContextService;
- system?: ContextSystem;
- request: ContextRequest;
- user?: {
- id: string;
- username?: string;
- email?: string;
- };
- page?: {
- url: string;
- };
- [key: string]: unknown;
-}
-
-interface Marks {
- agent?: {
- [name: string]: number;
- };
-}
-
-export interface TransactionV1 extends APMDocV1 {
- version: 'v1';
+export interface Transaction extends APMDoc {
processor: Processor;
- context: Context;
transaction: {
- duration: {
- us: number;
- };
+ duration: { us: number };
id: string;
- marks?: Marks;
- name: string; // name could be missing in ES but the UI will always only aggregate on transactions with a name
- result?: string;
- sampled: boolean;
- span_count?: {
- dropped?: {
- total?: number;
+ marks?: {
+ // "agent": not defined by APM Server - only sent by RUM agent
+ agent?: {
+ [name: string]: number;
};
};
- type: string;
- };
-}
-
-export interface TransactionV2 extends APMDocV2 {
- version: 'v2';
- processor: Processor;
- context: Context;
- transaction: {
- duration: {
- us: number;
- };
- id: string;
- marks?: Marks;
name: string; // name could be missing in ES but the UI will always only aggregate on transactions with a name
result?: string;
sampled: boolean;
-
span_count?: {
- started?: number; // only v2
- dropped?: {
- total?: number;
- };
+ started?: number;
+ dropped?: number;
};
type: string;
};
- kubernetes?: {
- pod: {
- uid: string;
- };
- };
- docker?: {
- container: {
- id: string;
- };
- };
- container: {
- id: string;
- };
-}
-export type Transaction = TransactionV1 | TransactionV2;
+ // Shared by errors and transactions
+ container?: Container;
+ context?: Context;
+ host?: Host;
+ http?: Http;
+ kubernetes?: Kubernetes;
+ process?: Process;
+ service: Service;
+ url?: Url;
+ user?: User;
+}
diff --git a/x-pack/plugins/apm/typings/es_schemas/fields/Container.ts b/x-pack/plugins/apm/typings/es_schemas/fields/Container.ts
new file mode 100644
index 0000000000000..61306636a9fad
--- /dev/null
+++ b/x-pack/plugins/apm/typings/es_schemas/fields/Container.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export interface Container {
+ id: string;
+}
diff --git a/x-pack/plugins/apm/typings/es_schemas/fields/Context.ts b/x-pack/plugins/apm/typings/es_schemas/fields/Context.ts
new file mode 100644
index 0000000000000..b6b9ad000c703
--- /dev/null
+++ b/x-pack/plugins/apm/typings/es_schemas/fields/Context.ts
@@ -0,0 +1,10 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export interface Context {
+ page?: { url: string }; // only for RUM agent
+ [key: string]: unknown;
+}
diff --git a/x-pack/plugins/apm/typings/es_schemas/fields/Host.ts b/x-pack/plugins/apm/typings/es_schemas/fields/Host.ts
new file mode 100644
index 0000000000000..c0f89cdc5d1d5
--- /dev/null
+++ b/x-pack/plugins/apm/typings/es_schemas/fields/Host.ts
@@ -0,0 +1,12 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export interface Host {
+ architecture?: string;
+ hostname?: string;
+ ip?: string;
+ os?: { platform?: string };
+}
diff --git a/x-pack/plugins/apm/typings/es_schemas/fields/Http.ts b/x-pack/plugins/apm/typings/es_schemas/fields/Http.ts
new file mode 100644
index 0000000000000..664f5432e9870
--- /dev/null
+++ b/x-pack/plugins/apm/typings/es_schemas/fields/Http.ts
@@ -0,0 +1,10 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export interface Http {
+ request: { method: string };
+ response: { status_code: number };
+}
diff --git a/x-pack/plugins/apm/typings/es_schemas/fields/Kubernetes.ts b/x-pack/plugins/apm/typings/es_schemas/fields/Kubernetes.ts
new file mode 100644
index 0000000000000..a7313bac75ba2
--- /dev/null
+++ b/x-pack/plugins/apm/typings/es_schemas/fields/Kubernetes.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export interface Kubernetes {
+ pod: { uid: string };
+}
diff --git a/x-pack/plugins/apm/typings/es_schemas/fields/Process.ts b/x-pack/plugins/apm/typings/es_schemas/fields/Process.ts
new file mode 100644
index 0000000000000..63e1faa382163
--- /dev/null
+++ b/x-pack/plugins/apm/typings/es_schemas/fields/Process.ts
@@ -0,0 +1,12 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export interface Process {
+ args: string[];
+ pid: number;
+ ppid: number;
+ title: string;
+}
diff --git a/x-pack/plugins/apm/typings/es_schemas/fields/Service.ts b/x-pack/plugins/apm/typings/es_schemas/fields/Service.ts
new file mode 100644
index 0000000000000..09020ce61c6e4
--- /dev/null
+++ b/x-pack/plugins/apm/typings/es_schemas/fields/Service.ts
@@ -0,0 +1,21 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export interface Service {
+ name: string;
+ framework?: {
+ name: string;
+ version: string;
+ };
+ runtime?: {
+ name: string;
+ version: string;
+ };
+ language?: {
+ name: string;
+ version?: string;
+ };
+}
diff --git a/x-pack/plugins/apm/typings/es_schemas/Stackframe.ts b/x-pack/plugins/apm/typings/es_schemas/fields/Stackframe.ts
similarity index 100%
rename from x-pack/plugins/apm/typings/es_schemas/Stackframe.ts
rename to x-pack/plugins/apm/typings/es_schemas/fields/Stackframe.ts
diff --git a/x-pack/plugins/apm/typings/es_schemas/fields/Url.ts b/x-pack/plugins/apm/typings/es_schemas/fields/Url.ts
new file mode 100644
index 0000000000000..8d7a469be8ab1
--- /dev/null
+++ b/x-pack/plugins/apm/typings/es_schemas/fields/Url.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export interface Url {
+ full: string;
+}
diff --git a/x-pack/plugins/apm/typings/es_schemas/fields/User.ts b/x-pack/plugins/apm/typings/es_schemas/fields/User.ts
new file mode 100644
index 0000000000000..2786410659a8c
--- /dev/null
+++ b/x-pack/plugins/apm/typings/es_schemas/fields/User.ts
@@ -0,0 +1,11 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export interface User {
+ id: string;
+ username?: string;
+ email?: string;
+}
diff --git a/yarn.lock b/yarn.lock
index a1d1f2f09667d..ae32b8dbcb582 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -11137,11 +11137,6 @@ icss-utils@^2.1.0:
dependencies:
postcss "^6.0.1"
-idx@^2.5.2:
- version "2.5.2"
- resolved "https://registry.yarnpkg.com/idx/-/idx-2.5.2.tgz#4b405c2e6d68d04136e0a368a7ab35b9caa0595f"
- integrity sha512-MLoGF4lQU5q/RqJJjRsuid52emu7tPVtSSZaYXsqRvSjvXdBEmIwk2urvbNvPBRU9Ox9I4WYnxiz2GjhU34Lrw==
-
ieee754@^1.1.4:
version "1.1.8"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
From 049a2ee33ad3dc1437d36f85dd251b5afc43054f Mon Sep 17 00:00:00 2001
From: Christopher Davies
Date: Thu, 24 Jan 2019 08:17:20 -0500
Subject: [PATCH 29/29] Fix uiSettings tests
---
src/server/saved_objects/service/create_saved_objects_service.js | 1 -
src/ui/ui_settings/routes/__tests__/index_missing.js | 1 -
2 files changed, 2 deletions(-)
diff --git a/src/server/saved_objects/service/create_saved_objects_service.js b/src/server/saved_objects/service/create_saved_objects_service.js
index 5a7160a353abe..00e6238555742 100644
--- a/src/server/saved_objects/service/create_saved_objects_service.js
+++ b/src/server/saved_objects/service/create_saved_objects_service.js
@@ -38,7 +38,6 @@ export function createSavedObjectsService(server, schema, serializer, migrator)
const index = server.config().get('kibana.index');
await adminCluster.callWithInternalUser('indices.putTemplate', {
name: `kibana_index_template:${index}`,
- include_type_name: true,
body: {
template: index,
settings: {
diff --git a/src/ui/ui_settings/routes/__tests__/index_missing.js b/src/ui/ui_settings/routes/__tests__/index_missing.js
index 81020fd9a54b8..7d3b977ba1874 100644
--- a/src/ui/ui_settings/routes/__tests__/index_missing.js
+++ b/src/ui/ui_settings/routes/__tests__/index_missing.js
@@ -42,7 +42,6 @@ export function indexMissingSuite() {
async assertValidKibanaIndex() {
const resp = await callCluster('indices.get', {
index: indexName,
- include_type_name: true,
});
expect(resp[indexName].mappings.properties).to.have.keys(