ConfigPath
| Root configuration path used by the plugin, defaults to "id" in snake\_case format. |
| [id](./kibana-plugin-core-server.discoveredplugin.id.md) | PluginName
| Identifier of the plugin. |
| [optionalPlugins](./kibana-plugin-core-server.discoveredplugin.optionalplugins.md) | readonly PluginName[]
| An optional list of the other plugins that if installed and enabled \*\*may be\*\* leveraged by this plugin for some additional functionality but otherwise are not required for this plugin to work properly. |
+| [requiredBundles](./kibana-plugin-core-server.discoveredplugin.requiredbundles.md) | readonly PluginName[]
| List of plugin ids that this plugin's UI code imports modules from that are not in requiredPlugins
. |
| [requiredPlugins](./kibana-plugin-core-server.discoveredplugin.requiredplugins.md) | readonly PluginName[]
| An optional list of the other plugins that \*\*must be\*\* installed and enabled for this plugin to function properly. |
diff --git a/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.requiredbundles.md b/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.requiredbundles.md
new file mode 100644
index 0000000000000..6d54adb5236ea
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.requiredbundles.md
@@ -0,0 +1,18 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [DiscoveredPlugin](./kibana-plugin-core-server.discoveredplugin.md) > [requiredBundles](./kibana-plugin-core-server.discoveredplugin.requiredbundles.md)
+
+## DiscoveredPlugin.requiredBundles property
+
+List of plugin ids that this plugin's UI code imports modules from that are not in `requiredPlugins`.
+
+Signature:
+
+```typescript
+readonly requiredBundles: readonly PluginName[];
+```
+
+## Remarks
+
+The plugins listed here will be loaded in the browser, even if the plugin is disabled. Required by `@kbn/optimizer` to support cross-plugin imports. "core" and plugins already listed in `requiredPlugins` do not need to be duplicated here.
+
diff --git a/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md b/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md
index 5edee51d6c523..6db2f89590149 100644
--- a/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md
+++ b/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md
@@ -25,6 +25,7 @@ Should never be used in code outside of Core but is exported for documentation p
| [id](./kibana-plugin-core-server.pluginmanifest.id.md) | PluginName
| Identifier of the plugin. Must be a string in camelCase. Part of a plugin public contract. Other plugins leverage it to access plugin API, navigate to the plugin, etc. |
| [kibanaVersion](./kibana-plugin-core-server.pluginmanifest.kibanaversion.md) | string
| The version of Kibana the plugin is compatible with, defaults to "version". |
| [optionalPlugins](./kibana-plugin-core-server.pluginmanifest.optionalplugins.md) | readonly PluginName[]
| An optional list of the other plugins that if installed and enabled \*\*may be\*\* leveraged by this plugin for some additional functionality but otherwise are not required for this plugin to work properly. |
+| [requiredBundles](./kibana-plugin-core-server.pluginmanifest.requiredbundles.md) | readonly string[]
| List of plugin ids that this plugin's UI code imports modules from that are not in requiredPlugins
. |
| [requiredPlugins](./kibana-plugin-core-server.pluginmanifest.requiredplugins.md) | readonly PluginName[]
| An optional list of the other plugins that \*\*must be\*\* installed and enabled for this plugin to function properly. |
| [server](./kibana-plugin-core-server.pluginmanifest.server.md) | boolean
| Specifies whether plugin includes some server-side specific functionality. |
| [ui](./kibana-plugin-core-server.pluginmanifest.ui.md) | boolean
| Specifies whether plugin includes some client/browser specific functionality that should be included into client bundle via public/ui_plugin.js
file. |
diff --git a/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.requiredbundles.md b/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.requiredbundles.md
new file mode 100644
index 0000000000000..98505d07101fe
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.requiredbundles.md
@@ -0,0 +1,18 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [PluginManifest](./kibana-plugin-core-server.pluginmanifest.md) > [requiredBundles](./kibana-plugin-core-server.pluginmanifest.requiredbundles.md)
+
+## PluginManifest.requiredBundles property
+
+List of plugin ids that this plugin's UI code imports modules from that are not in `requiredPlugins`.
+
+Signature:
+
+```typescript
+readonly requiredBundles: readonly string[];
+```
+
+## Remarks
+
+The plugins listed here will be loaded in the browser, even if the plugin is disabled. Required by `@kbn/optimizer` to support cross-plugin imports. "core" and plugins already listed in `requiredPlugins` do not need to be duplicated here.
+
diff --git a/examples/bfetch_explorer/kibana.json b/examples/bfetch_explorer/kibana.json
index 0039e9647bf83..f32cdfc13a1fe 100644
--- a/examples/bfetch_explorer/kibana.json
+++ b/examples/bfetch_explorer/kibana.json
@@ -5,5 +5,6 @@
"server": true,
"ui": true,
"requiredPlugins": ["bfetch", "developerExamples"],
- "optionalPlugins": []
+ "optionalPlugins": [],
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/examples/dashboard_embeddable_examples/kibana.json b/examples/dashboard_embeddable_examples/kibana.json
index bb2ced569edb5..807229fad9dcf 100644
--- a/examples/dashboard_embeddable_examples/kibana.json
+++ b/examples/dashboard_embeddable_examples/kibana.json
@@ -5,5 +5,6 @@
"server": false,
"ui": true,
"requiredPlugins": ["embeddable", "embeddableExamples", "dashboard", "developerExamples"],
- "optionalPlugins": []
+ "optionalPlugins": [],
+ "requiredBundles": ["esUiShared"]
}
diff --git a/examples/embeddable_examples/kibana.json b/examples/embeddable_examples/kibana.json
index 8ae04c1f6c644..771c19cfdbd3d 100644
--- a/examples/embeddable_examples/kibana.json
+++ b/examples/embeddable_examples/kibana.json
@@ -6,5 +6,6 @@
"ui": true,
"requiredPlugins": ["embeddable", "uiActions"],
"optionalPlugins": [],
- "extraPublicDirs": ["public/todo", "public/hello_world", "public/todo/todo_ref_embeddable"]
+ "extraPublicDirs": ["public/todo", "public/hello_world", "public/todo/todo_ref_embeddable"],
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/examples/state_containers_examples/kibana.json b/examples/state_containers_examples/kibana.json
index 66da207cb4e77..58346af8f1d19 100644
--- a/examples/state_containers_examples/kibana.json
+++ b/examples/state_containers_examples/kibana.json
@@ -5,5 +5,6 @@
"server": true,
"ui": true,
"requiredPlugins": ["navigation", "data", "developerExamples"],
- "optionalPlugins": []
+ "optionalPlugins": [],
+ "requiredBundles": ["kibanaUtils", "kibanaReact"]
}
diff --git a/examples/ui_action_examples/kibana.json b/examples/ui_action_examples/kibana.json
index cd12442daf61c..0e0b6b6830b95 100644
--- a/examples/ui_action_examples/kibana.json
+++ b/examples/ui_action_examples/kibana.json
@@ -5,5 +5,6 @@
"server": false,
"ui": true,
"requiredPlugins": ["uiActions"],
- "optionalPlugins": []
+ "optionalPlugins": [],
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/examples/ui_actions_explorer/kibana.json b/examples/ui_actions_explorer/kibana.json
index f57072e89b06d..0a55e60374710 100644
--- a/examples/ui_actions_explorer/kibana.json
+++ b/examples/ui_actions_explorer/kibana.json
@@ -5,5 +5,6 @@
"server": false,
"ui": true,
"requiredPlugins": ["uiActions", "uiActionsExamples", "developerExamples"],
- "optionalPlugins": []
+ "optionalPlugins": [],
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json
index 20c8046daa65e..33f53e336598d 100644
--- a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json
+++ b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json
@@ -1,4 +1,5 @@
{
"id": "bar",
- "ui": true
+ "ui": true,
+ "requiredBundles": ["foo"]
}
diff --git a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/_other_styles.scss b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/_other_styles.scss
new file mode 100644
index 0000000000000..2c1b9562b9567
--- /dev/null
+++ b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/_other_styles.scss
@@ -0,0 +1,3 @@
+p {
+ background-color: rebeccapurple;
+}
diff --git a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/styles.scss b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/styles.scss
index e71a2d485a2f8..1dc7bbe9daeb0 100644
--- a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/styles.scss
+++ b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/styles.scss
@@ -1,3 +1,5 @@
+@import "./other_styles.scss";
+
body {
width: $globalStyleConstant;
background-image: url("ui/icon.svg");
diff --git a/packages/kbn-optimizer/src/cli.ts b/packages/kbn-optimizer/src/cli.ts
index 0916f12a7110d..9d3f4b88a258f 100644
--- a/packages/kbn-optimizer/src/cli.ts
+++ b/packages/kbn-optimizer/src/cli.ts
@@ -87,6 +87,11 @@ run(
throw createFlagError('expected --report-stats to have no value');
}
+ const filter = typeof flags.filter === 'string' ? [flags.filter] : flags.filter;
+ if (!Array.isArray(filter) || !filter.every((f) => typeof f === 'string')) {
+ throw createFlagError('expected --filter to be one or more strings');
+ }
+
const config = OptimizerConfig.create({
repoRoot: REPO_ROOT,
watch,
@@ -99,6 +104,7 @@ run(
extraPluginScanDirs,
inspectWorkers,
includeCoreBundle,
+ filter,
});
let update$ = runOptimizer(config);
@@ -128,12 +134,13 @@ run(
'inspect-workers',
'report-stats',
],
- string: ['workers', 'scan-dir'],
+ string: ['workers', 'scan-dir', 'filter'],
default: {
core: true,
examples: true,
cache: true,
'inspect-workers': true,
+ filter: [],
},
help: `
--watch run the optimizer in watch mode
@@ -142,6 +149,7 @@ run(
--profile profile the webpack builds and write stats.json files to build outputs
--no-core disable generating the core bundle
--no-cache disable the cache
+ --filter comma-separated list of bundle id filters, results from multiple flags are merged, * and ! are supported
--no-examples don't build the example plugins
--dist create bundles that are suitable for inclusion in the Kibana distributable
--scan-dir add a directory to the list of directories scanned for plugins (specify as many times as necessary)
diff --git a/packages/kbn-optimizer/src/common/bundle.test.ts b/packages/kbn-optimizer/src/common/bundle.test.ts
index b209bbca25ac4..6197a08485854 100644
--- a/packages/kbn-optimizer/src/common/bundle.test.ts
+++ b/packages/kbn-optimizer/src/common/bundle.test.ts
@@ -50,6 +50,7 @@ it('creates cache keys', () => {
"spec": Object {
"contextDir": "/foo/bar",
"id": "bar",
+ "manifestPath": undefined,
"outputDir": "/foo/bar/target",
"publicDirNames": Array [
"public",
@@ -85,6 +86,7 @@ it('parses bundles from JSON specs', () => {
},
"contextDir": "/foo/bar",
"id": "bar",
+ "manifestPath": undefined,
"outputDir": "/foo/bar/target",
"publicDirNames": Array [
"public",
diff --git a/packages/kbn-optimizer/src/common/bundle.ts b/packages/kbn-optimizer/src/common/bundle.ts
index 80af94c30f8da..a354da7a21521 100644
--- a/packages/kbn-optimizer/src/common/bundle.ts
+++ b/packages/kbn-optimizer/src/common/bundle.ts
@@ -18,6 +18,7 @@
*/
import Path from 'path';
+import Fs from 'fs';
import { BundleCache } from './bundle_cache';
import { UnknownVals } from './ts_helpers';
@@ -25,6 +26,11 @@ import { includes, ascending, entriesToObject } from './array_helpers';
const VALID_BUNDLE_TYPES = ['plugin' as const, 'entry' as const];
+const DEFAULT_IMPLICIT_BUNDLE_DEPS = ['core'];
+
+const isStringArray = (input: any): input is string[] =>
+ Array.isArray(input) && input.every((x) => typeof x === 'string');
+
export interface BundleSpec {
readonly type: typeof VALID_BUNDLE_TYPES[0];
/** Unique id for this bundle */
@@ -37,6 +43,8 @@ export interface BundleSpec {
readonly sourceRoot: string;
/** Absolute path to the directory where output should be written */
readonly outputDir: string;
+ /** Absolute path to a kibana.json manifest file, if omitted we assume there are not dependenices */
+ readonly manifestPath?: string;
}
export class Bundle {
@@ -56,6 +64,12 @@ export class Bundle {
public readonly sourceRoot: BundleSpec['sourceRoot'];
/** Absolute path to the output directory for this bundle */
public readonly outputDir: BundleSpec['outputDir'];
+ /**
+ * Absolute path to a manifest file with "requiredBundles" which will be
+ * used to allow bundleRefs from this bundle to the exports of another bundle.
+ * Every bundle mentioned in the `requiredBundles` must be built together.
+ */
+ public readonly manifestPath: BundleSpec['manifestPath'];
public readonly cache: BundleCache;
@@ -66,6 +80,7 @@ export class Bundle {
this.contextDir = spec.contextDir;
this.sourceRoot = spec.sourceRoot;
this.outputDir = spec.outputDir;
+ this.manifestPath = spec.manifestPath;
this.cache = new BundleCache(Path.resolve(this.outputDir, '.kbn-optimizer-cache'));
}
@@ -96,8 +111,54 @@ export class Bundle {
contextDir: this.contextDir,
sourceRoot: this.sourceRoot,
outputDir: this.outputDir,
+ manifestPath: this.manifestPath,
};
}
+
+ readBundleDeps(): { implicit: string[]; explicit: string[] } {
+ if (!this.manifestPath) {
+ return {
+ implicit: [...DEFAULT_IMPLICIT_BUNDLE_DEPS],
+ explicit: [],
+ };
+ }
+
+ let json: string;
+ try {
+ json = Fs.readFileSync(this.manifestPath, 'utf8');
+ } catch (error) {
+ if (error.code !== 'ENOENT') {
+ throw error;
+ }
+
+ json = '{}';
+ }
+
+ let parsedManifest: { requiredPlugins?: string[]; requiredBundles?: string[] };
+ try {
+ parsedManifest = JSON.parse(json);
+ } catch (error) {
+ throw new Error(
+ `unable to parse manifest at [${this.manifestPath}], error: [${error.message}]`
+ );
+ }
+
+ if (typeof parsedManifest === 'object' && parsedManifest) {
+ const explicit = parsedManifest.requiredBundles || [];
+ const implicit = [...DEFAULT_IMPLICIT_BUNDLE_DEPS, ...(parsedManifest.requiredPlugins || [])];
+
+ if (isStringArray(explicit) && isStringArray(implicit)) {
+ return {
+ explicit,
+ implicit,
+ };
+ }
+ }
+
+ throw new Error(
+ `Expected "requiredBundles" and "requiredPlugins" in manifest file [${this.manifestPath}] to be arrays of strings`
+ );
+ }
}
/**
@@ -152,6 +213,13 @@ export function parseBundles(json: string) {
throw new Error('`bundles[]` must have an absolute path `outputDir` property');
}
+ const { manifestPath } = spec;
+ if (manifestPath !== undefined) {
+ if (!(typeof manifestPath === 'string' && Path.isAbsolute(manifestPath))) {
+ throw new Error('`bundles[]` must have an absolute path `manifestPath` property');
+ }
+ }
+
return new Bundle({
type,
id,
@@ -159,6 +227,7 @@ export function parseBundles(json: string) {
contextDir,
sourceRoot,
outputDir,
+ manifestPath,
});
}
);
diff --git a/packages/kbn-optimizer/src/common/bundle_cache.ts b/packages/kbn-optimizer/src/common/bundle_cache.ts
index 5ae3e4c28a201..7607e270b5b4f 100644
--- a/packages/kbn-optimizer/src/common/bundle_cache.ts
+++ b/packages/kbn-optimizer/src/common/bundle_cache.ts
@@ -24,6 +24,7 @@ export interface State {
optimizerCacheKey?: unknown;
cacheKey?: unknown;
moduleCount?: number;
+ workUnits?: number;
files?: string[];
bundleRefExportIds?: string[];
}
@@ -96,6 +97,10 @@ export class BundleCache {
return this.get().cacheKey;
}
+ public getWorkUnits() {
+ return this.get().workUnits;
+ }
+
public getOptimizerCacheKey() {
return this.get().optimizerCacheKey;
}
diff --git a/packages/kbn-optimizer/src/common/bundle_refs.ts b/packages/kbn-optimizer/src/common/bundle_refs.ts
index a5c60f2031c0b..85731f32f8991 100644
--- a/packages/kbn-optimizer/src/common/bundle_refs.ts
+++ b/packages/kbn-optimizer/src/common/bundle_refs.ts
@@ -114,6 +114,10 @@ export class BundleRefs {
constructor(private readonly refs: BundleRef[]) {}
+ public forBundleIds(bundleIds: string[]) {
+ return this.refs.filter((r) => bundleIds.includes(r.bundleId));
+ }
+
public filterByExportIds(exportIds: string[]) {
return this.refs.filter((r) => exportIds.includes(r.exportId));
}
diff --git a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap
index d04d4100e8632..4fc259d270e94 100644
--- a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap
+++ b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap
@@ -10,6 +10,7 @@ OptimizerConfig {
},
"contextDir": + {i18n.translate( + 'xpack.apm.settings.anomaly_detection.legacy_jobs.body', + { + defaultMessage: + 'We have discovered legacy Machine Learning jobs from our previous integration which are no longer being used in the APM app', + } + )} +
+{i18n.AUTHENTICATION_DESCRIPTION_PART1}
+{i18n.AUTHENTICATION_DESCRIPTION_PART2}
+{i18n.FLOW_DESCRIPTION_PART1}
+{i18n.FLOW_DESCRIPTION_PART2}
++ {i18n.SYSTEM_DESCRIPTION_PART1}{' '} + + {i18n.SYSTEM_NAME} + {' '} + {i18n.SYSTEM_DESCRIPTION_PART2} +
+{i18n.SYSTEM_DESCRIPTION_PART3}
+{i18n.PROCESS_DESCRIPTION_PART1}
+{i18n.PROCESS_DESCRIPTION_PART2}
+{i18n.SOCKET_DESCRIPTION_PART1}
+{i18n.SOCKET_DESCRIPTION_PART2}
++ {i18n.SURICATA_DESCRIPTION_PART1}{' '} + + {i18n.SURICATA_NAME} + {' '} + {i18n.SURICATA_DESCRIPTION_PART2} +
+ ), + example: SuricataExample, + searchableDescription: `${i18n.SURICATA_DESCRIPTION_PART1} ${i18n.SURICATA_NAME} ${i18n.SURICATA_DESCRIPTION_PART2}`, + }, + { + id: RowRendererId.zeek, + name: i18n.ZEEK_NAME, + description: ( ++ {i18n.ZEEK_DESCRIPTION_PART1}{' '} + + {i18n.ZEEK_NAME} + {' '} + {i18n.ZEEK_DESCRIPTION_PART2} +
+ ), + example: ZeekExample, + searchableDescription: `${i18n.ZEEK_DESCRIPTION_PART1} ${i18n.ZEEK_NAME} ${i18n.ZEEK_DESCRIPTION_PART2}`, + }, +]; diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/catalog/translations.ts b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/catalog/translations.ts new file mode 100644 index 0000000000000..f4d473cdfd3d2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/catalog/translations.ts @@ -0,0 +1,215 @@ +/* + * 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'; + +export const AUDITD_NAME = i18n.translate('xpack.securitySolution.eventRenderers.auditdName', { + defaultMessage: 'Auditd', +}); + +export const AUDITD_DESCRIPTION_PART1 = i18n.translate( + 'xpack.securitySolution.eventRenderers.auditdDescriptionPart1', + { + defaultMessage: 'audit events convey security-relevant logs from the Linux Audit Framework.', + } +); + +export const AUDITD_FILE_NAME = i18n.translate( + 'xpack.securitySolution.eventRenderers.auditdFileName', + { + defaultMessage: 'Auditd File', + } +); + +export const AUDITD_FILE_DESCRIPTION_PART1 = i18n.translate( + 'xpack.securitySolution.eventRenderers.auditdFileDescriptionPart1', + { + defaultMessage: + 'File events show users (and system accounts) performing CRUD operations on files via specific processes.', + } +); + +export const AUTHENTICATION_NAME = i18n.translate( + 'xpack.securitySolution.eventRenderers.authenticationName', + { + defaultMessage: 'Authentication', + } +); + +export const AUTHENTICATION_DESCRIPTION_PART1 = i18n.translate( + 'xpack.securitySolution.eventRenderers.authenticationDescriptionPart1', + { + defaultMessage: + 'Authentication events show users (and system accounts) successfully or unsuccessfully logging into hosts.', + } +); + +export const AUTHENTICATION_DESCRIPTION_PART2 = i18n.translate( + 'xpack.securitySolution.eventRenderers.authenticationDescriptionPart2', + { + defaultMessage: + 'Some authentication events may include additional details when users authenticate on behalf of other users.', + } +); + +export const DNS_NAME = i18n.translate('xpack.securitySolution.eventRenderers.dnsName', { + defaultMessage: 'Domain Name System (DNS)', +}); + +export const DNS_DESCRIPTION_PART1 = i18n.translate( + 'xpack.securitySolution.eventRenderers.dnsDescriptionPart1', + { + defaultMessage: + 'Domain Name System (DNS) events show users (and system accounts) making requests via specific processes to translate from host names to IP addresses.', + } +); + +export const FILE_NAME = i18n.translate('xpack.securitySolution.eventRenderers.fileName', { + defaultMessage: 'File', +}); + +export const FILE_DESCRIPTION_PART1 = i18n.translate( + 'xpack.securitySolution.eventRenderers.fileDescriptionPart1', + { + defaultMessage: + 'File events show users (and system accounts) performing CRUD operations on files via specific processes.', + } +); + +export const FIM_NAME = i18n.translate('xpack.securitySolution.eventRenderers.fimName', { + defaultMessage: 'File Integrity Module (FIM)', +}); + +export const FIM_DESCRIPTION_PART1 = i18n.translate( + 'xpack.securitySolution.eventRenderers.fimDescriptionPart1', + { + defaultMessage: + 'File Integrity Module (FIM) events show users (and system accounts) performing CRUD operations on files via specific processes.', + } +); + +export const FLOW_NAME = i18n.translate('xpack.securitySolution.eventRenderers.flowName', { + defaultMessage: 'Flow', +}); + +export const FLOW_DESCRIPTION_PART1 = i18n.translate( + 'xpack.securitySolution.eventRenderers.flowDescriptionPart1', + { + defaultMessage: + "The Flow renderer visualizes the flow of data between a source and destination. It's applicable to many types of events.", + } +); + +export const FLOW_DESCRIPTION_PART2 = i18n.translate( + 'xpack.securitySolution.eventRenderers.flowDescriptionPart2', + { + defaultMessage: + 'The hosts, ports, protocol, direction, duration, amount transferred, process, geographic location, and other details are visualized when available.', + } +); + +export const PROCESS = i18n.translate('xpack.securitySolution.eventRenderers.processName', { + defaultMessage: 'Process', +}); + +export const PROCESS_DESCRIPTION_PART1 = i18n.translate( + 'xpack.securitySolution.eventRenderers.processDescriptionPart1', + { + defaultMessage: + 'Process events show users (and system accounts) starting and stopping processes.', + } +); + +export const PROCESS_DESCRIPTION_PART2 = i18n.translate( + 'xpack.securitySolution.eventRenderers.processDescriptionPart2', + { + defaultMessage: + 'Details including the command line arguments, parent process, and if applicable, file hashes are displayed when available.', + } +); + +export const SOCKET_NAME = i18n.translate('xpack.securitySolution.eventRenderers.socketName', { + defaultMessage: 'Socket (Network)', +}); + +export const SOCKET_DESCRIPTION_PART1 = i18n.translate( + 'xpack.securitySolution.eventRenderers.socketDescriptionPart1', + { + defaultMessage: + 'Socket (Network) events show processes listening, accepting, and closing connections.', + } +); + +export const SOCKET_DESCRIPTION_PART2 = i18n.translate( + 'xpack.securitySolution.eventRenderers.socketDescriptionPart2', + { + defaultMessage: + 'Details including the protocol, ports, and a community ID for correlating all network events related to a single flow are displayed when available.', + } +); + +export const SURICATA_NAME = i18n.translate('xpack.securitySolution.eventRenderers.suricataName', { + defaultMessage: 'Suricata', +}); + +export const SURICATA_DESCRIPTION_PART1 = i18n.translate( + 'xpack.securitySolution.eventRenderers.suricataDescriptionPart1', + { + defaultMessage: 'Summarizes', + } +); + +export const SURICATA_DESCRIPTION_PART2 = i18n.translate( + 'xpack.securitySolution.eventRenderers.suricataDescriptionPart2', + { + defaultMessage: + 'intrusion detection (IDS), inline intrusion prevention (IPS), and network security monitoring (NSM) events', + } +); + +export const SYSTEM_NAME = i18n.translate('xpack.securitySolution.eventRenderers.systemName', { + defaultMessage: 'System', +}); + +export const SYSTEM_DESCRIPTION_PART1 = i18n.translate( + 'xpack.securitySolution.eventRenderers.systemDescriptionPart1', + { + defaultMessage: 'The Auditbeat', + } +); + +export const SYSTEM_DESCRIPTION_PART2 = i18n.translate( + 'xpack.securitySolution.eventRenderers.systemDescriptionPart2', + { + defaultMessage: 'module collects various security related information about a system.', + } +); + +export const SYSTEM_DESCRIPTION_PART3 = i18n.translate( + 'xpack.securitySolution.eventRenderers.systemDescriptionPart3', + { + defaultMessage: + 'All datasets send both periodic state information (e.g. all currently running processes) and real-time changes (e.g. when a new process starts or stops).', + } +); + +export const ZEEK_NAME = i18n.translate('xpack.securitySolution.eventRenderers.zeekName', { + defaultMessage: 'Zeek (formerly Bro)', +}); + +export const ZEEK_DESCRIPTION_PART1 = i18n.translate( + 'xpack.securitySolution.eventRenderers.zeekDescriptionPart1', + { + defaultMessage: 'Summarizes events from the', + } +); + +export const ZEEK_DESCRIPTION_PART2 = i18n.translate( + 'xpack.securitySolution.eventRenderers.zeekDescriptionPart2', + { + defaultMessage: 'Network Security Monitoring (NSM) tool', + } +); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/constants.ts b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/constants.ts new file mode 100644 index 0000000000000..4749afda9570a --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/constants.ts @@ -0,0 +1,7 @@ +/* + * 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 ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID = 'row-renderer-example'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/auditd.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/auditd.tsx new file mode 100644 index 0000000000000..d90d0fdfa558b --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/auditd.tsx @@ -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. + */ + +import React from 'react'; + +import { mockTimelineData } from '../../../../common/mock/mock_timeline_data'; +import { createGenericAuditRowRenderer } from '../../timeline/body/renderers/auditd/generic_row_renderer'; +import { CONNECTED_USING } from '../../timeline/body/renderers/auditd/translations'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const AuditdExampleComponent: React.FC = () => { + const auditdRowRenderer = createGenericAuditRowRenderer({ + actionName: 'connected-to', + text: CONNECTED_USING, + }); + + return ( + <> + {auditdRowRenderer.renderRow({ + browserFields: {}, + data: mockTimelineData[26].ecs, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + > + ); +}; +export const AuditdExample = React.memo(AuditdExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/auditd_file.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/auditd_file.tsx new file mode 100644 index 0000000000000..fc8e51864f50a --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/auditd_file.tsx @@ -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. + */ + +import React from 'react'; + +import { mockTimelineData } from '../../../../common/mock/mock_timeline_data'; +import { createGenericFileRowRenderer } from '../../timeline/body/renderers/auditd/generic_row_renderer'; +import { OPENED_FILE, USING } from '../../timeline/body/renderers/auditd/translations'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const AuditdFileExampleComponent: React.FC = () => { + const auditdFileRowRenderer = createGenericFileRowRenderer({ + actionName: 'opened-file', + text: `${OPENED_FILE} ${USING}`, + }); + + return ( + <> + {auditdFileRowRenderer.renderRow({ + browserFields: {}, + data: mockTimelineData[27].ecs, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + > + ); +}; +export const AuditdFileExample = React.memo(AuditdFileExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/index.tsx new file mode 100644 index 0000000000000..3cc39a3bf7050 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/index.tsx @@ -0,0 +1,18 @@ +/* + * 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 * from './auditd'; +export * from './auditd_file'; +export * from './netflow'; +export * from './suricata'; +export * from './system'; +export * from './system_dns'; +export * from './system_endgame_process'; +export * from './system_file'; +export * from './system_fim'; +export * from './system_security_event'; +export * from './system_socket'; +export * from './zeek'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/netflow.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/netflow.tsx new file mode 100644 index 0000000000000..a276bafb65c60 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/netflow.tsx @@ -0,0 +1,22 @@ +/* + * 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 { getMockNetflowData } from '../../../../common/mock/netflow'; +import { netflowRowRenderer } from '../../timeline/body/renderers/netflow/netflow_row_renderer'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const NetflowExampleComponent: React.FC = () => ( + <> + {netflowRowRenderer.renderRow({ + browserFields: {}, + data: getMockNetflowData(), + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + > +); +export const NetflowExample = React.memo(NetflowExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/suricata.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/suricata.tsx new file mode 100644 index 0000000000000..318f427b81f28 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/suricata.tsx @@ -0,0 +1,22 @@ +/* + * 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 { mockTimelineData } from '../../../../common/mock/mock_timeline_data'; +import { suricataRowRenderer } from '../../timeline/body/renderers/suricata/suricata_row_renderer'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const SuricataExampleComponent: React.FC = () => ( + <> + {suricataRowRenderer.renderRow({ + browserFields: {}, + data: mockTimelineData[2].ecs, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + > +); +export const SuricataExample = React.memo(SuricataExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system.tsx new file mode 100644 index 0000000000000..c8c3b48ac366a --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system.tsx @@ -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. + */ + +import React from 'react'; + +import { TERMINATED_PROCESS } from '../../timeline/body/renderers/system/translations'; +import { createGenericSystemRowRenderer } from '../../timeline/body/renderers/system/generic_row_renderer'; +import { mockEndgameTerminationEvent } from '../../../../common/mock/mock_endgame_ecs_data'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const SystemExampleComponent: React.FC = () => { + const systemRowRenderer = createGenericSystemRowRenderer({ + actionName: 'termination_event', + text: TERMINATED_PROCESS, + }); + + return ( + <> + {systemRowRenderer.renderRow({ + browserFields: {}, + data: mockEndgameTerminationEvent, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + > + ); +}; +export const SystemExample = React.memo(SystemExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_dns.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_dns.tsx new file mode 100644 index 0000000000000..4937b0f05ce7c --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_dns.tsx @@ -0,0 +1,26 @@ +/* + * 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 { createDnsRowRenderer } from '../../timeline/body/renderers/system/generic_row_renderer'; +import { mockEndgameDnsRequest } from '../../../../common/mock/mock_endgame_ecs_data'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const SystemDnsExampleComponent: React.FC = () => { + const systemDnsRowRenderer = createDnsRowRenderer(); + + return ( + <> + {systemDnsRowRenderer.renderRow({ + browserFields: {}, + data: mockEndgameDnsRequest, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + > + ); +}; +export const SystemDnsExample = React.memo(SystemDnsExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_endgame_process.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_endgame_process.tsx new file mode 100644 index 0000000000000..675bc172ab6f7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_endgame_process.tsx @@ -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. + */ + +import React from 'react'; + +import { createEndgameProcessRowRenderer } from '../../timeline/body/renderers/system/generic_row_renderer'; +import { mockEndgameCreationEvent } from '../../../../common/mock/mock_endgame_ecs_data'; +import { PROCESS_STARTED } from '../../timeline/body/renderers/system/translations'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const SystemEndgameProcessExampleComponent: React.FC = () => { + const systemEndgameProcessRowRenderer = createEndgameProcessRowRenderer({ + actionName: 'creation_event', + text: PROCESS_STARTED, + }); + + return ( + <> + {systemEndgameProcessRowRenderer.renderRow({ + browserFields: {}, + data: mockEndgameCreationEvent, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + > + ); +}; +export const SystemEndgameProcessExample = React.memo(SystemEndgameProcessExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_file.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_file.tsx new file mode 100644 index 0000000000000..62c243a7e8502 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_file.tsx @@ -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. + */ + +import React from 'react'; + +import { mockEndgameFileDeleteEvent } from '../../../../common/mock/mock_endgame_ecs_data'; +import { createGenericFileRowRenderer } from '../../timeline/body/renderers/system/generic_row_renderer'; +import { DELETED_FILE } from '../../timeline/body/renderers/system/translations'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const SystemFileExampleComponent: React.FC = () => { + const systemFileRowRenderer = createGenericFileRowRenderer({ + actionName: 'file_delete_event', + text: DELETED_FILE, + }); + + return ( + <> + {systemFileRowRenderer.renderRow({ + browserFields: {}, + data: mockEndgameFileDeleteEvent, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + > + ); +}; +export const SystemFileExample = React.memo(SystemFileExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_fim.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_fim.tsx new file mode 100644 index 0000000000000..ad3eeb7f797ff --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_fim.tsx @@ -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. + */ + +import React from 'react'; + +import { mockEndgameFileCreateEvent } from '../../../../common/mock/mock_endgame_ecs_data'; +import { createFimRowRenderer } from '../../timeline/body/renderers/system/generic_row_renderer'; +import { CREATED_FILE } from '../../timeline/body/renderers/system/translations'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const SystemFimExampleComponent: React.FC = () => { + const systemFimRowRenderer = createFimRowRenderer({ + actionName: 'file_create_event', + text: CREATED_FILE, + }); + + return ( + <> + {systemFimRowRenderer.renderRow({ + browserFields: {}, + data: mockEndgameFileCreateEvent, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + > + ); +}; +export const SystemFimExample = React.memo(SystemFimExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_security_event.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_security_event.tsx new file mode 100644 index 0000000000000..bc577771cc90c --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_security_event.tsx @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; + +import { createSecurityEventRowRenderer } from '../../timeline/body/renderers/system/generic_row_renderer'; +import { mockEndgameUserLogon } from '../../../../common/mock/mock_endgame_ecs_data'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const SystemSecurityEventExampleComponent: React.FC = () => { + const systemSecurityEventRowRenderer = createSecurityEventRowRenderer({ + actionName: 'user_logon', + }); + + return ( + <> + {systemSecurityEventRowRenderer.renderRow({ + browserFields: {}, + data: mockEndgameUserLogon, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + > + ); +}; +export const SystemSecurityEventExample = React.memo(SystemSecurityEventExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_socket.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_socket.tsx new file mode 100644 index 0000000000000..dd119d1b60f39 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/system_socket.tsx @@ -0,0 +1,29 @@ +/* + * 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 { ACCEPTED_A_CONNECTION_VIA } from '../../timeline/body/renderers/system/translations'; +import { createSocketRowRenderer } from '../../timeline/body/renderers/system/generic_row_renderer'; +import { mockEndgameIpv4ConnectionAcceptEvent } from '../../../../common/mock/mock_endgame_ecs_data'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const SystemSocketExampleComponent: React.FC = () => { + const systemSocketRowRenderer = createSocketRowRenderer({ + actionName: 'ipv4_connection_accept_event', + text: ACCEPTED_A_CONNECTION_VIA, + }); + return ( + <> + {systemSocketRowRenderer.renderRow({ + browserFields: {}, + data: mockEndgameIpv4ConnectionAcceptEvent, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + > + ); +}; +export const SystemSocketExample = React.memo(SystemSocketExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/zeek.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/zeek.tsx new file mode 100644 index 0000000000000..56f0d207fbc6d --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/zeek.tsx @@ -0,0 +1,22 @@ +/* + * 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 { mockTimelineData } from '../../../../common/mock/mock_timeline_data'; +import { zeekRowRenderer } from '../../timeline/body/renderers/zeek/zeek_row_renderer'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const ZeekExampleComponent: React.FC = () => ( + <> + {zeekRowRenderer.renderRow({ + browserFields: {}, + data: mockTimelineData[13].ecs, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + > +); +export const ZeekExample = React.memo(ZeekExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx new file mode 100644 index 0000000000000..2792b264ba7e2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx @@ -0,0 +1,182 @@ +/* + * 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 { + EuiButtonEmpty, + EuiButtonIcon, + EuiText, + EuiToolTip, + EuiOverlayMask, + EuiModal, + EuiModalHeader, + EuiModalHeaderTitle, + EuiModalBody, + EuiButton, + EuiFlexGroup, + EuiFlexItem, + EuiInMemoryTable, +} from '@elastic/eui'; +import React, { useState, useCallback, useRef } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import styled from 'styled-components'; + +import { State } from '../../../common/store'; + +import { renderers } from './catalog'; +import { setExcludedRowRendererIds as dispatchSetExcludedRowRendererIds } from '../../../timelines/store/timeline/actions'; +import { RowRenderersBrowser } from './row_renderers_browser'; +import * as i18n from './translations'; + +const StyledEuiModal = styled(EuiModal)` + margin: 0 auto; + max-width: 95vw; + min-height: 95vh; + + > .euiModal__flex { + max-height: 95vh; + } +`; + +const StyledEuiModalBody = styled(EuiModalBody)` + .euiModalBody__overflow { + display: flex; + align-items: stretch; + overflow: hidden; + + > div { + display: flex; + flex-direction: column; + flex: 1; + + > div:first-child { + flex: 0; + } + + .euiBasicTable { + flex: 1; + overflow: auto; + } + } + } +`; + +const StyledEuiOverlayMask = styled(EuiOverlayMask)` + z-index: 8001; + padding-bottom: 0; + + > div { + width: 100%; + } +`; + +interface StatefulRowRenderersBrowserProps { + timelineId: string; +} + +const StatefulRowRenderersBrowserComponent: React.FC