diff --git a/.eslintrc.js b/.eslintrc.js
index 246702aedf863..dc2eaa993ce8b 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -536,9 +536,15 @@ module.exports = {
* ML overrides
*/
{
- files: ['x-pack/legacy/plugins/ml/**/*.js'],
+ files: ['x-pack/plugins/ml/**/*.js'],
rules: {
'no-shadow': 'error',
+ 'import/no-extraneous-dependencies': [
+ 'error',
+ {
+ packageDir: './x-pack',
+ },
+ ],
},
},
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 71d857c1c9041..4a061d7415990 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -4,7 +4,7 @@
# App
/x-pack/plugins/lens/ @elastic/kibana-app
-/x-pack/legacy/plugins/graph/ @elastic/kibana-app
+/x-pack/plugins/graph/ @elastic/kibana-app
/src/legacy/server/url_shortening/ @elastic/kibana-app
/src/legacy/server/sample_data/ @elastic/kibana-app
/src/legacy/core_plugins/kibana/public/dashboard/ @elastic/kibana-app
@@ -12,13 +12,13 @@
/src/legacy/core_plugins/kibana/public/visualize/ @elastic/kibana-app
/src/legacy/core_plugins/kibana/public/local_application_service/ @elastic/kibana-app
/src/legacy/core_plugins/kibana/public/dev_tools/ @elastic/kibana-app
-/src/legacy/core_plugins/metrics/ @elastic/kibana-app
/src/legacy/core_plugins/vis_type_vislib/ @elastic/kibana-app
-/src/legacy/core_plugins/vis_type_xy/ @elastic/kibana-app
+/src/plugins/vis_type_xy/ @elastic/kibana-app
/src/plugins/kibana_legacy/ @elastic/kibana-app
/src/plugins/timelion/ @elastic/kibana-app
/src/plugins/dashboard/ @elastic/kibana-app
/src/plugins/discover/ @elastic/kibana-app
+/src/plugins/vis_type_timeseries/ @elastic/kibana-app
# Core UI
# Exclude tutorials folder for now because they are not owned by Kibana app and most will move out soon
@@ -80,6 +80,8 @@
/x-pack/legacy/plugins/ingest_manager/ @elastic/ingest-management
/x-pack/plugins/observability/ @elastic/logs-metrics-ui @elastic/apm-ui @elastic/uptime @elastic/ingest-management
/x-pack/legacy/plugins/monitoring/ @elastic/stack-monitoring-ui
+/x-pack/legacy/plugins/uptime @elastic/uptime
+/x-pack/plugins/uptime @elastic/uptime
# Machine Learning
/x-pack/legacy/plugins/ml/ @elastic/ml-ui
@@ -95,6 +97,7 @@
# Maps
/x-pack/legacy/plugins/maps/ @elastic/kibana-gis
+/x-pack/plugins/maps/ @elastic/kibana-gis
/x-pack/test/api_integration/apis/maps/ @elastic/kibana-gis
/x-pack/test/functional/apps/maps/ @elastic/kibana-gis
/x-pack/test/functional/es_archives/maps/ @elastic/kibana-gis
diff --git a/.sass-lint.yml b/.sass-lint.yml
index 0c33eaf794c69..5c2c88a1dad5d 100644
--- a/.sass-lint.yml
+++ b/.sass-lint.yml
@@ -9,9 +9,10 @@ files:
- 'x-pack/legacy/plugins/canvas/**/*.s+(a|c)ss'
- 'x-pack/plugins/triggers_actions_ui/**/*.s+(a|c)ss'
- 'x-pack/plugins/lens/**/*.s+(a|c)ss'
+ - 'x-pack/legacy/plugins/maps/**/*.s+(a|c)ss'
+ - 'x-pack/plugins/maps/**/*.s+(a|c)ss'
ignore:
- 'x-pack/legacy/plugins/canvas/shareable_runtime/**/*.s+(a|c)ss'
- - 'x-pack/legacy/plugins/maps/**/*.s+(a|c)ss'
rules:
quotes:
- 2
diff --git a/docs/apm/advanced-queries.asciidoc b/docs/apm/advanced-queries.asciidoc
index add6f601489e1..f89f994e59e57 100644
--- a/docs/apm/advanced-queries.asciidoc
+++ b/docs/apm/advanced-queries.asciidoc
@@ -1,14 +1,11 @@
+[role="xpack"]
[[advanced-queries]]
-=== Advanced queries
+=== Query your data
-When querying in the APM app, you're simply searching and selecting data from fields in Elasticsearch documents.
-Queries entered into the query bar are also added as parameters to the URL,
-so it's easy to share a specific query or view with others.
-
-You can begin to see some of the transaction fields available for filtering:
-
-[role="screenshot"]
-image::apm/images/apm-query-bar.png[Example of the Kibana Query bar in APM app in Kibana]
+Querying your APM data is a powerful tool that can make finding bottlenecks in your code even easier.
+Imagine you have a user that complains about a slow response time in a specific service.
+With the query bar, you can easily filter the APM app to only display trace data for that user,
+or, to only show transactions that are slower than a specified time threshold.
[float]
==== Example APM app queries
@@ -17,15 +14,24 @@ image::apm/images/apm-query-bar.png[Example of the Kibana Query bar in APM app i
* Filter by response status code: `context.response.status_code >= 400`
* Filter by single user ID: `context.user.id : 12`
+When querying in the APM app, you're merely searching and selecting data from fields in Elasticsearch documents.
+Queries entered into the query bar are also added as parameters to the URL,
+so it's easy to share a specific query or view with others.
+
+When you type, you can begin to see some of the transaction fields available for filtering:
+
+[role="screenshot"]
+image::apm/images/apm-query-bar.png[Example of the Kibana Query bar in APM app in Kibana]
+
TIP: Read the {kibana-ref}/kuery-query.html[Kibana Query Language Enhancements] documentation to learn more about the capabilities of the {kib} query language.
[float]
[[discover-advanced-queries]]
=== Querying in Discover
-It may also be helpful to view your APM data in {kibana-ref}/discover.html[*Discover*].
+Alternatively, you can query your APM documents in {kibana-ref}/discover.html[*Discover*].
Querying documents in *Discover* works the same way as querying in the APM app,
-and all of the example APM app queries can also be used in *Discover*.
+and *Discover* supports all of the example APM app queries shown on this page.
[float]
==== Example Discover query
@@ -33,7 +39,7 @@ and all of the example APM app queries can also be used in *Discover*.
One example where you may want to make use of *Discover*,
is for viewing _all_ transactions for an endpoint, instead of just a sample.
-TIP: Starting in v7.6, you can view 10 samples per bucket in the APM app, instead of just one.
+TIP: Starting in v7.6, you can view ten samples per bucket in the APM app, instead of just one.
Use the APM app to find a transaction name and time bucket that you're interested in learning more about.
Then, switch to *Discover* and make a search:
diff --git a/docs/apm/agent-configuration.asciidoc b/docs/apm/agent-configuration.asciidoc
index 0d2834c1a400e..d911c2154ea4c 100644
--- a/docs/apm/agent-configuration.asciidoc
+++ b/docs/apm/agent-configuration.asciidoc
@@ -1,12 +1,16 @@
[role="xpack"]
[[agent-configuration]]
-=== APM Agent configuration
+=== APM Agent central configuration
-APM Agent configuration allows you to fine-tune your agent configuration directly in Kibana.
-Best of all, changes are automatically propagated to your APM agents so there's no need to redeploy.
+++++
+Configure APM agents with central config
+++++
-To get started, simply choose the services and environments you wish to configure.
-The APM app will let you know when your configurations have been applied by your agents.
+APM Agent configuration allows you to fine-tune your agent configuration from within the APM app.
+Changes are automatically propagated to your APM agents, so there's no need to redeploy.
+
+To get started, choose the services and environments you wish to configure.
+The APM app will let you know when your agents have applied your configurations.
[role="screenshot"]
image::apm/images/apm-agent-configuration.png[APM Agent configuration in Kibana]
@@ -14,29 +18,28 @@ image::apm/images/apm-agent-configuration.png[APM Agent configuration in Kibana]
[float]
==== Precedence
-Configurations set with APM Agent configuration take precedence over configurations set locally in the Agent.
+Configurations set from the APM app take precedence over configurations set locally in each Agent.
However, if APM Server is slow to respond, is offline, reports an error, etc.,
APM agents will use local defaults until they're able to update the configuration.
-For this reason, it is still important to set custom default configurations locally in each of your agents.
+For this reason, it is still essential to set custom default configurations locally in each of your agents.
[float]
==== APM Server setup
This feature requires {apm-server-ref}/setup-kibana-endpoint.html[Kibana endpoint configuration] in APM Server.
-Why is additional configuration needed in APM Server?
-That's because APM Server acts as a proxy between the agents and Kibana.
+APM Server acts as a proxy between the agents and Kibana.
Kibana communicates any changed settings to APM Server so that your agents only need to poll APM Server to determine which settings have changed.
[float]
==== Supported configurations
-Each Agent has its own list of supported configurations.
+Each Agent has a list of supported configurations.
After selecting a Service name and environment in the APM app,
-a list of all available configuration options,
+a list of all supported configuration options,
including descriptions and default values, will be displayed.
-Supported configurations are also marked in each Agent's configuration documentation:
+Supported configurations are also tagged with the image:./images/dynamic-config.svg[] badge in each Agent's configuration reference:
[horizontal]
Go Agent:: {apm-go-ref}/configuration.html[Configuration reference]
diff --git a/docs/apm/api.asciidoc b/docs/apm/api.asciidoc
index a8f4f4bf0baaa..93733f5990a46 100644
--- a/docs/apm/api.asciidoc
+++ b/docs/apm/api.asciidoc
@@ -1,6 +1,10 @@
[role="xpack"]
[[apm-api]]
-== API
+== APM app API
+
+++++
+REST API
+++++
Some APM app features are provided via a REST API:
diff --git a/docs/apm/apm-alerts.asciidoc b/docs/apm/apm-alerts.asciidoc
index b8552c007b13d..75ce5f56c96c6 100644
--- a/docs/apm/apm-alerts.asciidoc
+++ b/docs/apm/apm-alerts.asciidoc
@@ -1,12 +1,16 @@
[role="xpack"]
[[apm-alerts]]
-=== Create an alert
+=== Alerts
+
+++++
+Create an alert
+++++
beta::[]
-The APM app is integrated with Kibana's {kibana-ref}/alerting-getting-started.html[alerting and actions] feature.
-It provides a set of built-in **actions** and APM specific threshold **alerts** for you to use,
-and allows all alerts to be centrally managed from <>.
+The APM app integrates with Kibana's {kibana-ref}/alerting-getting-started.html[alerting and actions] feature.
+It provides a set of built-in **actions** and APM specific threshold **alerts** for you to use
+and enables central management of all alerts from <>.
[role="screenshot"]
image::apm/images/apm-alert.png[Create an alert in the APM app]
@@ -28,9 +32,9 @@ This guide creates an alert for the `opbeans-java` service based on the followin
From the APM app, navigate to the `opbeans-java` service and select
**Alerts** > **Create threshold alert** > **Transaction duration**.
-The name of your alert will automatically be set as `Transaction duration | opbeans-java`,
-and the alert will be tagged with `apm` and `service.name:opbeans-java`.
-Feel free to edit either of these defaults.
+`Transaction duration | opbeans-java` is automatically set as the name of the alert,
+and `apm` and `service.name:opbeans-java` are added as tags.
+It's fine to change the name of the alert, but do not edit the tags.
Based on the alert criteria, define the following alert details:
@@ -42,7 +46,7 @@ Based on the alert criteria, define the following alert details:
* **FOR THE LAST** - `5 minutes`
Select an action type.
-Multiple action types can be selected, but in this example we want to post to a slack channel.
+Multiple action types can be selected, but in this example, we want to post to a Slack channel.
Select **Slack** > **Create a connector**.
Enter a name for the connector,
and paste the webhook URL.
@@ -63,9 +67,9 @@ This guide creates an alert for the `opbeans-python` service based on the follow
From the APM app, navigate to the `opbeans-python` service and select
**Alerts** > **Create threshold alert** > **Error rate**.
-The name of your alert will automatically be set as `Error rate | opbeans-python`,
-and the alert will be tagged with `apm` and `service.name:opbeans-python`.
-Feel free to edit either of these defaults.
+`Error rate | opbeans-python` is automatically set as the name of the alert,
+and `apm` and `service.name:opbeans-python` are added as tags.
+It's fine to change the name of the alert, but do not edit the tags.
Based on the alert criteria, define the following alert details:
@@ -93,5 +97,5 @@ From this page, you can create, edit, disable, mute, and delete alerts, and crea
See {kibana-ref}/alerting-getting-started.html[alerting and actions] for more information.
NOTE: If you are using an **on-premise** Elastic Stack deployment with security,
-TLS must be configured for communication between Elasticsearch and Kibana.
+communication between Elasticsearch and Kibana must have TLS configured.
More information is in the alerting {kibana-ref}/alerting-getting-started.html#alerting-setup-prerequisites[prerequisites].
\ No newline at end of file
diff --git a/docs/apm/bottlenecks.asciidoc b/docs/apm/bottlenecks.asciidoc
deleted file mode 100644
index fbde3e9ddcbd6..0000000000000
--- a/docs/apm/bottlenecks.asciidoc
+++ /dev/null
@@ -1,25 +0,0 @@
-[role="xpack"]
-[[apm-bottlenecks]]
-== Visualizing Application Bottlenecks
-
-Elastic APM captures different types of information from within instrumented applications:
-
-* {apm-overview-ref-v}/transaction-spans.html[*Spans*] contain information about a specific code path that has been executed.
-They measure from the start to end of an activity,
-and they can have a parent/child relationship with other spans.
-* {apm-overview-ref-v}/transactions.html[*Transactions*] are a special kind of span that have extra metadata associated with them.
-You can think of transactions as the highest level of work you’re measuring within a service.
-As an example, a transaction could be a request to your server, a batch job, or a custom transaction type.
-* {apm-overview-ref-v}/errors.html[*Errors*] contain information about the original exception that occurred or about a log created when the exception occurred.
-
-Each of these information types have a specific page associated with them in the APM app.
-These various pages display the captured data in curated charts and tables that allow you to easily compare and debug your applications.
-
-For example, you can see information about response times, requests per minute, and status codes per endpoint.
-You can even dive into a specific request sample and get a complete waterfall view of what your application is spending its time on.
-You might see that your bottlenecks are in database queries, cache calls, or external requests.
-For each incoming request and each application error,
-you can also see contextual information such as the request header, user information,
-system values, or custom data that you manually attached to the request.
-
-Having access to application-level insights with just a few clicks can drastically decrease the time you spend debugging errors, slow response times, and crashes.
diff --git a/docs/apm/custom-links.asciidoc b/docs/apm/custom-links.asciidoc
index 75c1c9d0009a2..4fdf39b643f94 100644
--- a/docs/apm/custom-links.asciidoc
+++ b/docs/apm/custom-links.asciidoc
@@ -1,6 +1,11 @@
+[role="xpack"]
[[custom-links]]
=== Custom links
+++++
+Create custom links
+++++
+
Elastic's custom link feature allows you to easily create up to 500 dynamic links
based on your specific APM data.
Custom links can be filtered to only appear in the APM app for relevant services,
@@ -12,7 +17,7 @@ Ready to dive in? Jump straight to the <>.
[[custom-links-create]]
=== Create a link
-Each custom link consists of a label, url, and optional filter.
+Each custom link consists of a label, URL, and optional filter.
The easiest way to create a custom link is from within the actions dropdown in the transaction detail page.
This method will automatically apply filters, scoping the link to that specific service,
environment, transaction type, and transaction name.
@@ -25,8 +30,7 @@ and selecting **Create custom link**.
==== Label
The name of your custom link.
-This text will be shown in the actions context menu,
-so keep it as short as possible.
+The actions context menu displays this text, so keep it as short as possible.
TIP: Custom links are displayed alphabetically in the actions menu.
@@ -39,8 +43,8 @@ URLs support dynamic field name variables, encapsulated in double curly brackets
These variables will be replaced with transaction metadata when the link is clicked.
Because everyone's data is different,
-you'll need to examine your own traces to see what metadata is available for use.
-The easiest way to do this is to select a trace in the APM app, and click **Metadata** in the **Trace Sample** table.
+you'll need to examine your traces to see what metadata is available for use.
+To do this, select a trace in the APM app, and click **Metadata** in the **Trace Sample** table.
[role="screenshot"]
image::apm/images/example-metadata.png[Example metadata]
@@ -49,7 +53,7 @@ image::apm/images/example-metadata.png[Example metadata]
[[custom-links-filters]]
==== Filters
-Filter each link to only appear so it only appears for specific services or transactions.
+Filter each link to only appear for specific services or transactions.
You can filter on the following fields:
* `service.name`
@@ -57,7 +61,7 @@ You can filter on the following fields:
* `transaction.type`
* `transaction.name`
-Multiple values are allowed when comma separated.
+Multiple values are allowed when comma-separated.
[float]
[[custom-links-examples]]
@@ -68,7 +72,7 @@ Multiple values are allowed when comma separated.
:github-query-params: https://help.github.com/en/github/managing-your-work-on-github/about-automation-for-issues-and-pull-requests-with-query-parameters
Not sure where to start with custom links?
-Take a look at the examples below, and customize them to your liking!
+Take a look at the examples below and customize them to your liking!
[float]
[[custom-links-examples-email]]
diff --git a/docs/apm/deployment-annotations.asciidoc b/docs/apm/deployment-annotations.asciidoc
new file mode 100644
index 0000000000000..6feadf8463226
--- /dev/null
+++ b/docs/apm/deployment-annotations.asciidoc
@@ -0,0 +1,17 @@
+[role="xpack"]
+[[transactions-annotations]]
+=== Track deployments with annotations
+
+++++
+Track deployments
+++++
+
+For enhanced visibility into your deployments, we offer deployment annotations on all transaction charts.
+This feature automatically tags new deployments, so you can easily see if your deploy has increased response times
+for an end-user, or if the memory/CPU footprint of your application has changed.
+Being able to identify bad deployments quickly enables you to rollback and fix issues without causing costly outages.
+
+Deployment annotations are automatically enabled, and appear when the `service.version` of your app changes.
+
+[role="screenshot"]
+image::apm/images/apm-transaction-annotation.png[Example view of transactions annotation in the APM app in Kibana]
diff --git a/docs/apm/error-reports-watcher.asciidoc b/docs/apm/error-reports-watcher.asciidoc
new file mode 100644
index 0000000000000..f41597932b751
--- /dev/null
+++ b/docs/apm/error-reports-watcher.asciidoc
@@ -0,0 +1,18 @@
+[role="xpack"]
+[[errors-alerts-with-watcher]]
+=== Error reports with Watcher
+
+++++
+Enable error reports
+++++
+
+You can use the power of the alerting features with Watcher to get reports on error occurrences.
+The Watcher assistant, which is available on the errors overview, can help you set up a watch per service.
+
+Configure the watch with an occurrences threshold, time interval, and the desired actions, such as email or Slack notifications.
+With Watcher, your team can set up reports within minutes.
+
+Watches are managed separately in the dedicated Watcher UI available in Advanced Settings.
+
+[role="screenshot"]
+image::apm/images/apm-errors-watcher-assistant.png[Example view of the Watcher assistant for errors in APM app in Kibana]
diff --git a/docs/apm/errors.asciidoc b/docs/apm/errors.asciidoc
index 689fa1fffa89e..49351ec255858 100644
--- a/docs/apm/errors.asciidoc
+++ b/docs/apm/errors.asciidoc
@@ -1,7 +1,8 @@
+[role="xpack"]
[[errors]]
=== Errors overview
-TIP: {apm-overview-ref-v}/errors.html[Errors] are defined as groups of exceptions with matching exception or log messages.
+TIP: {apm-overview-ref-v}/errors.html[Errors] are groups of exceptions with a similar exception or log message.
The *Errors* overview provides a high-level view of the error message and culprit,
the number of occurrences, and the most recent occurrence.
@@ -20,7 +21,7 @@ image::apm/images/apm-error-group.png[Example view of the error group page in th
Here, you'll see the error message, culprit, and the number of occurrences over time.
Further down, you'll see the Error occurrence table.
-This is where you can see the details of a sampled error within this group.
+This table shows the details of a sampled error within this group.
The error shown is always the most recent to occur.
Each error occurrence features a breakdown of the exception, including the stack trace from when the error occurred,
@@ -28,19 +29,4 @@ and additional contextual information to help debug the issue.
In some cases, you might also see a Transaction sample ID.
This feature allows you to make a connection between the errors and transactions,
by linking you to the specific transaction where the error occurred.
-This allows you to see the whole trace, including which services the request went through.
-
-[float]
-[[errors-alerts-with-watcher]]
-==== Error reports with Watcher
-
-You can use the power of the alerting features with Watcher to get reports on error occurrences.
-The Watcher assistant, which is available on the errors overview, can help you set up a watch per service.
-
-Configure the watch with an occurrences threshold, time interval, and the desired actions, such as email or Slack notifications.
-With Watcher, your team can set up reports within minutes.
-
-Watches are managed separately in the dedicated Watcher UI available in Advanced Settings.
-
-[role="screenshot"]
-image::apm/images/apm-errors-watcher-assistant.png[Example view of the Watcher assistant for errors in APM app in Kibana]
\ No newline at end of file
+This allows you to see the whole trace, including which services the request went through.
diff --git a/docs/apm/filters.asciidoc b/docs/apm/filters.asciidoc
index 99ba827b0198d..d53adb439f0c8 100644
--- a/docs/apm/filters.asciidoc
+++ b/docs/apm/filters.asciidoc
@@ -1,6 +1,11 @@
+[role="xpack"]
[[filters]]
=== Filters
+++++
+Filter data
+++++
+
APM provides two different ways you can filter your data within the APM App:
* <>
@@ -42,7 +47,7 @@ It allows you to view only relevant data, and is especially useful for separatin
By default, all environments are displayed. If there are no environment options, you'll see "not defined".
Service environments are defined when configuring your APM agents.
-It's very important to be consistent when naming environments in your agents.
+It's vital to be consistent when naming environments in your agents.
See the documentation for each agent you're using to learn how to configure service environments:
* *Go:* {apm-go-ref}/configuration.html#config-environment[`ELASTIC_APM_ENVIRONMENT`]
@@ -62,9 +67,9 @@ but only where they are applicable -- they are typically most useful in their or
As an example, if you select a host on the Services overview, then select a transaction group,
the host filter will still be applied.
-These filters are very useful for quickly and easily removing noise from your data.
+These filters are very useful for quickly and easily removing noise from your data.
With just a click, you can filter your transactions by the transaction result,
-host, container ID, and more.
+host, container ID, and more.
[role="screenshot"]
image::apm/images/local-filter.png[Local filters available in the APM app in Kibana]
\ No newline at end of file
diff --git a/docs/apm/getting-started.asciidoc b/docs/apm/getting-started.asciidoc
index 4a391f1a49672..89ce0be1499c5 100644
--- a/docs/apm/getting-started.asciidoc
+++ b/docs/apm/getting-started.asciidoc
@@ -1,22 +1,45 @@
[role="xpack"]
[[apm-getting-started]]
-== Getting Started
+== Get started with the APM app
-If you have not already installed and configured Elastic APM,
-the *Setup Instructions* will get you started.
+++++
+Get started
+++++
-[role="screenshot"]
-image::apm/images/apm-setup.png[Installation instructions on the APM page in Kibana]
+Elastic APM captures different types of information from within instrumented applications:
+* *Spans* contain information about the execution of a specific code path.
+They measure from the start to end of an activity,
+and they can have a parent/child relationship with other spans.
+* *Transactions* are a special kind of span;
+they are the first span for a particular service and have extra metadata associated with them.
+As an example, a transaction could be a request to your server, a batch job, or a custom transaction type.
+*Traces* link together related transactions to show an end-to-end performance of how a request was served and which services were part of it.
+* *Errors* contain information about the original exception that occurred or about a log created when the exception occurred.
-Index patterns tell Kibana which Elasticsearch indices you want to explore.
-An APM index pattern is necessary for certain features in the APM app, like the query bar.
-To set up the correct index pattern,
-simply click *Load Kibana objects* at the bottom of the Setup Instructions.
+Curated charts and tables display the different types of APM data, which allows you to compare and debug your applications easily.
-After you install an Elastic APM agent library in your application,
-the application automatically appears in the APM app in {kib}.
-No further configuration is required.
+* <>
+* <>
+* <>
+* <>
+* <>
+* <>
+* <>
-[role="screenshot"]
-image::apm/images/apm-index-pattern.png[Setup index pattern for APM in Kibana]
+TIP: Want to learn more about the Elastic APM ecosystem?
+See the {apm-get-started-ref}/overview.html[APM Overview].
+
+include::services.asciidoc[]
+
+include::traces.asciidoc[]
+
+include::transactions.asciidoc[]
+
+include::spans.asciidoc[]
+
+include::errors.asciidoc[]
+
+include::metrics.asciidoc[]
+
+include::service-maps.asciidoc[]
diff --git a/docs/apm/how-to-guides.asciidoc b/docs/apm/how-to-guides.asciidoc
new file mode 100644
index 0000000000000..9b0efb4f7a359
--- /dev/null
+++ b/docs/apm/how-to-guides.asciidoc
@@ -0,0 +1,32 @@
+[role="xpack"]
+[[apm-how-to]]
+== How-to guides
+
+Learn how to perform common APM app tasks.
+
+
+* <>
+* <>
+* <>
+* <>
+* <>
+* <>
+* <>
+* <>
+
+
+include::agent-configuration.asciidoc[]
+
+include::apm-alerts.asciidoc[]
+
+include::custom-links.asciidoc[]
+
+include::error-reports-watcher.asciidoc[]
+
+include::filters.asciidoc[]
+
+include::machine-learning.asciidoc[]
+
+include::advanced-queries.asciidoc[]
+
+include::deployment-annotations.asciidoc[]
\ No newline at end of file
diff --git a/docs/apm/images/dynamic-config.svg b/docs/apm/images/dynamic-config.svg
new file mode 100644
index 0000000000000..df62a3c84f4b4
--- /dev/null
+++ b/docs/apm/images/dynamic-config.svg
@@ -0,0 +1 @@
+ Dynamic Dynamic
\ No newline at end of file
diff --git a/docs/apm/index.asciidoc b/docs/apm/index.asciidoc
index d3f0dc5b7f11f..79190efccdff2 100644
--- a/docs/apm/index.asciidoc
+++ b/docs/apm/index.asciidoc
@@ -4,25 +4,35 @@
[partintro]
--
-Elastic Application Performance Monitoring (APM) automatically collects in-depth
-performance metrics and errors from inside your applications.
-
-The **APM** app in {kib} is provided with the basic license. It
-enables developers to drill down into the performance data for their applications
-and quickly locate the performance bottlenecks.
-
-* <>
-* <>
-* <>
-
-NOTE: For more information about the components of Elastic APM,
-see the {apm-get-started-ref}/overview.html[APM Overview].
+The APM app in {kib} is provided with the basic license.
+It allows you to monitor your software services and applications in real-time;
+visualize detailed performance information on your services,
+identify and analyze errors,
+and monitor host-level and agent-specific metrics like JVM and Go runtime metrics.
+
+[float]
+[[apm-bottlenecks]]
+== Visualizing application bottlenecks
+
+Having access to application-level insights with just a few clicks can drastically decrease the time you spend
+debugging errors, slow response times, and crashes.
+
+For example, you can see information about response times, requests per minute, and status codes per endpoint.
+You can even dive into a specific request sample and get a complete waterfall view of what your application is spending its time on.
+You might see that your bottlenecks are in database queries, cache calls, or external requests.
+For each incoming request and each application error,
+you can also see contextual information such as the request header, user information,
+system values, or custom data that you manually attached to the request.
--
+include::set-up.asciidoc[]
+
include::getting-started.asciidoc[]
-include::bottlenecks.asciidoc[]
+include::how-to-guides.asciidoc[]
-include::using-the-apm-ui.asciidoc[]
+include::settings.asciidoc[]
include::api.asciidoc[]
+
+include::troubleshooting.asciidoc[]
diff --git a/docs/apm/machine-learning.asciidoc b/docs/apm/machine-learning.asciidoc
new file mode 100644
index 0000000000000..9d347fc4f1111
--- /dev/null
+++ b/docs/apm/machine-learning.asciidoc
@@ -0,0 +1,27 @@
+[role="xpack"]
+[[machine-learning-integration]]
+=== Machine Learning integration
+
+++++
+Integrate with machine learning
+++++
+
+The Machine Learning integration will initiate a new job predefined to calculate anomaly scores on transaction response times.
+The response time graph will show the expected bounds and add an annotation when the anomaly score is 75 or above.
+Jobs can be created per transaction type, and based on the average response time.
+Manage jobs in the *Machine Learning jobs management*.
+
+[role="screenshot"]
+image::apm/images/apm-ml-integration.png[Example view of anomaly scores on response times in APM app in Kibana]
+
+[float]
+[[create-ml-integration]]
+=== Create a new machine learning job
+
+To enable machine learning anomaly detection, first choose a service to monitor.
+Then, select **Integrations** > **Enable ML anomaly detection** and click **Create job**.
+That's it! After a few minutes, the job will begin calculating results;
+it might take additional time for results to appear on your graph.
+
+APM specific anomaly detection wizards are also available for certain Agents.
+See the machine learning {ml-docs}/ootb-ml-jobs-apm.html[APM anomaly detection configurations] for more information.
diff --git a/docs/apm/metrics.asciidoc b/docs/apm/metrics.asciidoc
index ab394b785ef84..e82a4fbd5c291 100644
--- a/docs/apm/metrics.asciidoc
+++ b/docs/apm/metrics.asciidoc
@@ -1,3 +1,4 @@
+[role="xpack"]
[[metrics]]
=== Metrics overview
@@ -5,7 +6,7 @@ The *Metrics* overview provides agent-specific metrics,
which lets you perform more in-depth root cause analysis investigations within the APM app.
If you're experiencing a problem with your service, you can use this page to attempt to find the underlying cause.
-For example, you might be able to correlate a high number of errors with a long transaction duration, high CPU usage, or a memory leak.
+For example, you might be able to correlate a high number of errors with a long transaction duration, high CPU usage, or a memory leak.
[role="screenshot"]
image::apm/images/apm-metrics.png[Example view of the Metrics overview in APM app in Kibana]
@@ -17,19 +18,3 @@ thread count, garbage collection rate, and garbage collection time spent per min
[role="screenshot"]
image::apm/images/jvm-metrics.png[Example view of the Metrics overview for the Java Agent]
-
-[[machine-learning-integration]]
-=== Machine Learning integration
-
-The Machine Learning integration will initiate a new job predefined to calculate anomaly scores on transaction response times.
-The response time graph will show the expected bounds and annotate the graph when the anomaly score is 75 or above.
-
-[role="screenshot"]
-image::apm/images/apm-ml-integration.png[Example view of anomaly scores on response times in APM app in Kibana]
-
-Jobs can be created per transaction type and based on the average response time.
-You can manage jobs in the *Machine Learning jobs management*.
-It might take some time for results to appear on the graph.
-
-Machine learning is a platinum feature. For a comparison of the Elastic license levels,
-see https://www.elastic.co/subscriptions[the subscription page].
\ No newline at end of file
diff --git a/docs/apm/service-maps.asciidoc b/docs/apm/service-maps.asciidoc
index e0d84f33b4dcb..be86b9d522ac5 100644
--- a/docs/apm/service-maps.asciidoc
+++ b/docs/apm/service-maps.asciidoc
@@ -1,37 +1,53 @@
+[role="xpack"]
[[service-maps]]
=== Service maps
beta::[]
-A service map is a real-time diagram of the interactions occurring in your application’s architecture.
-It allows you to easily visualize data flow and high-level statistics, like average transaction duration,
-requests per minute, errors per minute, and metrics, allowing you to quickly assess the status of your services.
+WARNING: Service map support for Internet Explorer 11 is extremely limited.
+Please use Chrome or Firefox if available.
-Our beta offering creates two types of service maps:
+A service map is a real-time visual representation of the instrumented services in your application's architecture.
+It shows you how these services are connected, along with high-level metrics like average transaction duration,
+requests per minute, and errors per minute, that allow you to quickly assess the status of your services.
-* Global: All services and connections are shown.
-* Service-specific: Selecting a specific service will highlight it's connections.
+We currently surface two types of service maps:
+
+* Global: All services instrumented with APM agents and the connections between them are shown.
+* Service-specific: Highlight connections for a selected service.
[role="screenshot"]
image::apm/images/service-maps.png[Example view of service maps in the APM app in Kibana]
+[float]
+[[service-maps-how]]
+=== How do service maps work?
+
+Service maps rely on distributed traces to draw connections between services.
+As {apm-overview-ref-v}/distributed-tracing.html[distributed tracing] is enabled out-of-the-box for supported technologies, so are service maps.
+However, if a service isn't instrumented,
+or a `traceparent` header isn't being propagated to it,
+distributed tracing will not work, and the connection will not be drawn on the map.
+
[float]
[[visualize-your-architecture]]
=== Visualize your architecture
Select the **Service Map** tab to get started.
-By default, all services and connections are shown.
-Whether your onboarding a new engineer, or just trying to grasp the big picture,
+By default, all instrumented services and connections are shown.
+Whether you're onboarding a new engineer, or just trying to grasp the big picture,
click around, zoom in and out, and begin to visualize how your services are connected.
If there's a specific service that interests you, select that service to highlight its connections.
Clicking **Focus map** will refocus the map on that specific service and lock the connection highlighting.
-From here, select **Service Details**, or click on the **Transaction** tab to jump to the Transaction overview.
+From here, select **Service Details**, or click on the **Transaction** tab to jump to the Transaction overview
+for the selected service.
You can also use the tabs at the top of the page to easily jump to the **Errors** or **Metrics** overview.
-While it's not possible to query in service maps, it is possible to filter by environment.
+Filter out your maps by picking the environment from the environment drop-down filter.
This can be useful if you have two or more services, in separate environments, but with the same name.
-Use the environment drop down to only see the data you're interested in, like `dev` or `production`.
+Use the environment drop-down to only see the data you're interested in, like `dev` or `production`.
+Additional filters are not currently available for service maps.
[role="screenshot"]
image::apm/images/service-maps-java.png[Example view of service maps with Java highlighted in the APM app in Kibana]
@@ -46,3 +62,18 @@ Nodes appear on the map in one of two shapes:
* **Diamond**: Databases, external, and messaging. Interior icons represent the generic type,
with specific icons for known entities, like Elasticsearch.
Type and subtype are based on `span.type`, and `span.subtype`.
+
+[float]
+[[service-maps-supported]]
+=== Supported APM Agents
+
+Service maps are supported for the following Agent versions:
+
+[horizontal]
+Go Agent:: >= v1.7.0
+Java Agent:: >= v1.13.0
+.NET Agent:: >= v1.3.0
+Node.js Agent:: >= v3.6.0
+Python Agent:: >= v5.5.0
+Ruby Agent:: >= v3.6.0
+Real User Monitoring (RUM) Agent:: >= v4.7.0
diff --git a/docs/apm/services.asciidoc b/docs/apm/services.asciidoc
index 9af3e74562dab..395e23c379306 100644
--- a/docs/apm/services.asciidoc
+++ b/docs/apm/services.asciidoc
@@ -1,9 +1,9 @@
+[role="xpack"]
[[services]]
=== Services overview
-The *Services* overview gives you quick insights into the health and general performance of each service.
-
-You can add services by setting the `service.name` configuration in each of the {apm-agents-ref}[APM agents] you’re instrumenting.
+The *Services* overview gives you quick insights into the health and general performance of all of your instrumented services.
+Services are sorted by the `service.name` configured in each of the {apm-agents-ref}[APM agents] you’ve installed.
[role="screenshot"]
image::apm/images/apm-services-overview.png[Example view of services table the APM app in Kibana]
\ No newline at end of file
diff --git a/docs/apm/set-up.asciidoc b/docs/apm/set-up.asciidoc
new file mode 100644
index 0000000000000..c5bf5e13b640b
--- /dev/null
+++ b/docs/apm/set-up.asciidoc
@@ -0,0 +1,35 @@
+[role="xpack"]
+[[apm-ui]]
+== Set up the APM app
+
+++++
+Set up
+++++
+
+APM is available via the navigation sidebar in {Kib}.
+If you have not already installed and configured Elastic APM,
+the *Setup Instructions* in Kibana will get you started.
+
+[role="screenshot"]
+image::apm/images/apm-setup.png[Installation instructions on the APM page in Kibana]
+
+[float]
+[[apm-configure-index-pattern]]
+=== Load the index pattern
+
+Index patterns tell Kibana which Elasticsearch indices you want to explore.
+An APM index pattern is necessary for certain features in the APM app, like the query bar.
+To set up the correct index pattern,
+simply click *Load Kibana objects* at the bottom of the Setup Instructions.
+
+[role="screenshot"]
+image::apm/images/apm-index-pattern.png[Setup index pattern for APM in Kibana]
+
+To use a custom index pattern, see <>.
+
+[float]
+[[apm-getting-started-next]]
+=== Next steps
+
+No further configuration in the APM app is required.
+Install an APM Agent library in your service to begin visualizing and analyzing your data!
diff --git a/docs/apm/settings.asciidoc b/docs/apm/settings.asciidoc
index 37122fc9c635d..44da63143f63f 100644
--- a/docs/apm/settings.asciidoc
+++ b/docs/apm/settings.asciidoc
@@ -1,18 +1,23 @@
// Do not link directly to this page.
// Link to the anchor in `/docs/settings/apm-settings.asciidoc` instead.
+[role="xpack"]
[[apm-settings-in-kibana]]
-=== APM settings in Kibana
+== APM app settings
+
+++++
+Settings
+++++
You do not need to configure any settings to use the APM app. It is enabled by default.
[float]
[[apm-indices-settings]]
-==== APM Indices
+=== APM Indices
include::./../settings/apm-settings.asciidoc[tag=apm-indices-settings]
[float]
[[general-apm-settings]]
-==== General APM settings
+=== General APM settings
include::./../settings/apm-settings.asciidoc[tag=general-apm-settings]
diff --git a/docs/apm/spans.asciidoc b/docs/apm/spans.asciidoc
index ef21e1c5333e0..2eed339160fc4 100644
--- a/docs/apm/spans.asciidoc
+++ b/docs/apm/spans.asciidoc
@@ -1,7 +1,8 @@
+[role="xpack"]
[[spans]]
=== Span timeline
-TIP: A {apm-overview-ref-v}/transaction-spans.html[span] is defined as the duration of a single event.
+TIP: A {apm-overview-ref-v}/transaction-spans.html[span] is the duration of a single event.
Spans are automatically captured by APM agents, and you can also define custom spans.
Each span has a type and is defined by a different color in the timeline/waterfall visualization.
@@ -28,7 +29,7 @@ Services in a distributed trace are separated by color and listed in the order t
[role="screenshot"]
image::apm/images/apm-services-trace.png[Example of distributed trace colors in the APM app in Kibana]
-Don't forget, a distributed trace includes more than one transaction.
+Don't forget; a distributed trace includes more than one transaction.
When viewing these distributed traces in the timeline waterfall, you'll see this image:apm/images/transaction-icon.png[APM icon] icon,
which indicates the next transaction in the trace.
These transactions can be expanded and viewed in detail by clicking on them.
diff --git a/docs/apm/traces.asciidoc b/docs/apm/traces.asciidoc
index 09d8f52b92840..8eef3d9bed4db 100644
--- a/docs/apm/traces.asciidoc
+++ b/docs/apm/traces.asciidoc
@@ -1,12 +1,17 @@
+[role="xpack"]
[[traces]]
=== Traces overview
+TIP: Traces link together related transactions to show an end-to-end performance of how a request was served
+and which services were part of it.
+In addition to the Traces overview, you can view your application traces in the <>.
+
The *Traces* overview displays the entry transaction for all traces in your application.
If you're using <>, this view is key to finding the critical paths within your application.
Transactions with the same name are grouped together and only shown once in this table.
By default, transactions are sorted by _Impact_.
-Impact helps show the most used and slowest endpoints in your service - in other words,
+Impact helps show the most used and slowest endpoints in your service--in other words,
it's the collective amount of pain a specific endpoint is causing your users.
If there's a particular endpoint you're worried about, you can click on it to view the <>.
@@ -33,4 +38,4 @@ You can use the <> to view a waterfall displa
[role="screenshot"]
image::apm/images/apm-distributed-tracing.png[Example view of the distributed tracing in APM app in Kibana]
-TIP: Distributed tracing is supported by all APM agents and there’s no additional configuration needed.
\ No newline at end of file
+TIP: Distributed tracing is supported by all APM agents, and there's no additional configuration needed.
\ No newline at end of file
diff --git a/docs/apm/transactions.asciidoc b/docs/apm/transactions.asciidoc
index 1eb037009efff..2e1022e6d684c 100644
--- a/docs/apm/transactions.asciidoc
+++ b/docs/apm/transactions.asciidoc
@@ -1,3 +1,4 @@
+[role="xpack"]
[[transactions]]
=== Transaction overview
@@ -56,20 +57,6 @@ For further details, including troubleshooting and custom implementation instruc
refer to the documentation for each {apm-agents-ref}[APM Agent] you've implemented.
====
-[[transactions-annotations]]
-==== Transaction annotations
-
-For enhanced visibility into your deployments, we offer deployment annotations on all transaction charts.
-This feature automatically tags new deployments, so you can easily see if your deploy has increased response times
-for an end-user, or if the memory/CPU footprint of your application has increased.
-Being able to quickly identify bad deployments enables you to rollback and fix issues without causing costly outages.
-
-Deployment annotations are automatically enabled, and appear when the `service.version` of your app changes.
-
-[role="screenshot"]
-image::apm/images/apm-transaction-annotation.png[Example view of transactions annotation in the APM app in Kibana]
-
-
[[rum-transaction-overview]]
==== RUM Transaction overview
@@ -82,7 +69,7 @@ image::apm/images/apm-geo-ui.jpg[average page load duration distribution]
This data is available due to the geo-ip and user agent pipelines being enabled by default,
which allows for the capture of geo-location and user agent data.
These visualizations make it easy for you to visualize performance information about your
-end users' experience based on their location.
+end-users' experience based on their location.
[[transaction-details]]
==== Transaction details
@@ -103,7 +90,7 @@ The number of requests per bucket is displayed when hovering over the graph, and
[role="screenshot"]
image::apm/images/apm-transaction-duration-dist.png[Example view of transactions duration distribution graph]
-This graph shows a typical distribution, and indicates most of our requests were served quickly - awesome!
+This graph shows a typical distribution, and indicates most of our requests were served quickly--awesome!
It's the requests on the right, the ones taking longer than average, that we probably want to focus on.
When you select one of these buckets,
diff --git a/docs/apm/troubleshooting.asciidoc b/docs/apm/troubleshooting.asciidoc
index c6174e1786c78..eb4fb790afd7f 100644
--- a/docs/apm/troubleshooting.asciidoc
+++ b/docs/apm/troubleshooting.asciidoc
@@ -1,19 +1,24 @@
-[[troubleshooting]]
-=== Troubleshooting common problems
+[[troubleshooting]]
+== Troubleshoot common problems
+
+++++
+Troubleshooting
+++++
If you have something to add to this section, please consider creating a pull request with
your proposed changes at https://github.com/elastic/kibana.
-Also check out the https://discuss.elastic.co/c/apm[APM discussion forum].
+Also, check out the https://discuss.elastic.co/c/apm[APM discussion forum].
+[float]
[[no-apm-data-found]]
-==== No APM data found
+=== No APM data found
This section can help with any of the following:
* Data isn't displaying in the APM app
-* You're seeing a message like "No Services Found",
-* You're seeing errors like "Fielddata is disabled on text fields by default..."
+* You see a message like "No Services Found",
+* You see errors like "Fielddata is disabled on text fields by default..."
There are a number of factors that could be at play here.
One important thing to double-check first is your index template.
@@ -52,12 +57,13 @@ you can customize the indices that the APM app uses to display data.
Navigate to *APM* > *Settings* > *Indices*, and change all `apm_oss.*Pattern` values to
include the new index pattern. For example: `customIndexName-*`.
-==== Unknown route
+[float]
+=== Unknown route
The {apm-app-ref}/transactions.html[transaction overview] will only display helpful information
when the transactions in your services are named correctly.
If you're seeing "GET unknown route" or "unknown route" in the APM app,
-it could be a sign that something isn't working like it should.
+it could be a sign that something isn't working as it should.
Elastic APM Agents come with built-in support for popular frameworks out-of-the-box.
This means, among other things, that the Agent will try to automatically name HTTP requests.
@@ -71,7 +77,8 @@ To resolve this, you'll need to head over to the relevant {apm-agents-ref}[Agent
Specifically, view the Agent's supported technologies page.
You can also use the Agent's public API to manually set a name for the transaction.
-==== Fields are not searchable
+[float]
+=== Fields are not searchable
In Elasticsearch, index templates are used to define settings and mappings that determine how fields should be analyzed.
The recommended index template file for APM Server is installed by the APM Server packages.
@@ -92,7 +99,7 @@ Selecting the `apm-*` index pattern shows a listing of every field defined in th
*Ensure a field is searchable*
There are two things you can do to if you'd like to ensure a field is searchable:
-1. Index your additional data as {apm-overview-ref}/metadata.html[labels] instead.
+1. Index your additional data as {apm-overview-ref-v}/metadata.html[labels] instead.
These are dynamic by default, which means they will be indexed and become searchable and aggregatable.
2. Use the {apm-server-ref}/configuration-template.html[`append_fields`] feature. As an example,
diff --git a/docs/apm/using-the-apm-ui.asciidoc b/docs/apm/using-the-apm-ui.asciidoc
deleted file mode 100644
index 904718999069d..0000000000000
--- a/docs/apm/using-the-apm-ui.asciidoc
+++ /dev/null
@@ -1,51 +0,0 @@
-[role="xpack"]
-[[apm-ui]]
-== Using APM
-
-APM is designed to be as intuitive as possible,
-but you might come across certain terms or concepts that don’t feel native to you.
-Not to worry, we've created this guide to help you get the most out of Elastic APM.
-
-APM is available via the navigation sidebar in {Kib}.
-
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-
-include::filters.asciidoc[]
-
-include::services.asciidoc[]
-
-include::traces.asciidoc[]
-
-include::transactions.asciidoc[]
-
-include::spans.asciidoc[]
-
-include::service-maps.asciidoc[]
-
-include::errors.asciidoc[]
-
-include::metrics.asciidoc[]
-
-include::apm-alerts.asciidoc[]
-
-include::agent-configuration.asciidoc[]
-
-include::custom-links.asciidoc[]
-
-include::advanced-queries.asciidoc[]
-
-include::settings.asciidoc[]
-
-include::troubleshooting.asciidoc[]
diff --git a/docs/ingest_manager/index.asciidoc b/docs/ingest_manager/index.asciidoc
index 1254f412e14c5..22afa88c919e4 100644
--- a/docs/ingest_manager/index.asciidoc
+++ b/docs/ingest_manager/index.asciidoc
@@ -113,7 +113,7 @@ Ingest Management enforces an indexing strategy to allow the system to automatic
{type}-{dataset}-{namespace}
```
-The `{type}` can be `logs` or `metrics`. The `{namespace}` is the part where the user can use free form. The only two requirement are that it has only characters allowed in an Elasticsearch index name and does NOT contain a `-`. The `dataset` is defined by the data that is indexed. The same requirements as for the namespace apply. It is expected that the fields for type, namespace and dataset are part of each event and are constant keywords.
+The `{type}` can be `logs` or `metrics`. The `{namespace}` is the part where the user can use free form. The only two requirement are that it has only characters allowed in an Elasticsearch index name and does NOT contain a `-`. The `dataset` is defined by the data that is indexed. The same requirements as for the namespace apply. It is expected that the fields for type, namespace and dataset are part of each event and are constant keywords. If there is a dataset or a namespace with a `-` inside, it is recommended to replace it either by a `.` or a `_`.
Note: More `{type}`s might be added in the future like `apm` and `endpoint`.
@@ -126,6 +126,8 @@ This indexing strategy has a few advantages:
* Having a global metrics and logs template, allows to create new indices on demand which still follow the convention. This is common in the case of k8s as an example.
* Constant keywords allow to narrow down the indices we need to access for querying very efficiently. This is especially relevant in environments which a large number of indices or with indices on slower nodes.
+Overall it creates smaller indices in size, makes querying more efficient and allows users to define their own naming parts in namespace and still benefiting from all features that can be built on top of the indexing startegy.
+
=== Ingest Pipeline
The ingest pipelines for a specific dataset will have the following naming scheme:
diff --git a/docs/settings/apm-settings.asciidoc b/docs/settings/apm-settings.asciidoc
index 91bbef5690fd5..fd53c3aeb3605 100644
--- a/docs/settings/apm-settings.asciidoc
+++ b/docs/settings/apm-settings.asciidoc
@@ -5,7 +5,10 @@
APM settings
++++
-You do not need to configure any settings to use the APM app. It is enabled by default.
+These settings allow the APM app to function, and specify the data that it surfaces.
+Unless you've customized your setup,
+you do not need to configure any settings to use the APM app.
+It is enabled by default.
[float]
[[apm-indices-settings-kb]]
@@ -33,29 +36,29 @@ image::settings/images/apm-settings.png[APM app settings in Kibana]
If you'd like to change any of the default values,
copy and paste the relevant settings into your `kibana.yml` configuration file.
+Changing these settings may disable features of the APM App.
-xpack.apm.enabled:: Set to `false` to disabled the APM plugin {kib}. Defaults to
-`true`.
+xpack.apm.enabled:: Set to `false` to disable the APM app. Defaults to `true`.
-xpack.apm.ui.enabled:: Set to `false` to hide the APM plugin {kib} from the menu. Defaults to
-`true`.
+xpack.apm.ui.enabled:: Set to `false` to hide the APM app from the menu. Defaults to `true`.
-xpack.apm.ui.transactionGroupBucketSize:: Number of top transaction groups displayed in APM plugin in Kibana. Defaults to `100`.
+xpack.apm.ui.transactionGroupBucketSize:: Number of top transaction groups displayed in the APM app. Defaults to `100`.
-xpack.apm.ui.maxTraceItems:: Max number of child items displayed when viewing trace details. Defaults to `1000`.
+xpack.apm.ui.maxTraceItems:: Maximum number of child items displayed when viewing trace details. Defaults to `1000`.
-apm_oss.indexPattern:: Index pattern is used for integrations with Machine Learning and Kuery Bar. It must match all apm indices. Defaults to `apm-*`.
+apm_oss.indexPattern:: The index pattern used for integrations with Machine Learning and Query Bar.
+It must match all apm indices. Defaults to `apm-*`.
-apm_oss.errorIndices:: Matcher for indices containing error documents. Defaults to `apm-*`.
+apm_oss.errorIndices:: Matcher for all {apm-server-ref}/error-indices.html[error indices]. Defaults to `apm-*`.
-apm_oss.onboardingIndices:: Matcher for indices containing onboarding documents. Defaults to `apm-*`.
+apm_oss.onboardingIndices:: Matcher for all onboarding indices. Defaults to `apm-*`.
-apm_oss.spanIndices:: Matcher for indices containing span documents. Defaults to `apm-*`.
+apm_oss.spanIndices:: Matcher for all {apm-server-ref}/span-indices.html[span indices]. Defaults to `apm-*`.
-apm_oss.transactionIndices:: Matcher for indices containing transaction documents. Defaults to `apm-*`.
+apm_oss.transactionIndices:: Matcher for all {apm-server-ref}/transaction-indices.html[transaction indices]. Defaults to `apm-*`.
-apm_oss.metricsIndices:: Matcher for indices containing metric documents. Defaults to `apm-*`.
+apm_oss.metricsIndices:: Matcher for all {apm-server-ref}/metricset-indices.html[metrics indices]. Defaults to `apm-*`.
-apm_oss.sourcemapIndices:: Matcher for indices containing sourcemap documents. Defaults to `apm-*`.
+apm_oss.sourcemapIndices:: Matcher for all {apm-server-ref}/sourcemap-indices.html[source map indices]. Defaults to `apm-*`.
// end::general-apm-settings[]
diff --git a/docs/user/alerting/action-types.asciidoc b/docs/user/alerting/action-types.asciidoc
index 02c09736e1fa0..2913bf28dd765 100644
--- a/docs/user/alerting/action-types.asciidoc
+++ b/docs/user/alerting/action-types.asciidoc
@@ -2,181 +2,46 @@
[[action-types]]
== Action and connector types
-{kib} provides the following types of actions:
+Actions are Kibana services or integrations with third-party systems that run as background tasks on the Kibana server when alert conditions are met. {kib} provides the following types of actions:
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
+[cols="2"]
+|===
-This section describes how to configure connectors and actions for each type.
+a| <>
-[NOTE]
-==============================================
-Some action types are paid commercial features, while others are free.
-For a comparison of the Elastic license levels,
-see https://www.elastic.co/subscriptions[the subscription page].
-==============================================
-
-[float]
-[[email-action-type]]
-=== Email
-
-The email action type uses the SMTP protocol to send mail message, using an integration of https://nodemailer.com/[Nodemailer]. Email message text is sent as both plain text and html text.
-
-[float]
-[[email-connector-configuration]]
-==== Connector configuration
-
-Email connectors have the following configuration properties:
-
-Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action.
-Sender:: The from address for all emails sent with this connector, specified in `user@host-name` format.
-Host:: Host name of the service provider. If you are using the <> setting, make sure this hostname is whitelisted.
-Port:: The port to connect to on the service provider.
-Secure:: If true the connection will use TLS when connecting to the service provider. See https://nodemailer.com/smtp/#tls-options[nodemailer TLS documentation] for more information.
-Username:: username for 'login' type authentication.
-Password:: password for 'login' type authentication.
-
-[float]
-[[email-action-configuration]]
-==== Action configuration
-
-Email actions have the following configuration properties:
-
-To, CC, BCC:: Each is a list of addresses. Addresses can be specified in `user@host-name` format, or in `name ` format. One of To, CC, or BCC must contain an entry.
-Subject:: The subject line of the email.
-Message:: The message text of the email. Markdown format is supported.
-
-[float]
-[[index-action-type]]
-=== Index
-
-The index action type will index a document into {es}.
-
-[float]
-[[index-connector-configuration]]
-==== Connector configuration
-
-Index connectors have the following configuration properties:
-
-Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action.
-Index:: The {es} index to be written to.
-Refresh:: Setting for the {ref}/docs-refresh.html[refresh] policy for the write request.
-Execution time field:: This field will be automatically set to the time the alert condition was detected.
-
-[float]
-[[index-action-configuration]]
-==== Action configuration
-
-Index actions have the following properties:
-
-Document:: The document to index in json format.
-
-[float]
-[[pagerduty-action-type]]
-=== PagerDuty
-
-The PagerDuty action type uses the https://v2.developer.pagerduty.com/docs/events-api-v2[v2 Events API] to trigger, acknowledge, and resolve PagerDuty alerts.
-
-[float]
-[[pagerduty-connector-configuration]]
-==== Connector configuration
+| Send email from your server.
-PagerDuty connectors have the following configuration properties:
+a| <>
-Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action.
-API URL:: An optional PagerDuty event URL. Defaults to `https://events.pagerduty.com/v2/enqueue`. If you are using the <> setting, make sure the hostname is whitelisted.
-Routing Key:: A 32 character PagerDuty Integration Key for an integration on a service or on a global ruleset.
+| Index data into Elasticsearch.
-[float]
-[[pagerduty-action-configuration]]
-==== Action configuration
+a| <>
-PagerDuty actions have the following properties:
+| Send an event in PagerDuty.
-Severity:: The perceived severity of on the affected system. This can be one of `Critical`, `Error`, `Warning` or `Info`(default).
-Event action:: One of `Trigger` (default), `Resolve`, or `Acknowledge`. See https://v2.developer.pagerduty.com/docs/events-api-v2#event-action[event action] for more details.
-Dedup Key:: All actions sharing this key will be associated with the same PagerDuty alert. This value is used to correlate trigger and resolution. This value is *optional*, and if unset defaults to `action:`. The maximum length is *255* characters. See https://v2.developer.pagerduty.com/docs/events-api-v2#alert-de-duplication[alert deduplication] for details.
-Timestamp:: An *optional* https://v2.developer.pagerduty.com/v2/docs/types#datetime[ISO-8601 format date-time], indicating the time the event was detected or generated.
-Component:: An *optional* value indicating the component of the source machine that is responsible for the event, for example `mysql` or `eth0`.
-Group:: An *optional* value indicating the logical grouping of components of a service, for example `app-stack`.
-Source:: An *optional* value indicating the affected system, preferably a hostname or fully qualified domain name. Defaults to the {kib} saved object id of the action.
-Summary:: An *optional* text summary of the event, defaults to `No summary provided`. The maximum length is 1024 characters.
-Class:: An *optional* value indicating the class/type of the event, for example `ping failure` or `cpu load`.
+a| <>
-For more details on these properties, see https://v2.developer.pagerduty.com/v2/docs/send-an-event-events-api-v2[PagerDuty v2 event parameters].
+| Add a message to a Kibana log.
-[float]
-[[server-log-action-type]]
-=== Server log
+a| <>
-This action type writes and entry to the {kib} server log.
+| Send a message to a Slack channel or user.
-[float]
-[[server-log-connector-configuration]]
-==== Connector configuration
+a| <>
-Server log connectors have the following configuration properties:
+| Send a request to a web service.
+|===
-Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action.
-
-[float]
-[[server-log-action-configuration]]
-==== Action configuration
-
-Server log actions have the following properties:
-
-Message:: The message to log.
-
-[float]
-[[slack-action-type]]
-=== Slack
-
-The Slack action type uses https://api.slack.com/incoming-webhooks[Slack Incoming Webhooks].
-
-[float]
-[[slack-connector-configuration]]
-==== Connector configuration
-
-Slack connectors have the following configuration properties:
-
-Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action.
-Webhook URL:: The URL of the incoming webhook. See https://api.slack.com/messaging/webhooks#getting_started[Slack Incoming Webhooks] for instructions on generating this URL. If you are using the <> setting, make sure the hostname is whitelisted.
-
-[float]
-[[slack-action-configuration]]
-==== Action configuration
-
-Slack actions have the following properties:
-
-Message:: The message text, converted to the `text` field in the Webhook JSON payload. Currently only the text field is supported. Markdown, images, and other advanced formatting are not yet supported.
-
-[float]
-[[webhook-action-type]]
-=== Webhook
-
-The Webhook action type uses https://github.com/axios/axios[axios] to send a POST or PUT request to a web service.
-
-[float]
-[[webhook-connector-configuration]]
-==== Connector configuration
-
-Webhook connectors have the following configuration properties:
-
-Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action.
-URL:: The request URL. If you are using the <> setting, make sure the hostname is whitelisted.
-Method:: HTTP request method, either `post`(default) or `put`.
-Headers:: A set of key-value pairs sent as headers with the request
-User:: An optional username. If set, HTTP basic authentication is used. Currently only basic authentication is supported.
-Password:: An optional password. If set, HTTP basic authentication is used. Currently only basic authentication is supported.
-
-[float]
-[[webhook-action-configuration]]
-==== Action configuration
-
-Webhook actions have the following properties:
+[NOTE]
+==============================================
+Some action types are paid commercial features, while others are free.
+For a comparison of the Elastic subscription levels,
+see https://www.elastic.co/subscriptions[the subscription page].
+==============================================
-Body:: A json payload sent to the request URL.
\ No newline at end of file
+include::action-types/email.asciidoc[]
+include::action-types/index.asciidoc[]
+include::action-types/pagerduty.asciidoc[]
+include::action-types/server-log.asciidoc[]
+include::action-types/slack.asciidoc[]
+include::action-types/webhook.asciidoc[]
diff --git a/docs/user/alerting/action-types/email.asciidoc b/docs/user/alerting/action-types/email.asciidoc
new file mode 100644
index 0000000000000..be3623dd9e59c
--- /dev/null
+++ b/docs/user/alerting/action-types/email.asciidoc
@@ -0,0 +1,29 @@
+[role="xpack"]
+[[email-action-type]]
+== Email action type
+
+The email action type uses the SMTP protocol to send mail message, using an integration of https://nodemailer.com/[Nodemailer]. Email message text is sent as both plain text and html text.
+
+[float]
+[[email-connector-configuration]]
+==== Connector configuration
+
+Email connectors have the following configuration properties:
+
+Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action.
+Sender:: The from address for all emails sent with this connector, specified in `user@host-name` format.
+Host:: Host name of the service provider. If you are using the <> setting, make sure this hostname is whitelisted.
+Port:: The port to connect to on the service provider.
+Secure:: If true the connection will use TLS when connecting to the service provider. See https://nodemailer.com/smtp/#tls-options[nodemailer TLS documentation] for more information.
+Username:: username for 'login' type authentication.
+Password:: password for 'login' type authentication.
+
+[float]
+[[email-action-configuration]]
+==== Action configuration
+
+Email actions have the following configuration properties:
+
+To, CC, BCC:: Each is a list of addresses. Addresses can be specified in `user@host-name` format, or in `name ` format. One of To, CC, or BCC must contain an entry.
+Subject:: The subject line of the email.
+Message:: The message text of the email. Markdown format is supported.
\ No newline at end of file
diff --git a/docs/user/alerting/action-types/index.asciidoc b/docs/user/alerting/action-types/index.asciidoc
new file mode 100644
index 0000000000000..75d9e57b1f212
--- /dev/null
+++ b/docs/user/alerting/action-types/index.asciidoc
@@ -0,0 +1,24 @@
+[role="xpack"]
+[[index-action-type]]
+== Index action type
+
+The index action type will index a document into {es}.
+
+[float]
+[[index-connector-configuration]]
+==== Connector configuration
+
+Index connectors have the following configuration properties:
+
+Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action.
+Index:: The {es} index to be written to.
+Refresh:: Setting for the {ref}/docs-refresh.html[refresh] policy for the write request.
+Execution time field:: This field will be automatically set to the time the alert condition was detected.
+
+[float]
+[[index-action-configuration]]
+==== Action configuration
+
+Index actions have the following properties:
+
+Document:: The document to index in json format.
\ No newline at end of file
diff --git a/docs/user/alerting/action-types/pagerduty.asciidoc b/docs/user/alerting/action-types/pagerduty.asciidoc
new file mode 100644
index 0000000000000..50a1f31e4a9ae
--- /dev/null
+++ b/docs/user/alerting/action-types/pagerduty.asciidoc
@@ -0,0 +1,33 @@
+[role="xpack"]
+[[pagerduty-action-type]]
+== PagerDuty action type
+
+The PagerDuty action type uses the https://v2.developer.pagerduty.com/docs/events-api-v2[v2 Events API] to trigger, acknowledge, and resolve PagerDuty alerts.
+
+[float]
+[[pagerduty-connector-configuration]]
+==== Connector configuration
+
+PagerDuty connectors have the following configuration properties:
+
+Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action.
+API URL:: An optional PagerDuty event URL. Defaults to `https://events.pagerduty.com/v2/enqueue`. If you are using the <> setting, make sure the hostname is whitelisted.
+Routing Key:: A 32 character PagerDuty Integration Key for an integration on a service or on a global ruleset.
+
+[float]
+[[pagerduty-action-configuration]]
+==== Action configuration
+
+PagerDuty actions have the following properties:
+
+Severity:: The perceived severity of on the affected system. This can be one of `Critical`, `Error`, `Warning` or `Info`(default).
+Event action:: One of `Trigger` (default), `Resolve`, or `Acknowledge`. See https://v2.developer.pagerduty.com/docs/events-api-v2#event-action[event action] for more details.
+Dedup Key:: All actions sharing this key will be associated with the same PagerDuty alert. This value is used to correlate trigger and resolution. This value is *optional*, and if unset defaults to `action:`. The maximum length is *255* characters. See https://v2.developer.pagerduty.com/docs/events-api-v2#alert-de-duplication[alert deduplication] for details.
+Timestamp:: An *optional* https://v2.developer.pagerduty.com/v2/docs/types#datetime[ISO-8601 format date-time], indicating the time the event was detected or generated.
+Component:: An *optional* value indicating the component of the source machine that is responsible for the event, for example `mysql` or `eth0`.
+Group:: An *optional* value indicating the logical grouping of components of a service, for example `app-stack`.
+Source:: An *optional* value indicating the affected system, preferably a hostname or fully qualified domain name. Defaults to the {kib} saved object id of the action.
+Summary:: An *optional* text summary of the event, defaults to `No summary provided`. The maximum length is 1024 characters.
+Class:: An *optional* value indicating the class/type of the event, for example `ping failure` or `cpu load`.
+
+For more details on these properties, see https://v2.developer.pagerduty.com/v2/docs/send-an-event-events-api-v2[PagerDuty v2 event parameters].
\ No newline at end of file
diff --git a/docs/user/alerting/action-types/server-log.asciidoc b/docs/user/alerting/action-types/server-log.asciidoc
new file mode 100644
index 0000000000000..4efbdf3bea099
--- /dev/null
+++ b/docs/user/alerting/action-types/server-log.asciidoc
@@ -0,0 +1,21 @@
+[role="xpack"]
+[[server-log-action-type]]
+== Server log action type
+
+This action type writes and entry to the {kib} server log.
+
+[float]
+[[server-log-connector-configuration]]
+==== Connector configuration
+
+Server log connectors have the following configuration properties:
+
+Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action.
+
+[float]
+[[server-log-action-configuration]]
+==== Action configuration
+
+Server log actions have the following properties:
+
+Message:: The message to log.
\ No newline at end of file
diff --git a/docs/user/alerting/action-types/slack.asciidoc b/docs/user/alerting/action-types/slack.asciidoc
new file mode 100644
index 0000000000000..a4bacbf162e46
--- /dev/null
+++ b/docs/user/alerting/action-types/slack.asciidoc
@@ -0,0 +1,22 @@
+[role="xpack"]
+[[slack-action-type]]
+== Slack action type
+
+The Slack action type uses https://api.slack.com/incoming-webhooks[Slack Incoming Webhooks].
+
+[float]
+[[slack-connector-configuration]]
+==== Connector configuration
+
+Slack connectors have the following configuration properties:
+
+Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action.
+Webhook URL:: The URL of the incoming webhook. See https://api.slack.com/messaging/webhooks#getting_started[Slack Incoming Webhooks] for instructions on generating this URL. If you are using the <> setting, make sure the hostname is whitelisted.
+
+[float]
+[[slack-action-configuration]]
+==== Action configuration
+
+Slack actions have the following properties:
+
+Message:: The message text, converted to the `text` field in the Webhook JSON payload. Currently only the text field is supported. Markdown, images, and other advanced formatting are not yet supported.
\ No newline at end of file
diff --git a/docs/user/alerting/action-types/webhook.asciidoc b/docs/user/alerting/action-types/webhook.asciidoc
new file mode 100644
index 0000000000000..8c211aa83af89
--- /dev/null
+++ b/docs/user/alerting/action-types/webhook.asciidoc
@@ -0,0 +1,26 @@
+[role="xpack"]
+[[webhook-action-type]]
+== Webhook action type
+
+The Webhook action type uses https://github.com/axios/axios[axios] to send a POST or PUT request to a web service.
+
+[float]
+[[webhook-connector-configuration]]
+==== Connector configuration
+
+Webhook connectors have the following configuration properties:
+
+Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action.
+URL:: The request URL. If you are using the <> setting, make sure the hostname is whitelisted.
+Method:: HTTP request method, either `post`(default) or `put`.
+Headers:: A set of key-value pairs sent as headers with the request
+User:: An optional username. If set, HTTP basic authentication is used. Currently only basic authentication is supported.
+Password:: An optional password. If set, HTTP basic authentication is used. Currently only basic authentication is supported.
+
+[float]
+[[webhook-action-configuration]]
+==== Action configuration
+
+Webhook actions have the following properties:
+
+Body:: A json payload sent to the request URL.
\ No newline at end of file
diff --git a/docs/user/alerting/index.asciidoc b/docs/user/alerting/index.asciidoc
index f556cf71bf06c..df11f5f03a7de 100644
--- a/docs/user/alerting/index.asciidoc
+++ b/docs/user/alerting/index.asciidoc
@@ -154,10 +154,13 @@ Pre-packaged *alert types* simplify setup, hide the details complex domain-speci
[[alerting-setup-prerequisites]]
== Setup and prerequisites
+If you are using an *on-premises* Elastic Stack deployment:
+
+* In the kibana.yml configuration file, add the <> setting.
+
If you are using an *on-premises* Elastic Stack deployment with <>:
-* TLS must be configured for communication <>. {kib} alerting uses <> to secure background alert checks and actions, and API keys require {ref}/configuring-tls.html#tls-http[TLS on the HTTP interface].
-* In the kibana.yml configuration file, add the <>
+* Transport Layer Security (TLS) must be configured for communication <>. {kib} alerting uses <> to secure background alert checks and actions, and API keys require {ref}/configuring-tls.html#tls-http[TLS on the HTTP interface].
[float]
[[alerting-security]]
diff --git a/docs/user/reporting/chromium-sandbox.asciidoc b/docs/user/reporting/chromium-sandbox.asciidoc
index 5d4fbfb153a0b..bfef5b8b86c6b 100644
--- a/docs/user/reporting/chromium-sandbox.asciidoc
+++ b/docs/user/reporting/chromium-sandbox.asciidoc
@@ -11,12 +11,12 @@ sandboxing techniques differ for each operating system.
The Linux sandbox depends on user namespaces, which were introduced with the 3.8 Linux kernel. However, many
distributions don't have user namespaces enabled by default, or they require the CAP_SYS_ADMIN capability. {reporting}
will automatically disable the sandbox when it is running on Debian and CentOS as additional steps are required to enable
-unprivileged usernamespaces. In these situations, you'll see the following message in your {kib} logs:
-`Enabling the Chromium sandbox provides an additional layer of protection`.
+unprivileged usernamespaces. In these situations, you'll see the following message in your {kib} startup logs:
+`Chromium sandbox provides an additional layer of protection, but is not supported for your OS.
+Automatically setting 'xpack.reporting.capture.browser.chromium.disableSandbox: true'.`
-If your kernel is 3.8 or newer, it's
-recommended to enable usernamespaces and set `xpack.reporting.capture.browser.chromium.disableSandbox: false` in your
-`kibana.yml` to enable the sandbox.
+Reporting will automatically enable the Chromium sandbox at startup when a supported OS is detected. However, if your kernel is 3.8 or newer, it's
+recommended to set `xpack.reporting.capture.browser.chromium.disableSandbox: false` in your `kibana.yml` to explicitly enable usernamespaces.
==== Docker
When running {kib} in a Docker container, all container processes are run within a usernamespace with seccomp-bpf and
diff --git a/examples/embeddable_examples/common/index.ts b/examples/embeddable_examples/common/index.ts
new file mode 100644
index 0000000000000..726420fb9bdc3
--- /dev/null
+++ b/examples/embeddable_examples/common/index.ts
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+export { TodoSavedObjectAttributes } from './todo_saved_object_attributes';
diff --git a/examples/embeddable_examples/common/todo_saved_object_attributes.ts b/examples/embeddable_examples/common/todo_saved_object_attributes.ts
new file mode 100644
index 0000000000000..21b6df20fea90
--- /dev/null
+++ b/examples/embeddable_examples/common/todo_saved_object_attributes.ts
@@ -0,0 +1,26 @@
+/*
+ * 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 { SavedObjectAttributes } from '../../../src/core/types';
+
+export interface TodoSavedObjectAttributes extends SavedObjectAttributes {
+ task: string;
+ icon?: string;
+ title?: string;
+}
diff --git a/examples/embeddable_examples/kibana.json b/examples/embeddable_examples/kibana.json
index c70bc7009ff51..f446e7f31ac8e 100644
--- a/examples/embeddable_examples/kibana.json
+++ b/examples/embeddable_examples/kibana.json
@@ -3,7 +3,7 @@
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["embeddable_examples"],
- "server": false,
+ "server": true,
"ui": true,
"requiredPlugins": ["embeddable"],
"optionalPlugins": []
diff --git a/examples/embeddable_examples/public/create_sample_data.ts b/examples/embeddable_examples/public/create_sample_data.ts
new file mode 100644
index 0000000000000..bd5ade18aa91e
--- /dev/null
+++ b/examples/embeddable_examples/public/create_sample_data.ts
@@ -0,0 +1,36 @@
+/*
+ * 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 { SavedObjectsClientContract } from 'kibana/public';
+import { TodoSavedObjectAttributes } from '../common';
+
+export async function createSampleData(client: SavedObjectsClientContract) {
+ await client.create(
+ 'todo',
+ {
+ task: 'Take the garbage out',
+ title: 'Garbage',
+ icon: 'trash',
+ },
+ {
+ id: 'sample-todo-saved-object',
+ overwrite: true,
+ }
+ );
+}
diff --git a/examples/embeddable_examples/public/index.ts b/examples/embeddable_examples/public/index.ts
index 5fcd454b17a5c..4aac63fb52e2b 100644
--- a/examples/embeddable_examples/public/index.ts
+++ b/examples/embeddable_examples/public/index.ts
@@ -17,7 +17,6 @@
* under the License.
*/
-import { PluginInitializer } from 'kibana/public';
export {
HELLO_WORLD_EMBEDDABLE,
HelloWorldEmbeddable,
@@ -26,18 +25,8 @@ export {
export { ListContainer, LIST_CONTAINER } from './list_container';
export { TODO_EMBEDDABLE } from './todo';
-import {
- EmbeddableExamplesPlugin,
- EmbeddableExamplesSetupDependencies,
- EmbeddableExamplesStartDependencies,
-} from './plugin';
+import { EmbeddableExamplesPlugin } from './plugin';
export { SearchableListContainer, SEARCHABLE_LIST_CONTAINER } from './searchable_list_container';
export { MULTI_TASK_TODO_EMBEDDABLE } from './multi_task_todo';
-
-export const plugin: PluginInitializer<
- void,
- void,
- EmbeddableExamplesSetupDependencies,
- EmbeddableExamplesStartDependencies
-> = () => new EmbeddableExamplesPlugin();
+export const plugin = () => new EmbeddableExamplesPlugin();
diff --git a/examples/embeddable_examples/public/plugin.ts b/examples/embeddable_examples/public/plugin.ts
index 31a3037332dda..75d34d2d6878f 100644
--- a/examples/embeddable_examples/public/plugin.ts
+++ b/examples/embeddable_examples/public/plugin.ts
@@ -21,12 +21,20 @@ import { EmbeddableSetup, EmbeddableStart } from '../../../src/plugins/embeddabl
import { Plugin, CoreSetup, CoreStart } from '../../../src/core/public';
import { HelloWorldEmbeddableFactory, HELLO_WORLD_EMBEDDABLE } from './hello_world';
import { TODO_EMBEDDABLE, TodoEmbeddableFactory, TodoInput, TodoOutput } from './todo';
-import { MULTI_TASK_TODO_EMBEDDABLE, MultiTaskTodoEmbeddableFactory } from './multi_task_todo';
+import {
+ MULTI_TASK_TODO_EMBEDDABLE,
+ MultiTaskTodoEmbeddableFactory,
+ MultiTaskTodoInput,
+ MultiTaskTodoOutput,
+} from './multi_task_todo';
import {
SEARCHABLE_LIST_CONTAINER,
SearchableListContainerFactory,
} from './searchable_list_container';
import { LIST_CONTAINER, ListContainerFactory } from './list_container';
+import { createSampleData } from './create_sample_data';
+import { TodoRefInput, TodoRefOutput, TODO_REF_EMBEDDABLE } from './todo/todo_ref_embeddable';
+import { TodoRefEmbeddableFactory } from './todo/todo_ref_embeddable_factory';
export interface EmbeddableExamplesSetupDependencies {
embeddable: EmbeddableSetup;
@@ -36,9 +44,18 @@ export interface EmbeddableExamplesStartDependencies {
embeddable: EmbeddableStart;
}
+export interface EmbeddableExamplesStart {
+ createSampleData: () => Promise;
+}
+
export class EmbeddableExamplesPlugin
implements
- Plugin {
+ Plugin<
+ void,
+ EmbeddableExamplesStart,
+ EmbeddableExamplesSetupDependencies,
+ EmbeddableExamplesStartDependencies
+ > {
public setup(
core: CoreSetup,
deps: EmbeddableExamplesSetupDependencies
@@ -48,7 +65,7 @@ export class EmbeddableExamplesPlugin
new HelloWorldEmbeddableFactory()
);
- deps.embeddable.registerEmbeddableFactory(
+ deps.embeddable.registerEmbeddableFactory(
MULTI_TASK_TODO_EMBEDDABLE,
new MultiTaskTodoEmbeddableFactory()
);
@@ -73,9 +90,21 @@ export class EmbeddableExamplesPlugin
openModal: (await core.getStartServices())[0].overlays.openModal,
}))
);
+
+ deps.embeddable.registerEmbeddableFactory(
+ TODO_REF_EMBEDDABLE,
+ new TodoRefEmbeddableFactory(async () => ({
+ savedObjectsClient: (await core.getStartServices())[0].savedObjects.client,
+ getEmbeddableFactory: (await core.getStartServices())[1].embeddable.getEmbeddableFactory,
+ }))
+ );
}
- public start(core: CoreStart, deps: EmbeddableExamplesStartDependencies) {}
+ public start(core: CoreStart, deps: EmbeddableExamplesStartDependencies) {
+ return {
+ createSampleData: () => createSampleData(core.savedObjects.client),
+ };
+ }
public stop() {}
}
diff --git a/examples/embeddable_examples/public/todo/README.md b/examples/embeddable_examples/public/todo/README.md
new file mode 100644
index 0000000000000..e782511f093b3
--- /dev/null
+++ b/examples/embeddable_examples/public/todo/README.md
@@ -0,0 +1,43 @@
+There are two examples in here:
+ - TodoEmbeddable
+ - TodoRefEmbeddable
+
+ # TodoEmbeddable
+
+ The first example you should review is the HelloWorldEmbeddable. That is as basic an embeddable as you can get.
+ This embeddable is the next step up - an embeddable that renders dynamic input data. The data is simple:
+ - a required task string
+ - an optional title
+ - an optional icon string
+ - an optional search string
+
+It also has output data, which is `hasMatch` - whether or not the search string has matched any input data.
+
+`hasMatch` is a better fit for output data than input data, because it's state that is _derived_ from input data.
+
+For example, if it was input data, you could create a TodoEmbeddable with input like this:
+
+```ts
+ todoEmbeddableFactory.create({ task: 'take out the garabage', search: 'garbage', hasMatch: false });
+```
+
+That's wrong because there is actually a match from the search string inside the task.
+
+The TodoEmbeddable component itself doesn't do anything with the `hasMatch` variable other than set it, but
+if you check out `SearchableListContainer`, you can see an example where this output data is being used.
+
+## TodoRefEmbeddable
+
+This is an example of an embeddable based off of a saved object. The input is just the `savedObjectId` and
+the `search` string. It has even more output parameters, and this time, it does read it's own output parameters in
+order to calculate `hasMatch`.
+
+Output:
+```ts
+{
+ hasMatch: boolean,
+ savedAttributes?: TodoSavedAttributes
+}
+```
+
+`savedAttributes` is optional because it's possible a TodoSavedObject could not be found with the given savedObjectId.
diff --git a/examples/embeddable_examples/public/todo/todo_ref_component.tsx b/examples/embeddable_examples/public/todo/todo_ref_component.tsx
new file mode 100644
index 0000000000000..8e0a17be1ec72
--- /dev/null
+++ b/examples/embeddable_examples/public/todo/todo_ref_component.tsx
@@ -0,0 +1,86 @@
+/*
+ * 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 React from 'react';
+import { EuiFlexItem, EuiFlexGroup } from '@elastic/eui';
+
+import { EuiText } from '@elastic/eui';
+import { EuiAvatar } from '@elastic/eui';
+import { EuiIcon } from '@elastic/eui';
+import { EuiFlexGrid } from '@elastic/eui';
+import { withEmbeddableSubscription } from '../../../../src/plugins/embeddable/public';
+import { TodoRefInput, TodoRefOutput, TodoRefEmbeddable } from './todo_ref_embeddable';
+
+interface Props {
+ embeddable: TodoRefEmbeddable;
+ input: TodoRefInput;
+ output: TodoRefOutput;
+}
+
+function wrapSearchTerms(task?: string, search?: string) {
+ if (!search) return task;
+ if (!task) return task;
+ const parts = task.split(new RegExp(`(${search})`, 'g'));
+ return parts.map((part, i) =>
+ part === search ? (
+
+ {part}
+
+ ) : (
+ part
+ )
+ );
+}
+
+export function TodoRefEmbeddableComponentInner({
+ input: { search },
+ output: { savedAttributes },
+}: Props) {
+ const icon = savedAttributes?.icon;
+ const title = savedAttributes?.title;
+ const task = savedAttributes?.task;
+ return (
+
+
+ {icon ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ {wrapSearchTerms(title || '', search)}
+
+
+
+ {wrapSearchTerms(task, search)}
+
+
+
+
+ );
+}
+
+export const TodoRefEmbeddableComponent = withEmbeddableSubscription<
+ TodoRefInput,
+ TodoRefOutput,
+ TodoRefEmbeddable
+>(TodoRefEmbeddableComponentInner);
diff --git a/examples/embeddable_examples/public/todo/todo_ref_embeddable.tsx b/examples/embeddable_examples/public/todo/todo_ref_embeddable.tsx
new file mode 100644
index 0000000000000..da2dfb2c1a290
--- /dev/null
+++ b/examples/embeddable_examples/public/todo/todo_ref_embeddable.tsx
@@ -0,0 +1,153 @@
+/*
+ * 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 React from 'react';
+import ReactDOM from 'react-dom';
+import { Subscription } from 'rxjs';
+import { TodoSavedObjectAttributes } from 'examples/embeddable_examples/common';
+import { SavedObjectsClientContract } from 'kibana/public';
+import {
+ Embeddable,
+ IContainer,
+ EmbeddableOutput,
+ SavedObjectEmbeddableInput,
+} from '../../../../src/plugins/embeddable/public';
+import { TodoRefEmbeddableComponent } from './todo_ref_component';
+
+// Notice this is not the same value as the 'todo' saved object type. Many of our
+// cases in prod today use the same value, but this is unnecessary.
+export const TODO_REF_EMBEDDABLE = 'TODO_REF_EMBEDDABLE';
+
+export interface TodoRefInput extends SavedObjectEmbeddableInput {
+ /**
+ * Optional search string which will be used to highlight search terms as
+ * well as calculate `output.hasMatch`.
+ */
+ search?: string;
+}
+
+export interface TodoRefOutput extends EmbeddableOutput {
+ /**
+ * Should be true if input.search is defined and the task or title contain
+ * search as a substring.
+ */
+ hasMatch: boolean;
+ /**
+ * Will contain the saved object attributes of the Todo Saved Object that matches
+ * `input.savedObjectId`. If the id is invalid, this may be undefined.
+ */
+ savedAttributes?: TodoSavedObjectAttributes;
+}
+
+/**
+ * Returns whether any attributes contain the search string. If search is empty, true is returned. If
+ * there are no savedAttributes, false is returned.
+ * @param search - the search string
+ * @param savedAttributes - the saved object attributes for the saved object with id `input.savedObjectId`
+ */
+function getHasMatch(search?: string, savedAttributes?: TodoSavedObjectAttributes): boolean {
+ if (!search) return true;
+ if (!savedAttributes) return false;
+ return Boolean(
+ (savedAttributes.task && savedAttributes.task.match(search)) ||
+ (savedAttributes.title && savedAttributes.title.match(search))
+ );
+}
+
+/**
+ * This is an example of an embeddable that is backed by a saved object. It's essentially the
+ * same as `TodoEmbeddable` but that is "by value", while this is "by reference".
+ */
+export class TodoRefEmbeddable extends Embeddable {
+ public readonly type = TODO_REF_EMBEDDABLE;
+ private subscription: Subscription;
+ private node?: HTMLElement;
+ private savedObjectsClient: SavedObjectsClientContract;
+ private savedObjectId?: string;
+
+ constructor(
+ initialInput: TodoRefInput,
+ {
+ parent,
+ savedObjectsClient,
+ }: {
+ parent?: IContainer;
+ savedObjectsClient: SavedObjectsClientContract;
+ }
+ ) {
+ super(initialInput, { hasMatch: false }, parent);
+ this.savedObjectsClient = savedObjectsClient;
+
+ this.subscription = this.getInput$().subscribe(async () => {
+ // There is a little more work today for this embeddable because it has
+ // more output it needs to update in response to input state changes.
+ let savedAttributes: TodoSavedObjectAttributes | undefined;
+
+ // Since this is an expensive task, we save a local copy of the previous
+ // savedObjectId locally and only retrieve the new saved object if the id
+ // actually changed.
+ if (this.savedObjectId !== this.input.savedObjectId) {
+ this.savedObjectId = this.input.savedObjectId;
+ const todoSavedObject = await this.savedObjectsClient.get(
+ 'todo',
+ this.input.savedObjectId
+ );
+ savedAttributes = todoSavedObject?.attributes;
+ }
+
+ // The search string might have changed as well so we need to make sure we recalculate
+ // hasMatch.
+ this.updateOutput({
+ hasMatch: getHasMatch(this.input.search, savedAttributes),
+ savedAttributes,
+ });
+ });
+ }
+
+ public render(node: HTMLElement) {
+ if (this.node) {
+ ReactDOM.unmountComponentAtNode(this.node);
+ }
+ this.node = node;
+ ReactDOM.render( , node);
+ }
+
+ /**
+ * Lets re-sync our saved object to make sure it's up to date!
+ */
+ public async reload() {
+ this.savedObjectId = this.input.savedObjectId;
+ const todoSavedObject = await this.savedObjectsClient.get(
+ 'todo',
+ this.input.savedObjectId
+ );
+ const savedAttributes = todoSavedObject?.attributes;
+ this.updateOutput({
+ hasMatch: getHasMatch(this.input.search, savedAttributes),
+ savedAttributes,
+ });
+ }
+
+ public destroy() {
+ super.destroy();
+ this.subscription.unsubscribe();
+ if (this.node) {
+ ReactDOM.unmountComponentAtNode(this.node);
+ }
+ }
+}
diff --git a/examples/embeddable_examples/public/todo/todo_ref_embeddable_factory.tsx b/examples/embeddable_examples/public/todo/todo_ref_embeddable_factory.tsx
new file mode 100644
index 0000000000000..e585ddd89674f
--- /dev/null
+++ b/examples/embeddable_examples/public/todo/todo_ref_embeddable_factory.tsx
@@ -0,0 +1,83 @@
+/*
+ * 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 { i18n } from '@kbn/i18n';
+import { SavedObjectsClientContract } from 'kibana/public';
+import { TodoSavedObjectAttributes } from 'examples/embeddable_examples/common';
+import {
+ IContainer,
+ EmbeddableStart,
+ ErrorEmbeddable,
+ EmbeddableFactoryDefinition,
+} from '../../../../src/plugins/embeddable/public';
+import {
+ TodoRefEmbeddable,
+ TODO_REF_EMBEDDABLE,
+ TodoRefInput,
+ TodoRefOutput,
+} from './todo_ref_embeddable';
+
+interface StartServices {
+ getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
+ savedObjectsClient: SavedObjectsClientContract;
+}
+
+export class TodoRefEmbeddableFactory
+ implements
+ EmbeddableFactoryDefinition<
+ TodoRefInput,
+ TodoRefOutput,
+ TodoRefEmbeddable,
+ TodoSavedObjectAttributes
+ > {
+ public readonly type = TODO_REF_EMBEDDABLE;
+ public readonly savedObjectMetaData = {
+ name: 'Todo',
+ includeFields: ['task', 'icon', 'title'],
+ type: 'todo',
+ getIconForSavedObject: () => 'pencil',
+ };
+
+ constructor(private getStartServices: () => Promise) {}
+
+ public async isEditable() {
+ return true;
+ }
+
+ public createFromSavedObject = (
+ savedObjectId: string,
+ input: Partial & { id: string },
+ parent?: IContainer
+ ): Promise => {
+ return this.create({ ...input, savedObjectId }, parent);
+ };
+
+ public async create(input: TodoRefInput, parent?: IContainer) {
+ const { savedObjectsClient } = await this.getStartServices();
+ return new TodoRefEmbeddable(input, {
+ parent,
+ savedObjectsClient,
+ });
+ }
+
+ public getDisplayName() {
+ return i18n.translate('embeddableExamples.todo.displayName', {
+ defaultMessage: 'Todo (by reference)',
+ });
+ }
+}
diff --git a/examples/embeddable_examples/server/index.ts b/examples/embeddable_examples/server/index.ts
new file mode 100644
index 0000000000000..9ddc3bc2cf715
--- /dev/null
+++ b/examples/embeddable_examples/server/index.ts
@@ -0,0 +1,24 @@
+/*
+ * 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 { PluginInitializer } from 'kibana/server';
+
+import { EmbeddableExamplesPlugin } from './plugin';
+
+export const plugin: PluginInitializer = () => new EmbeddableExamplesPlugin();
diff --git a/examples/embeddable_examples/server/plugin.ts b/examples/embeddable_examples/server/plugin.ts
new file mode 100644
index 0000000000000..d956b834d0d3c
--- /dev/null
+++ b/examples/embeddable_examples/server/plugin.ts
@@ -0,0 +1,31 @@
+/*
+ * 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 { Plugin, CoreSetup, CoreStart } from 'kibana/server';
+import { todoSavedObject } from './todo_saved_object';
+
+export class EmbeddableExamplesPlugin implements Plugin {
+ public setup(core: CoreSetup) {
+ core.savedObjects.registerType(todoSavedObject);
+ }
+
+ public start(core: CoreStart) {}
+
+ public stop() {}
+}
diff --git a/src/legacy/core_plugins/vis_type_xy/public/legacy.ts b/examples/embeddable_examples/server/todo_saved_object.ts
similarity index 50%
rename from src/legacy/core_plugins/vis_type_xy/public/legacy.ts
rename to examples/embeddable_examples/server/todo_saved_object.ts
index 740ceeaac6a7d..0f67c53cfa3e1 100644
--- a/src/legacy/core_plugins/vis_type_xy/public/legacy.ts
+++ b/examples/embeddable_examples/server/todo_saved_object.ts
@@ -17,24 +17,24 @@
* under the License.
*/
-import { npSetup, npStart } from 'ui/new_platform';
-import { PluginInitializerContext } from 'kibana/public';
+import { SavedObjectsType } from 'kibana/server';
-import { plugin } from '.';
-import { VisTypeXyPluginSetupDependencies, VisTypeXyPluginStartDependencies } from './plugin';
-
-const setupPlugins: Readonly = {
- expressions: npSetup.plugins.expressions,
- visualizations: npSetup.plugins.visualizations,
- charts: npSetup.plugins.charts,
-};
-
-const startPlugins: Readonly = {
- expressions: npStart.plugins.expressions,
- visualizations: npStart.plugins.visualizations,
+export const todoSavedObject: SavedObjectsType = {
+ name: 'todo',
+ hidden: false,
+ namespaceAgnostic: true,
+ mappings: {
+ properties: {
+ title: {
+ type: 'keyword',
+ },
+ task: {
+ type: 'text',
+ },
+ icon: {
+ type: 'keyword',
+ },
+ },
+ },
+ migrations: {},
};
-
-const pluginInstance = plugin({} as PluginInitializerContext);
-
-export const setup = pluginInstance.setup(npSetup.core, setupPlugins);
-export const start = pluginInstance.start(npStart.core, startPlugins);
diff --git a/examples/embeddable_examples/tsconfig.json b/examples/embeddable_examples/tsconfig.json
index 091130487791b..7fa03739119b4 100644
--- a/examples/embeddable_examples/tsconfig.json
+++ b/examples/embeddable_examples/tsconfig.json
@@ -6,6 +6,7 @@
},
"include": [
"index.ts",
+ "common/**/*.ts",
"public/**/*.ts",
"public/**/*.tsx",
"server/**/*.ts",
diff --git a/examples/embeddable_explorer/public/plugin.tsx b/examples/embeddable_explorer/public/plugin.tsx
index 7c75b108d9912..bba1b1748e207 100644
--- a/examples/embeddable_explorer/public/plugin.tsx
+++ b/examples/embeddable_explorer/public/plugin.tsx
@@ -18,6 +18,7 @@
*/
import { Plugin, CoreSetup, AppMountParameters } from 'kibana/public';
+import { EmbeddableExamplesStart } from 'examples/embeddable_examples/public/plugin';
import { UiActionsService } from '../../../src/plugins/ui_actions/public';
import { EmbeddableStart } from '../../../src/plugins/embeddable/public';
import { Start as InspectorStart } from '../../../src/plugins/inspector/public';
@@ -26,6 +27,7 @@ interface StartDeps {
uiActions: UiActionsService;
embeddable: EmbeddableStart;
inspector: InspectorStart;
+ embeddableExamples: EmbeddableExamplesStart;
}
export class EmbeddableExplorerPlugin implements Plugin {
@@ -36,6 +38,7 @@ export class EmbeddableExplorerPlugin implements Plugin {
private readonly log: Logger;
private readonly config$: Observable;
- private subscription: Subscription | undefined;
+ private subscription?: Subscription;
private stop$ = new Subject();
private kibanaVersion: string;
- createClient: InternalElasticsearchServiceSetup['createClient'] | undefined;
- dataClient: InternalElasticsearchServiceSetup['dataClient'] | undefined;
- adminClient: InternalElasticsearchServiceSetup['adminClient'] | undefined;
+ private createClient?: (
+ type: string,
+ clientConfig?: Partial
+ ) => ICustomClusterClient;
+ private adminClient?: IClusterClient;
constructor(private readonly coreContext: CoreContext) {
this.kibanaVersion = coreContext.env.packageInfo.version;
diff --git a/src/core/server/server.ts b/src/core/server/server.ts
index 07ea431dd3a0d..684f50a5666e1 100644
--- a/src/core/server/server.ts
+++ b/src/core/server/server.ts
@@ -201,7 +201,7 @@ export class Server {
uiSettings: uiSettingsStart,
};
- const pluginsStart = await this.plugins.start(this.coreStart!);
+ const pluginsStart = await this.plugins.start(this.coreStart);
await this.legacy.start({
core: {
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js
index d770e8334b3af..72276a38f6ac2 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js
@@ -828,13 +828,9 @@ function discoverController(
if (newSavedQueryId) {
setAppState({ savedQuery: newSavedQueryId });
} else {
- //reset filters and query string, remove savedQuery from state
+ // remove savedQueryId from state
const state = {
...appStateContainer.getState(),
- query: getDefaultQuery(
- localStorage.get('kibana.userQueryLanguage') || config.get('search:queryLanguage')
- ),
- filters: [],
};
delete state.savedQuery;
appStateContainer.set(state);
diff --git a/src/legacy/core_plugins/vis_type_timeseries/index.ts b/src/legacy/core_plugins/vis_type_timeseries/index.ts
deleted file mode 100644
index 596fd5b581a71..0000000000000
--- a/src/legacy/core_plugins/vis_type_timeseries/index.ts
+++ /dev/null
@@ -1,45 +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 { resolve } from 'path';
-import { Legacy } from 'kibana';
-
-import { LegacyPluginApi, LegacyPluginInitializer } from '../../../../src/legacy/types';
-
-const metricsPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) =>
- new Plugin({
- id: 'metrics',
- require: ['kibana', 'elasticsearch'],
- publicDir: resolve(__dirname, 'public'),
- uiExports: {
- styleSheetPaths: resolve(__dirname, 'public/index.scss'),
- hacks: [resolve(__dirname, 'public/legacy')],
- injectDefaultVars: server => ({}),
- },
- config(Joi: any) {
- return Joi.object({
- enabled: Joi.boolean().default(true),
- chartResolution: Joi.number().default(150),
- minimumBucketSize: Joi.number().default(10),
- }).default();
- },
- } as Legacy.PluginSpecOptions);
-
-// eslint-disable-next-line import/no-default-export
-export default metricsPluginInitializer;
diff --git a/src/legacy/core_plugins/vis_type_timeseries/package.json b/src/legacy/core_plugins/vis_type_timeseries/package.json
deleted file mode 100644
index 6b4874dfe6a68..0000000000000
--- a/src/legacy/core_plugins/vis_type_timeseries/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "author": "Chris Cowan",
- "name": "metrics",
- "version": "kibana"
-}
-
diff --git a/src/legacy/core_plugins/vis_type_vislib/public/legacy.ts b/src/legacy/core_plugins/vis_type_vislib/public/legacy.ts
index aa11e0ef41fba..579caa1cb88f6 100644
--- a/src/legacy/core_plugins/vis_type_vislib/public/legacy.ts
+++ b/src/legacy/core_plugins/vis_type_vislib/public/legacy.ts
@@ -30,6 +30,7 @@ const setupPlugins: Readonly = {
expressions: npSetup.plugins.expressions,
visualizations: npSetup.plugins.visualizations,
charts: npSetup.plugins.charts,
+ visTypeXy: npSetup.plugins.visTypeXy,
};
const startPlugins: Readonly = {
diff --git a/src/legacy/core_plugins/vis_type_vislib/public/plugin.ts b/src/legacy/core_plugins/vis_type_vislib/public/plugin.ts
index 2731fb6f5fbe6..ef3f664252856 100644
--- a/src/legacy/core_plugins/vis_type_vislib/public/plugin.ts
+++ b/src/legacy/core_plugins/vis_type_vislib/public/plugin.ts
@@ -24,6 +24,7 @@ import {
PluginInitializerContext,
} from 'kibana/public';
+import { VisTypeXyPluginSetup } from 'src/plugins/vis_type_xy/public';
import { Plugin as ExpressionsPublicPlugin } from '../../../../plugins/expressions/public';
import { VisualizationsSetup } from '../../../../plugins/visualizations/public';
import { createVisTypeVislibVisFn } from './vis_type_vislib_vis_fn';
@@ -39,7 +40,6 @@ import {
createGoalVisTypeDefinition,
} from './vis_type_vislib_vis_types';
import { ChartsPluginSetup } from '../../../../plugins/charts/public';
-import { ConfigSchema as VisTypeXyConfigSchema } from '../../vis_type_xy';
import { DataPublicPluginStart } from '../../../../plugins/data/public';
import { setFormatService, setDataActions } from './services';
@@ -53,6 +53,7 @@ export interface VisTypeVislibPluginSetupDependencies {
expressions: ReturnType;
visualizations: VisualizationsSetup;
charts: ChartsPluginSetup;
+ visTypeXy?: VisTypeXyPluginSetup;
}
/** @internal */
@@ -68,7 +69,7 @@ export class VisTypeVislibPlugin implements Plugin {
public async setup(
core: VisTypeVislibCoreSetup,
- { expressions, visualizations, charts }: VisTypeVislibPluginSetupDependencies
+ { expressions, visualizations, charts, visTypeXy }: VisTypeVislibPluginSetupDependencies
) {
const visualizationDependencies: Readonly = {
uiSettings: core.uiSettings,
@@ -86,12 +87,8 @@ export class VisTypeVislibPlugin implements Plugin {
];
const vislibFns = [createVisTypeVislibVisFn(), createPieVisFn()];
- const visTypeXy = core.injectedMetadata.getInjectedVar('visTypeXy') as
- | VisTypeXyConfigSchema['visTypeXy']
- | undefined;
-
// if visTypeXy plugin is disabled it's config will be undefined
- if (!visTypeXy || !visTypeXy.enabled) {
+ if (!visTypeXy) {
const convertedTypes: any[] = [];
const convertedFns: any[] = [];
diff --git a/src/legacy/core_plugins/vis_type_xy/index.ts b/src/legacy/core_plugins/vis_type_xy/index.ts
deleted file mode 100644
index 58d2e425eef40..0000000000000
--- a/src/legacy/core_plugins/vis_type_xy/index.ts
+++ /dev/null
@@ -1,56 +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 { resolve } from 'path';
-import { Legacy } from 'kibana';
-
-import { LegacyPluginApi, LegacyPluginInitializer } from '../../types';
-
-export interface ConfigSchema {
- visTypeXy: {
- enabled: boolean;
- };
-}
-
-const visTypeXyPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) =>
- new Plugin({
- id: 'visTypeXy',
- require: ['kibana', 'elasticsearch', 'visualizations', 'interpreter'],
- publicDir: resolve(__dirname, 'public'),
- uiExports: {
- hacks: [resolve(__dirname, 'public/legacy')],
- injectDefaultVars(server): ConfigSchema {
- const config = server.config();
-
- return {
- visTypeXy: {
- enabled: config.get('visTypeXy.enabled') as boolean,
- },
- };
- },
- },
- config(Joi: any) {
- return Joi.object({
- enabled: Joi.boolean().default(false),
- }).default();
- },
- } as Legacy.PluginSpecOptions);
-
-// eslint-disable-next-line import/no-default-export
-export default visTypeXyPluginInitializer;
diff --git a/src/legacy/core_plugins/vis_type_xy/package.json b/src/legacy/core_plugins/vis_type_xy/package.json
deleted file mode 100644
index 920f7dcb44e87..0000000000000
--- a/src/legacy/core_plugins/vis_type_xy/package.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "visTypeXy",
- "version": "kibana"
-}
diff --git a/src/legacy/ui/public/new_platform/new_platform.ts b/src/legacy/ui/public/new_platform/new_platform.ts
index 21b80e827e4c2..80fb837258d4c 100644
--- a/src/legacy/ui/public/new_platform/new_platform.ts
+++ b/src/legacy/ui/public/new_platform/new_platform.ts
@@ -22,6 +22,7 @@ import { IScope } from 'angular';
import { UiActionsStart, UiActionsSetup } from 'src/plugins/ui_actions/public';
import { EmbeddableStart, EmbeddableSetup } from 'src/plugins/embeddable/public';
import { createBrowserHistory } from 'history';
+import { VisTypeXyPluginSetup } from 'src/plugins/vis_type_xy/public';
import { DashboardStart } from '../../../../plugins/dashboard/public';
import { setSetupServices, setStartServices } from './set_services';
import {
@@ -93,6 +94,7 @@ export interface PluginsSetup {
savedObjectsManagement: SavedObjectsManagementPluginSetup;
mapsLegacy: MapsLegacyPluginSetup;
indexPatternManagement: IndexPatternManagementSetup;
+ visTypeXy?: VisTypeXyPluginSetup;
}
export interface PluginsStart {
diff --git a/src/plugins/console/server/lib/spec_definitions/js/ingest.ts b/src/plugins/console/server/lib/spec_definitions/js/ingest.ts
index 1182dc075f42f..20dbeda5e0b3d 100644
--- a/src/plugins/console/server/lib/spec_definitions/js/ingest.ts
+++ b/src/plugins/console/server/lib/spec_definitions/js/ingest.ts
@@ -57,6 +57,49 @@ const bytesProcessorDefinition = {
},
};
+// Based on https://www.elastic.co/guide/en/elasticsearch/reference/master/ingest-circle-processor.html
+const circleProcessorDefinition = {
+ circle: {
+ __template: {
+ field: '',
+ error_distance: '',
+ shape_type: '',
+ },
+ field: '',
+ target_field: '',
+ error_distance: '',
+ shape_type: {
+ __one_of: ['geo_shape', 'shape'],
+ },
+ ignore_missing: {
+ __one_of: [false, true],
+ },
+ ...commonPipelineParams,
+ },
+};
+
+// Based on https://www.elastic.co/guide/en/elasticsearch/reference/master/csv-processor.html
+const csvProcessorDefinition = {
+ csv: {
+ __template: {
+ field: '',
+ target_fields: [''],
+ },
+ field: '',
+ target_fields: [''],
+ separator: '',
+ quote: '',
+ empty_value: '',
+ trim: {
+ __one_of: [true, false],
+ },
+ ignore_missing: {
+ __one_of: [false, true],
+ },
+ ...commonPipelineParams,
+ },
+};
+
// Based on https://www.elastic.co/guide/en/elasticsearch/reference/master/convert-processor.html
const convertProcessorDefinition = {
convert: {
@@ -174,6 +217,25 @@ const foreachProcessorDefinition = {
},
};
+// Based on https://www.elastic.co/guide/en/elasticsearch/reference/master/geoip-processor.html
+const geoipProcessorDefinition = {
+ geoip: {
+ __template: {
+ field: '',
+ },
+ field: '',
+ target_field: '',
+ database_file: '',
+ properties: [''],
+ ignore_missing: {
+ __one_of: [false, true],
+ },
+ first_only: {
+ __one_of: [false, true],
+ },
+ },
+};
+
// Based on https://www.elastic.co/guide/en/elasticsearch/reference/master/grok-processor.html
const grokProcessorDefinition = {
grok: {
@@ -209,6 +271,37 @@ const gsubProcessorDefinition = {
},
};
+// Based on https://www.elastic.co/guide/en/elasticsearch/reference/master/htmlstrip-processor.html
+const htmlStripProcessorDefinition = {
+ html_strip: {
+ __template: {
+ field: '',
+ },
+ field: '',
+ target_field: '',
+ ignore_missing: {
+ __one_of: [false, true],
+ },
+ ...commonPipelineParams,
+ },
+};
+
+// Based on https://www.elastic.co/guide/en/elasticsearch/reference/master/inference-processor.html
+const inferenceProcessorDefinition = {
+ inference: {
+ __template: {
+ model_id: '',
+ field_map: {},
+ inference_config: {},
+ },
+ model_id: '',
+ field_map: {},
+ inference_config: {},
+ target_field: '',
+ ...commonPipelineParams,
+ },
+};
+
// Based on https://www.elastic.co/guide/en/elasticsearch/reference/master/join-processor.html
const joinProcessorDefinition = {
join: {
@@ -338,6 +431,18 @@ const setProcessorDefinition = {
},
};
+// Based on https://www.elastic.co/guide/en/elasticsearch/reference/master/ingest-node-set-security-user-processor.html
+const setSecurityUserProcessorDefinition = {
+ set_security_user: {
+ __template: {
+ field: '',
+ },
+ field: '',
+ properties: [''],
+ ...commonPipelineParams,
+ },
+};
+
// Based on https://www.elastic.co/guide/en/elasticsearch/reference/master/split-processor.html
const splitProcessorDefinition = {
split: {
@@ -394,10 +499,43 @@ const uppercaseProcessorDefinition = {
},
};
+// Based on https://www.elastic.co/guide/en/elasticsearch/reference/master/urldecode-processor.html
+const urlDecodeProcessorDefinition = {
+ urldecode: {
+ __template: {
+ field: '',
+ },
+ field: '',
+ target_field: '',
+ ignore_missing: {
+ __one_of: [false, true],
+ },
+ ...commonPipelineParams,
+ },
+};
+
+// Based on https://www.elastic.co/guide/en/elasticsearch/reference/master/user-agent-processor.html
+const userAgentProcessorDefinition = {
+ user_agent: {
+ __template: {
+ field: '',
+ },
+ field: '',
+ target_field: '',
+ regex_file: '',
+ properties: [''],
+ ignore_missing: {
+ __one_of: [false, true],
+ },
+ },
+};
+
const processorDefinition = {
__one_of: [
appendProcessorDefinition,
bytesProcessorDefinition,
+ csvProcessorDefinition,
+ circleProcessorDefinition,
convertProcessorDefinition,
dateProcessorDefinition,
dateIndexNameProcessorDefinition,
@@ -406,8 +544,11 @@ const processorDefinition = {
dropProcessorDefinition,
failProcessorDefinition,
foreachProcessorDefinition,
+ geoipProcessorDefinition,
grokProcessorDefinition,
gsubProcessorDefinition,
+ htmlStripProcessorDefinition,
+ inferenceProcessorDefinition,
joinProcessorDefinition,
jsonProcessorDefinition,
kvProcessorDefinition,
@@ -417,10 +558,13 @@ const processorDefinition = {
renameProcessorDefinition,
scriptProcessorDefinition,
setProcessorDefinition,
+ setSecurityUserProcessorDefinition,
splitProcessorDefinition,
sortProcessorDefinition,
trimProcessorDefinition,
uppercaseProcessorDefinition,
+ urlDecodeProcessorDefinition,
+ userAgentProcessorDefinition,
],
};
diff --git a/src/plugins/dashboard/public/application/actions/replace_panel_flyout.tsx b/src/plugins/dashboard/public/application/actions/replace_panel_flyout.tsx
index d182deb813e11..fe9a19030602e 100644
--- a/src/plugins/dashboard/public/application/actions/replace_panel_flyout.tsx
+++ b/src/plugins/dashboard/public/application/actions/replace_panel_flyout.tsx
@@ -28,6 +28,7 @@ import {
EmbeddableInput,
EmbeddableOutput,
EmbeddableStart,
+ SavedObjectEmbeddableInput,
} from '../../embeddable_plugin';
interface Props {
@@ -66,7 +67,7 @@ export class ReplacePanelFlyout extends React.Component {
});
};
- public onReplacePanel = async (id: string, type: string, name: string) => {
+ public onReplacePanel = async (savedObjectId: string, type: string, name: string) => {
const originalPanels = this.props.container.getInput().panels;
const filteredPanels = { ...originalPanels };
@@ -76,7 +77,9 @@ export class ReplacePanelFlyout extends React.Component {
const nny = (filteredPanels[this.props.panelToRemove.id] as DashboardPanelState).gridData.y;
// add the new view
- const newObj = await this.props.container.addSavedObjectEmbeddable(type, id);
+ const newObj = await this.props.container.addNewEmbeddable(type, {
+ savedObjectId,
+ });
const finalPanels = _.cloneDeep(this.props.container.getInput().panels);
(finalPanels[newObj.id] as DashboardPanelState).gridData.w = nnw;
diff --git a/src/plugins/dashboard/public/application/dashboard_app_controller.tsx b/src/plugins/dashboard/public/application/dashboard_app_controller.tsx
index babd1fac274eb..283fe9f0a83a4 100644
--- a/src/plugins/dashboard/public/application/dashboard_app_controller.tsx
+++ b/src/plugins/dashboard/public/application/dashboard_app_controller.tsx
@@ -53,6 +53,7 @@ import {
isErrorEmbeddable,
openAddPanelFlyout,
ViewMode,
+ SavedObjectEmbeddableInput,
ContainerOutput,
} from '../../../embeddable/public';
import { NavAction, SavedDashboardPanel } from '../types';
@@ -394,7 +395,7 @@ export class DashboardAppController {
if ($routeParams[DashboardConstants.ADD_EMBEDDABLE_TYPE]) {
const type = $routeParams[DashboardConstants.ADD_EMBEDDABLE_TYPE];
const id = $routeParams[DashboardConstants.ADD_EMBEDDABLE_ID];
- container.addSavedObjectEmbeddable(type, id);
+ container.addNewEmbeddable(type, { savedObjectId: id });
removeQueryParam(history, DashboardConstants.ADD_EMBEDDABLE_TYPE);
removeQueryParam(history, DashboardConstants.ADD_EMBEDDABLE_ID);
}
diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx
index 7f3a2913daac3..50089f1f061f4 100644
--- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx
+++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx
@@ -55,7 +55,7 @@ export interface DashboardContainerInput extends ContainerInput {
description?: string;
isFullScreenMode: boolean;
panels: {
- [panelId: string]: DashboardPanelState;
+ [panelId: string]: DashboardPanelState;
};
isEmptyState?: boolean;
}
diff --git a/src/plugins/dashboard/public/application/embeddable/types.ts b/src/plugins/dashboard/public/application/embeddable/types.ts
index 3df305b0d7f1b..6d0221cb10e8b 100644
--- a/src/plugins/dashboard/public/application/embeddable/types.ts
+++ b/src/plugins/dashboard/public/application/embeddable/types.ts
@@ -16,6 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
+import { SavedObjectEmbeddableInput } from 'src/plugins/embeddable/public';
import { PanelState, EmbeddableInput } from '../../embeddable_plugin';
export type PanelId = string;
export type SavedObjectId = string;
@@ -28,7 +29,8 @@ export interface GridData {
i: string;
}
-export interface DashboardPanelState
- extends PanelState {
+export interface DashboardPanelState<
+ TEmbeddableInput extends EmbeddableInput | SavedObjectEmbeddableInput = SavedObjectEmbeddableInput
+> extends PanelState {
readonly gridData: GridData;
}
diff --git a/src/plugins/dashboard/public/application/lib/embeddable_saved_object_converters.test.ts b/src/plugins/dashboard/public/application/lib/embeddable_saved_object_converters.test.ts
index 447563bbfbcfa..25ce203332422 100644
--- a/src/plugins/dashboard/public/application/lib/embeddable_saved_object_converters.test.ts
+++ b/src/plugins/dashboard/public/application/lib/embeddable_saved_object_converters.test.ts
@@ -23,11 +23,6 @@ import {
} from './embeddable_saved_object_converters';
import { SavedDashboardPanel } from '../../types';
import { DashboardPanelState } from '../embeddable';
-import { EmbeddableInput } from 'src/plugins/embeddable/public';
-
-interface CustomInput extends EmbeddableInput {
- something: string;
-}
test('convertSavedDashboardPanelToPanelState', () => {
const savedDashboardPanel: SavedDashboardPanel = {
@@ -58,8 +53,8 @@ test('convertSavedDashboardPanelToPanelState', () => {
explicitInput: {
something: 'hi!',
id: '123',
+ savedObjectId: 'savedObjectId',
},
- savedObjectId: 'savedObjectId',
type: 'search',
});
});
@@ -86,7 +81,7 @@ test('convertSavedDashboardPanelToPanelState does not include undefined id', ()
});
test('convertPanelStateToSavedDashboardPanel', () => {
- const dashboardPanel: DashboardPanelState = {
+ const dashboardPanel: DashboardPanelState = {
gridData: {
x: 0,
y: 0,
@@ -94,10 +89,10 @@ test('convertPanelStateToSavedDashboardPanel', () => {
w: 15,
i: '123',
},
- savedObjectId: 'savedObjectId',
explicitInput: {
something: 'hi!',
id: '123',
+ savedObjectId: 'savedObjectId',
},
type: 'search',
};
@@ -121,7 +116,7 @@ test('convertPanelStateToSavedDashboardPanel', () => {
});
test('convertPanelStateToSavedDashboardPanel will not add an undefined id when not needed', () => {
- const dashboardPanel: DashboardPanelState = {
+ const dashboardPanel: DashboardPanelState = {
gridData: {
x: 0,
y: 0,
diff --git a/src/plugins/dashboard/public/application/lib/embeddable_saved_object_converters.ts b/src/plugins/dashboard/public/application/lib/embeddable_saved_object_converters.ts
index 01cd55df0d8e9..b19ef31ccb9ac 100644
--- a/src/plugins/dashboard/public/application/lib/embeddable_saved_object_converters.ts
+++ b/src/plugins/dashboard/public/application/lib/embeddable_saved_object_converters.ts
@@ -19,6 +19,7 @@
import { omit } from 'lodash';
import { SavedDashboardPanel } from '../../types';
import { DashboardPanelState } from '../embeddable';
+import { SavedObjectEmbeddableInput } from '../../embeddable_plugin';
export function convertSavedDashboardPanelToPanelState(
savedDashboardPanel: SavedDashboardPanel
@@ -26,9 +27,9 @@ export function convertSavedDashboardPanelToPanelState(
return {
type: savedDashboardPanel.type,
gridData: savedDashboardPanel.gridData,
- ...(savedDashboardPanel.id !== undefined && { savedObjectId: savedDashboardPanel.id }),
explicitInput: {
id: savedDashboardPanel.panelIndex,
+ ...(savedDashboardPanel.id !== undefined && { savedObjectId: savedDashboardPanel.id }),
...(savedDashboardPanel.title !== undefined && { title: savedDashboardPanel.title }),
...savedDashboardPanel.embeddableConfig,
},
@@ -42,13 +43,14 @@ export function convertPanelStateToSavedDashboardPanel(
const customTitle: string | undefined = panelState.explicitInput.title
? (panelState.explicitInput.title as string)
: undefined;
+ const savedObjectId = (panelState.explicitInput as SavedObjectEmbeddableInput).savedObjectId;
return {
version,
type: panelState.type,
gridData: panelState.gridData,
panelIndex: panelState.explicitInput.id,
- embeddableConfig: omit(panelState.explicitInput, 'id'),
+ embeddableConfig: omit(panelState.explicitInput, ['id', 'savedObjectId']),
...(customTitle && { title: customTitle }),
- ...(panelState.savedObjectId !== undefined && { id: panelState.savedObjectId }),
+ ...(savedObjectId !== undefined && { id: savedObjectId }),
};
}
diff --git a/src/plugins/data/public/ui/query_string_input/language_switcher.tsx b/src/plugins/data/public/ui/query_string_input/language_switcher.tsx
index 63f6997ce2fc3..ded48d462722d 100644
--- a/src/plugins/data/public/ui/query_string_input/language_switcher.tsx
+++ b/src/plugins/data/public/ui/query_string_input/language_switcher.tsx
@@ -61,6 +61,7 @@ export function QueryLanguageSwitcher(props: Props) {
size="xs"
onClick={() => setIsPopoverOpen(!isPopoverOpen)}
className="euiFormControlLayout__append"
+ data-test-subj={'switchQueryLanguageButton'}
>
{props.language === 'lucene' ? luceneLabel : kqlLabel}
diff --git a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx
index 5ca334d6bdcfe..7723254f3aa51 100644
--- a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx
+++ b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx
@@ -124,7 +124,8 @@ export function createSearchBar({ core, storage, data }: StatefulSearchBarDeps)
const onQuerySubmitRef = useRef(props.onQuerySubmit);
const defaultQuery = {
query: '',
- language: core.uiSettings.get('search:queryLanguage'),
+ language:
+ storage.get('kibana.userQueryLanguage') || core.uiSettings.get('search:queryLanguage'),
};
const [query, setQuery] = useState(props.query || defaultQuery);
@@ -161,7 +162,7 @@ export function createSearchBar({ core, storage, data }: StatefulSearchBarDeps)
setQuery,
savedQueryId: props.savedQueryId,
notifications: core.notifications,
- uiSettings: core.uiSettings,
+ defaultLanguage: defaultQuery.language,
});
// Fire onQuerySubmit on query or timerange change
diff --git a/src/plugins/data/public/ui/search_bar/lib/use_saved_query.ts b/src/plugins/data/public/ui/search_bar/lib/use_saved_query.ts
index 817e890b7b42b..79aee3438d7aa 100644
--- a/src/plugins/data/public/ui/search_bar/lib/use_saved_query.ts
+++ b/src/plugins/data/public/ui/search_bar/lib/use_saved_query.ts
@@ -29,8 +29,8 @@ interface UseSavedQueriesProps {
queryService: DataPublicPluginStart['query'];
setQuery: Function;
notifications: CoreStart['notifications'];
- uiSettings: CoreStart['uiSettings'];
savedQueryId?: string;
+ defaultLanguage: string;
}
interface UseSavedQueriesReturn {
@@ -41,7 +41,7 @@ interface UseSavedQueriesReturn {
export const useSavedQuery = (props: UseSavedQueriesProps): UseSavedQueriesReturn => {
// Handle saved queries
- const defaultLanguage = props.uiSettings.get('search:queryLanguage');
+ const defaultLanguage = props.defaultLanguage;
const [savedQuery, setSavedQuery] = useState();
// Effect is used to convert a saved query id into an object
diff --git a/src/plugins/embeddable/README.md b/src/plugins/embeddable/README.md
index 1fe91f426f43f..343a1cc32cd10 100644
--- a/src/plugins/embeddable/README.md
+++ b/src/plugins/embeddable/README.md
@@ -1,39 +1,25 @@
-# The Embeddable API V2
+# Embeddables
-The Embeddable API's main goal is to have documented and standardized ways to share and exchange information and functionality across applications and plugins.
+Embeddables are re-usable widgets that can be rendered in any environment or plugin. Developers can embed them directly in their plugin. End users can dynamically add them to any embeddable _containers_.
-There are three main pieces of this infrastructure:
- - Embeddables & Containers
- - Actions
- - Triggers
+## Embeddable containers
-## Embeddables & Containers
+Containers are a special type of embeddable that can contain nested embeddables. Embeddables can be dynamically added to embeddable _containers_. Currently only dashboard uses this interface.
-Embeddables are isolated, serializable, renderable widgets. A developer can hard code an embeddable inside their
-application, or they can use some built in actions to allow users to dynamically add them to *containers*.
-
-Containers are a special type of embeddable that can contain nested embeddables.
-
-## Actions
-
-Actions are pluggable pieces of functionality exposed to the user that take an embeddable as context, plus an optional action context.
-
-## Triggers
-
-Triggers are the way actions are connected to a user action. We ship with two default triggers, `CONTEXT_MENU_TRIGGER` and `APPLY_FILTER`.
-
-Actions attached to the `CONTEXT_MENU_TRIGGER` will be displayed in supported embeddables context menu to the user. Actions attached to the `APPLY_FILTER` trigger will show up when any embeddable emits this trigger.
+## Examples
-A developer can register new triggers that their embeddables, or external components, can emit (as long as they have an embeddable to pass along as context).
+Many example embeddables are implemented and registered [here](https://github.com/elastic/kibana/tree/master/examples/embeddable_examples). They can be played around with and explored [in the Embeddable Explorer example plugin](https://github.com/elastic/kibana/tree/master/examples/embeddable_explorer). Just run kibana with
-## Examples
+```
+yarn start --run-examples
+```
-Many examples can be viewed in the functionally tested `kbn_tp_embeddable_explorer` plugin, as well as the jest tested classes inside the `embeddable_api/public/test_samples` folder.
+and navigate to the Embeddable explorer app.
## Testing
Run unit tests
```shell
-node scripts/jest embeddable_api
+node scripts/jest embeddable
```
diff --git a/src/plugins/embeddable/public/index.ts b/src/plugins/embeddable/public/index.ts
index 23275fbe8e8f0..bdb7bfbddc308 100644
--- a/src/plugins/embeddable/public/index.ts
+++ b/src/plugins/embeddable/public/index.ts
@@ -61,6 +61,8 @@ export {
PropertySpec,
ViewMode,
withEmbeddableSubscription,
+ SavedObjectEmbeddableInput,
+ isSavedObjectEmbeddableInput,
} from './lib';
export function plugin(initializerContext: PluginInitializerContext) {
diff --git a/src/plugins/embeddable/public/lib/actions/edit_panel_action.test.tsx b/src/plugins/embeddable/public/lib/actions/edit_panel_action.test.tsx
index ce733bba6dda5..d07bf915845e9 100644
--- a/src/plugins/embeddable/public/lib/actions/edit_panel_action.test.tsx
+++ b/src/plugins/embeddable/public/lib/actions/edit_panel_action.test.tsx
@@ -56,7 +56,7 @@ test('getHref returns the edit urls', async () => {
if (action.getHref) {
const embeddable = new EditableEmbeddable({ id: '123', viewMode: ViewMode.EDIT }, true);
expect(
- action.getHref({
+ await action.getHref({
embeddable,
})
).toBe(embeddable.getOutput().editUrl);
diff --git a/src/plugins/embeddable/public/lib/actions/edit_panel_action.ts b/src/plugins/embeddable/public/lib/actions/edit_panel_action.ts
index 9125dc0813f98..044e7b5d35ad8 100644
--- a/src/plugins/embeddable/public/lib/actions/edit_panel_action.ts
+++ b/src/plugins/embeddable/public/lib/actions/edit_panel_action.ts
@@ -62,11 +62,16 @@ export class EditPanelAction implements Action {
return Boolean(canEditEmbeddable && inDashboardEditMode);
}
- public async execute() {
- return;
+ public async execute(context: ActionContext) {
+ const href = await this.getHref(context);
+ if (href) {
+ // TODO: when apps start using browser router instead of hash router this has to be fixed
+ // https://github.com/elastic/kibana/issues/58217
+ window.location.href = href;
+ }
}
- public getHref({ embeddable }: ActionContext): string {
+ public async getHref({ embeddable }: ActionContext): Promise {
const editUrl = embeddable ? embeddable.getOutput().editUrl : undefined;
return editUrl ? editUrl : '';
}
diff --git a/src/plugins/embeddable/public/lib/containers/container.ts b/src/plugins/embeddable/public/lib/containers/container.ts
index 4ab74e1883917..ffbe75f66b581 100644
--- a/src/plugins/embeddable/public/lib/containers/container.ts
+++ b/src/plugins/embeddable/public/lib/containers/container.ts
@@ -30,6 +30,7 @@ import {
import { IContainer, ContainerInput, ContainerOutput, PanelState } from './i_container';
import { PanelNotFoundError, EmbeddableFactoryNotFoundError } from '../errors';
import { EmbeddableStart } from '../../plugin';
+import { isSavedObjectEmbeddableInput } from '../embeddables/saved_object_embeddable';
const getKeys = (o: T): Array => Object.keys(o) as Array;
@@ -98,17 +99,6 @@ export abstract class Container<
return this.createAndSaveEmbeddable(type, panelState);
}
- public async addSavedObjectEmbeddable<
- TEmbeddableInput extends EmbeddableInput = EmbeddableInput,
- TEmbeddable extends IEmbeddable = IEmbeddable
- >(type: string, savedObjectId: string): Promise {
- const factory = this.getFactory(type) as EmbeddableFactory;
- const panelState = this.createNewPanelState(factory);
- panelState.savedObjectId = savedObjectId;
-
- return this.createAndSaveEmbeddable(type, panelState);
- }
-
public removeEmbeddable(embeddableId: string) {
// Just a shortcut for removing the panel from input state, all internal state will get cleaned up naturally
// by the listener.
@@ -304,8 +294,10 @@ export abstract class Container<
throw new EmbeddableFactoryNotFoundError(panel.type);
}
- embeddable = panel.savedObjectId
- ? await factory.createFromSavedObject(panel.savedObjectId, inputForChild, this)
+ // TODO: lets get rid of this distinction with factories, I don't think it will be needed
+ // anymore after this change.
+ embeddable = isSavedObjectEmbeddableInput(inputForChild)
+ ? await factory.createFromSavedObject(inputForChild.savedObjectId, inputForChild, this)
: await factory.create(inputForChild, this);
} catch (e) {
embeddable = new ErrorEmbeddable(e, { id: panel.explicitInput.id }, this);
@@ -323,23 +315,6 @@ export abstract class Container<
return;
}
- if (embeddable.getOutput().savedObjectId) {
- this.updateInput({
- panels: {
- ...this.input.panels,
- [panel.explicitInput.id]: {
- ...this.input.panels[panel.explicitInput.id],
- ...(embeddable.getOutput().savedObjectId
- ? { savedObjectId: embeddable.getOutput().savedObjectId }
- : undefined),
- explicitInput: {
- ...this.input.panels[panel.explicitInput.id].explicitInput,
- },
- },
- },
- } as Partial);
- }
-
this.children[embeddable.id] = embeddable;
this.updateOutput({
embeddableLoaded: {
diff --git a/src/plugins/embeddable/public/lib/containers/i_container.ts b/src/plugins/embeddable/public/lib/containers/i_container.ts
index 7da5f92ec92c1..31a7cd4f2e559 100644
--- a/src/plugins/embeddable/public/lib/containers/i_container.ts
+++ b/src/plugins/embeddable/public/lib/containers/i_container.ts
@@ -25,9 +25,7 @@ import {
IEmbeddable,
} from '../embeddables';
-export interface PanelState {
- savedObjectId?: string;
-
+export interface PanelState {
// The type of embeddable in this panel. Will be used to find the factory in which to
// load the embeddable.
type: string;
@@ -89,17 +87,6 @@ export interface IContainer<
*/
removeEmbeddable(embeddableId: string): void;
- /**
- * Adds a new embeddable that is backed off of a saved object.
- */
- addSavedObjectEmbeddable<
- EEI extends EmbeddableInput = EmbeddableInput,
- E extends Embeddable = Embeddable
- >(
- type: string,
- savedObjectId: string
- ): Promise;
-
/**
* Adds a new embeddable to the container. `explicitInput` may partially specify the required embeddable input,
* but the remainder must come from inherited container state.
diff --git a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts
index 6345c34b0dda2..c0fb98d2559db 100644
--- a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts
+++ b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts
@@ -26,6 +26,11 @@ import { TriggerContextMapping } from '../../../../ui_actions/public';
export interface EmbeddableInput {
viewMode?: ViewMode;
title?: string;
+ /**
+ * Note this is not a saved object id. It is used to uniquely identify this
+ * Embeddable instance from others (e.g. inside a container). It's possible to
+ * have two Embeddables where everything else is the same but the id.
+ */
id: string;
lastReloadRequestTime?: number;
hidePanelTitles?: boolean;
@@ -44,6 +49,8 @@ export interface EmbeddableInput {
* Whether this embeddable should not execute triggers.
*/
disableTriggers?: boolean;
+
+ [key: string]: unknown;
}
export interface EmbeddableOutput {
diff --git a/src/plugins/embeddable/public/lib/embeddables/index.ts b/src/plugins/embeddable/public/lib/embeddables/index.ts
index 4d6ab37a50c05..ad8b9c35e60be 100644
--- a/src/plugins/embeddable/public/lib/embeddables/index.ts
+++ b/src/plugins/embeddable/public/lib/embeddables/index.ts
@@ -25,3 +25,4 @@ export { ErrorEmbeddable, isErrorEmbeddable } from './error_embeddable';
export { withEmbeddableSubscription } from './with_subscription';
export { EmbeddableFactoryRenderer } from './embeddable_factory_renderer';
export { EmbeddableRoot } from './embeddable_root';
+export * from './saved_object_embeddable';
diff --git a/src/plugins/embeddable/public/lib/embeddables/saved_object_embeddable.ts b/src/plugins/embeddable/public/lib/embeddables/saved_object_embeddable.ts
new file mode 100644
index 0000000000000..6ca1800b16de4
--- /dev/null
+++ b/src/plugins/embeddable/public/lib/embeddables/saved_object_embeddable.ts
@@ -0,0 +1,30 @@
+/*
+ * 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 { EmbeddableInput } from '..';
+
+export interface SavedObjectEmbeddableInput extends EmbeddableInput {
+ savedObjectId: string;
+}
+
+export function isSavedObjectEmbeddableInput(
+ input: EmbeddableInput | SavedObjectEmbeddableInput
+): input is SavedObjectEmbeddableInput {
+ return (input as SavedObjectEmbeddableInput).savedObjectId !== undefined;
+}
diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_flyout.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_flyout.tsx
index 50d8bcef8506c..5bf3f69a95c30 100644
--- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_flyout.tsx
+++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_flyout.tsx
@@ -33,6 +33,7 @@ import { EmbeddableStart } from 'src/plugins/embeddable/public';
import { IContainer } from '../../../../containers';
import { EmbeddableFactoryNotFoundError } from '../../../../errors';
import { SavedObjectFinderCreateNew } from './saved_object_finder_create_new';
+import { SavedObjectEmbeddableInput } from '../../../../embeddables';
interface Props {
onClose: () => void;
@@ -98,8 +99,18 @@ export class AddPanelFlyout extends React.Component {
}
};
- public onAddPanel = async (id: string, type: string, name: string) => {
- this.props.container.addSavedObjectEmbeddable(type, id);
+ public onAddPanel = async (savedObjectId: string, savedObjectType: string, name: string) => {
+ const factoryForSavedObjectType = [...this.props.getAllFactories()].find(
+ factory => factory.savedObjectMetaData && factory.savedObjectMetaData.type === savedObjectType
+ );
+ if (!factoryForSavedObjectType) {
+ throw new EmbeddableFactoryNotFoundError(savedObjectType);
+ }
+
+ this.props.container.addNewEmbeddable(
+ factoryForSavedObjectType.type,
+ { savedObjectId }
+ );
this.showToast(name);
};
diff --git a/src/plugins/embeddable/public/tests/container.test.ts b/src/plugins/embeddable/public/tests/container.test.ts
index 87076399465d3..1aae43550ec6f 100644
--- a/src/plugins/embeddable/public/tests/container.test.ts
+++ b/src/plugins/embeddable/public/tests/container.test.ts
@@ -641,8 +641,7 @@ test('container stores ErrorEmbeddables when a saved object cannot be found', as
panels: {
'123': {
type: 'vis',
- explicitInput: { id: '123' },
- savedObjectId: '456',
+ explicitInput: { id: '123', savedObjectId: '456' },
},
},
viewMode: ViewMode.EDIT,
@@ -663,8 +662,7 @@ test('ErrorEmbeddables get updated when parent does', async done => {
panels: {
'123': {
type: 'vis',
- explicitInput: { id: '123' },
- savedObjectId: '456',
+ explicitInput: { id: '123', savedObjectId: '456' },
},
},
viewMode: ViewMode.EDIT,
diff --git a/src/plugins/expressions/server/legacy.ts b/src/plugins/expressions/server/legacy.ts
index 17aa1c66a6835..1487f9f6734e9 100644
--- a/src/plugins/expressions/server/legacy.ts
+++ b/src/plugins/expressions/server/legacy.ts
@@ -26,7 +26,7 @@ import { register, registryFactory, Registry, Fn } from '@kbn/interpreter/common
import Boom from 'boom';
import { schema } from '@kbn/config-schema';
-import { CoreSetup, Logger } from 'src/core/server';
+import { CoreSetup, Logger, APICaller } from 'src/core/server';
import { ExpressionsServerSetupDependencies } from './plugin';
import { typeSpecs, ExpressionType } from '../common';
import { serializeProvider } from '../common';
@@ -97,7 +97,10 @@ export const createLegacyServerEndpoints = (
* @param {*} handlers - The Canvas handlers
* @param {*} fnCall - Describes the function being run `{ functionName, args, context }`
*/
- async function runFunction(handlers: any, fnCall: any) {
+ async function runFunction(
+ handlers: { environment: string; elasticsearchClient: APICaller },
+ fnCall: any
+ ) {
const { functionName, args, context } = fnCall;
const { deserialize } = serializeProvider(registries.types.toJS());
const fnDef = registries.serverFunctions.toJS()[functionName];
@@ -112,18 +115,14 @@ export const createLegacyServerEndpoints = (
* results back using ND-JSON.
*/
plugins.bfetch.addBatchProcessingRoute(`/api/interpreter/fns`, request => {
- const scopedClient = core.elasticsearch.dataClient.asScoped(request);
- const handlers = {
- environment: 'server',
- elasticsearchClient: async (
- endpoint: string,
- clientParams: Record = {},
- options?: any
- ) => scopedClient.callAsCurrentUser(endpoint, clientParams, options),
- };
-
return {
onBatchItem: async (fnCall: any) => {
+ const [coreStart] = await core.getStartServices();
+ const handlers = {
+ environment: 'server',
+ elasticsearchClient: coreStart.elasticsearch.legacy.client.asScoped(request)
+ .callAsCurrentUser,
+ };
const result = await runFunction(handlers, fnCall);
if (typeof result === 'undefined') {
throw new Error(`Function ${fnCall.functionName} did not return anything.`);
diff --git a/src/plugins/ui_actions/public/actions/action.ts b/src/plugins/ui_actions/public/actions/action.ts
index f532c2c8aa219..feaa1f6a60e2f 100644
--- a/src/plugins/ui_actions/public/actions/action.ts
+++ b/src/plugins/ui_actions/public/actions/action.ts
@@ -63,9 +63,11 @@ export interface Action {
isCompatible(context: Context): Promise;
/**
- * If this returns something truthy, this is used in addition to the `execute` method when clicked.
+ * If this returns something truthy, this will be used as [href] attribute on a link if possible (e.g. in context menu item)
+ * to support right click -> open in a new tab behavior.
+ * For regular click navigation is prevented and `execute()` takes control.
*/
- getHref?(context: Context): string | undefined;
+ getHref?(context: Context): Promise;
/**
* Executes the action.
diff --git a/src/plugins/ui_actions/public/actions/action_definition.ts b/src/plugins/ui_actions/public/actions/action_definition.ts
index 3eaa13572a826..79fda78401abd 100644
--- a/src/plugins/ui_actions/public/actions/action_definition.ts
+++ b/src/plugins/ui_actions/public/actions/action_definition.ts
@@ -63,7 +63,7 @@ export interface ActionDefinition {
/**
* If this returns something truthy, this is used in addition to the `execute` method when clicked.
*/
- getHref?(context: ActionContextMapping[T]): string | undefined;
+ getHref?(context: ActionContextMapping[T]): Promise;
/**
* Executes the action.
diff --git a/src/plugins/ui_actions/public/actions/create_action.ts b/src/plugins/ui_actions/public/actions/create_action.ts
index 90a9415c0b497..cc66f221e4082 100644
--- a/src/plugins/ui_actions/public/actions/create_action.ts
+++ b/src/plugins/ui_actions/public/actions/create_action.ts
@@ -28,7 +28,6 @@ export function createAction(action: ActionDefinition):
id: action.type,
isCompatible: () => Promise.resolve(true),
getDisplayName: () => '',
- getHref: () => undefined,
...action,
};
}
diff --git a/src/plugins/ui_actions/public/context_menu/build_eui_context_menu_panels.tsx b/src/plugins/ui_actions/public/context_menu/build_eui_context_menu_panels.tsx
index 3dce2c1f4c257..d26740ffdf033 100644
--- a/src/plugins/ui_actions/public/context_menu/build_eui_context_menu_panels.tsx
+++ b/src/plugins/ui_actions/public/context_menu/build_eui_context_menu_panels.tsx
@@ -71,7 +71,7 @@ async function buildEuiContextMenuPanelItems({
}
items.push(
- convertPanelActionToContextMenuItem({
+ await convertPanelActionToContextMenuItem({
action,
actionContext,
closeMenu,
@@ -88,9 +88,9 @@ async function buildEuiContextMenuPanelItems ({
*
* @param {ContextMenuAction} action
* @param {Embeddable} embeddable
- * @return {EuiContextMenuPanelItemDescriptor}
+ * @return {Promise}
*/
-function convertPanelActionToContextMenuItem({
+async function convertPanelActionToContextMenuItem ({
action,
actionContext,
closeMenu,
@@ -98,7 +98,7 @@ function convertPanelActionToContextMenuItem ({
action: Action ;
actionContext: A;
closeMenu: () => void;
-}): EuiContextMenuPanelItemDescriptor {
+}): Promise {
const menuPanelItem: EuiContextMenuPanelItemDescriptor = {
name: action.MenuItem
? React.createElement(uiToReactComponent(action.MenuItem), {
@@ -110,13 +110,33 @@ function convertPanelActionToContextMenuItem({
'data-test-subj': `embeddablePanelAction-${action.id}`,
};
- menuPanelItem.onClick = () => {
- action.execute(actionContext);
+ menuPanelItem.onClick = event => {
+ if (event.currentTarget instanceof HTMLAnchorElement) {
+ // from react-router's
+ if (
+ !event.defaultPrevented && // onClick prevented default
+ event.button === 0 && // ignore everything but left clicks
+ (!event.currentTarget.target || event.currentTarget.target === '_self') && // let browser handle "target=_blank" etc.
+ !(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) // ignore clicks with modifier keys
+ ) {
+ event.preventDefault();
+ action.execute(actionContext);
+ } else {
+ // let browser handle navigation
+ }
+ } else {
+ // not a link
+ action.execute(actionContext);
+ }
+
closeMenu();
};
- if (action.getHref && action.getHref(actionContext)) {
- menuPanelItem.href = action.getHref(actionContext);
+ if (action.getHref) {
+ const href = await action.getHref(actionContext);
+ if (href) {
+ menuPanelItem.href = href;
+ }
}
return menuPanelItem;
diff --git a/src/plugins/ui_actions/public/triggers/trigger_internal.ts b/src/plugins/ui_actions/public/triggers/trigger_internal.ts
index 5b670df354f78..1fc92d7c0cb1b 100644
--- a/src/plugins/ui_actions/public/triggers/trigger_internal.ts
+++ b/src/plugins/ui_actions/public/triggers/trigger_internal.ts
@@ -55,13 +55,6 @@ export class TriggerInternal {
action: Action,
context: TriggerContextMapping[T]
) {
- const href = action.getHref && action.getHref(context);
-
- if (href) {
- window.location.href = href;
- return;
- }
-
await action.execute(context);
}
diff --git a/src/plugins/vis_type_timeseries/kibana.json b/src/plugins/vis_type_timeseries/kibana.json
index d77f4ac92da16..305e159ac2505 100644
--- a/src/plugins/vis_type_timeseries/kibana.json
+++ b/src/plugins/vis_type_timeseries/kibana.json
@@ -3,5 +3,7 @@
"version": "8.0.0",
"kibanaVersion": "kibana",
"server": true,
+ "ui": true,
+ "requiredPlugins": ["data", "expressions", "visualizations"],
"optionalPlugins": ["usageCollection"]
}
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/_mixins.scss b/src/plugins/vis_type_timeseries/public/application/_mixins.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/_mixins.scss
rename to src/plugins/vis_type_timeseries/public/application/_mixins.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/_tvb_editor.scss b/src/plugins/vis_type_timeseries/public/application/_tvb_editor.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/_tvb_editor.scss
rename to src/plugins/vis_type_timeseries/public/application/_tvb_editor.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/_variables.scss b/src/plugins/vis_type_timeseries/public/application/_variables.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/_variables.scss
rename to src/plugins/vis_type_timeseries/public/application/_variables.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/_annotations_editor.scss b/src/plugins/vis_type_timeseries/public/application/components/_annotations_editor.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/_annotations_editor.scss
rename to src/plugins/vis_type_timeseries/public/application/components/_annotations_editor.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/_color_picker.scss b/src/plugins/vis_type_timeseries/public/application/components/_color_picker.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/_color_picker.scss
rename to src/plugins/vis_type_timeseries/public/application/components/_color_picker.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/_color_rules.scss b/src/plugins/vis_type_timeseries/public/application/components/_color_rules.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/_color_rules.scss
rename to src/plugins/vis_type_timeseries/public/application/components/_color_rules.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/_custom_color_picker.scss b/src/plugins/vis_type_timeseries/public/application/components/_custom_color_picker.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/_custom_color_picker.scss
rename to src/plugins/vis_type_timeseries/public/application/components/_custom_color_picker.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/_error.scss b/src/plugins/vis_type_timeseries/public/application/components/_error.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/_error.scss
rename to src/plugins/vis_type_timeseries/public/application/components/_error.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/_index.scss b/src/plugins/vis_type_timeseries/public/application/components/_index.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/_index.scss
rename to src/plugins/vis_type_timeseries/public/application/components/_index.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/_markdown_editor.scss b/src/plugins/vis_type_timeseries/public/application/components/_markdown_editor.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/_markdown_editor.scss
rename to src/plugins/vis_type_timeseries/public/application/components/_markdown_editor.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/_no_data.scss b/src/plugins/vis_type_timeseries/public/application/components/_no_data.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/_no_data.scss
rename to src/plugins/vis_type_timeseries/public/application/components/_no_data.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/_series_editor.scss b/src/plugins/vis_type_timeseries/public/application/components/_series_editor.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/_series_editor.scss
rename to src/plugins/vis_type_timeseries/public/application/components/_series_editor.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/_vis_editor.scss b/src/plugins/vis_type_timeseries/public/application/components/_vis_editor.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/_vis_editor.scss
rename to src/plugins/vis_type_timeseries/public/application/components/_vis_editor.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/_vis_editor_visualization.scss b/src/plugins/vis_type_timeseries/public/application/components/_vis_editor_visualization.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/_vis_editor_visualization.scss
rename to src/plugins/vis_type_timeseries/public/application/components/_vis_editor_visualization.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/_vis_picker.scss b/src/plugins/vis_type_timeseries/public/application/components/_vis_picker.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/_vis_picker.scss
rename to src/plugins/vis_type_timeseries/public/application/components/_vis_picker.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/_vis_with_splits.scss b/src/plugins/vis_type_timeseries/public/application/components/_vis_with_splits.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/_vis_with_splits.scss
rename to src/plugins/vis_type_timeseries/public/application/components/_vis_with_splits.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/add_delete_buttons.js b/src/plugins/vis_type_timeseries/public/application/components/add_delete_buttons.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/add_delete_buttons.js
rename to src/plugins/vis_type_timeseries/public/application/components/add_delete_buttons.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/add_delete_buttons.test.js b/src/plugins/vis_type_timeseries/public/application/components/add_delete_buttons.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/add_delete_buttons.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/add_delete_buttons.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/_agg_row.scss b/src/plugins/vis_type_timeseries/public/application/components/aggs/_agg_row.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/_agg_row.scss
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/_agg_row.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/_index.scss b/src/plugins/vis_type_timeseries/public/application/components/aggs/_index.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/_index.scss
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/_index.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/agg.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/agg.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/agg.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/agg.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/agg_row.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_row.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/agg_row.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/agg_row.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/agg_select.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_select.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/agg_select.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/agg_select.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/aggs.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/aggs.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/aggs.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/aggs.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/calculation.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/calculation.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/calculation.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/calculation.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/cumulative_sum.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/cumulative_sum.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/cumulative_sum.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/cumulative_sum.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/derivative.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/derivative.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/derivative.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/derivative.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/field_select.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/field_select.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/filter_ratio.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/filter_ratio.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/filter_ratio.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/filter_ratio.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/math.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/math.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/math.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/math.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/metric_select.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/metric_select.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/metric_select.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/metric_select.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/moving_average.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/moving_average.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/moving_average.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/moving_average.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/percentile.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/index.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/index.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/index.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/index.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/multi_value_row.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/multi_value_row.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/multi_value_row.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/multi_value_row.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/percentile_rank.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/percentile_rank.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/percentile_rank.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/percentile_rank.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/percentile_rank_values.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/percentile_rank_values.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/percentile_rank_values.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_rank/percentile_rank_values.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_ui.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_ui.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_ui.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/percentile_ui.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/positive_only.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/positive_only.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/positive_only.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/positive_only.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/positive_rate.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/positive_rate.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/positive_rate.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/positive_rate.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/serial_diff.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/serial_diff.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/serial_diff.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/serial_diff.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/series_agg.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/series_agg.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/series_agg.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/series_agg.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/static.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/static.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/static.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/static.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_agg.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/std_agg.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_agg.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/std_agg.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_deviation.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/std_deviation.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_deviation.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/std_deviation.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_sibling.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/std_sibling.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_sibling.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/std_sibling.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/temporary_unsupported_agg.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/temporary_unsupported_agg.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/temporary_unsupported_agg.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/temporary_unsupported_agg.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/top_hit.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/top_hit.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/top_hit.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/top_hit.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/unsupported_agg.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/unsupported_agg.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/unsupported_agg.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/unsupported_agg.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/vars.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/vars.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/vars.js
rename to src/plugins/vis_type_timeseries/public/application/components/aggs/vars.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/annotations_editor.js b/src/plugins/vis_type_timeseries/public/application/components/annotations_editor.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/annotations_editor.js
rename to src/plugins/vis_type_timeseries/public/application/components/annotations_editor.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/color_picker.js b/src/plugins/vis_type_timeseries/public/application/components/color_picker.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/color_picker.js
rename to src/plugins/vis_type_timeseries/public/application/components/color_picker.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/color_picker.test.js b/src/plugins/vis_type_timeseries/public/application/components/color_picker.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/color_picker.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/color_picker.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/color_rules.js b/src/plugins/vis_type_timeseries/public/application/components/color_rules.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/color_rules.js
rename to src/plugins/vis_type_timeseries/public/application/components/color_rules.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/color_rules.test.js b/src/plugins/vis_type_timeseries/public/application/components/color_rules.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/color_rules.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/color_rules.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/custom_color_picker.js b/src/plugins/vis_type_timeseries/public/application/components/custom_color_picker.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/custom_color_picker.js
rename to src/plugins/vis_type_timeseries/public/application/components/custom_color_picker.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/data_format_picker.js b/src/plugins/vis_type_timeseries/public/application/components/data_format_picker.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/data_format_picker.js
rename to src/plugins/vis_type_timeseries/public/application/components/data_format_picker.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/error.js b/src/plugins/vis_type_timeseries/public/application/components/error.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/error.js
rename to src/plugins/vis_type_timeseries/public/application/components/error.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/icon_select/__snapshots__/icon_select.test.js.snap b/src/plugins/vis_type_timeseries/public/application/components/icon_select/__snapshots__/icon_select.test.js.snap
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/icon_select/__snapshots__/icon_select.test.js.snap
rename to src/plugins/vis_type_timeseries/public/application/components/icon_select/__snapshots__/icon_select.test.js.snap
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/icon_select/icon_select.js b/src/plugins/vis_type_timeseries/public/application/components/icon_select/icon_select.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/icon_select/icon_select.js
rename to src/plugins/vis_type_timeseries/public/application/components/icon_select/icon_select.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/icon_select/icon_select.test.js b/src/plugins/vis_type_timeseries/public/application/components/icon_select/icon_select.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/icon_select/icon_select.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/icon_select/icon_select.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/index_pattern.js b/src/plugins/vis_type_timeseries/public/application/components/index_pattern.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/index_pattern.js
rename to src/plugins/vis_type_timeseries/public/application/components/index_pattern.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/agg_to_component.js b/src/plugins/vis_type_timeseries/public/application/components/lib/agg_to_component.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/agg_to_component.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/agg_to_component.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/calculate_siblings.js b/src/plugins/vis_type_timeseries/public/application/components/lib/calculate_siblings.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/calculate_siblings.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/calculate_siblings.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/calculate_siblings.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/calculate_siblings.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/calculate_siblings.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/calculate_siblings.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/charts.js b/src/plugins/vis_type_timeseries/public/application/components/lib/charts.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/charts.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/charts.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/collection_actions.js b/src/plugins/vis_type_timeseries/public/application/components/lib/collection_actions.js
similarity index 82%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/collection_actions.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/collection_actions.js
index 79cbe98b3d3db..3eae18111bb4d 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/collection_actions.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/lib/collection_actions.js
@@ -18,7 +18,6 @@
*/
import uuid from 'uuid';
-import _ from 'lodash';
const newFn = () => ({ id: uuid.v1() });
@@ -30,9 +29,7 @@ export function handleChange(props, doc) {
if (row.id === doc.id) return doc;
return row;
});
- if (_.isFunction(props.onChange)) {
- props.onChange(_.assign({}, model, part));
- }
+ props.onChange?.({ ...model, ...part });
}
export function handleDelete(props, doc) {
@@ -40,20 +37,15 @@ export function handleDelete(props, doc) {
const collection = model[name] || [];
const part = {};
part[name] = collection.filter(row => row.id !== doc.id);
- if (_.isFunction(props.onChange)) {
- props.onChange(_.assign({}, model, part));
- }
+ props.onChange?.({ ...model, ...part });
}
export function handleAdd(props, fn = newFn) {
- if (!_.isFunction(fn)) fn = newFn;
const { model, name } = props;
const collection = model[name] || [];
const part = {};
part[name] = collection.concat([fn()]);
- if (_.isFunction(props.onChange)) {
- props.onChange(_.assign({}, model, part));
- }
+ props.onChange?.({ ...model, ...part });
}
export const collectionActions = { handleAdd, handleDelete, handleChange };
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/collection_actions.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/collection_actions.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/collection_actions.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/collection_actions.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/convert_series_to_vars.js b/src/plugins/vis_type_timeseries/public/application/components/lib/convert_series_to_vars.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/convert_series_to_vars.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/convert_series_to_vars.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/convert_series_to_vars.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/convert_series_to_vars.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/convert_series_to_vars.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/convert_series_to_vars.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_change_handler.js b/src/plugins/vis_type_timeseries/public/application/components/lib/create_change_handler.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_change_handler.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/create_change_handler.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_number_handler.js b/src/plugins/vis_type_timeseries/public/application/components/lib/create_number_handler.js
similarity index 92%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_number_handler.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/create_number_handler.js
index fd432add43295..3bc8fd87f73dd 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_number_handler.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/lib/create_number_handler.js
@@ -25,8 +25,6 @@ export const createNumberHandler = handleChange => {
if (!detectIE() || e.keyCode === 13) e.preventDefault();
const value = Number(_.get(e, 'target.value', defaultValue));
- if (_.isFunction(handleChange)) {
- return handleChange({ [name]: value });
- }
+ return handleChange?.({ [name]: value });
};
};
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_number_handler.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/create_number_handler.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_number_handler.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/create_number_handler.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_select_handler.js b/src/plugins/vis_type_timeseries/public/application/components/lib/create_select_handler.js
similarity index 86%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_select_handler.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/create_select_handler.js
index 30937b97d353f..cfc6a4dc57871 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_select_handler.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/lib/create_select_handler.js
@@ -21,10 +21,8 @@ import _ from 'lodash';
export const createSelectHandler = handleChange => {
return name => selectedOptions => {
- if (_.isFunction(handleChange)) {
- return handleChange({
- [name]: _.get(selectedOptions, '[0].value', null),
- });
- }
+ return handleChange?.({
+ [name]: _.get(selectedOptions, '[0].value', null),
+ });
};
};
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_select_handler.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/create_select_handler.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_select_handler.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/create_select_handler.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_text_handler.js b/src/plugins/vis_type_timeseries/public/application/components/lib/create_text_handler.js
similarity index 92%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_text_handler.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/create_text_handler.js
index 8e2624488d954..82cc071b59d51 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_text_handler.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/lib/create_text_handler.js
@@ -26,8 +26,6 @@ export const createTextHandler = handleChange => {
if (!detectIE() || e.keyCode === 13) e.preventDefault();
const value = _.get(e, 'target.value', defaultValue);
- if (_.isFunction(handleChange)) {
- return handleChange({ [name]: value });
- }
+ return handleChange?.({ [name]: value });
};
};
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_text_handler.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/create_text_handler.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_text_handler.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/create_text_handler.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_xaxis_formatter.js b/src/plugins/vis_type_timeseries/public/application/components/lib/create_xaxis_formatter.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_xaxis_formatter.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/create_xaxis_formatter.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/detect_ie.js b/src/plugins/vis_type_timeseries/public/application/components/lib/detect_ie.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/detect_ie.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/detect_ie.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/durations.js b/src/plugins/vis_type_timeseries/public/application/components/lib/durations.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/durations.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/durations.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/durations.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/durations.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/durations.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/durations.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_axis_label_string.js b/src/plugins/vis_type_timeseries/public/application/components/lib/get_axis_label_string.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_axis_label_string.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/get_axis_label_string.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_axis_label_string.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/get_axis_label_string.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_axis_label_string.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/get_axis_label_string.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_default_query_language.js b/src/plugins/vis_type_timeseries/public/application/components/lib/get_default_query_language.js
similarity index 94%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_default_query_language.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/get_default_query_language.js
index 26723da5ab5c9..972f937ad109d 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_default_query_language.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/lib/get_default_query_language.js
@@ -17,7 +17,7 @@
* under the License.
*/
-import { getUISettings } from '../../services';
+import { getUISettings } from '../../../services';
export function getDefaultQueryLanguage() {
return getUISettings().get('search:queryLanguage');
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_display_name.js b/src/plugins/vis_type_timeseries/public/application/components/lib/get_display_name.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_display_name.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/get_display_name.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_interval.js b/src/plugins/vis_type_timeseries/public/application/components/lib/get_interval.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_interval.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/get_interval.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/new_metric_agg_fn.js b/src/plugins/vis_type_timeseries/public/application/components/lib/new_metric_agg_fn.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/new_metric_agg_fn.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/new_metric_agg_fn.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/new_series_fn.js b/src/plugins/vis_type_timeseries/public/application/components/lib/new_series_fn.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/new_series_fn.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/new_series_fn.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/re_id_series.js b/src/plugins/vis_type_timeseries/public/application/components/lib/re_id_series.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/re_id_series.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/re_id_series.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/re_id_series.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/re_id_series.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/re_id_series.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/re_id_series.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/reorder.js b/src/plugins/vis_type_timeseries/public/application/components/lib/reorder.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/reorder.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/reorder.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/replace_vars.js b/src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/replace_vars.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/replace_vars.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/replace_vars.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/series_change_handler.js b/src/plugins/vis_type_timeseries/public/application/components/lib/series_change_handler.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/series_change_handler.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/series_change_handler.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/stacked.js b/src/plugins/vis_type_timeseries/public/application/components/lib/stacked.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/stacked.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/stacked.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/tick_formatter.js b/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.js
similarity index 97%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/tick_formatter.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.js
index 3ab8e0f6b885e..fd316e66a16fb 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/tick_formatter.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.js
@@ -20,7 +20,7 @@
import handlebars from 'handlebars/dist/handlebars';
import { isNumber } from 'lodash';
import { inputFormats, outputFormats, isDuration } from '../lib/durations';
-import { getFieldFormats } from '../../services';
+import { getFieldFormats } from '../../../services';
export const createTickFormatter = (format = '0,0.[00]', template, getConfig = null) => {
const fieldFormats = getFieldFormats();
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/tick_formatter.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.test.js
similarity index 98%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/lib/tick_formatter.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.test.js
index e87cba126bb46..ee10b254a9e15 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/tick_formatter.test.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.test.js
@@ -19,7 +19,7 @@
import { createTickFormatter } from './tick_formatter';
import { getFieldFormatsRegistry } from '../../../../../../test_utils/public/stub_field_formats';
-import { setFieldFormats } from '../../services';
+import { setFieldFormats } from '../../../services';
const mockUiSettings = {
get: item => {
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/markdown_editor.js b/src/plugins/vis_type_timeseries/public/application/components/markdown_editor.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/markdown_editor.js
rename to src/plugins/vis_type_timeseries/public/application/components/markdown_editor.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/no_data.js b/src/plugins/vis_type_timeseries/public/application/components/no_data.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/no_data.js
rename to src/plugins/vis_type_timeseries/public/application/components/no_data.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config.js b/src/plugins/vis_type_timeseries/public/application/components/panel_config.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config.js
rename to src/plugins/vis_type_timeseries/public/application/components/panel_config.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/_index.scss b/src/plugins/vis_type_timeseries/public/application/components/panel_config/_index.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/_index.scss
rename to src/plugins/vis_type_timeseries/public/application/components/panel_config/_index.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/_panel_config.scss b/src/plugins/vis_type_timeseries/public/application/components/panel_config/_panel_config.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/_panel_config.scss
rename to src/plugins/vis_type_timeseries/public/application/components/panel_config/_panel_config.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/gauge.js b/src/plugins/vis_type_timeseries/public/application/components/panel_config/gauge.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/gauge.js
rename to src/plugins/vis_type_timeseries/public/application/components/panel_config/gauge.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/gauge.test.js b/src/plugins/vis_type_timeseries/public/application/components/panel_config/gauge.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/gauge.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/panel_config/gauge.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/markdown.js b/src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/markdown.js
rename to src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/metric.js b/src/plugins/vis_type_timeseries/public/application/components/panel_config/metric.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/metric.js
rename to src/plugins/vis_type_timeseries/public/application/components/panel_config/metric.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/table.js b/src/plugins/vis_type_timeseries/public/application/components/panel_config/table.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/table.js
rename to src/plugins/vis_type_timeseries/public/application/components/panel_config/table.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/timeseries.js b/src/plugins/vis_type_timeseries/public/application/components/panel_config/timeseries.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/timeseries.js
rename to src/plugins/vis_type_timeseries/public/application/components/panel_config/timeseries.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/top_n.js b/src/plugins/vis_type_timeseries/public/application/components/panel_config/top_n.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/top_n.js
rename to src/plugins/vis_type_timeseries/public/application/components/panel_config/top_n.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/query_bar_wrapper.js b/src/plugins/vis_type_timeseries/public/application/components/query_bar_wrapper.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/query_bar_wrapper.js
rename to src/plugins/vis_type_timeseries/public/application/components/query_bar_wrapper.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/series.js b/src/plugins/vis_type_timeseries/public/application/components/series.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/series.js
rename to src/plugins/vis_type_timeseries/public/application/components/series.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/series_config.js b/src/plugins/vis_type_timeseries/public/application/components/series_config.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/series_config.js
rename to src/plugins/vis_type_timeseries/public/application/components/series_config.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/series_drag_handler.js b/src/plugins/vis_type_timeseries/public/application/components/series_drag_handler.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/series_drag_handler.js
rename to src/plugins/vis_type_timeseries/public/application/components/series_drag_handler.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/series_editor.js b/src/plugins/vis_type_timeseries/public/application/components/series_editor.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/series_editor.js
rename to src/plugins/vis_type_timeseries/public/application/components/series_editor.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/split.js b/src/plugins/vis_type_timeseries/public/application/components/split.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/split.js
rename to src/plugins/vis_type_timeseries/public/application/components/split.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/__snapshots__/terms.test.js.snap b/src/plugins/vis_type_timeseries/public/application/components/splits/__snapshots__/terms.test.js.snap
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/splits/__snapshots__/terms.test.js.snap
rename to src/plugins/vis_type_timeseries/public/application/components/splits/__snapshots__/terms.test.js.snap
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/everything.js b/src/plugins/vis_type_timeseries/public/application/components/splits/everything.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/splits/everything.js
rename to src/plugins/vis_type_timeseries/public/application/components/splits/everything.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/filter.js b/src/plugins/vis_type_timeseries/public/application/components/splits/filter.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/splits/filter.js
rename to src/plugins/vis_type_timeseries/public/application/components/splits/filter.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/filter_items.js b/src/plugins/vis_type_timeseries/public/application/components/splits/filter_items.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/splits/filter_items.js
rename to src/plugins/vis_type_timeseries/public/application/components/splits/filter_items.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/filters.js b/src/plugins/vis_type_timeseries/public/application/components/splits/filters.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/splits/filters.js
rename to src/plugins/vis_type_timeseries/public/application/components/splits/filters.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/group_by_select.js b/src/plugins/vis_type_timeseries/public/application/components/splits/group_by_select.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/splits/group_by_select.js
rename to src/plugins/vis_type_timeseries/public/application/components/splits/group_by_select.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/terms.js b/src/plugins/vis_type_timeseries/public/application/components/splits/terms.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/splits/terms.js
rename to src/plugins/vis_type_timeseries/public/application/components/splits/terms.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/terms.test.js b/src/plugins/vis_type_timeseries/public/application/components/splits/terms.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/splits/terms.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/splits/terms.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/unsupported_split.js b/src/plugins/vis_type_timeseries/public/application/components/splits/unsupported_split.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/splits/unsupported_split.js
rename to src/plugins/vis_type_timeseries/public/application/components/splits/unsupported_split.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/svg/bomb_icon.js b/src/plugins/vis_type_timeseries/public/application/components/svg/bomb_icon.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/svg/bomb_icon.js
rename to src/plugins/vis_type_timeseries/public/application/components/svg/bomb_icon.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/svg/fire_icon.js b/src/plugins/vis_type_timeseries/public/application/components/svg/fire_icon.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/svg/fire_icon.js
rename to src/plugins/vis_type_timeseries/public/application/components/svg/fire_icon.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor.js b/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js
similarity index 99%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_editor.js
index b4845696fc8c0..7075e86eb56bf 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js
@@ -30,7 +30,7 @@ import { createBrushHandler } from '../lib/create_brush_handler';
import { fetchFields } from '../lib/fetch_fields';
import { extractIndexPatterns } from '../../../../../plugins/vis_type_timeseries/common/extract_index_patterns';
import { esKuery } from '../../../../../plugins/data/public';
-import { getSavedObjectsClient, getUISettings, getDataStart, getCoreStart } from '../services';
+import { getSavedObjectsClient, getUISettings, getDataStart, getCoreStart } from '../../services';
import { CoreStartContextProvider } from '../contexts/query_input_bar_context';
import { KibanaContextProvider } from '../../../../../plugins/kibana_react/public';
@@ -96,7 +96,7 @@ export class VisEditor extends Component {
return true;
};
- handleChange = async partialModel => {
+ handleChange = partialModel => {
if (isEmpty(partialModel)) {
return;
}
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor_visualization.js b/src/plugins/vis_type_timeseries/public/application/components/vis_editor_visualization.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor_visualization.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_editor_visualization.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_picker.js b/src/plugins/vis_type_timeseries/public/application/components/vis_picker.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_picker.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_picker.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/_index.scss b/src/plugins/vis_type_timeseries/public/application/components/vis_types/_index.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/_index.scss
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/_index.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/_vis_types.scss b/src/plugins/vis_type_timeseries/public/application/components/vis_types/_vis_types.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/_vis_types.scss
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/_vis_types.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/gauge/series.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/series.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/gauge/series.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/series.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/gauge/series.test.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/series.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/gauge/series.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/series.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/gauge/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/vis.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/gauge/vis.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/vis.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/markdown/_markdown.scss b/src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/_markdown.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/markdown/_markdown.scss
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/_markdown.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/markdown/series.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/series.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/markdown/series.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/series.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/markdown/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/vis.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/markdown/vis.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/vis.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/metric/series.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/series.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/metric/series.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/series.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/metric/series.test.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/series.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/metric/series.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/series.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/metric/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/vis.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/metric/vis.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/vis.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/config.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/config.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/config.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/table/config.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/is_sortable.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/is_sortable.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/is_sortable.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/table/is_sortable.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/series.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/series.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/series.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/table/series.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js
similarity index 99%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/vis.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js
index 1fe9358cbfea9..c6f1db149928c 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/vis.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js
@@ -27,7 +27,7 @@ import { EuiToolTip, EuiIcon } from '@elastic/eui';
import { replaceVars } from '../../lib/replace_vars';
import { fieldFormats } from '../../../../../../../plugins/data/public';
import { FormattedMessage } from '@kbn/i18n/react';
-import { getFieldFormats } from '../../../services';
+import { getFieldFormats } from '../../../../services';
import { METRIC_TYPES } from '../../../../../../../plugins/vis_type_timeseries/common/metric_types';
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/config.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/config.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/config.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/config.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/series.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/series.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/series.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/series.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js
similarity index 99%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/vis.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js
index f559bc38b6c58..1004f7ee96a54 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/vis.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js
@@ -34,7 +34,7 @@ import { getInterval } from '../../lib/get_interval';
import { areFieldsDifferent } from '../../lib/charts';
import { createXaxisFormatter } from '../../lib/create_xaxis_formatter';
import { STACKED_OPTIONS } from '../../../visualizations/constants';
-import { getCoreStart, getUISettings } from '../../../services';
+import { getCoreStart, getUISettings } from '../../../../services';
export class TimeseriesVisualization extends Component {
static propTypes = {
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/top_n/series.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/top_n/series.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/top_n/series.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/top_n/series.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/top_n/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/top_n/vis.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/top_n/vis.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_types/top_n/vis.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_with_splits.js b/src/plugins/vis_type_timeseries/public/application/components/vis_with_splits.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/vis_with_splits.js
rename to src/plugins/vis_type_timeseries/public/application/components/vis_with_splits.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/visualization.js b/src/plugins/vis_type_timeseries/public/application/components/visualization.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/visualization.js
rename to src/plugins/vis_type_timeseries/public/application/components/visualization.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/yes_no.js b/src/plugins/vis_type_timeseries/public/application/components/yes_no.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/yes_no.js
rename to src/plugins/vis_type_timeseries/public/application/components/yes_no.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/yes_no.test.js b/src/plugins/vis_type_timeseries/public/application/components/yes_no.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/components/yes_no.test.js
rename to src/plugins/vis_type_timeseries/public/application/components/yes_no.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/contexts/form_validation_context.js b/src/plugins/vis_type_timeseries/public/application/contexts/form_validation_context.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/contexts/form_validation_context.js
rename to src/plugins/vis_type_timeseries/public/application/contexts/form_validation_context.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/contexts/query_input_bar_context.ts b/src/plugins/vis_type_timeseries/public/application/contexts/query_input_bar_context.ts
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/contexts/query_input_bar_context.ts
rename to src/plugins/vis_type_timeseries/public/application/contexts/query_input_bar_context.ts
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/contexts/vis_data_context.js b/src/plugins/vis_type_timeseries/public/application/contexts/vis_data_context.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/contexts/vis_data_context.js
rename to src/plugins/vis_type_timeseries/public/application/contexts/vis_data_context.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/editor_controller.js b/src/plugins/vis_type_timeseries/public/application/editor_controller.js
similarity index 94%
rename from src/legacy/core_plugins/vis_type_timeseries/public/editor_controller.js
rename to src/plugins/vis_type_timeseries/public/application/editor_controller.js
index 16a6348712065..af50d3a06d1fc 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/editor_controller.js
+++ b/src/plugins/vis_type_timeseries/public/application/editor_controller.js
@@ -20,7 +20,8 @@
import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { fetchIndexPatternFields } from './lib/fetch_fields';
-import { getSavedObjectsClient, getUISettings, getI18n } from './services';
+import { getSavedObjectsClient, getUISettings, getI18n } from '../services';
+import { VisEditor } from './components/vis_editor';
export class EditorController {
constructor(el, vis, eventEmitter, embeddableHandler) {
@@ -55,19 +56,14 @@ export class EditorController {
this.state.isLoaded = true;
};
- getComponent = () => {
- return this.state.vis.type.editorConfig.component;
- };
-
async render(params) {
- const Component = this.getComponent();
const I18nContext = getI18n().Context;
!this.state.isLoaded && (await this.fetchDefaultParams());
render(
- getUISettings().get('theme:darkMode');
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/lib/validate_interval.js b/src/plugins/vis_type_timeseries/public/application/lib/validate_interval.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/lib/validate_interval.js
rename to src/plugins/vis_type_timeseries/public/application/lib/validate_interval.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/constants/chart.js b/src/plugins/vis_type_timeseries/public/application/visualizations/constants/chart.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/constants/chart.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/constants/chart.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/constants/icons.js b/src/plugins/vis_type_timeseries/public/application/visualizations/constants/icons.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/constants/icons.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/constants/icons.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/constants/index.js b/src/plugins/vis_type_timeseries/public/application/visualizations/constants/index.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/constants/index.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/constants/index.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/active_cursor.js b/src/plugins/vis_type_timeseries/public/application/visualizations/lib/active_cursor.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/active_cursor.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/lib/active_cursor.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/calc_dimensions.js b/src/plugins/vis_type_timeseries/public/application/visualizations/lib/calc_dimensions.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/calc_dimensions.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/lib/calc_dimensions.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/calculate_coordinates.js b/src/plugins/vis_type_timeseries/public/application/visualizations/lib/calculate_coordinates.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/calculate_coordinates.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/lib/calculate_coordinates.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/get_value_by.js b/src/plugins/vis_type_timeseries/public/application/visualizations/lib/get_value_by.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/get_value_by.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/lib/get_value_by.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/_annotation.scss b/src/plugins/vis_type_timeseries/public/application/visualizations/views/_annotation.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/_annotation.scss
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/_annotation.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/_gauge.scss b/src/plugins/vis_type_timeseries/public/application/visualizations/views/_gauge.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/_gauge.scss
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/_gauge.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/_index.scss b/src/plugins/vis_type_timeseries/public/application/visualizations/views/_index.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/_index.scss
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/_index.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/_metric.scss b/src/plugins/vis_type_timeseries/public/application/visualizations/views/_metric.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/_metric.scss
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/_metric.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/_top_n.scss b/src/plugins/vis_type_timeseries/public/application/visualizations/views/_top_n.scss
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/_top_n.scss
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/_top_n.scss
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/annotation.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/annotation.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/annotation.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/annotation.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/gauge.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/gauge.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/gauge.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/gauge.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/gauge_vis.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/gauge_vis.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/gauge_vis.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/gauge_vis.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/metric.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/metric.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/metric.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/metric.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/__mocks__/@elastic/charts.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/__mocks__/@elastic/charts.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/__mocks__/@elastic/charts.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/__mocks__/@elastic/charts.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/__snapshots__/area_decorator.test.js.snap b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/__snapshots__/area_decorator.test.js.snap
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/__snapshots__/area_decorator.test.js.snap
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/__snapshots__/area_decorator.test.js.snap
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/__snapshots__/bar_decorator.test.js.snap b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/__snapshots__/bar_decorator.test.js.snap
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/__snapshots__/bar_decorator.test.js.snap
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/__snapshots__/bar_decorator.test.js.snap
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/area_decorator.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/area_decorator.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/area_decorator.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/area_decorator.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/area_decorator.test.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/area_decorator.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/area_decorator.test.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/area_decorator.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/bar_decorator.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/bar_decorator.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/bar_decorator.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/bar_decorator.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/bar_decorator.test.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/bar_decorator.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/bar_decorator.test.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/bar_decorator.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/index.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js
similarity index 99%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/index.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js
index 3ce3aae2649e1..b1c3c7ac6b67a 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/index.js
+++ b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js
@@ -33,7 +33,7 @@ import {
import { EuiIcon } from '@elastic/eui';
import { getTimezone } from '../../../lib/get_timezone';
import { eventBus, ACTIVE_CURSOR } from '../../lib/active_cursor';
-import { getUISettings } from '../../../services';
+import { getUISettings } from '../../../../services';
import { GRID_LINE_CONFIG, ICON_TYPES_MAP, STACKED_OPTIONS } from '../../constants';
import { AreaSeriesDecorator } from './decorators/area_decorator';
import { BarSeriesDecorator } from './decorators/bar_decorator';
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/model/__snapshots__/charts.test.js.snap b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/model/__snapshots__/charts.test.js.snap
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/model/__snapshots__/charts.test.js.snap
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/model/__snapshots__/charts.test.js.snap
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/model/charts.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/model/charts.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/model/charts.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/model/charts.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/model/charts.test.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/model/charts.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/model/charts.test.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/model/charts.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/__snapshots__/series_styles.test.js.snap b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/__snapshots__/series_styles.test.js.snap
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/__snapshots__/series_styles.test.js.snap
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/__snapshots__/series_styles.test.js.snap
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/series_styles.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/series_styles.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/series_styles.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/series_styles.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/series_styles.test.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/series_styles.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/series_styles.test.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/series_styles.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/stack_format.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/stack_format.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/stack_format.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/stack_format.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/stack_format.test.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/stack_format.test.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/stack_format.test.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/stack_format.test.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/theme.test.ts b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/theme.test.ts
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/theme.test.ts
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/theme.test.ts
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/theme.ts b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/theme.ts
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/theme.ts
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/utils/theme.ts
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/top_n.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/top_n.js
similarity index 100%
rename from src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/top_n.js
rename to src/plugins/vis_type_timeseries/public/application/visualizations/views/top_n.js
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/index.ts b/src/plugins/vis_type_timeseries/public/index.ts
similarity index 93%
rename from src/legacy/core_plugins/vis_type_timeseries/public/index.ts
rename to src/plugins/vis_type_timeseries/public/index.ts
index 16b099ba16ae9..fbf4a81b6ad1b 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/index.ts
+++ b/src/plugins/vis_type_timeseries/public/index.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import { PluginInitializerContext } from '../../../../core/public';
+import { PluginInitializerContext } from '../../../core/public';
import { MetricsPlugin as Plugin } from './plugin';
export function plugin(initializerContext: PluginInitializerContext) {
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/metrics_fn.ts b/src/plugins/vis_type_timeseries/public/metrics_fn.ts
similarity index 92%
rename from src/legacy/core_plugins/vis_type_timeseries/public/metrics_fn.ts
rename to src/plugins/vis_type_timeseries/public/metrics_fn.ts
index 1f9cbecc2a354..008b13cce6565 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/metrics_fn.ts
+++ b/src/plugins/vis_type_timeseries/public/metrics_fn.ts
@@ -19,12 +19,8 @@
import { get } from 'lodash';
import { i18n } from '@kbn/i18n';
-import {
- ExpressionFunctionDefinition,
- KibanaContext,
- Render,
-} from '../../../../plugins/expressions/public';
-import { PersistedState } from '../../../../plugins/visualizations/public';
+import { ExpressionFunctionDefinition, KibanaContext, Render } from '../../expressions/public';
+import { PersistedState } from '../../visualizations/public';
// @ts-ignore
import { metricsRequestHandler } from './request_handler';
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/metrics_type.ts b/src/plugins/vis_type_timeseries/public/metrics_type.ts
similarity index 85%
rename from src/legacy/core_plugins/vis_type_timeseries/public/metrics_type.ts
rename to src/plugins/vis_type_timeseries/public/metrics_type.ts
index 1db35c406eb13..f83881a619a59 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/metrics_type.ts
+++ b/src/plugins/vis_type_timeseries/public/metrics_type.ts
@@ -21,11 +21,10 @@ import { i18n } from '@kbn/i18n';
// @ts-ignore
import { metricsRequestHandler } from './request_handler';
+import { EditorController } from './application';
// @ts-ignore
-import { EditorController } from './editor_controller';
-// @ts-ignore
-import { PANEL_TYPES } from '../../../../plugins/vis_type_timeseries/common/panel_types';
-import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/public';
+import { PANEL_TYPES } from '../common/panel_types';
+import { defaultFeedbackMessage } from '../../kibana_utils/public';
export const metricsVisDefinition = {
name: 'metrics',
@@ -69,12 +68,9 @@ export const metricsVisDefinition = {
show_legend: 1,
show_grid: 1,
},
- component: require('./components/vis_editor').VisEditor,
+ component: require('./application/components/vis_editor').VisEditor,
},
editor: EditorController,
- editorConfig: {
- component: require('./components/vis_editor').VisEditor,
- },
options: {
showQueryBar: false,
showFilterBar: false,
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/plugin.ts b/src/plugins/vis_type_timeseries/public/plugin.ts
similarity index 89%
rename from src/legacy/core_plugins/vis_type_timeseries/public/plugin.ts
rename to src/plugins/vis_type_timeseries/public/plugin.ts
index 0310ecf6cfd87..e6c92c31450e7 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/plugin.ts
+++ b/src/plugins/vis_type_timeseries/public/plugin.ts
@@ -16,9 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
+
+import './application/index.scss';
+
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'kibana/public';
-import { Plugin as ExpressionsPublicPlugin } from '../../../../plugins/expressions/public';
-import { VisualizationsSetup } from '../../../../plugins/visualizations/public';
+import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public';
+import { VisualizationsSetup } from '../../visualizations/public';
import { createMetricsFn } from './metrics_fn';
import { metricsVisDefinition } from './metrics_type';
@@ -30,7 +33,7 @@ import {
setCoreStart,
setDataStart,
} from './services';
-import { DataPublicPluginStart } from '../../../../plugins/data/public';
+import { DataPublicPluginStart } from '../../data/public';
/** @internal */
export interface MetricsPluginSetupDependencies {
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/request_handler.js b/src/plugins/vis_type_timeseries/public/request_handler.js
similarity index 95%
rename from src/legacy/core_plugins/vis_type_timeseries/public/request_handler.js
rename to src/plugins/vis_type_timeseries/public/request_handler.js
index 2cac1567a6eb7..bd6c6d9553930 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/request_handler.js
+++ b/src/plugins/vis_type_timeseries/public/request_handler.js
@@ -17,8 +17,7 @@
* under the License.
*/
-import { validateInterval } from './lib/validate_interval';
-import { getTimezone } from './lib/get_timezone';
+import { getTimezone, validateInterval } from './application';
import { getUISettings, getDataStart, getCoreStart } from './services';
export const metricsRequestHandler = async ({
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/services.ts b/src/plugins/vis_type_timeseries/public/services.ts
similarity index 90%
rename from src/legacy/core_plugins/vis_type_timeseries/public/services.ts
rename to src/plugins/vis_type_timeseries/public/services.ts
index 64ee897247b89..d93a376584eac 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/services.ts
+++ b/src/plugins/vis_type_timeseries/public/services.ts
@@ -18,8 +18,8 @@
*/
import { I18nStart, SavedObjectsStart, IUiSettingsClient, CoreStart } from 'src/core/public';
-import { createGetterSetter } from '../../../../plugins/kibana_utils/public';
-import { DataPublicPluginStart } from '../../../../plugins/data/public';
+import { createGetterSetter } from '../../kibana_utils/public';
+import { DataPublicPluginStart } from '../../data/public';
export const [getUISettings, setUISettings] = createGetterSetter('UISettings');
diff --git a/src/plugins/vis_type_xy/kibana.json b/src/plugins/vis_type_xy/kibana.json
new file mode 100644
index 0000000000000..ca02da45e9112
--- /dev/null
+++ b/src/plugins/vis_type_xy/kibana.json
@@ -0,0 +1,7 @@
+{
+ "id": "visTypeXy",
+ "version": "kibana",
+ "server": true,
+ "ui": true,
+ "requiredPlugins": ["charts", "expressions", "visualizations"]
+}
diff --git a/src/legacy/core_plugins/vis_type_xy/public/index.ts b/src/plugins/vis_type_xy/public/index.ts
similarity index 89%
rename from src/legacy/core_plugins/vis_type_xy/public/index.ts
rename to src/plugins/vis_type_xy/public/index.ts
index 218dc8aa8a683..9af75ce9059e9 100644
--- a/src/legacy/core_plugins/vis_type_xy/public/index.ts
+++ b/src/plugins/vis_type_xy/public/index.ts
@@ -17,9 +17,11 @@
* under the License.
*/
-import { PluginInitializerContext } from '../../../../core/public';
+import { PluginInitializerContext } from '../../../core/public';
import { VisTypeXyPlugin as Plugin } from './plugin';
+export { VisTypeXyPluginSetup } from './plugin';
+
export function plugin(initializerContext: PluginInitializerContext) {
return new Plugin(initializerContext);
}
diff --git a/src/legacy/core_plugins/vis_type_xy/public/plugin.ts b/src/plugins/vis_type_xy/public/plugin.ts
similarity index 85%
rename from src/legacy/core_plugins/vis_type_xy/public/plugin.ts
rename to src/plugins/vis_type_xy/public/plugin.ts
index ab01b6b3153fb..667018c1e6e30 100644
--- a/src/legacy/core_plugins/vis_type_xy/public/plugin.ts
+++ b/src/plugins/vis_type_xy/public/plugin.ts
@@ -25,18 +25,18 @@ import {
PluginInitializerContext,
} from 'kibana/public';
-import { Plugin as ExpressionsPublicPlugin } from '../../../../plugins/expressions/public';
-import {
- VisualizationsSetup,
- VisualizationsStart,
-} from '../../../../plugins/visualizations/public';
-import { ChartsPluginSetup } from '../../../../plugins/charts/public';
+import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public';
+import { VisualizationsSetup, VisualizationsStart } from '../../visualizations/public';
+import { ChartsPluginSetup } from '../../charts/public';
export interface VisTypeXyDependencies {
uiSettings: IUiSettingsClient;
charts: ChartsPluginSetup;
}
+// eslint-disable-next-line @typescript-eslint/no-empty-interface
+export interface VisTypeXyPluginSetup {}
+
/** @internal */
export interface VisTypeXyPluginSetupDependencies {
expressions: ReturnType;
@@ -53,7 +53,7 @@ export interface VisTypeXyPluginStartDependencies {
type VisTypeXyCoreSetup = CoreSetup;
/** @internal */
-export class VisTypeXyPlugin implements Plugin {
+export class VisTypeXyPlugin implements Plugin {
constructor(public initializerContext: PluginInitializerContext) {}
public async setup(
@@ -77,6 +77,8 @@ export class VisTypeXyPlugin implements Plugin {
visTypeDefinitions.forEach((vis: any) =>
visualizations.createBaseVisualization(vis(visualizationDependencies))
);
+
+ return {};
}
public start(core: CoreStart, deps: VisTypeXyPluginStartDependencies) {
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/legacy.ts b/src/plugins/vis_type_xy/server/index.ts
similarity index 59%
rename from src/legacy/core_plugins/vis_type_timeseries/public/legacy.ts
rename to src/plugins/vis_type_xy/server/index.ts
index 42f116701be51..afc879dc9c845 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/legacy.ts
+++ b/src/plugins/vis_type_xy/server/index.ts
@@ -17,17 +17,13 @@
* under the License.
*/
-import { PluginInitializerContext } from 'kibana/public';
-import { npSetup, npStart } from 'ui/new_platform';
-import { MetricsPluginSetupDependencies } from './plugin';
-import { plugin } from '.';
+import { schema } from '@kbn/config-schema';
-const plugins: Readonly = {
- expressions: npSetup.plugins.expressions,
- visualizations: npSetup.plugins.visualizations,
+export const config = {
+ schema: schema.object({ enabled: schema.boolean({ defaultValue: false }) }),
};
-const pluginInstance = plugin({} as PluginInitializerContext);
-
-export const setup = pluginInstance.setup(npSetup.core, plugins);
-export const start = pluginInstance.start(npStart.core, npStart.plugins);
+export const plugin = () => ({
+ setup() {},
+ start() {},
+});
diff --git a/test/examples/embeddables/adding_children.ts b/test/examples/embeddables/adding_children.ts
index 110b8ce573332..5fe88b5dd33f0 100644
--- a/test/examples/embeddables/adding_children.ts
+++ b/test/examples/embeddables/adding_children.ts
@@ -23,6 +23,7 @@ import { PluginFunctionalProviderContext } from 'test/plugin_functional/services
// eslint-disable-next-line import/no-default-export
export default function({ getService }: PluginFunctionalProviderContext) {
const testSubjects = getService('testSubjects');
+ const flyout = getService('flyout');
describe('creating and adding children', () => {
before(async () => {
@@ -39,5 +40,15 @@ export default function({ getService }: PluginFunctionalProviderContext) {
const tasks = await testSubjects.getVisibleTextAll('todoEmbeddableTask');
expect(tasks).to.eql(['Goes out on Wednesdays!', 'new task']);
});
+
+ it('Can add a child backed off a saved object', async () => {
+ await testSubjects.click('embeddablePanelToggleMenuIcon');
+ await testSubjects.click('embeddablePanelAction-ACTION_ADD_PANEL');
+ await testSubjects.click('savedObjectTitleGarbage');
+ await testSubjects.moveMouseTo('euiFlyoutCloseButton');
+ await flyout.ensureClosed('dashboardAddPanel');
+ const tasks = await testSubjects.getVisibleTextAll('todoEmbeddableTask');
+ expect(tasks).to.eql(['Goes out on Wednesdays!', 'new task', 'Take the garbage out']);
+ });
});
}
diff --git a/test/functional/apps/discover/_saved_queries.js b/test/functional/apps/discover/_saved_queries.js
index 3cdaccf32cdc3..76f3a3aea365f 100644
--- a/test/functional/apps/discover/_saved_queries.js
+++ b/test/functional/apps/discover/_saved_queries.js
@@ -147,6 +147,25 @@ export default function({ getService, getPageObjects }) {
await savedQueryManagementComponent.clearCurrentlyLoadedQuery();
expect(await queryBar.getQueryString()).to.eql('');
});
+
+ // https://github.com/elastic/kibana/issues/63505
+ it('allows clearing if non default language was remembered in localstorage', async () => {
+ await queryBar.switchQueryLanguage('lucene');
+ await PageObjects.common.navigateToApp('discover'); // makes sure discovered is reloaded without any state in url
+ await queryBar.expectQueryLanguageOrFail('lucene'); // make sure lucene is remembered after refresh (comes from localstorage)
+ await savedQueryManagementComponent.loadSavedQuery('OkResponse');
+ await queryBar.expectQueryLanguageOrFail('kql');
+ await savedQueryManagementComponent.clearCurrentlyLoadedQuery();
+ await queryBar.expectQueryLanguageOrFail('lucene');
+ });
+
+ // fails: bug in discover https://github.com/elastic/kibana/issues/63561
+ // unskip this test when bug is fixed
+ it.skip('changing language removes saved query', async () => {
+ await savedQueryManagementComponent.loadSavedQuery('OkResponse');
+ await queryBar.switchQueryLanguage('lucene');
+ expect(await queryBar.getQueryString()).to.eql('');
+ });
});
});
}
diff --git a/test/functional/services/query_bar.ts b/test/functional/services/query_bar.ts
index ace8b97155c09..7c7fd2d81f170 100644
--- a/test/functional/services/query_bar.ts
+++ b/test/functional/services/query_bar.ts
@@ -17,6 +17,7 @@
* under the License.
*/
+import expect from '@kbn/expect';
import { FtrProviderContext } from '../ftr_provider_context';
export function QueryBarProvider({ getService, getPageObjects }: FtrProviderContext) {
@@ -25,6 +26,7 @@ export function QueryBarProvider({ getService, getPageObjects }: FtrProviderCont
const log = getService('log');
const PageObjects = getPageObjects(['header', 'common']);
const find = getService('find');
+ const browser = getService('browser');
class QueryBar {
async getQueryString(): Promise {
@@ -62,6 +64,24 @@ export function QueryBarProvider({ getService, getPageObjects }: FtrProviderCont
public async clickQuerySubmitButton(): Promise {
await testSubjects.click('querySubmitButton');
}
+
+ public async switchQueryLanguage(lang: 'kql' | 'lucene'): Promise {
+ await testSubjects.click('switchQueryLanguageButton');
+ const kqlToggle = await testSubjects.find('languageToggle');
+ const currentLang =
+ (await kqlToggle.getAttribute('aria-checked')) === 'true' ? 'kql' : 'lucene';
+ if (lang !== currentLang) {
+ await kqlToggle.click();
+ }
+
+ await browser.pressKeys(browser.keys.ESCAPE); // close popover
+ await this.expectQueryLanguageOrFail(lang); // make sure lang is switched
+ }
+
+ public async expectQueryLanguageOrFail(lang: 'kql' | 'lucene'): Promise {
+ const queryLanguageButton = await testSubjects.find('switchQueryLanguageButton');
+ expect((await queryLanguageButton.getVisibleText()).toLowerCase()).to.eql(lang);
+ }
}
return new QueryBar();
diff --git a/test/plugin_functional/plugins/kbn_sample_panel_action/public/sample_panel_link.ts b/test/plugin_functional/plugins/kbn_sample_panel_action/public/sample_panel_link.ts
index b0f1219a815a3..faa774b8485b1 100644
--- a/test/plugin_functional/plugins/kbn_sample_panel_action/public/sample_panel_link.ts
+++ b/test/plugin_functional/plugins/kbn_sample_panel_action/public/sample_panel_link.ts
@@ -26,6 +26,8 @@ export const createSamplePanelLink = (): Action =>
createAction({
type: SAMPLE_PANEL_LINK,
getDisplayName: () => 'Sample panel Link',
- execute: async () => {},
- getHref: () => 'https://example.com/kibana/test',
+ execute: async () => {
+ window.location.href = 'https://example.com/kibana/test';
+ },
+ getHref: async () => 'https://example.com/kibana/test',
});
diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/dashboard_input.ts b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/dashboard_input.ts
index bb8951680be35..37ef8cad948cb 100644
--- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/dashboard_input.ts
+++ b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/dashboard_input.ts
@@ -47,7 +47,7 @@ export const dashboardInput: DashboardContainerInput = {
explicitInput: {
id: '2',
firstName: 'Sue',
- } as any,
+ },
},
'822cd0f0-ce7c-419d-aeaa-1171cf452745': {
gridData: {
@@ -60,8 +60,8 @@ export const dashboardInput: DashboardContainerInput = {
type: 'visualization',
explicitInput: {
id: '822cd0f0-ce7c-419d-aeaa-1171cf452745',
+ savedObjectId: '3fe22200-3dcb-11e8-8660-4d65aa086b3c',
},
- savedObjectId: '3fe22200-3dcb-11e8-8660-4d65aa086b3c',
},
'66f0a265-7b06-4974-accd-d05f74f7aa82': {
gridData: {
@@ -74,8 +74,8 @@ export const dashboardInput: DashboardContainerInput = {
type: 'visualization',
explicitInput: {
id: '66f0a265-7b06-4974-accd-d05f74f7aa82',
+ savedObjectId: '4c0f47e0-3dcd-11e8-8660-4d65aa086b3c',
},
- savedObjectId: '4c0f47e0-3dcd-11e8-8660-4d65aa086b3c',
},
'b2861741-40b9-4dc8-b82b-080c6e29a551': {
gridData: {
@@ -88,8 +88,8 @@ export const dashboardInput: DashboardContainerInput = {
type: 'search',
explicitInput: {
id: 'b2861741-40b9-4dc8-b82b-080c6e29a551',
+ savedObjectId: 'be5accf0-3dca-11e8-8660-4d65aa086b3c',
},
- savedObjectId: 'be5accf0-3dca-11e8-8660-4d65aa086b3c',
},
},
isFullScreenMode: false,
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Contents.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Contents.tsx
index 52263878ca915..491ebdc5aad15 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Contents.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Contents.tsx
@@ -27,6 +27,30 @@ interface ContentsProps {
selectedNodeServiceName: string;
}
+// IE 11 does not handle flex properties as expected. With browser detection,
+// we can use regular div elements to render contents that are almost identical.
+//
+// This method of detecting IE is from a Stack Overflow answer:
+// https://stackoverflow.com/a/21825207
+//
+// @ts-ignore `documentMode` is not recognized as a valid property of `document`.
+const isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
+
+const FlexColumnGroup = (props: {
+ children: React.ReactNode;
+ style: React.CSSProperties;
+ direction: 'column';
+ gutterSize: 's';
+}) => {
+ if (isIE11) {
+ const { direction, gutterSize, ...rest } = props;
+ return
;
+ }
+ return ;
+};
+const FlexColumnItem = (props: { children: React.ReactNode }) =>
+ isIE11 ?
: ;
+
export function Contents({
selectedNodeData,
isService,
@@ -36,18 +60,18 @@ export function Contents({
}: ContentsProps) {
const frameworkName = selectedNodeData[SERVICE_FRAMEWORK_NAME];
return (
-
-
+
{label}
-
-
+
+
{isService ? (
)}
-
+
{isService && (
)}
-
+
);
}
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/cytoscapeOptions.ts b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/cytoscapeOptions.ts
index 92f66f698f044..bf0e052b951ae 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/cytoscapeOptions.ts
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/cytoscapeOptions.ts
@@ -12,6 +12,17 @@ import {
} from '../../../../../../../plugins/apm/common/elasticsearch_fieldnames';
import { defaultIcon, iconForNode } from './icons';
+// IE 11 does not properly load some SVGs or draw certain shapes. This causes
+// a runtime error and the map fails work at all. We would prefer to do some
+// kind of feature detection rather than browser detection, but some of these
+// limitations are not well documented for older browsers.
+//
+// This method of detecting IE is from a Stack Overflow answer:
+// https://stackoverflow.com/a/21825207
+//
+// @ts-ignore `documentMode` is not recognized as a valid property of `document`.
+const isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
+
export const animationOptions: cytoscape.AnimationOptions = {
duration: parseInt(theme.euiAnimSpeedNormal, 10),
// @ts-ignore The cubic-bezier options here are not recognized by the cytoscape types
@@ -37,8 +48,9 @@ const style: cytoscape.Stylesheet[] = [
// used here.
//
// @ts-ignore
- 'background-image': (el: cytoscape.NodeSingular) =>
- iconForNode(el) ?? defaultIcon,
+ 'background-image': isIE11
+ ? undefined
+ : (el: cytoscape.NodeSingular) => iconForNode(el) ?? defaultIcon,
'background-height': (el: cytoscape.NodeSingular) =>
isService(el) ? '60%' : '40%',
'background-width': (el: cytoscape.NodeSingular) =>
@@ -65,7 +77,7 @@ const style: cytoscape.Stylesheet[] = [
'min-zoomed-font-size': parseInt(theme.euiSizeL, 10),
'overlay-opacity': 0,
shape: (el: cytoscape.NodeSingular) =>
- isService(el) ? 'ellipse' : 'diamond',
+ isService(el) ? (isIE11 ? 'rectangle' : 'ellipse') : 'diamond',
'text-background-color': theme.euiColorLightestShade,
'text-background-opacity': 0,
'text-background-padding': theme.paddingSizes.xs,
@@ -87,12 +99,12 @@ const style: cytoscape.Stylesheet[] = [
'line-color': lineColor,
'overlay-opacity': 0,
'target-arrow-color': lineColor,
- 'target-arrow-shape': 'triangle',
+ 'target-arrow-shape': isIE11 ? 'none' : 'triangle',
// The DefinitelyTyped definitions don't specify this property since it's
// fairly new.
//
// @ts-ignore
- 'target-distance-from-node': theme.paddingSizes.xs,
+ 'target-distance-from-node': isIE11 ? undefined : theme.paddingSizes.xs,
width: 1,
'source-arrow-shape': 'none',
'z-index': zIndexEdge
@@ -101,12 +113,16 @@ const style: cytoscape.Stylesheet[] = [
{
selector: 'edge[bidirectional]',
style: {
- 'source-arrow-shape': 'triangle',
+ 'source-arrow-shape': isIE11 ? 'none' : 'triangle',
'source-arrow-color': lineColor,
- 'target-arrow-shape': 'triangle',
+ 'target-arrow-shape': isIE11 ? 'none' : 'triangle',
// @ts-ignore
- 'source-distance-from-node': parseInt(theme.paddingSizes.xs, 10),
- 'target-distance-from-node': parseInt(theme.paddingSizes.xs, 10)
+ 'source-distance-from-node': isIE11
+ ? undefined
+ : parseInt(theme.paddingSizes.xs, 10),
+ 'target-distance-from-node': isIE11
+ ? undefined
+ : parseInt(theme.paddingSizes.xs, 10)
}
},
// @ts-ignore DefinitelyTyped says visibility is "none" but it's
diff --git a/x-pack/legacy/plugins/canvas/public/application.tsx b/x-pack/legacy/plugins/canvas/public/application.tsx
index 79b3918fef99b..f75b3b427c41b 100644
--- a/x-pack/legacy/plugins/canvas/public/application.tsx
+++ b/x-pack/legacy/plugins/canvas/public/application.tsx
@@ -104,8 +104,9 @@ export const initializeCanvas = async (
href: getDocumentationLinks().canvas,
},
],
- content: domNode => () => {
+ content: domNode => {
ReactDOM.render( , domNode);
+ return () => ReactDOM.unmountComponentAtNode(domNode);
},
});
diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/style_settings/_style_settings.scss b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/style_settings/_style_settings.scss
index 249b6dfca5c76..f9ad412f7e48a 100644
--- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/style_settings/_style_settings.scss
+++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/style_settings/_style_settings.scss
@@ -1,3 +1,3 @@
.mapStyleSettings__fixedBox {
- width: $euiSize * 7.5;
-}
\ No newline at end of file
+ width: $euiSize * 7.5;
+}
diff --git a/x-pack/legacy/plugins/reporting/__snapshots__/index.test.ts.snap b/x-pack/legacy/plugins/reporting/__snapshots__/index.test.ts.snap
deleted file mode 100644
index 3ae3079da136b..0000000000000
--- a/x-pack/legacy/plugins/reporting/__snapshots__/index.test.ts.snap
+++ /dev/null
@@ -1,387 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`config schema with context {"dev":false,"dist":false} produces correct config 1`] = `
-Object {
- "capture": Object {
- "browser": Object {
- "autoDownload": true,
- "chromium": Object {
- "disableSandbox": "",
- "maxScreenshotDimension": 1950,
- "proxy": Object {
- "enabled": false,
- },
- },
- "type": "chromium",
- },
- "concurrency": 4,
- "loadDelay": 3000,
- "maxAttempts": 1,
- "networkPolicy": Object {
- "enabled": true,
- "rules": Array [
- Object {
- "allow": true,
- "protocol": "http:",
- },
- Object {
- "allow": true,
- "protocol": "https:",
- },
- Object {
- "allow": true,
- "protocol": "ws:",
- },
- Object {
- "allow": true,
- "protocol": "wss:",
- },
- Object {
- "allow": true,
- "protocol": "data:",
- },
- Object {
- "allow": false,
- },
- ],
- },
- "settleTime": 1000,
- "timeout": 20000,
- "timeouts": Object {
- "openUrl": 30000,
- "renderComplete": 30000,
- "waitForElements": 30000,
- },
- "viewport": Object {
- "height": 1200,
- "width": 1950,
- },
- "zoom": 2,
- },
- "csv": Object {
- "checkForFormulas": true,
- "enablePanelActionDownload": true,
- "maxSizeBytes": 10485760,
- "scroll": Object {
- "duration": "30s",
- "size": 500,
- },
- "useByteOrderMarkEncoding": false,
- },
- "enabled": true,
- "encryptionKey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- "index": ".reporting",
- "kibanaServer": Object {},
- "poll": Object {
- "jobCompletionNotifier": Object {
- "interval": 10000,
- "intervalErrorMultiplier": 5,
- },
- "jobsRefresh": Object {
- "interval": 5000,
- "intervalErrorMultiplier": 5,
- },
- },
- "queue": Object {
- "indexInterval": "week",
- "pollEnabled": true,
- "pollInterval": 3000,
- "pollIntervalErrorMultiplier": 10,
- "timeout": 120000,
- },
- "roles": Object {
- "allow": Array [
- "reporting_user",
- ],
- },
-}
-`;
-
-exports[`config schema with context {"dev":false,"dist":true} produces correct config 1`] = `
-Object {
- "capture": Object {
- "browser": Object {
- "autoDownload": false,
- "chromium": Object {
- "disableSandbox": "",
- "maxScreenshotDimension": 1950,
- "proxy": Object {
- "enabled": false,
- },
- },
- "type": "chromium",
- },
- "concurrency": 4,
- "loadDelay": 3000,
- "maxAttempts": 3,
- "networkPolicy": Object {
- "enabled": true,
- "rules": Array [
- Object {
- "allow": true,
- "protocol": "http:",
- },
- Object {
- "allow": true,
- "protocol": "https:",
- },
- Object {
- "allow": true,
- "protocol": "ws:",
- },
- Object {
- "allow": true,
- "protocol": "wss:",
- },
- Object {
- "allow": true,
- "protocol": "data:",
- },
- Object {
- "allow": false,
- },
- ],
- },
- "settleTime": 1000,
- "timeout": 20000,
- "timeouts": Object {
- "openUrl": 30000,
- "renderComplete": 30000,
- "waitForElements": 30000,
- },
- "viewport": Object {
- "height": 1200,
- "width": 1950,
- },
- "zoom": 2,
- },
- "csv": Object {
- "checkForFormulas": true,
- "enablePanelActionDownload": true,
- "maxSizeBytes": 10485760,
- "scroll": Object {
- "duration": "30s",
- "size": 500,
- },
- "useByteOrderMarkEncoding": false,
- },
- "enabled": true,
- "index": ".reporting",
- "kibanaServer": Object {},
- "poll": Object {
- "jobCompletionNotifier": Object {
- "interval": 10000,
- "intervalErrorMultiplier": 5,
- },
- "jobsRefresh": Object {
- "interval": 5000,
- "intervalErrorMultiplier": 5,
- },
- },
- "queue": Object {
- "indexInterval": "week",
- "pollEnabled": true,
- "pollInterval": 3000,
- "pollIntervalErrorMultiplier": 10,
- "timeout": 120000,
- },
- "roles": Object {
- "allow": Array [
- "reporting_user",
- ],
- },
-}
-`;
-
-exports[`config schema with context {"dev":true,"dist":false} produces correct config 1`] = `
-Object {
- "capture": Object {
- "browser": Object {
- "autoDownload": true,
- "chromium": Object {
- "disableSandbox": "",
- "maxScreenshotDimension": 1950,
- "proxy": Object {
- "enabled": false,
- },
- },
- "type": "chromium",
- },
- "concurrency": 4,
- "loadDelay": 3000,
- "maxAttempts": 1,
- "networkPolicy": Object {
- "enabled": true,
- "rules": Array [
- Object {
- "allow": true,
- "protocol": "http:",
- },
- Object {
- "allow": true,
- "protocol": "https:",
- },
- Object {
- "allow": true,
- "protocol": "ws:",
- },
- Object {
- "allow": true,
- "protocol": "wss:",
- },
- Object {
- "allow": true,
- "protocol": "data:",
- },
- Object {
- "allow": false,
- },
- ],
- },
- "settleTime": 1000,
- "timeout": 20000,
- "timeouts": Object {
- "openUrl": 30000,
- "renderComplete": 30000,
- "waitForElements": 30000,
- },
- "viewport": Object {
- "height": 1200,
- "width": 1950,
- },
- "zoom": 2,
- },
- "csv": Object {
- "checkForFormulas": true,
- "enablePanelActionDownload": true,
- "maxSizeBytes": 10485760,
- "scroll": Object {
- "duration": "30s",
- "size": 500,
- },
- "useByteOrderMarkEncoding": false,
- },
- "enabled": true,
- "encryptionKey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- "index": ".reporting",
- "kibanaServer": Object {},
- "poll": Object {
- "jobCompletionNotifier": Object {
- "interval": 10000,
- "intervalErrorMultiplier": 5,
- },
- "jobsRefresh": Object {
- "interval": 5000,
- "intervalErrorMultiplier": 5,
- },
- },
- "queue": Object {
- "indexInterval": "week",
- "pollEnabled": true,
- "pollInterval": 3000,
- "pollIntervalErrorMultiplier": 10,
- "timeout": 120000,
- },
- "roles": Object {
- "allow": Array [
- "reporting_user",
- ],
- },
-}
-`;
-
-exports[`config schema with context {"dev":true,"dist":true} produces correct config 1`] = `
-Object {
- "capture": Object {
- "browser": Object {
- "autoDownload": false,
- "chromium": Object {
- "disableSandbox": "",
- "maxScreenshotDimension": 1950,
- "proxy": Object {
- "enabled": false,
- },
- },
- "type": "chromium",
- },
- "concurrency": 4,
- "loadDelay": 3000,
- "maxAttempts": 3,
- "networkPolicy": Object {
- "enabled": true,
- "rules": Array [
- Object {
- "allow": true,
- "protocol": "http:",
- },
- Object {
- "allow": true,
- "protocol": "https:",
- },
- Object {
- "allow": true,
- "protocol": "ws:",
- },
- Object {
- "allow": true,
- "protocol": "wss:",
- },
- Object {
- "allow": true,
- "protocol": "data:",
- },
- Object {
- "allow": false,
- },
- ],
- },
- "settleTime": 1000,
- "timeout": 20000,
- "timeouts": Object {
- "openUrl": 30000,
- "renderComplete": 30000,
- "waitForElements": 30000,
- },
- "viewport": Object {
- "height": 1200,
- "width": 1950,
- },
- "zoom": 2,
- },
- "csv": Object {
- "checkForFormulas": true,
- "enablePanelActionDownload": true,
- "maxSizeBytes": 10485760,
- "scroll": Object {
- "duration": "30s",
- "size": 500,
- },
- "useByteOrderMarkEncoding": false,
- },
- "enabled": true,
- "index": ".reporting",
- "kibanaServer": Object {},
- "poll": Object {
- "jobCompletionNotifier": Object {
- "interval": 10000,
- "intervalErrorMultiplier": 5,
- },
- "jobsRefresh": Object {
- "interval": 5000,
- "intervalErrorMultiplier": 5,
- },
- },
- "queue": Object {
- "indexInterval": "week",
- "pollEnabled": true,
- "pollInterval": 3000,
- "pollIntervalErrorMultiplier": 10,
- "timeout": 120000,
- },
- "roles": Object {
- "allow": Array [
- "reporting_user",
- ],
- },
-}
-`;
diff --git a/x-pack/legacy/plugins/reporting/config.ts b/x-pack/legacy/plugins/reporting/config.ts
deleted file mode 100644
index 5eceb84c83e43..0000000000000
--- a/x-pack/legacy/plugins/reporting/config.ts
+++ /dev/null
@@ -1,183 +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 { BROWSER_TYPE } from './common/constants';
-// @ts-ignore untyped module
-import { config as appConfig } from './server/config/config';
-import { getDefaultChromiumSandboxDisabled } from './server/browsers';
-
-export async function config(Joi: any) {
- return Joi.object({
- enabled: Joi.boolean().default(true),
- kibanaServer: Joi.object({
- protocol: Joi.string().valid(['http', 'https']),
- hostname: Joi.string().invalid('0'),
- port: Joi.number().integer(),
- }).default(),
- queue: Joi.object({
- indexInterval: Joi.string().default('week'),
- pollEnabled: Joi.boolean().default(true),
- pollInterval: Joi.number()
- .integer()
- .default(3000),
- pollIntervalErrorMultiplier: Joi.number()
- .integer()
- .default(10),
- timeout: Joi.number()
- .integer()
- .default(120000),
- }).default(),
- capture: Joi.object({
- timeouts: Joi.object({
- openUrl: Joi.number()
- .integer()
- .default(30000),
- waitForElements: Joi.number()
- .integer()
- .default(30000),
- renderComplete: Joi.number()
- .integer()
- .default(30000),
- }).default(),
- networkPolicy: Joi.object({
- enabled: Joi.boolean().default(true),
- rules: Joi.array()
- .items(
- Joi.object({
- allow: Joi.boolean().required(),
- protocol: Joi.string(),
- host: Joi.string(),
- })
- )
- .default([
- { allow: true, protocol: 'http:' },
- { allow: true, protocol: 'https:' },
- { allow: true, protocol: 'ws:' },
- { allow: true, protocol: 'wss:' },
- { allow: true, protocol: 'data:' },
- { allow: false }, // Default action is to deny!
- ]),
- }).default(),
- zoom: Joi.number()
- .integer()
- .default(2),
- viewport: Joi.object({
- width: Joi.number()
- .integer()
- .default(1950),
- height: Joi.number()
- .integer()
- .default(1200),
- }).default(),
- timeout: Joi.number()
- .integer()
- .default(20000), // deprecated
- loadDelay: Joi.number()
- .integer()
- .default(3000),
- settleTime: Joi.number()
- .integer()
- .default(1000), // deprecated
- concurrency: Joi.number()
- .integer()
- .default(appConfig.concurrency), // deprecated
- browser: Joi.object({
- type: Joi.any()
- .valid(BROWSER_TYPE)
- .default(BROWSER_TYPE),
- autoDownload: Joi.boolean().when('$dist', {
- is: true,
- then: Joi.default(false),
- otherwise: Joi.default(true),
- }),
- chromium: Joi.object({
- inspect: Joi.boolean()
- .when('$dev', {
- is: false,
- then: Joi.valid(false),
- else: Joi.default(false),
- })
- .default(),
- disableSandbox: Joi.boolean().default(await getDefaultChromiumSandboxDisabled()),
- proxy: Joi.object({
- enabled: Joi.boolean().default(false),
- server: Joi.string()
- .uri({ scheme: ['http', 'https'] })
- .when('enabled', {
- is: Joi.valid(false),
- then: Joi.valid(null),
- else: Joi.required(),
- }),
- bypass: Joi.array()
- .items(Joi.string().regex(/^[^\s]+$/))
- .when('enabled', {
- is: Joi.valid(false),
- then: Joi.valid(null),
- else: Joi.default([]),
- }),
- }).default(),
- maxScreenshotDimension: Joi.number()
- .integer()
- .default(1950),
- }).default(),
- }).default(),
- maxAttempts: Joi.number()
- .integer()
- .greater(0)
- .when('$dist', {
- is: true,
- then: Joi.default(3),
- otherwise: Joi.default(1),
- })
- .default(),
- }).default(),
- csv: Joi.object({
- useByteOrderMarkEncoding: Joi.boolean().default(false),
- checkForFormulas: Joi.boolean().default(true),
- enablePanelActionDownload: Joi.boolean().default(true),
- maxSizeBytes: Joi.number()
- .integer()
- .default(1024 * 1024 * 10), // bytes in a kB * kB in a mB * 10
- scroll: Joi.object({
- duration: Joi.string()
- .regex(/^[0-9]+(d|h|m|s|ms|micros|nanos)$/, { name: 'DurationString' })
- .default('30s'),
- size: Joi.number()
- .integer()
- .default(500),
- }).default(),
- }).default(),
- encryptionKey: Joi.when(Joi.ref('$dist'), {
- is: true,
- then: Joi.string(),
- otherwise: Joi.string().default('a'.repeat(32)),
- }),
- roles: Joi.object({
- allow: Joi.array()
- .items(Joi.string())
- .default(['reporting_user']),
- }).default(),
- index: Joi.string().default('.reporting'),
- poll: Joi.object({
- jobCompletionNotifier: Joi.object({
- interval: Joi.number()
- .integer()
- .default(10000),
- intervalErrorMultiplier: Joi.number()
- .integer()
- .default(5),
- }).default(),
- jobsRefresh: Joi.object({
- interval: Joi.number()
- .integer()
- .default(5000),
- intervalErrorMultiplier: Joi.number()
- .integer()
- .default(5),
- }).default(),
- }).default(),
- }).default();
-}
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/layouts/layout.ts b/x-pack/legacy/plugins/reporting/export_types/common/layouts/layout.ts
index 2c43517dbcaa9..5cd2f3e636a93 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/layouts/layout.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/layouts/layout.ts
@@ -54,7 +54,7 @@ export abstract class Layout {
public abstract getPdfPageSize(pageSizeParams: PageSizeParams): string | Size;
- public abstract getViewport(itemsCount: number): ViewZoomWidthHeight;
+ public abstract getViewport(itemsCount: number): ViewZoomWidthHeight | null;
public abstract getBrowserZoom(): number;
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.test.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.test.ts
index 75ac3dca4ffa0..68d660257a56d 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.test.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.test.ts
@@ -22,6 +22,7 @@ import { LevelLogger } from '../../../../server/lib';
import { createMockBrowserDriverFactory, createMockLayoutInstance } from '../../../../test_helpers';
import { ConditionalHeaders, HeadlessChromiumDriver } from '../../../../types';
import { CaptureConfig } from '../../../../server/types';
+import * as contexts from './constants';
import { screenshotsObservableFactory } from './observable';
import { ElementsPositionAndAttribute } from './types';
@@ -57,10 +58,30 @@ describe('Screenshot Observable Pipeline', () => {
expect(result).toMatchInlineSnapshot(`
Array [
Object {
+ "elementsPositionAndAttributes": Array [
+ Object {
+ "attributes": Object {
+ "description": "Default ",
+ "title": "Default Mock Title",
+ },
+ "position": Object {
+ "boundingClientRect": Object {
+ "height": 600,
+ "left": 0,
+ "top": 0,
+ "width": 800,
+ },
+ "scroll": Object {
+ "x": 0,
+ "y": 0,
+ },
+ },
+ },
+ ],
"error": undefined,
"screenshots": Array [
Object {
- "base64EncodedData": "allyourBase64 of boundingClientRect,scroll",
+ "base64EncodedData": "allyourBase64",
"description": "Default ",
"title": "Default Mock Title",
},
@@ -95,6 +116,26 @@ describe('Screenshot Observable Pipeline', () => {
expect(result).toMatchInlineSnapshot(`
Array [
Object {
+ "elementsPositionAndAttributes": Array [
+ Object {
+ "attributes": Object {
+ "description": "Default ",
+ "title": "Default Mock Title",
+ },
+ "position": Object {
+ "boundingClientRect": Object {
+ "height": 600,
+ "left": 0,
+ "top": 0,
+ "width": 800,
+ },
+ "scroll": Object {
+ "x": 0,
+ "y": 0,
+ },
+ },
+ },
+ ],
"error": undefined,
"screenshots": Array [
Object {
@@ -106,6 +147,26 @@ describe('Screenshot Observable Pipeline', () => {
"timeRange": "Default GetTimeRange Result",
},
Object {
+ "elementsPositionAndAttributes": Array [
+ Object {
+ "attributes": Object {
+ "description": "Default ",
+ "title": "Default Mock Title",
+ },
+ "position": Object {
+ "boundingClientRect": Object {
+ "height": 600,
+ "left": 0,
+ "top": 0,
+ "width": 800,
+ },
+ "scroll": Object {
+ "x": 0,
+ "y": 0,
+ },
+ },
+ },
+ ],
"error": undefined,
"screenshots": Array [
Object {
@@ -150,10 +211,27 @@ describe('Screenshot Observable Pipeline', () => {
await expect(getScreenshot()).resolves.toMatchInlineSnapshot(`
Array [
Object {
+ "elementsPositionAndAttributes": Array [
+ Object {
+ "attributes": Object {},
+ "position": Object {
+ "boundingClientRect": Object {
+ "height": 200,
+ "left": 0,
+ "top": 0,
+ "width": 200,
+ },
+ "scroll": Object {
+ "x": 0,
+ "y": 0,
+ },
+ },
+ },
+ ],
"error": [Error: An error occurred when trying to read the page for visualization panel info. You may need to increase 'xpack.reporting.capture.timeouts.waitForElements'. Error: Mock error!],
"screenshots": Array [
Object {
- "base64EncodedData": "allyourBase64 of boundingClientRect,scroll",
+ "base64EncodedData": "allyourBase64",
"description": undefined,
"title": undefined,
},
@@ -161,10 +239,27 @@ describe('Screenshot Observable Pipeline', () => {
"timeRange": null,
},
Object {
+ "elementsPositionAndAttributes": Array [
+ Object {
+ "attributes": Object {},
+ "position": Object {
+ "boundingClientRect": Object {
+ "height": 200,
+ "left": 0,
+ "top": 0,
+ "width": 200,
+ },
+ "scroll": Object {
+ "x": 0,
+ "y": 0,
+ },
+ },
+ },
+ ],
"error": [Error: An error occurred when trying to read the page for visualization panel info. You may need to increase 'xpack.reporting.capture.timeouts.waitForElements'. Error: Mock error!],
"screenshots": Array [
Object {
- "base64EncodedData": "allyourBase64 of boundingClientRect,scroll",
+ "base64EncodedData": "allyourBase64",
"description": undefined,
"title": undefined,
},
@@ -208,10 +303,27 @@ describe('Screenshot Observable Pipeline', () => {
await expect(getScreenshot()).resolves.toMatchInlineSnapshot(`
Array [
Object {
+ "elementsPositionAndAttributes": Array [
+ Object {
+ "attributes": Object {},
+ "position": Object {
+ "boundingClientRect": Object {
+ "height": 200,
+ "left": 0,
+ "top": 0,
+ "width": 200,
+ },
+ "scroll": Object {
+ "x": 0,
+ "y": 0,
+ },
+ },
+ },
+ ],
"error": "Instant timeout has fired!",
"screenshots": Array [
Object {
- "base64EncodedData": "allyourBase64 of boundingClientRect,scroll",
+ "base64EncodedData": "allyourBase64",
"description": undefined,
"title": undefined,
},
@@ -221,5 +333,69 @@ describe('Screenshot Observable Pipeline', () => {
]
`);
});
+
+ it(`uses defaults for element positions and size when Kibana page is not ready`, async () => {
+ // mocks
+ const mockBrowserEvaluate = jest.fn();
+ mockBrowserEvaluate.mockImplementation(() => {
+ const lastCallIndex = mockBrowserEvaluate.mock.calls.length - 1;
+ const { context: mockCall } = mockBrowserEvaluate.mock.calls[lastCallIndex][1];
+
+ if (mockCall === contexts.CONTEXT_ELEMENTATTRIBUTES) {
+ return Promise.resolve(null);
+ } else {
+ return Promise.resolve();
+ }
+ });
+ mockBrowserDriverFactory = await createMockBrowserDriverFactory(logger, {
+ evaluate: mockBrowserEvaluate,
+ });
+ mockLayout.getViewport = () => null;
+
+ // test
+ const getScreenshots$ = screenshotsObservableFactory(mockConfig, mockBrowserDriverFactory);
+ const getScreenshot = async () => {
+ return await getScreenshots$({
+ logger,
+ urls: ['/welcome/home/start/index.php3?page=./home.php3'],
+ conditionalHeaders: {} as ConditionalHeaders,
+ layout: mockLayout,
+ browserTimezone: 'UTC',
+ }).toPromise();
+ };
+
+ await expect(getScreenshot()).resolves.toMatchInlineSnapshot(`
+ Array [
+ Object {
+ "elementsPositionAndAttributes": Array [
+ Object {
+ "attributes": Object {},
+ "position": Object {
+ "boundingClientRect": Object {
+ "height": 1200,
+ "left": 0,
+ "top": 0,
+ "width": 1800,
+ },
+ "scroll": Object {
+ "x": 0,
+ "y": 0,
+ },
+ },
+ },
+ ],
+ "error": undefined,
+ "screenshots": Array [
+ Object {
+ "base64EncodedData": "allyourBase64",
+ "description": undefined,
+ "title": undefined,
+ },
+ ],
+ "timeRange": undefined,
+ },
+ ]
+ `);
+ });
});
});
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.ts
index 53a11c18abd79..519a3289395b9 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.ts
@@ -18,6 +18,9 @@ import { ScreenSetupData, ScreenshotObservableOpts, ScreenshotResults } from './
import { waitForRenderComplete } from './wait_for_render';
import { waitForVisualizations } from './wait_for_visualizations';
+const DEFAULT_SCREENSHOT_CLIP_HEIGHT = 1200;
+const DEFAULT_SCREENSHOT_CLIP_WIDTH = 1800;
+
export function screenshotsObservableFactory(
captureConfig: CaptureConfig,
browserDriverFactory: HeadlessChromiumDriverFactory
@@ -42,7 +45,7 @@ export function screenshotsObservableFactory(
mergeMap(() => openUrl(captureConfig, driver, url, conditionalHeaders, logger)),
mergeMap(() => getNumberOfItems(captureConfig, driver, layout, logger)),
mergeMap(async itemsCount => {
- const viewport = layout.getViewport(itemsCount);
+ const viewport = layout.getViewport(itemsCount) || getDefaultViewPort();
await Promise.all([
driver.setViewport(viewport, logger),
waitForVisualizations(captureConfig, driver, itemsCount, layout, logger),
@@ -83,7 +86,12 @@ export function screenshotsObservableFactory(
: getDefaultElementPosition(layout.getViewport(1));
const screenshots = await getScreenshots(driver, elements, logger);
const { timeRange, error: setupError } = data;
- return { timeRange, screenshots, error: setupError };
+ return {
+ timeRange,
+ screenshots,
+ error: setupError,
+ elementsPositionAndAttributes: elements,
+ };
}
)
);
@@ -97,17 +105,30 @@ export function screenshotsObservableFactory(
};
}
+/*
+ * If Kibana is showing a non-HTML error message, the viewport might not be
+ * provided by the browser.
+ */
+const getDefaultViewPort = () => ({
+ height: DEFAULT_SCREENSHOT_CLIP_HEIGHT,
+ width: DEFAULT_SCREENSHOT_CLIP_WIDTH,
+ zoom: 1,
+});
/*
* If an error happens setting up the page, we don't know if there actually
* are any visualizations showing. These defaults should help capture the page
* enough for the user to see the error themselves
*/
-const getDefaultElementPosition = ({ height, width }: { height: number; width: number }) => [
- {
+const getDefaultElementPosition = (dimensions: { height?: number; width?: number } | null) => {
+ const height = dimensions?.height || DEFAULT_SCREENSHOT_CLIP_HEIGHT;
+ const width = dimensions?.width || DEFAULT_SCREENSHOT_CLIP_WIDTH;
+
+ const defaultObject = {
position: {
boundingClientRect: { top: 0, left: 0, height, width },
scroll: { x: 0, y: 0 },
},
attributes: {},
- },
-];
+ };
+ return [defaultObject];
+};
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts
index 76613c2d631d6..e113a5d228cd7 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts
@@ -45,4 +45,5 @@ export interface ScreenshotResults {
timeRange: TimeRange | null;
screenshots: Screenshot[];
error?: Error;
+ elementsPositionAndAttributes?: ElementsPositionAndAttribute[]; // NOTE: for testing
}
diff --git a/x-pack/legacy/plugins/reporting/index.test.ts b/x-pack/legacy/plugins/reporting/index.test.ts
deleted file mode 100644
index 8148adab67874..0000000000000
--- a/x-pack/legacy/plugins/reporting/index.test.ts
+++ /dev/null
@@ -1,34 +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 { reporting } from './index';
-import { getConfigSchema } from '../../../test_utils';
-
-// The snapshot records the number of cpus available
-// to make the snapshot deterministic `os.cpus` needs to be mocked
-// but the other members on `os` must remain untouched
-jest.mock('os', () => {
- const os = jest.requireActual('os');
- os.cpus = () => [{}, {}, {}, {}];
- return os;
-});
-
-// eslint-disable-next-line jest/valid-describe
-const describeWithContext = describe.each([
- [{ dev: false, dist: false }],
- [{ dev: true, dist: false }],
- [{ dev: false, dist: true }],
- [{ dev: true, dist: true }],
-]);
-
-describeWithContext('config schema with context %j', context => {
- it('produces correct config', async () => {
- const schema = await getConfigSchema(reporting);
- const value: any = await schema.validate({}, { context });
- value.capture.browser.chromium.disableSandbox = '';
- await expect(value).toMatchSnapshot();
- });
-});
diff --git a/x-pack/legacy/plugins/reporting/index.ts b/x-pack/legacy/plugins/reporting/index.ts
index a5d27d0545da1..fb95e2c2edc24 100644
--- a/x-pack/legacy/plugins/reporting/index.ts
+++ b/x-pack/legacy/plugins/reporting/index.ts
@@ -8,7 +8,6 @@ import { i18n } from '@kbn/i18n';
import { Legacy } from 'kibana';
import { resolve } from 'path';
import { PLUGIN_ID, UI_SETTINGS_CUSTOM_PDF_LOGO } from './common/constants';
-import { config as reportingConfig } from './config';
import { legacyInit } from './server/legacy';
import { ReportingPluginSpecOptions } from './types';
@@ -17,10 +16,8 @@ const kbToBase64Length = (kb: number) => Math.floor((kb * 1024 * 8) / 6);
export const reporting = (kibana: any) => {
return new kibana.Plugin({
id: PLUGIN_ID,
- configPrefix: 'xpack.reporting',
publicDir: resolve(__dirname, 'public'),
require: ['kibana', 'elasticsearch', 'xpack_main'],
- config: reportingConfig,
uiExports: {
uiSettingDefaults: {
@@ -47,14 +44,5 @@ export const reporting = (kibana: any) => {
async init(server: Legacy.Server) {
return legacyInit(server, this);
},
-
- deprecations({ unused }: any) {
- return [
- unused('capture.concurrency'),
- unused('capture.timeout'),
- unused('capture.settleTime'),
- unused('kibanaApp'),
- ];
- },
} as ReportingPluginSpecOptions);
};
diff --git a/x-pack/legacy/plugins/reporting/log_configuration.ts b/x-pack/legacy/plugins/reporting/log_configuration.ts
deleted file mode 100644
index 7aaed2038bd52..0000000000000
--- a/x-pack/legacy/plugins/reporting/log_configuration.ts
+++ /dev/null
@@ -1,35 +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 getosSync, { LinuxOs } from 'getos';
-import { promisify } from 'util';
-import { BROWSER_TYPE } from './common/constants';
-import { CaptureConfig } from './server/types';
-import { Logger } from './types';
-
-const getos = promisify(getosSync);
-
-export async function logConfiguration(captureConfig: CaptureConfig, logger: Logger) {
- const {
- browser: {
- type: browserType,
- chromium: { disableSandbox },
- },
- } = captureConfig;
-
- logger.debug(`Browser type: ${browserType}`);
- if (browserType === BROWSER_TYPE) {
- logger.debug(`Chromium sandbox disabled: ${disableSandbox}`);
- }
-
- const os = await getos();
- const { os: osName, dist, release } = os as LinuxOs;
- if (dist) {
- logger.debug(`Running on os "${osName}", distribution "${dist}", release "${release}"`);
- } else {
- logger.debug(`Running on os "${osName}"`);
- }
-}
diff --git a/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts b/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts
index 4b80e129c04da..dfaa87021c31c 100644
--- a/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts
+++ b/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts
@@ -190,19 +190,14 @@ export class HeadlessChromiumDriver {
}
public async screenshot(elementPosition: ElementPosition): Promise {
- let clip;
- if (elementPosition) {
- const { boundingClientRect, scroll = { x: 0, y: 0 } } = elementPosition;
- clip = {
+ const { boundingClientRect, scroll } = elementPosition;
+ const screenshot = await this.page.screenshot({
+ clip: {
x: boundingClientRect.left + scroll.x,
y: boundingClientRect.top + scroll.y,
height: boundingClientRect.height,
width: boundingClientRect.width,
- };
- }
-
- const screenshot = await this.page.screenshot({
- clip,
+ },
});
return screenshot.toString('base64');
diff --git a/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver_factory/args.ts b/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver_factory/args.ts
index a2f7a1f3ad0da..928f3b8377809 100644
--- a/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver_factory/args.ts
+++ b/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver_factory/args.ts
@@ -10,7 +10,7 @@ type ViewportConfig = CaptureConfig['viewport'];
type BrowserConfig = CaptureConfig['browser']['chromium'];
interface LaunchArgs {
- userDataDir: BrowserConfig['userDataDir'];
+ userDataDir: string;
viewport: ViewportConfig;
disableSandbox: BrowserConfig['disableSandbox'];
proxy: BrowserConfig['proxy'];
diff --git a/x-pack/legacy/plugins/reporting/server/browsers/index.ts b/x-pack/legacy/plugins/reporting/server/browsers/index.ts
index 1e42e2736962e..7f902c84308f6 100644
--- a/x-pack/legacy/plugins/reporting/server/browsers/index.ts
+++ b/x-pack/legacy/plugins/reporting/server/browsers/index.ts
@@ -8,7 +8,6 @@ import * as chromiumDefinition from './chromium';
export { ensureAllBrowsersDownloaded } from './download';
export { createBrowserDriverFactory } from './create_browser_driver_factory';
-export { getDefaultChromiumSandboxDisabled } from './default_chromium_sandbox_disabled';
export { HeadlessChromiumDriver } from './chromium/driver';
export { HeadlessChromiumDriverFactory } from './chromium/driver_factory';
diff --git a/x-pack/legacy/plugins/reporting/server/config/index.ts b/x-pack/legacy/plugins/reporting/server/config/index.ts
index b7b67b57932eb..c6b915be3a94a 100644
--- a/x-pack/legacy/plugins/reporting/server/config/index.ts
+++ b/x-pack/legacy/plugins/reporting/server/config/index.ts
@@ -6,10 +6,9 @@
import { Legacy } from 'kibana';
import { CoreSetup } from 'src/core/server';
-import { i18n } from '@kbn/i18n';
-import crypto from 'crypto';
import { get } from 'lodash';
-import { NetworkPolicy } from '../../types';
+import { ConfigType as ReportingConfigType } from '../../../../../plugins/reporting/server';
+export { ReportingConfigType };
// make config.get() aware of the value type it returns
interface Config {
@@ -56,131 +55,6 @@ export interface ReportingConfig extends Config {
kbnConfig: Config;
}
-type BrowserType = 'chromium';
-
-interface BrowserConfig {
- inspect: boolean;
- userDataDir: string;
- viewport: { width: number; height: number };
- disableSandbox: boolean;
- proxy: {
- enabled: boolean;
- server?: string;
- bypass?: string[];
- };
-}
-
-interface CaptureConfig {
- browser: {
- type: BrowserType;
- autoDownload: boolean;
- chromium: BrowserConfig;
- };
- maxAttempts: number;
- networkPolicy: NetworkPolicy;
- loadDelay: number;
- timeouts: {
- openUrl: number;
- waitForElements: number;
- renderComplete: number;
- };
- viewport: any;
- zoom: any;
-}
-
-interface QueueConfig {
- indexInterval: string;
- pollEnabled: boolean;
- pollInterval: number;
- pollIntervalErrorMultiplier: number;
- timeout: number;
-}
-
-interface ScrollConfig {
- duration: string;
- size: number;
-}
-
-export interface ReportingConfigType {
- capture: CaptureConfig;
- csv: {
- scroll: ScrollConfig;
- enablePanelActionDownload: boolean;
- checkForFormulas: boolean;
- maxSizeBytes: number;
- useByteOrderMarkEncoding: boolean;
- };
- encryptionKey: string;
- kibanaServer: any;
- index: string;
- queue: QueueConfig;
- roles: any;
-}
-
-const addConfigDefaults = (
- server: Legacy.Server,
- core: CoreSetup,
- baseConfig: ReportingConfigType
-) => {
- // encryption key
- let encryptionKey = baseConfig.encryptionKey;
- if (encryptionKey === undefined) {
- server.log(
- ['reporting', 'config', 'warning'],
- i18n.translate('xpack.reporting.selfCheckEncryptionKey.warning', {
- defaultMessage:
- `Generating a random key for {setting}. To prevent pending reports ` +
- `from failing on restart, please set {setting} in kibana.yml`,
- values: {
- setting: 'xpack.reporting.encryptionKey',
- },
- })
- );
- encryptionKey = crypto.randomBytes(16).toString('hex');
- }
-
- const { kibanaServer: reportingServer } = baseConfig;
- const serverInfo = core.http.getServerInfo();
-
- // kibanaServer.hostname, default to server.host, don't allow "0"
- let kibanaServerHostname = reportingServer.hostname ? reportingServer.hostname : serverInfo.host;
- if (kibanaServerHostname === '0') {
- server.log(
- ['reporting', 'config', 'warning'],
- i18n.translate('xpack.reporting.selfCheckHostname.warning', {
- defaultMessage:
- `Found 'server.host: "0"' in settings. This is incompatible with Reporting. ` +
- `To enable Reporting to work, '{setting}: 0.0.0.0' is being automatically to the configuration. ` +
- `You can change to 'server.host: 0.0.0.0' or add '{setting}: 0.0.0.0' in kibana.yml to prevent this message.`,
- values: {
- setting: 'xpack.reporting.kibanaServer.hostname',
- },
- })
- );
- kibanaServerHostname = '0.0.0.0';
- }
-
- // kibanaServer.port, default to server.port
- const kibanaServerPort = reportingServer.port
- ? reportingServer.port
- : serverInfo.port; // prettier-ignore
-
- // kibanaServer.protocol, default to server.protocol
- const kibanaServerProtocol = reportingServer.protocol
- ? reportingServer.protocol
- : serverInfo.protocol;
-
- return {
- ...baseConfig,
- encryptionKey,
- kibanaServer: {
- hostname: kibanaServerHostname,
- port: kibanaServerPort,
- protocol: kibanaServerProtocol,
- },
- };
-};
-
export const buildConfig = (
core: CoreSetup,
server: Legacy.Server,
@@ -204,10 +78,8 @@ export const buildConfig = (
},
};
- // spreading arguments as an array allows the return type to be known by the compiler
- reportingConfig = addConfigDefaults(server, core, reportingConfig);
return {
- get: (...keys: string[]) => get(reportingConfig, keys.join('.'), null),
+ get: (...keys: string[]) => get(reportingConfig, keys.join('.'), null), // spreading arguments as an array allows the return type to be known by the compiler
kbnConfig: {
get: (...keys: string[]) => get(kbnConfig, keys.join('.'), null),
},
diff --git a/x-pack/legacy/plugins/reporting/server/legacy.ts b/x-pack/legacy/plugins/reporting/server/legacy.ts
index 679b42aca6de5..d044dc866ed0e 100644
--- a/x-pack/legacy/plugins/reporting/server/legacy.ts
+++ b/x-pack/legacy/plugins/reporting/server/legacy.ts
@@ -5,7 +5,9 @@
*/
import { Legacy } from 'kibana';
+import { take } from 'rxjs/operators';
import { PluginInitializerContext } from 'src/core/server';
+import { PluginsSetup } from '../../../../plugins/reporting/server';
import { SecurityPluginSetup } from '../../../../plugins/security/server';
import { ReportingPluginSpecOptions } from '../types';
import { buildConfig } from './config';
@@ -17,7 +19,6 @@ const buildLegacyDependencies = (
reportingPlugin: ReportingPluginSpecOptions
): LegacySetup => ({
route: server.route.bind(server),
- config: server.config,
plugins: {
xpack_main: server.plugins.xpack_main,
reporting: reportingPlugin,
@@ -32,14 +33,13 @@ export const legacyInit = async (
reportingLegacyPlugin: ReportingPluginSpecOptions
) => {
const { core: coreSetup } = server.newPlatform.setup;
- const legacyConfig = server.config();
- const reportingConfig = buildConfig(coreSetup, server, legacyConfig.get('xpack.reporting'));
-
+ const { config$ } = (server.newPlatform.setup.plugins.reporting as PluginsSetup).__legacy;
+ const reportingConfig = await config$.pipe(take(1)).toPromise();
const __LEGACY = buildLegacyDependencies(server, reportingLegacyPlugin);
const pluginInstance = plugin(
server.newPlatform.coreContext as PluginInitializerContext,
- reportingConfig
+ buildConfig(coreSetup, server, reportingConfig)
);
await pluginInstance.setup(coreSetup, {
elasticsearch: coreSetup.elasticsearch,
diff --git a/x-pack/legacy/plugins/reporting/server/lib/esqueue/__tests__/worker.js b/x-pack/legacy/plugins/reporting/server/lib/esqueue/__tests__/worker.js
index ad93a1882746d..ea80a652bb506 100644
--- a/x-pack/legacy/plugins/reporting/server/lib/esqueue/__tests__/worker.js
+++ b/x-pack/legacy/plugins/reporting/server/lib/esqueue/__tests__/worker.js
@@ -760,6 +760,27 @@ describe('Worker class', function() {
});
});
+ it('handle warnings in the output by reflecting a warning status', () => {
+ const workerFn = () => {
+ return Promise.resolve({
+ ...payload,
+ warnings: [`Don't run with scissors!`],
+ });
+ };
+ worker = new Worker(mockQueue, 'test', workerFn, defaultWorkerOptions);
+
+ return worker
+ ._performJob({
+ test: true,
+ ...job,
+ })
+ .then(() => {
+ sinon.assert.calledOnce(updateSpy);
+ const doc = updateSpy.firstCall.args[1].body.doc;
+ expect(doc).to.have.property('status', constants.JOB_STATUS_WARNINGS);
+ });
+ });
+
it('should emit completion event', function(done) {
worker = new Worker(mockQueue, 'test', noop, defaultWorkerOptions);
diff --git a/x-pack/legacy/plugins/reporting/server/lib/esqueue/constants/statuses.js b/x-pack/legacy/plugins/reporting/server/lib/esqueue/constants/statuses.ts
similarity index 89%
rename from x-pack/legacy/plugins/reporting/server/lib/esqueue/constants/statuses.js
rename to x-pack/legacy/plugins/reporting/server/lib/esqueue/constants/statuses.ts
index 620a567e18fe7..7c7f1431adf23 100644
--- a/x-pack/legacy/plugins/reporting/server/lib/esqueue/constants/statuses.js
+++ b/x-pack/legacy/plugins/reporting/server/lib/esqueue/constants/statuses.ts
@@ -8,6 +8,7 @@ export const statuses = {
JOB_STATUS_PENDING: 'pending',
JOB_STATUS_PROCESSING: 'processing',
JOB_STATUS_COMPLETED: 'completed',
+ JOB_STATUS_WARNINGS: 'completed_with_warnings',
JOB_STATUS_FAILED: 'failed',
JOB_STATUS_CANCELLED: 'cancelled',
};
diff --git a/x-pack/legacy/plugins/reporting/server/lib/esqueue/helpers/index_timestamp.js b/x-pack/legacy/plugins/reporting/server/lib/esqueue/helpers/index_timestamp.js
index 6cdbe8f968f75..ceb4ef43b2d9d 100644
--- a/x-pack/legacy/plugins/reporting/server/lib/esqueue/helpers/index_timestamp.js
+++ b/x-pack/legacy/plugins/reporting/server/lib/esqueue/helpers/index_timestamp.js
@@ -8,6 +8,7 @@ import moment from 'moment';
export const intervals = ['year', 'month', 'week', 'day', 'hour', 'minute'];
+// TODO: This helper function can be removed by using `schema.duration` objects in the reporting config schema
export function indexTimestamp(intervalStr, separator = '-') {
if (separator.match(/[a-z]/i)) throw new Error('Interval separator can not be a letter');
diff --git a/x-pack/legacy/plugins/reporting/server/lib/esqueue/worker.js b/x-pack/legacy/plugins/reporting/server/lib/esqueue/worker.js
index 113059fa2fa47..ab0bb6740f078 100644
--- a/x-pack/legacy/plugins/reporting/server/lib/esqueue/worker.js
+++ b/x-pack/legacy/plugins/reporting/server/lib/esqueue/worker.js
@@ -285,8 +285,12 @@ export class Worker extends events.EventEmitter {
const completedTime = moment().toISOString();
const docOutput = this._formatOutput(output);
+ const status =
+ output && output.warnings && output.warnings.length > 0
+ ? constants.JOB_STATUS_WARNINGS
+ : constants.JOB_STATUS_COMPLETED;
const doc = {
- status: constants.JOB_STATUS_COMPLETED,
+ status,
completed_at: completedTime,
output: docOutput,
};
diff --git a/x-pack/legacy/plugins/reporting/server/plugin.ts b/x-pack/legacy/plugins/reporting/server/plugin.ts
index c9ed2e81c6792..e0fa99106a93e 100644
--- a/x-pack/legacy/plugins/reporting/server/plugin.ts
+++ b/x-pack/legacy/plugins/reporting/server/plugin.ts
@@ -5,15 +5,12 @@
*/
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'src/core/server';
-import { logConfiguration } from '../log_configuration';
import { createBrowserDriverFactory } from './browsers';
import { ReportingCore, ReportingConfig } from './core';
import { createQueueFactory, enqueueJobFactory, LevelLogger, runValidations } from './lib';
import { setFieldFormats } from './services';
import { ReportingSetup, ReportingSetupDeps, ReportingStart, ReportingStartDeps } from './types';
import { registerReportingUsageCollector } from './usage';
-// @ts-ignore no module definition
-import { mirrorPluginStatus } from '../../../server/lib/mirror_plugin_status';
export class ReportingPlugin
implements Plugin {
@@ -61,8 +58,6 @@ export class ReportingPlugin
setFieldFormats(plugins.data.fieldFormats);
- logConfiguration(this.config.get('capture'), this.logger);
-
return {};
}
diff --git a/x-pack/legacy/plugins/reporting/server/routes/lib/get_document_payload.ts b/x-pack/legacy/plugins/reporting/server/routes/lib/get_document_payload.ts
index aef37754681ec..c243d0b4266ea 100644
--- a/x-pack/legacy/plugins/reporting/server/routes/lib/get_document_payload.ts
+++ b/x-pack/legacy/plugins/reporting/server/routes/lib/get_document_payload.ts
@@ -9,6 +9,7 @@ import contentDisposition from 'content-disposition';
import * as _ from 'lodash';
import { CSV_JOB_TYPE } from '../../../common/constants';
import { ExportTypeDefinition, ExportTypesRegistry, JobDocOutput, JobSource } from '../../../types';
+import { statuses } from '../../lib/esqueue/constants/statuses';
interface ICustomHeaders {
[x: string]: any;
@@ -99,11 +100,11 @@ export function getDocumentPayloadFactory(exportTypesRegistry: ExportTypesRegist
const { status, jobtype: jobType, payload: { title } = { title: '' } } = doc._source;
const { output } = doc._source;
- if (status === 'completed') {
+ if (status === statuses.JOB_STATUS_COMPLETED || status === statuses.JOB_STATUS_WARNINGS) {
return getCompleted(output, jobType, title);
}
- if (status === 'failed') {
+ if (status === statuses.JOB_STATUS_FAILED) {
return getFailure(output);
}
diff --git a/x-pack/legacy/plugins/reporting/server/types.d.ts b/x-pack/legacy/plugins/reporting/server/types.d.ts
index bec00688432cc..fb77eae4e7eea 100644
--- a/x-pack/legacy/plugins/reporting/server/types.d.ts
+++ b/x-pack/legacy/plugins/reporting/server/types.d.ts
@@ -11,7 +11,7 @@ import { PluginStart as DataPluginStart } from '../../../../../src/plugins/data/
import { SecurityPluginSetup } from '../../../../plugins/security/server';
import { XPackMainPlugin } from '../../xpack_main/server/xpack_main';
import { ReportingPluginSpecOptions } from '../types';
-import { ReportingConfig, ReportingConfigType } from './core';
+import { ReportingConfigType } from './core';
export interface ReportingSetupDeps {
elasticsearch: ElasticsearchServiceSetup;
@@ -30,7 +30,6 @@ export type ReportingSetup = object;
export type ReportingStart = object;
export interface LegacySetup {
- config: Legacy.Server['config'];
plugins: {
xpack_main: XPackMainPlugin & {
status?: any;
diff --git a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_browserdriverfactory.ts b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_browserdriverfactory.ts
index 6e95bed2ecf92..1be10f6a2056f 100644
--- a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_browserdriverfactory.ts
+++ b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_browserdriverfactory.ts
@@ -34,7 +34,7 @@ const getMockElementsPositionAndAttributes = (
): ElementsPositionAndAttribute[] => [
{
position: {
- boundingClientRect: { top: 0, left: 0, width: 10, height: 11 },
+ boundingClientRect: { top: 0, left: 0, width: 800, height: 600 },
scroll: { x: 0, y: 0 },
},
attributes: { title, description },
@@ -78,7 +78,7 @@ mockBrowserEvaluate.mockImplementation(() => {
});
const mockScreenshot = jest.fn();
mockScreenshot.mockImplementation((item: ElementsPositionAndAttribute) => {
- return Promise.resolve(`allyourBase64 of ${Object.keys(item)}`);
+ return Promise.resolve(`allyourBase64`);
});
const getCreatePage = (driver: HeadlessChromiumDriver) =>
jest.fn().mockImplementation(() => Rx.of({ driver, exit$: Rx.never() }));
@@ -94,31 +94,23 @@ export const createMockBrowserDriverFactory = async (
logger: Logger,
opts: Partial = {}
): Promise => {
- const captureConfig = {
+ const captureConfig: CaptureConfig = {
timeouts: { openUrl: 30000, waitForElements: 30000, renderComplete: 30000 },
browser: {
type: 'chromium',
chromium: {
inspect: false,
disableSandbox: false,
- userDataDir: '/usr/data/dir',
- viewport: { width: 12, height: 12 },
proxy: { enabled: false, server: undefined, bypass: undefined },
},
autoDownload: false,
- inspect: true,
- userDataDir: '/usr/data/dir',
- viewport: { width: 12, height: 12 },
- disableSandbox: false,
- proxy: { enabled: false, server: undefined, bypass: undefined },
- maxScreenshotDimension: undefined,
},
networkPolicy: { enabled: true, rules: [] },
viewport: { width: 800, height: 600 },
loadDelay: 2000,
- zoom: 1,
+ zoom: 2,
maxAttempts: 1,
- } as CaptureConfig;
+ };
const binaryPath = '/usr/local/share/common/secure/';
const mockBrowserDriverFactory = await createDriverFactory(binaryPath, logger, captureConfig);
diff --git a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_layoutinstance.ts b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_layoutinstance.ts
index be60b56dcc0c1..81090e7616501 100644
--- a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_layoutinstance.ts
+++ b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_layoutinstance.ts
@@ -12,7 +12,7 @@ import { CaptureConfig } from '../server/types';
export const createMockLayoutInstance = (captureConfig: CaptureConfig) => {
const mockLayout = createLayout(captureConfig, {
id: LayoutTypes.PRESERVE_LAYOUT,
- dimensions: { height: 12, width: 12 },
+ dimensions: { height: 100, width: 100 },
}) as LayoutInstance;
mockLayout.selectors = {
renderComplete: 'renderedSelector',
diff --git a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_reportingplugin.ts b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_reportingplugin.ts
index 34ff91d1972a0..ec00023b4d449 100644
--- a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_reportingplugin.ts
+++ b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_reportingplugin.ts
@@ -11,7 +11,6 @@ jest.mock('../server/browsers');
jest.mock('../server/lib/create_queue');
jest.mock('../server/lib/enqueue_job');
jest.mock('../server/lib/validate');
-jest.mock('../log_configuration');
import { EventEmitter } from 'events';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
diff --git a/x-pack/legacy/plugins/reporting/types.d.ts b/x-pack/legacy/plugins/reporting/types.d.ts
index eec7da7dc6733..2e7da6663ab03 100644
--- a/x-pack/legacy/plugins/reporting/types.d.ts
+++ b/x-pack/legacy/plugins/reporting/types.d.ts
@@ -8,6 +8,7 @@ import { EventEmitter } from 'events';
import { ResponseObject } from 'hapi';
import { Legacy } from 'kibana';
import { CallCluster } from '../../../../src/legacy/core_plugins/elasticsearch';
+import { JobStatus } from '../../../plugins/reporting'; // reporting new platform
import { CancellationToken } from './common/cancellation_token';
import { ReportingCore } from './server/core';
import { LevelLogger } from './server/lib/level_logger';
@@ -150,7 +151,7 @@ export interface JobSource {
jobtype: string;
output: JobDocOutput;
payload: JobDocPayload;
- status: string; // completed, failed, etc
+ status: JobStatus;
};
}
diff --git a/x-pack/legacy/plugins/siem/public/mock/test_providers.tsx b/x-pack/legacy/plugins/siem/public/mock/test_providers.tsx
index c7692755c1330..952f7f51b63f2 100644
--- a/x-pack/legacy/plugins/siem/public/mock/test_providers.tsx
+++ b/x-pack/legacy/plugins/siem/public/mock/test_providers.tsx
@@ -20,6 +20,7 @@ import { ThemeProvider } from 'styled-components';
import { createStore, State } from '../store';
import { mockGlobalState } from './global_state';
import { createKibanaContextProviderMock } from './kibana_react';
+import { FieldHook, useForm } from '../shared_imports';
jest.mock('ui/new_platform');
@@ -91,3 +92,29 @@ const TestProviderWithoutDragAndDropComponent: React.FC = ({
);
export const TestProviderWithoutDragAndDrop = React.memo(TestProviderWithoutDragAndDropComponent);
+
+export const useFormFieldMock = (options?: Partial): FieldHook => {
+ const { form } = useForm();
+
+ return {
+ path: 'path',
+ type: 'type',
+ value: [],
+ isPristine: false,
+ isValidating: false,
+ isValidated: false,
+ isChangingValue: false,
+ form,
+ errors: [],
+ isValid: true,
+ getErrorsMessages: jest.fn(),
+ onChange: jest.fn(),
+ setValue: jest.fn(),
+ setErrors: jest.fn(),
+ clearErrors: jest.fn(),
+ validate: jest.fn(),
+ reset: jest.fn(),
+ __serializeOutput: jest.fn(),
+ ...options,
+ };
+};
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/activity_monitor/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/activity_monitor/index.test.tsx
new file mode 100644
index 0000000000000..c5a4057b64ea7
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/activity_monitor/index.test.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.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+
+import { ActivityMonitor } from './index';
+
+describe('activity_monitor', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('[title="Activity monitor"]')).toBeTruthy();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/detection_engine_header_page/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/detection_engine_header_page/index.test.tsx
new file mode 100644
index 0000000000000..a2685017f86d6
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/detection_engine_header_page/index.test.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.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+
+import { DetectionEngineHeaderPage } from './index';
+
+describe('detection_engine_header_page', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('[title="Title"]')).toBeTruthy();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/no_api_integration_callout/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/no_api_integration_callout/index.test.tsx
new file mode 100644
index 0000000000000..0e2589150e858
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/no_api_integration_callout/index.test.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.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+
+import { NoApiIntegrationKeyCallOut } from './index';
+
+describe('no_api_integration_callout', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('EuiCallOut')).toBeTruthy();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/no_write_signals_callout/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/no_write_signals_callout/index.test.tsx
new file mode 100644
index 0000000000000..2e6890e60fc61
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/no_write_signals_callout/index.test.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.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+
+import { NoWriteSignalsCallOut } from './index';
+
+describe('no_write_signals_callout', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('EuiCallOut')).toBeTruthy();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/index.test.tsx
new file mode 100644
index 0000000000000..b66a9fc881045
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/index.test.tsx
@@ -0,0 +1,43 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { SignalsTableComponent } from './index';
+
+describe('SignalsTableComponent', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper.find('[title="Signals"]')).toBeTruthy();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/index.tsx
index 6cdb2f326901e..ce8ae2054b2c7 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/index.tsx
@@ -61,7 +61,7 @@ interface OwnProps {
type SignalsTableComponentProps = OwnProps & PropsFromRedux;
-const SignalsTableComponent: React.FC = ({
+export const SignalsTableComponent: React.FC = ({
canUserCRUD,
clearEventsDeleted,
clearEventsLoading,
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/signals_filter_group/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/signals_filter_group/index.test.tsx
new file mode 100644
index 0000000000000..dd30bb1b0a74d
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/signals_filter_group/index.test.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.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+
+import { SignalsTableFilterGroup } from './index';
+
+describe('SignalsTableFilterGroup', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('EuiFilterButton')).toBeTruthy();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/signals_utility_bar/batch_actions.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/signals_utility_bar/batch_actions.tsx
deleted file mode 100644
index bb45ff68cb01d..0000000000000
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/signals_utility_bar/batch_actions.tsx
+++ /dev/null
@@ -1,92 +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 { EuiContextMenuItem } from '@elastic/eui';
-import React from 'react';
-import * as i18n from './translations';
-import { TimelineNonEcsData } from '../../../../../graphql/types';
-import { SendSignalsToTimeline, UpdateSignalsStatus } from '../types';
-import { FILTER_CLOSED, FILTER_OPEN } from '../signals_filter_group';
-
-interface GetBatchItems {
- areEventsLoading: boolean;
- allEventsSelected: boolean;
- selectedEventIds: Readonly>;
- updateSignalsStatus: UpdateSignalsStatus;
- sendSignalsToTimeline: SendSignalsToTimeline;
- closePopover: () => void;
- isFilteredToOpen: boolean;
-}
-/**
- * Returns ViewInTimeline / UpdateSignalStatus actions to be display within an EuiContextMenuPanel
- *
- * @param areEventsLoading are any events loading
- * @param allEventsSelected are all events on all pages selected
- * @param selectedEventIds
- * @param updateSignalsStatus function for updating signal status
- * @param sendSignalsToTimeline function for sending signals to timeline
- * @param closePopover
- * @param isFilteredToOpen currently selected filter options
- */
-export const getBatchItems = ({
- areEventsLoading,
- allEventsSelected,
- selectedEventIds,
- updateSignalsStatus,
- sendSignalsToTimeline,
- closePopover,
- isFilteredToOpen,
-}: GetBatchItems) => {
- const allDisabled = areEventsLoading || Object.keys(selectedEventIds).length === 0;
- const sendToTimelineDisabled = allEventsSelected || uniqueRuleCount(selectedEventIds) > 1;
- const filterString = isFilteredToOpen
- ? i18n.BATCH_ACTION_CLOSE_SELECTED
- : i18n.BATCH_ACTION_OPEN_SELECTED;
-
- return [
- {
- closePopover();
- sendSignalsToTimeline();
- }}
- >
- {i18n.BATCH_ACTION_VIEW_SELECTED_IN_TIMELINE}
- ,
-
- {
- closePopover();
- await updateSignalsStatus({
- signalIds: Object.keys(selectedEventIds),
- status: isFilteredToOpen ? FILTER_CLOSED : FILTER_OPEN,
- });
- }}
- >
- {filterString}
- ,
- ];
-};
-
-/**
- * Returns the number of unique rules for a given list of signals
- *
- * @param signals
- */
-export const uniqueRuleCount = (
- signals: Readonly>
-): number => {
- const ruleIds = Object.values(signals).flatMap(
- data => data.find(d => d.field === 'signal.rule.id')?.value
- );
-
- return Array.from(new Set(ruleIds)).length;
-};
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/signals_utility_bar/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/signals_utility_bar/index.test.tsx
new file mode 100644
index 0000000000000..6cab43b5285b5
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/signals_utility_bar/index.test.tsx
@@ -0,0 +1,33 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { SignalsUtilityBar } from './index';
+
+jest.mock('../../../../../lib/kibana');
+
+describe('SignalsUtilityBar', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper.find('[dataTestSubj="openCloseSignal"]')).toBeTruthy();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/index.test.tsx
new file mode 100644
index 0000000000000..6921c49d8a8b4
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/index.test.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 { shallow } from 'enzyme';
+
+import { SignalsHistogramPanel } from './index';
+
+jest.mock('../../../../lib/kibana');
+jest.mock('../../../../components/navigation/use_get_url_search');
+
+describe('SignalsHistogramPanel', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper.find('[id="detections-histogram"]')).toBeTruthy();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/signals_histogram.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/signals_histogram.test.tsx
new file mode 100644
index 0000000000000..5eb9beaaaf76a
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/signals_histogram.test.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 { shallow } from 'enzyme';
+
+import { SignalsHistogram } from './signals_histogram';
+
+jest.mock('../../../../lib/kibana');
+
+describe('SignalsHistogram', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper.find('Chart')).toBeTruthy();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/user_info/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/user_info/index.test.tsx
new file mode 100644
index 0000000000000..b3d710de5e94e
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/user_info/index.test.tsx
@@ -0,0 +1,50 @@
+/*
+ * 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 { renderHook } from '@testing-library/react-hooks';
+import { useUserInfo } from './index';
+
+import { usePrivilegeUser } from '../../../../containers/detection_engine/signals/use_privilege_user';
+import { useSignalIndex } from '../../../../containers/detection_engine/signals/use_signal_index';
+import { useKibana } from '../../../../lib/kibana';
+jest.mock('../../../../containers/detection_engine/signals/use_privilege_user');
+jest.mock('../../../../containers/detection_engine/signals/use_signal_index');
+jest.mock('../../../../lib/kibana');
+
+describe('useUserInfo', () => {
+ beforeAll(() => {
+ (usePrivilegeUser as jest.Mock).mockReturnValue({});
+ (useSignalIndex as jest.Mock).mockReturnValue({});
+ (useKibana as jest.Mock).mockReturnValue({
+ services: {
+ application: {
+ capabilities: {
+ siem: {
+ crud: true,
+ },
+ },
+ },
+ },
+ });
+ });
+ it('returns default state', () => {
+ const { result } = renderHook(() => useUserInfo());
+
+ expect(result).toEqual({
+ current: {
+ canUserCRUD: null,
+ hasEncryptionKey: null,
+ hasIndexManage: null,
+ hasIndexWrite: null,
+ isAuthenticated: null,
+ isSignalIndexExists: null,
+ loading: true,
+ signalIndexName: null,
+ },
+ error: undefined,
+ });
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
new file mode 100644
index 0000000000000..779e9a4557f2a
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
@@ -0,0 +1,43 @@
+/*
+ * 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 { shallow } from 'enzyme';
+import { useParams } from 'react-router-dom';
+
+import '../../mock/match_media';
+import { setAbsoluteRangeDatePicker } from '../../store/inputs/actions';
+import { DetectionEnginePageComponent } from './detection_engine';
+import { useUserInfo } from './components/user_info';
+
+jest.mock('./components/user_info');
+jest.mock('../../lib/kibana');
+jest.mock('react-router-dom', () => {
+ const originalModule = jest.requireActual('react-router-dom');
+
+ return {
+ ...originalModule,
+ useParams: jest.fn(),
+ };
+});
+
+describe('DetectionEnginePageComponent', () => {
+ beforeAll(() => {
+ (useParams as jest.Mock).mockReturnValue({});
+ (useUserInfo as jest.Mock).mockReturnValue({});
+ });
+ it('renders correctly', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper.find('WithSource')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index 1bd7ab2c4f1ae..a26d7f5672106 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -59,7 +59,7 @@ const detectionsTabs: Record = {
},
};
-const DetectionEnginePageComponent: React.FC = ({
+export const DetectionEnginePageComponent: React.FC = ({
filters,
query,
setAbsoluteRangeDatePicker,
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.test.tsx
new file mode 100644
index 0000000000000..f64526fd2f7c4
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.test.tsx
@@ -0,0 +1,19 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { DetectionEngineEmptyPage } from './detection_engine_empty_page';
+jest.mock('../../lib/kibana');
+
+describe('DetectionEngineEmptyPage', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('EmptyPage')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_no_signal_index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_no_signal_index.test.tsx
new file mode 100644
index 0000000000000..e9f05f7aafe3c
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_no_signal_index.test.tsx
@@ -0,0 +1,19 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { DetectionEngineNoIndex } from './detection_engine_no_signal_index';
+jest.mock('../../lib/kibana');
+
+describe('DetectionEngineNoIndex', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('EmptyPage')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_user_unauthenticated.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_user_unauthenticated.test.tsx
new file mode 100644
index 0000000000000..e71f4de2b010b
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_user_unauthenticated.test.tsx
@@ -0,0 +1,19 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { DetectionEngineUserUnauthenticated } from './detection_engine_user_unauthenticated';
+jest.mock('../../lib/kibana');
+
+describe('DetectionEngineUserUnauthenticated', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('EmptyPage')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/helpers.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/helpers.ts
deleted file mode 100644
index 1399df0fcf6d1..0000000000000
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/helpers.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-export const sampleChartOptions = [
- { text: 'Risk scores', value: 'risk_scores' },
- { text: 'Severities', value: 'severities' },
- { text: 'Top destination IPs', value: 'destination_ips' },
- { text: 'Top event actions', value: 'event_actions' },
- { text: 'Top event categories', value: 'event_categories' },
- { text: 'Top host names', value: 'host_names' },
- { text: 'Top rule types', value: 'rule_types' },
- { text: 'Top rules', value: 'rules' },
- { text: 'Top source IPs', value: 'source_ips' },
- { text: 'Top users', value: 'users' },
-];
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.test.tsx
new file mode 100644
index 0000000000000..6c4980f1d1500
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.test.tsx
@@ -0,0 +1,19 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import '../../mock/match_media';
+import { DetectionEngineContainer } from './index';
+
+describe('DetectionEngineContainer', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('ManageUserInfo')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.test.tsx
new file mode 100644
index 0000000000000..f4955c2a93b8d
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.test.tsx
@@ -0,0 +1,40 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { AllRules } from './index';
+
+jest.mock('react-router-dom', () => {
+ const originalModule = jest.requireActual('react-router-dom');
+
+ return {
+ ...originalModule,
+ useHistory: jest.fn(),
+ };
+});
+
+describe('AllRules', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper.find('[title="All rules"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.test.tsx
new file mode 100644
index 0000000000000..92f69d79110d2
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.test.tsx
@@ -0,0 +1,20 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { RulesTableFilters } from './rules_table_filters';
+
+describe('RulesTableFilters', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper.find('[data-test-subj="show-elastic-rules-filter-button"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.test.tsx
new file mode 100644
index 0000000000000..e31b8394e07d6
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.test.tsx
@@ -0,0 +1,25 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { TagsFilterPopover } from './tags_filter_popover';
+
+describe('TagsFilterPopover', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper.find('EuiPopover')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/accordion_title/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/accordion_title/index.test.tsx
new file mode 100644
index 0000000000000..9202da3336565
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/accordion_title/index.test.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.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+
+import { AccordionTitle } from './index';
+
+describe('AccordionTitle', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('h6').text()).toContain('title');
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/add_item_form/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/add_item_form/index.test.tsx
new file mode 100644
index 0000000000000..eafa89a33f596
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/add_item_form/index.test.tsx
@@ -0,0 +1,32 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { AddItem } from './index';
+import { useFormFieldMock } from '../../../../../../public/mock/test_providers';
+
+describe('AddItem', () => {
+ it('renders correctly', () => {
+ const Component = () => {
+ const field = useFormFieldMock();
+
+ return (
+
+ );
+ };
+ const wrapper = shallow( );
+
+ expect(wrapper.dive().find('[iconType="plusInCircle"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/all_rules_tables/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/all_rules_tables/index.test.tsx
new file mode 100644
index 0000000000000..3dab83bca2946
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/all_rules_tables/index.test.tsx
@@ -0,0 +1,46 @@
+/*
+ * 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, { useRef } from 'react';
+import { shallow } from 'enzyme';
+
+import { AllRulesTables } from './index';
+
+describe('AllRulesTables', () => {
+ it('renders correctly', () => {
+ const Component = () => {
+ const ref = useRef();
+
+ return (
+
+ );
+ };
+ const wrapper = shallow( );
+
+ expect(wrapper.dive().find('[data-test-subj="rules-table"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/anomaly_threshold_slider/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/anomaly_threshold_slider/index.test.tsx
new file mode 100644
index 0000000000000..c0e957d94261f
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/anomaly_threshold_slider/index.test.tsx
@@ -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 React from 'react';
+import { shallow } from 'enzyme';
+
+import { AnomalyThresholdSlider } from './index';
+import { useFormFieldMock } from '../../../../../mock';
+
+describe('AnomalyThresholdSlider', () => {
+ it('renders correctly', () => {
+ const Component = () => {
+ const field = useFormFieldMock();
+
+ return ;
+ };
+ const wrapper = shallow( );
+
+ expect(wrapper.dive().find('EuiRange')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/anomaly_threshold_slider/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/anomaly_threshold_slider/index.tsx
index 19d1c698cbd9b..01fddf98b97d8 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/anomaly_threshold_slider/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/anomaly_threshold_slider/index.tsx
@@ -16,10 +16,10 @@ interface AnomalyThresholdSliderProps {
type Event = React.ChangeEvent;
type EventArg = Event | React.MouseEvent;
-export const AnomalyThresholdSlider: React.FC = ({
+export const AnomalyThresholdSlider = ({
describedByIds = [],
field,
-}) => {
+}: AnomalyThresholdSliderProps) => {
const threshold = field.value as number;
const onThresholdChange = useCallback(
(event: EventArg) => {
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/description_step/ml_job_description.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/description_step/ml_job_description.test.tsx
new file mode 100644
index 0000000000000..59231c31d15bb
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/description_step/ml_job_description.test.tsx
@@ -0,0 +1,54 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { MlJobDescription, AuditIcon, JobStatusBadge } from './ml_job_description';
+jest.mock('../../../../../lib/kibana');
+
+const job = {
+ moduleId: 'moduleId',
+ defaultIndexPattern: 'defaultIndexPattern',
+ isCompatible: true,
+ isInstalled: true,
+ isElasticJob: true,
+ datafeedId: 'datafeedId',
+ datafeedIndices: [],
+ datafeedState: 'datafeedState',
+ description: 'description',
+ groups: [],
+ hasDatafeed: true,
+ id: 'id',
+ isSingleMetricViewerJob: false,
+ jobState: 'jobState',
+ memory_status: 'memory_status',
+ processed_record_count: 0,
+};
+
+describe('MlJobDescription', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('[data-test-subj="machineLearningJobId"]')).toHaveLength(1);
+ });
+});
+
+describe('AuditIcon', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('EuiToolTip')).toHaveLength(0);
+ });
+});
+
+describe('JobStatusBadge', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('EuiBadge')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/description_step/ml_job_description.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/description_step/ml_job_description.tsx
index 5a9593f1a6de2..1664ea320bc1e 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/description_step/ml_job_description.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/description_step/ml_job_description.tsx
@@ -20,7 +20,7 @@ enum MessageLevels {
error = 'error',
}
-const AuditIcon: React.FC<{
+const AuditIconComponent: React.FC<{
message: SiemJob['auditMessage'];
}> = ({ message }) => {
if (!message) {
@@ -45,7 +45,9 @@ const AuditIcon: React.FC<{
);
};
-export const JobStatusBadge: React.FC<{ job: SiemJob }> = ({ job }) => {
+export const AuditIcon = React.memo(AuditIconComponent);
+
+const JobStatusBadgeComponent: React.FC<{ job: SiemJob }> = ({ job }) => {
const isStarted = isJobStarted(job.jobState, job.datafeedState);
const color = isStarted ? 'secondary' : 'danger';
const text = isStarted ? ML_JOB_STARTED : ML_JOB_STOPPED;
@@ -57,6 +59,8 @@ export const JobStatusBadge: React.FC<{ job: SiemJob }> = ({ job }) => {
);
};
+export const JobStatusBadge = React.memo(JobStatusBadgeComponent);
+
const JobLink = styled(EuiLink)`
margin-right: ${({ theme }) => theme.eui.euiSizeS};
`;
@@ -65,7 +69,7 @@ const Wrapper = styled.div`
overflow: hidden;
`;
-export const MlJobDescription: React.FC<{ job: SiemJob }> = ({ job }) => {
+const MlJobDescriptionComponent: React.FC<{ job: SiemJob }> = ({ job }) => {
const jobUrl = useKibana().services.application.getUrlForApp(
`ml#/jobs?mlManagement=(jobId:${encodeURI(job.id)})`
);
@@ -83,6 +87,8 @@ export const MlJobDescription: React.FC<{ job: SiemJob }> = ({ job }) => {
);
};
+export const MlJobDescription = React.memo(MlJobDescriptionComponent);
+
export const buildMlJobDescription = (
jobId: string,
label: string,
diff --git a/x-pack/legacy/plugins/reporting/server/config/config.js b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/mitre/helpers.test.tsx
similarity index 53%
rename from x-pack/legacy/plugins/reporting/server/config/config.js
rename to x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/mitre/helpers.test.tsx
index 08e4db464b003..dc201eb21c911 100644
--- a/x-pack/legacy/plugins/reporting/server/config/config.js
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/mitre/helpers.test.tsx
@@ -4,18 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { cpus } from 'os';
+import { isMitreAttackInvalid } from './helpers';
-const defaultCPUCount = 2;
-
-function cpuCount() {
- try {
- return cpus().length;
- } catch (e) {
- return defaultCPUCount;
- }
-}
-
-export const config = {
- concurrency: cpuCount(),
-};
+describe('isMitreAttackInvalid', () => {
+ it('returns true if tacticName is empty', () => {
+ expect(isMitreAttackInvalid('', undefined)).toBe(true);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/mitre/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/mitre/index.test.tsx
new file mode 100644
index 0000000000000..3e8d542682456
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/mitre/index.test.tsx
@@ -0,0 +1,31 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { AddMitreThreat } from './index';
+import { useFormFieldMock } from '../../../../../mock';
+
+describe('AddMitreThreat', () => {
+ it('renders correctly', () => {
+ const Component = () => {
+ const field = useFormFieldMock();
+
+ return (
+
+ );
+ };
+ const wrapper = shallow( );
+
+ expect(wrapper.dive().find('[data-test-subj="addMitre"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/ml_job_select/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/ml_job_select/index.test.tsx
new file mode 100644
index 0000000000000..dea27d8d04536
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/ml_job_select/index.test.tsx
@@ -0,0 +1,31 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { MlJobSelect } from './index';
+import { useSiemJobs } from '../../../../../components/ml_popover/hooks/use_siem_jobs';
+import { useFormFieldMock } from '../../../../../mock';
+jest.mock('../../../../../components/ml_popover/hooks/use_siem_jobs');
+jest.mock('../../../../../lib/kibana');
+
+describe('MlJobSelect', () => {
+ beforeAll(() => {
+ (useSiemJobs as jest.Mock).mockReturnValue([false, []]);
+ });
+
+ it('renders correctly', () => {
+ const Component = () => {
+ const field = useFormFieldMock();
+
+ return ;
+ };
+ const wrapper = shallow( );
+
+ expect(wrapper.dive().find('[data-test-subj="mlJobSelect"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/optional_field_label/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/optional_field_label/index.test.tsx
new file mode 100644
index 0000000000000..789f12f290a34
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/optional_field_label/index.test.tsx
@@ -0,0 +1,17 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { OptionalFieldLabel } from './index';
+
+describe('OptionalFieldLabel', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow(OptionalFieldLabel);
+
+ expect(wrapper.find('EuiTextColor')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/pick_timeline/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/pick_timeline/index.test.tsx
new file mode 100644
index 0000000000000..fefc9697176c4
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/pick_timeline/index.test.tsx
@@ -0,0 +1,31 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { PickTimeline } from './index';
+import { useFormFieldMock } from '../../../../../mock';
+
+describe('PickTimeline', () => {
+ it('renders correctly', () => {
+ const Component = () => {
+ const field = useFormFieldMock();
+
+ return (
+
+ );
+ };
+ const wrapper = shallow( );
+
+ expect(wrapper.dive().find('[data-test-subj="pick-timeline"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/pre_packaged_rules/load_empty_prompt.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/pre_packaged_rules/load_empty_prompt.test.tsx
new file mode 100644
index 0000000000000..8ace42fc5c3f9
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/pre_packaged_rules/load_empty_prompt.test.tsx
@@ -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 React from 'react';
+import { shallow } from 'enzyme';
+
+import { PrePackagedRulesPrompt } from './load_empty_prompt';
+
+describe('PrePackagedRulesPrompt', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper.find('EmptyPrompt')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/pre_packaged_rules/load_empty_prompt.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/pre_packaged_rules/load_empty_prompt.tsx
index 1cff4751e8188..5d136265ef1f2 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/pre_packaged_rules/load_empty_prompt.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/pre_packaged_rules/load_empty_prompt.tsx
@@ -15,6 +15,8 @@ const EmptyPrompt = styled(EuiEmptyPrompt)`
align-self: center; /* Corrects horizontal centering in IE11 */
`;
+EmptyPrompt.displayName = 'EmptyPrompt';
+
interface PrePackagedRulesPromptProps {
createPrePackagedRules: () => void;
loading: boolean;
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/pre_packaged_rules/update_callout.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/pre_packaged_rules/update_callout.test.tsx
new file mode 100644
index 0000000000000..807da79fb7a1a
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/pre_packaged_rules/update_callout.test.tsx
@@ -0,0 +1,36 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { UpdatePrePackagedRulesCallOut } from './update_callout';
+import { useKibana } from '../../../../../lib/kibana';
+jest.mock('../../../../../lib/kibana');
+
+describe('UpdatePrePackagedRulesCallOut', () => {
+ beforeAll(() => {
+ (useKibana as jest.Mock).mockReturnValue({
+ services: {
+ docLinks: {
+ ELASTIC_WEBSITE_URL: '',
+ DOC_LINK_VERSION: '',
+ },
+ },
+ });
+ });
+ it('renders correctly', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper.find('EuiCallOut')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/query_bar/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/query_bar/index.test.tsx
new file mode 100644
index 0000000000000..cdd06ad58bb4b
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/query_bar/index.test.tsx
@@ -0,0 +1,37 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { QueryBarDefineRule } from './index';
+import { useFormFieldMock } from '../../../../../mock';
+
+jest.mock('../../../../../lib/kibana');
+
+describe('QueryBarDefineRule', () => {
+ it('renders correctly', () => {
+ const Component = () => {
+ const field = useFormFieldMock();
+
+ return (
+
+ );
+ };
+ const wrapper = shallow( );
+
+ expect(wrapper.dive().find('[data-test-subj="query-bar-define-rule"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/read_only_callout/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/read_only_callout/index.test.tsx
new file mode 100644
index 0000000000000..e761cb3323b2c
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/read_only_callout/index.test.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.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+
+import { ReadOnlyCallOut } from './index';
+
+describe('ReadOnlyCallOut', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('EuiCallOut')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_actions_field/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_actions_field/index.test.tsx
new file mode 100644
index 0000000000000..4cfad36b2933f
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_actions_field/index.test.tsx
@@ -0,0 +1,33 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { RuleActionsField } from './index';
+import { useKibana } from '../../../../../lib/kibana';
+import { useFormFieldMock } from '../../../../../mock';
+jest.mock('../../../../../lib/kibana');
+
+describe('RuleActionsField', () => {
+ it('should not render ActionForm is no actions are supported', () => {
+ (useKibana as jest.Mock).mockReturnValue({
+ services: {
+ triggers_actions_ui: {
+ actionTypeRegistry: {},
+ },
+ },
+ });
+ const Component = () => {
+ const field = useFormFieldMock();
+
+ return ;
+ };
+ const wrapper = shallow( );
+
+ expect(wrapper.dive().find('ActionForm')).toHaveLength(0);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_status/helpers.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_status/helpers.test.tsx
new file mode 100644
index 0000000000000..aba30e4b7f3ca
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_status/helpers.test.tsx
@@ -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.
+ */
+
+import { getStatusColor } from './helpers';
+
+describe('rule_status helpers', () => {
+ it('getStatusColor returns subdued if null was provided', () => {
+ expect(getStatusColor(null)).toBe('subdued');
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_status/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_status/index.test.tsx
new file mode 100644
index 0000000000000..6e230de11c4f3
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_status/index.test.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.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+
+import { RuleStatus } from './index';
+
+describe('RuleStatus', () => {
+ it('renders loader correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.dive().find('[data-test-subj="rule-status-loader"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/schedule_item_form/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/schedule_item_form/index.test.tsx
new file mode 100644
index 0000000000000..3829af02ca4f1
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/schedule_item_form/index.test.tsx
@@ -0,0 +1,31 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { ScheduleItem } from './index';
+import { useFormFieldMock } from '../../../../../mock';
+
+describe('ScheduleItem', () => {
+ it('renders correctly', () => {
+ const Component = () => {
+ const field = useFormFieldMock();
+
+ return (
+
+ );
+ };
+ const wrapper = shallow( );
+
+ expect(wrapper.dive().find('[data-test-subj="schedule-item"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/select_rule_type/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/select_rule_type/index.test.tsx
new file mode 100644
index 0000000000000..3d832d61abb28
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/select_rule_type/index.test.tsx
@@ -0,0 +1,25 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { SelectRuleType } from './index';
+import { useFormFieldMock } from '../../../../../mock';
+jest.mock('../../../../../lib/kibana');
+
+describe('SelectRuleType', () => {
+ it('renders correctly', () => {
+ const Component = () => {
+ const field = useFormFieldMock();
+
+ return ;
+ };
+ const wrapper = shallow( );
+
+ expect(wrapper.dive().find('[data-test-subj="selectRuleType"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/severity_badge/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/severity_badge/index.test.tsx
new file mode 100644
index 0000000000000..a9dddfedc2bab
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/severity_badge/index.test.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.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+
+import { SeverityBadge } from './index';
+
+describe('SeverityBadge', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('EuiHealth')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/status_icon/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/status_icon/index.test.tsx
new file mode 100644
index 0000000000000..89b8a56e79054
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/status_icon/index.test.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 { shallow } from 'enzyme';
+
+import { TestProviders } from '../../../../../mock';
+import { RuleStatusIcon } from './index';
+jest.mock('../../../../../lib/kibana');
+
+describe('RuleStatusIcon', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( , {
+ wrappingComponent: TestProviders,
+ });
+
+ expect(wrapper.find('EuiAvatar')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_content_wrapper/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_content_wrapper/index.test.tsx
new file mode 100644
index 0000000000000..af0547ea03261
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_content_wrapper/index.test.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.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+
+import { StepContentWrapper } from './index';
+
+describe('StepContentWrapper', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('div')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_content_wrapper/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_content_wrapper/index.tsx
index b04a321dab05b..a7343a87a7ef8 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_content_wrapper/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_content_wrapper/index.tsx
@@ -16,3 +16,5 @@ StyledDiv.defaultProps = {
};
export const StepContentWrapper = React.memo(StyledDiv);
+
+StepContentWrapper.displayName = 'StepContentWrapper';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_define_rule/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_define_rule/index.test.tsx
new file mode 100644
index 0000000000000..ebef6348d477e
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_define_rule/index.test.tsx
@@ -0,0 +1,20 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { StepDefineRule } from './index';
+
+jest.mock('../../../../../lib/kibana');
+
+describe('StepDefineRule', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('Form[data-test-subj="stepDefineRule"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_panel/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_panel/index.test.tsx
new file mode 100644
index 0000000000000..ce01d6995a2d8
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_panel/index.test.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 { shallow } from 'enzyme';
+
+import { StepPanel } from './index';
+
+describe('StepPanel', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow(
+
+
+
+ );
+
+ expect(wrapper.find('MyPanel')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_panel/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_panel/index.tsx
index 88cecadb8b137..1923ed09252dd 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_panel/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_panel/index.tsx
@@ -20,6 +20,8 @@ const MyPanel = styled(EuiPanel)`
position: relative;
`;
+MyPanel.displayName = 'MyPanel';
+
const StepPanelComponent: React.FC = ({ children, loading, title }) => (
{loading && }
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/index.test.tsx
new file mode 100644
index 0000000000000..69d118ba9f28e
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/index.test.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 { shallow } from 'enzyme';
+
+import { StepRuleActions } from './index';
+
+jest.mock('../../../../../lib/kibana');
+
+describe('StepRuleActions', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper.find('[data-test-subj="stepRuleActions"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/schema.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/schema.tsx
index bc3b0dfe720bc..1b27d0e0fcc0e 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/schema.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_rule_actions/schema.tsx
@@ -4,6 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
+/* istanbul ignore file */
+
import { i18n } from '@kbn/i18n';
import { FormSchema } from '../../../../../shared_imports';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_schedule_rule/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_schedule_rule/index.test.tsx
new file mode 100644
index 0000000000000..98de933590d60
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_schedule_rule/index.test.tsx
@@ -0,0 +1,27 @@
+/*
+ * 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 { shallow, mount } from 'enzyme';
+
+import { TestProviders } from '../../../../../mock';
+import { StepScheduleRule } from './index';
+
+describe('StepScheduleRule', () => {
+ it('renders correctly', () => {
+ const wrapper = mount( , {
+ wrappingComponent: TestProviders,
+ });
+
+ expect(wrapper.find('Form[data-test-subj="stepScheduleRule"]')).toHaveLength(1);
+ });
+
+ it('renders correctly if isReadOnlyView', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('StepContentWrapper')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_schedule_rule/schema.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_schedule_rule/schema.tsx
index 8fbfdf5f25a51..e79aec2be6e15 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_schedule_rule/schema.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_schedule_rule/schema.tsx
@@ -4,6 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
+/* istanbul ignore file */
+
import { i18n } from '@kbn/i18n';
import { OptionalFieldLabel } from '../optional_field_label';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/throttle_select_field/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/throttle_select_field/index.test.tsx
new file mode 100644
index 0000000000000..0ab19b671494e
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/throttle_select_field/index.test.tsx
@@ -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 React from 'react';
+import { shallow } from 'enzyme';
+
+import { ThrottleSelectField } from './index';
+import { useFormFieldMock } from '../../../../../mock';
+
+describe('ThrottleSelectField', () => {
+ it('renders correctly', () => {
+ const Component = () => {
+ const field = useFormFieldMock();
+
+ return ;
+ };
+ const wrapper = shallow( );
+
+ expect(wrapper.dive().find('SelectField')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/create/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/create/index.test.tsx
new file mode 100644
index 0000000000000..db32be652d0f7
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/create/index.test.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 React from 'react';
+import { shallow } from 'enzyme';
+
+import { TestProviders } from '../../../../mock';
+import { CreateRulePage } from './index';
+import { useUserInfo } from '../../components/user_info';
+
+jest.mock('../../components/user_info');
+
+describe('CreateRulePage', () => {
+ it('renders correctly', () => {
+ (useUserInfo as jest.Mock).mockReturnValue({});
+ const wrapper = shallow( , { wrappingComponent: TestProviders });
+
+ expect(wrapper.find('[title="Create new rule"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/failure_history.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/failure_history.test.tsx
new file mode 100644
index 0000000000000..a83ff4c54b076
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/failure_history.test.tsx
@@ -0,0 +1,27 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { TestProviders } from '../../../../mock';
+import { FailureHistory } from './failure_history';
+import { useRuleStatus } from '../../../../containers/detection_engine/rules';
+jest.mock('../../../../containers/detection_engine/rules');
+
+describe('FailureHistory', () => {
+ beforeAll(() => {
+ (useRuleStatus as jest.Mock).mockReturnValue([false, null]);
+ });
+
+ it('renders correctly', () => {
+ const wrapper = shallow( , {
+ wrappingComponent: TestProviders,
+ });
+
+ expect(wrapper.find('EuiBasicTable')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.test.tsx
new file mode 100644
index 0000000000000..19c6f39a9bc7e
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.test.tsx
@@ -0,0 +1,47 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import '../../../../mock/match_media';
+import { TestProviders } from '../../../../mock';
+import { RuleDetailsPageComponent } from './index';
+import { setAbsoluteRangeDatePicker } from '../../../../store/inputs/actions';
+import { useUserInfo } from '../../components/user_info';
+import { useParams } from 'react-router-dom';
+
+jest.mock('../../components/user_info');
+jest.mock('react-router-dom', () => {
+ const originalModule = jest.requireActual('react-router-dom');
+
+ return {
+ ...originalModule,
+ useParams: jest.fn(),
+ };
+});
+
+describe('RuleDetailsPageComponent', () => {
+ beforeAll(() => {
+ (useUserInfo as jest.Mock).mockReturnValue({});
+ (useParams as jest.Mock).mockReturnValue({});
+ });
+
+ it('renders correctly', () => {
+ const wrapper = shallow(
+ ,
+ {
+ wrappingComponent: TestProviders,
+ }
+ );
+
+ expect(wrapper.find('WithSource')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.tsx
index 2b648a3b3f825..14e5f2b90882e 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.tsx
@@ -88,7 +88,7 @@ const ruleDetailTabs = [
},
];
-const RuleDetailsPageComponent: FC = ({
+export const RuleDetailsPageComponent: FC = ({
filters,
query,
setAbsoluteRangeDatePicker,
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/status_failed_callout.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/status_failed_callout.test.tsx
new file mode 100644
index 0000000000000..3394b0fc8c5c0
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/status_failed_callout.test.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.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+
+import { RuleStatusFailedCallOut } from './status_failed_callout';
+
+describe('RuleStatusFailedCallOut', () => {
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('EuiCallOut')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/edit/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/edit/index.test.tsx
new file mode 100644
index 0000000000000..d22bc12abf9fa
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/edit/index.test.tsx
@@ -0,0 +1,33 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { TestProviders } from '../../../../mock';
+import { EditRulePage } from './index';
+import { useUserInfo } from '../../components/user_info';
+import { useParams } from 'react-router-dom';
+
+jest.mock('../../components/user_info');
+jest.mock('react-router-dom', () => {
+ const originalModule = jest.requireActual('react-router-dom');
+
+ return {
+ ...originalModule,
+ useParams: jest.fn(),
+ };
+});
+
+describe('EditRulePage', () => {
+ it('renders correctly', () => {
+ (useUserInfo as jest.Mock).mockReturnValue({});
+ (useParams as jest.Mock).mockReturnValue({});
+ const wrapper = shallow( , { wrappingComponent: TestProviders });
+
+ expect(wrapper.find('[title="Edit rule settings"]')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/helpers.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/helpers.test.tsx
index 443dbd2c93a35..1c01a19573cd6 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/helpers.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/helpers.test.tsx
@@ -302,11 +302,25 @@ describe('rule helpers', () => {
test('returns expected ActionsStepRule rule object', () => {
const mockedRule = {
...mockRule('test-id'),
- actions: [],
+ actions: [
+ {
+ id: 'id',
+ group: 'group',
+ params: {},
+ action_type_id: 'action_type_id',
+ },
+ ],
};
const result: ActionsStepRule = getActionsStepsData(mockedRule);
const expected = {
- actions: [],
+ actions: [
+ {
+ id: 'id',
+ group: 'group',
+ params: {},
+ actionTypeId: 'action_type_id',
+ },
+ ],
enabled: mockedRule.enabled,
isNew: false,
throttle: 'no_actions',
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx
new file mode 100644
index 0000000000000..3fa81ca3ced08
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx
@@ -0,0 +1,27 @@
+/*
+ * 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 { shallow } from 'enzyme';
+
+import { RulesPage } from './index';
+import { useUserInfo } from '../components/user_info';
+import { usePrePackagedRules } from '../../../containers/detection_engine/rules';
+
+jest.mock('../components/user_info');
+jest.mock('../../../containers/detection_engine/rules');
+
+describe('RulesPage', () => {
+ beforeAll(() => {
+ (useUserInfo as jest.Mock).mockReturnValue({});
+ (usePrePackagedRules as jest.Mock).mockReturnValue({});
+ });
+ it('renders correctly', () => {
+ const wrapper = shallow( );
+
+ expect(wrapper.find('AllRules')).toHaveLength(1);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/utils.test.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/utils.test.ts
new file mode 100644
index 0000000000000..34a521ed32b12
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/utils.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 { getBreadcrumbs } from './utils';
+
+describe('getBreadcrumbs', () => {
+ it('returns default value for incorrect params', () => {
+ expect(
+ getBreadcrumbs(
+ {
+ pageName: 'pageName',
+ detailName: 'detailName',
+ tabName: undefined,
+ search: '',
+ pathName: 'pathName',
+ },
+ []
+ )
+ ).toEqual([{ href: '#/link-to/detections', text: 'Detections' }]);
+ });
+});
diff --git a/x-pack/plugins/actions/server/plugin.test.ts b/x-pack/plugins/actions/server/plugin.test.ts
index 6215b08df81d4..fa5b2f9399a4d 100644
--- a/x-pack/plugins/actions/server/plugin.test.ts
+++ b/x-pack/plugins/actions/server/plugin.test.ts
@@ -99,6 +99,9 @@ describe('Actions Plugin', () => {
savedObjects: {
client: {},
},
+ elasticsearch: {
+ adminClient: jest.fn(),
+ },
},
} as any,
httpServerMock.createKibanaRequest(),
diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts
index ef3716070ab04..a8ab3bbb2fad2 100644
--- a/x-pack/plugins/actions/server/plugin.ts
+++ b/x-pack/plugins/actions/server/plugin.ts
@@ -11,13 +11,13 @@ import {
Plugin,
CoreSetup,
CoreStart,
- IClusterClient,
KibanaRequest,
Logger,
SharedGlobalConfig,
RequestHandler,
IContextProvider,
SavedObjectsServiceStart,
+ ElasticsearchServiceStart,
} from '../../../../src/core/server';
import {
@@ -89,7 +89,6 @@ export class ActionsPlugin implements Plugin, Plugi
private readonly logger: Logger;
private serverBasePath?: string;
- private adminClient?: IClusterClient;
private taskRunnerFactory?: TaskRunnerFactory;
private actionTypeRegistry?: ActionTypeRegistry;
private actionExecutor?: ActionExecutor;
@@ -173,7 +172,6 @@ export class ActionsPlugin implements Plugin, Plugi
this.actionTypeRegistry = actionTypeRegistry;
this.serverBasePath = core.http.basePath.serverBasePath;
this.actionExecutor = actionExecutor;
- this.adminClient = core.elasticsearch.adminClient;
this.spaces = plugins.spaces?.spacesService;
registerBuiltInActionTypes({
@@ -233,7 +231,6 @@ export class ActionsPlugin implements Plugin, Plugi
actionTypeRegistry,
taskRunnerFactory,
kibanaIndex,
- adminClient,
isESOUsingEphemeralEncryptionKey,
preconfiguredActions,
} = this;
@@ -242,7 +239,7 @@ export class ActionsPlugin implements Plugin, Plugi
logger,
eventLogger: this.eventLogger!,
spaces: this.spaces,
- getServices: this.getServicesFactory(core.savedObjects),
+ getServices: this.getServicesFactory(core.savedObjects, core.elasticsearch),
encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects,
actionTypeRegistry: actionTypeRegistry!,
preconfiguredActions,
@@ -282,7 +279,7 @@ export class ActionsPlugin implements Plugin, Plugi
savedObjectsClient: core.savedObjects.getScopedClient(request),
actionTypeRegistry: actionTypeRegistry!,
defaultKibanaIndex: await kibanaIndex,
- scopedClusterClient: adminClient!.asScoped(request),
+ scopedClusterClient: core.elasticsearch.legacy.client.asScoped(request),
preconfiguredActions,
});
},
@@ -291,11 +288,11 @@ export class ActionsPlugin implements Plugin, Plugi
}
private getServicesFactory(
- savedObjects: SavedObjectsServiceStart
+ savedObjects: SavedObjectsServiceStart,
+ elasticsearch: ElasticsearchServiceStart
): (request: KibanaRequest) => Services {
- const { adminClient } = this;
return request => ({
- callCluster: adminClient!.asScoped(request).callAsCurrentUser,
+ callCluster: elasticsearch.legacy.client.asScoped(request).callAsCurrentUser,
savedObjectsClient: savedObjects.getScopedClient(request),
});
}
@@ -303,12 +300,8 @@ export class ActionsPlugin implements Plugin, Plugi
private createRouteHandlerContext = (
defaultKibanaIndex: string
): IContextProvider, 'actions'> => {
- const {
- actionTypeRegistry,
- adminClient,
- isESOUsingEphemeralEncryptionKey,
- preconfiguredActions,
- } = this;
+ const { actionTypeRegistry, isESOUsingEphemeralEncryptionKey, preconfiguredActions } = this;
+
return async function actionsRouteHandlerContext(context, request) {
return {
getActionsClient: () => {
@@ -321,7 +314,7 @@ export class ActionsPlugin implements Plugin, Plugi
savedObjectsClient: context.core.savedObjects.client,
actionTypeRegistry: actionTypeRegistry!,
defaultKibanaIndex,
- scopedClusterClient: adminClient!.asScoped(request),
+ scopedClusterClient: context.core.elasticsearch.adminClient,
preconfiguredActions,
});
},
diff --git a/x-pack/plugins/actions/server/usage/task.ts b/x-pack/plugins/actions/server/usage/task.ts
index a07a2aa8f1c70..ed0d876ed0208 100644
--- a/x-pack/plugins/actions/server/usage/task.ts
+++ b/x-pack/plugins/actions/server/usage/task.ts
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { Logger, CoreSetup } from 'kibana/server';
+import { Logger, CoreSetup, APICaller } from 'kibana/server';
import moment from 'moment';
import {
RunContext,
@@ -62,7 +62,11 @@ async function scheduleTasks(logger: Logger, taskManager: TaskManagerStartContra
export function telemetryTaskRunner(logger: Logger, core: CoreSetup, kibanaIndex: string) {
return ({ taskInstance }: RunContext) => {
const { state } = taskInstance;
- const callCluster = core.elasticsearch.adminClient.callAsInternalUser;
+ const callCluster = (...args: Parameters) => {
+ return core.getStartServices().then(([{ elasticsearch: { legacy: { client } } }]) =>
+ client.callAsInternalUser(...args)
+ );
+ };
return {
async run() {
return Promise.all([
diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts
index fdca6c0a9b503..ad39d09bd6d3d 100644
--- a/x-pack/plugins/alerting/server/plugin.ts
+++ b/x-pack/plugins/alerting/server/plugin.ts
@@ -19,7 +19,6 @@ import { TaskRunnerFactory } from './task_runner';
import { AlertsClientFactory } from './alerts_client_factory';
import { LicenseState } from './lib/license_state';
import {
- IClusterClient,
KibanaRequest,
Logger,
PluginInitializerContext,
@@ -29,6 +28,7 @@ import {
IContextProvider,
RequestHandler,
SharedGlobalConfig,
+ ElasticsearchServiceStart,
} from '../../../../src/core/server';
import {
@@ -94,7 +94,6 @@ export class AlertingPlugin {
private readonly logger: Logger;
private alertTypeRegistry?: AlertTypeRegistry;
private readonly taskRunnerFactory: TaskRunnerFactory;
- private adminClient?: IClusterClient;
private serverBasePath?: string;
private licenseState: LicenseState | null = null;
private isESOUsingEphemeralEncryptionKey?: boolean;
@@ -119,7 +118,6 @@ export class AlertingPlugin {
}
public async setup(core: CoreSetup, plugins: AlertingPluginsSetup): Promise {
- this.adminClient = core.elasticsearch.adminClient;
this.licenseState = new LicenseState(plugins.licensing.license$);
this.spaces = plugins.spaces?.spacesService;
this.security = plugins.security;
@@ -223,7 +221,7 @@ export class AlertingPlugin {
taskRunnerFactory.initialize({
logger,
- getServices: this.getServicesFactory(core.savedObjects),
+ getServices: this.getServicesFactory(core.savedObjects, core.elasticsearch),
spaceIdToNamespace: this.spaceIdToNamespace,
actionsPlugin: plugins.actions,
encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects,
@@ -263,11 +261,11 @@ export class AlertingPlugin {
};
private getServicesFactory(
- savedObjects: SavedObjectsServiceStart
+ savedObjects: SavedObjectsServiceStart,
+ elasticsearch: ElasticsearchServiceStart
): (request: KibanaRequest) => Services {
- const { adminClient } = this;
return request => ({
- callCluster: adminClient!.asScoped(request).callAsCurrentUser,
+ callCluster: elasticsearch.legacy.client.asScoped(request).callAsCurrentUser,
savedObjectsClient: savedObjects.getScopedClient(request),
});
}
diff --git a/x-pack/plugins/alerting/server/usage/task.ts b/x-pack/plugins/alerting/server/usage/task.ts
index 3da60aef301e2..ab62d81d44f8a 100644
--- a/x-pack/plugins/alerting/server/usage/task.ts
+++ b/x-pack/plugins/alerting/server/usage/task.ts
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { Logger, CoreSetup } from 'kibana/server';
+import { Logger, CoreSetup, APICaller } from 'kibana/server';
import moment from 'moment';
import {
RunContext,
@@ -65,7 +65,12 @@ async function scheduleTasks(logger: Logger, taskManager: TaskManagerStartContra
export function telemetryTaskRunner(logger: Logger, core: CoreSetup, kibanaIndex: string) {
return ({ taskInstance }: RunContext) => {
const { state } = taskInstance;
- const callCluster = core.elasticsearch.adminClient.callAsInternalUser;
+ const callCluster = (...args: Parameters) => {
+ return core.getStartServices().then(([{ elasticsearch: { legacy: { client } } }]) =>
+ client.callAsInternalUser(...args)
+ );
+ };
+
return {
async run() {
return Promise.all([
diff --git a/x-pack/plugins/apm/server/plugin.ts b/x-pack/plugins/apm/server/plugin.ts
index e18b6d33ca419..b434d41982f4c 100644
--- a/x-pack/plugins/apm/server/plugin.ts
+++ b/x-pack/plugins/apm/server/plugin.ts
@@ -3,7 +3,13 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
-import { PluginInitializerContext, Plugin, CoreSetup } from 'src/core/server';
+import {
+ PluginInitializerContext,
+ Plugin,
+ CoreSetup,
+ CoreStart,
+ Logger
+} from 'src/core/server';
import { Observable, combineLatest, AsyncSubject } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { Server } from 'hapi';
@@ -37,6 +43,8 @@ export interface APMPluginContract {
}
export class APMPlugin implements Plugin {
+ private currentConfig?: APMConfig;
+ private logger?: Logger;
legacySetup$: AsyncSubject;
constructor(private readonly initContext: PluginInitializerContext) {
this.initContext = initContext;
@@ -56,7 +64,7 @@ export class APMPlugin implements Plugin {
actions?: ActionsPlugin['setup'];
}
) {
- const logger = this.initContext.logger.get();
+ this.logger = this.initContext.logger.get();
const config$ = this.initContext.config.create();
const mergedConfig$ = combineLatest(plugins.apm_oss.config$, config$).pipe(
map(([apmOssConfig, apmConfig]) => mergeConfigs(apmOssConfig, apmConfig))
@@ -71,49 +79,40 @@ export class APMPlugin implements Plugin {
}
this.legacySetup$.subscribe(__LEGACY => {
- createApmApi().init(core, { config$: mergedConfig$, logger, __LEGACY });
+ createApmApi().init(core, {
+ config$: mergedConfig$,
+ logger: this.logger!,
+ __LEGACY
+ });
});
- const currentConfig = await mergedConfig$.pipe(take(1)).toPromise();
+ this.currentConfig = await mergedConfig$.pipe(take(1)).toPromise();
if (
plugins.taskManager &&
plugins.usageCollection &&
- currentConfig['xpack.apm.telemetryCollectionEnabled']
+ this.currentConfig['xpack.apm.telemetryCollectionEnabled']
) {
createApmTelemetry({
core,
config$: mergedConfig$,
usageCollector: plugins.usageCollection,
taskManager: plugins.taskManager,
- logger
+ logger: this.logger
});
}
- // create agent configuration index without blocking setup lifecycle
- createApmAgentConfigurationIndex({
- esClient: core.elasticsearch.dataClient,
- config: currentConfig,
- logger
- });
- // create custom action index without blocking setup lifecycle
- createApmCustomLinkIndex({
- esClient: core.elasticsearch.dataClient,
- config: currentConfig,
- logger
- });
-
plugins.home.tutorials.registerTutorial(
tutorialProvider({
- isEnabled: currentConfig['xpack.apm.ui.enabled'],
- indexPatternTitle: currentConfig['apm_oss.indexPattern'],
+ isEnabled: this.currentConfig['xpack.apm.ui.enabled'],
+ indexPatternTitle: this.currentConfig['apm_oss.indexPattern'],
cloud: plugins.cloud,
indices: {
- errorIndices: currentConfig['apm_oss.errorIndices'],
- metricsIndices: currentConfig['apm_oss.metricsIndices'],
- onboardingIndices: currentConfig['apm_oss.onboardingIndices'],
- sourcemapIndices: currentConfig['apm_oss.sourcemapIndices'],
- transactionIndices: currentConfig['apm_oss.transactionIndices']
+ errorIndices: this.currentConfig['apm_oss.errorIndices'],
+ metricsIndices: this.currentConfig['apm_oss.metricsIndices'],
+ onboardingIndices: this.currentConfig['apm_oss.onboardingIndices'],
+ sourcemapIndices: this.currentConfig['apm_oss.sourcemapIndices'],
+ transactionIndices: this.currentConfig['apm_oss.transactionIndices']
}
})
);
@@ -127,12 +126,29 @@ export class APMPlugin implements Plugin {
getApmIndices: async () =>
getApmIndices({
savedObjectsClient: await getInternalSavedObjectsClient(core),
- config: currentConfig
+ config: await mergedConfig$.pipe(take(1)).toPromise()
})
};
}
- public async start() {}
+ public start(core: CoreStart) {
+ if (this.currentConfig == null || this.logger == null) {
+ throw new Error('APMPlugin needs to be setup before calling start()');
+ }
+
+ // create agent configuration index without blocking start lifecycle
+ createApmAgentConfigurationIndex({
+ esClient: core.elasticsearch.legacy.client,
+ config: this.currentConfig,
+ logger: this.logger
+ });
+ // create custom action index without blocking start lifecycle
+ createApmCustomLinkIndex({
+ esClient: core.elasticsearch.legacy.client,
+ config: this.currentConfig,
+ logger: this.logger
+ });
+ }
public stop() {}
}
diff --git a/x-pack/plugins/endpoint/common/generate_data.ts b/x-pack/plugins/endpoint/common/generate_data.ts
index 3f783d90e577d..1978d780f54f5 100644
--- a/x-pack/plugins/endpoint/common/generate_data.ts
+++ b/x-pack/plugins/endpoint/common/generate_data.ts
@@ -6,11 +6,8 @@
import uuid from 'uuid';
import seedrandom from 'seedrandom';
-import { AlertEvent, EndpointEvent, HostMetadata, OSFields, HostFields } from './types';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { PolicyData } from '../public/applications/endpoint/types';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { generatePolicy } from '../public/applications/endpoint/models/policy';
+import { AlertEvent, EndpointEvent, HostMetadata, OSFields, HostFields, PolicyData } from './types';
+import { factory as policyFactory } from './models/policy_config';
export type Event = AlertEvent | EndpointEvent;
@@ -474,7 +471,7 @@ export class EndpointDocGenerator {
streams: [],
config: {
policy: {
- value: generatePolicy(),
+ value: policyFactory(),
},
},
},
diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/models/policy.ts b/x-pack/plugins/endpoint/common/models/policy_config.ts
similarity index 89%
rename from x-pack/plugins/endpoint/public/applications/endpoint/models/policy.ts
rename to x-pack/plugins/endpoint/common/models/policy_config.ts
index 5269ee72f4039..199b8a91e4307 100644
--- a/x-pack/plugins/endpoint/public/applications/endpoint/models/policy.ts
+++ b/x-pack/plugins/endpoint/common/models/policy_config.ts
@@ -7,11 +7,9 @@
import { PolicyConfig, ProtectionModes } from '../types';
/**
- * Generate a new Policy model.
- * NOTE: in the near future, this will likely be removed and an API call to EPM will be used to retrieve
- * the latest from the Endpoint package
+ * Return a new default `PolicyConfig`.
*/
-export const generatePolicy = (): PolicyConfig => {
+export const factory = (): PolicyConfig => {
return {
windows: {
events: {
diff --git a/x-pack/plugins/endpoint/common/types.ts b/x-pack/plugins/endpoint/common/types.ts
index 403ca9832e191..7143f07d8c702 100644
--- a/x-pack/plugins/endpoint/common/types.ts
+++ b/x-pack/plugins/endpoint/common/types.ts
@@ -7,12 +7,15 @@
import { SearchResponse } from 'elasticsearch';
import { TypeOf } from '@kbn/config-schema';
import { alertingIndexGetQuerySchema } from './schema/alert_index';
+import { Datasource, NewDatasource } from '../../ingest_manager/common';
/**
* A deep readonly type that will make all children of a given object readonly recursively
*/
export type Immutable = T extends undefined | null | boolean | string | number
? T
+ : unknown extends T
+ ? unknown
: T extends Array
? ImmutableArray
: T extends Map
@@ -442,3 +445,125 @@ export type AlertingIndexGetQueryInput = KbnConfigSchemaInputTypeOf<
* Result of the validated query params when handling alert index requests.
*/
export type AlertingIndexGetQueryResult = TypeOf;
+
+/**
+ * Endpoint Policy configuration
+ */
+export interface PolicyConfig {
+ windows: {
+ events: {
+ dll_and_driver_load: boolean;
+ dns: boolean;
+ file: boolean;
+ network: boolean;
+ process: boolean;
+ registry: boolean;
+ security: boolean;
+ };
+ malware: MalwareFields;
+ logging: {
+ stdout: string;
+ file: string;
+ };
+ advanced: PolicyConfigAdvancedOptions;
+ };
+ mac: {
+ events: {
+ file: boolean;
+ process: boolean;
+ network: boolean;
+ };
+ malware: MalwareFields;
+ logging: {
+ stdout: string;
+ file: string;
+ };
+ advanced: PolicyConfigAdvancedOptions;
+ };
+ linux: {
+ events: {
+ file: boolean;
+ process: boolean;
+ network: boolean;
+ };
+ logging: {
+ stdout: string;
+ file: string;
+ };
+ advanced: PolicyConfigAdvancedOptions;
+ };
+}
+
+/**
+ * Windows-specific policy configuration that is supported via the UI
+ */
+type WindowsPolicyConfig = Pick;
+
+/**
+ * Mac-specific policy configuration that is supported via the UI
+ */
+type MacPolicyConfig = Pick;
+
+/**
+ * Linux-specific policy configuration that is supported via the UI
+ */
+type LinuxPolicyConfig = Pick;
+
+/**
+ * The set of Policy configuration settings that are show/edited via the UI
+ */
+export interface UIPolicyConfig {
+ windows: WindowsPolicyConfig;
+ mac: MacPolicyConfig;
+ linux: LinuxPolicyConfig;
+}
+
+interface PolicyConfigAdvancedOptions {
+ elasticsearch: {
+ indices: {
+ control: string;
+ event: string;
+ logging: string;
+ };
+ kernel: {
+ connect: boolean;
+ process: boolean;
+ };
+ };
+}
+
+/** Policy: Malware protection fields */
+export interface MalwareFields {
+ mode: ProtectionModes;
+}
+
+/** Policy protection mode options */
+export enum ProtectionModes {
+ detect = 'detect',
+ prevent = 'prevent',
+ preventNotify = 'preventNotify',
+ off = 'off',
+}
+
+/**
+ * Endpoint Policy data, which extends Ingest's `Datasource` type
+ */
+export type PolicyData = Datasource & NewPolicyData;
+
+/**
+ * New policy data. Used when updating the policy record via ingest APIs
+ */
+export type NewPolicyData = NewDatasource & {
+ inputs: [
+ {
+ type: 'endpoint';
+ enabled: boolean;
+ streams: [];
+ config: {
+ policy: {
+ value: PolicyConfig;
+ };
+ };
+ }
+ ];
+};
diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/models/index_pattern.ts b/x-pack/plugins/endpoint/public/applications/endpoint/models/index_pattern.ts
new file mode 100644
index 0000000000000..0cae054432f96
--- /dev/null
+++ b/x-pack/plugins/endpoint/public/applications/endpoint/models/index_pattern.ts
@@ -0,0 +1,16 @@
+/*
+ * 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 { all } from 'deepmerge';
+import { Immutable } from '../../../../common/types';
+import { IIndexPattern } from '../../../../../../../src/plugins/data/common';
+
+/**
+ * Model for the `IIndexPattern` interface exported by the `data` plugin.
+ */
+export function clone(value: IIndexPattern | Immutable): IIndexPattern {
+ return all([value]) as IIndexPattern;
+}
diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/models/policy_details_config.ts b/x-pack/plugins/endpoint/public/applications/endpoint/models/policy_details_config.ts
index bf96942e83a91..3e56b1ff14d65 100644
--- a/x-pack/plugins/endpoint/public/applications/endpoint/models/policy_details_config.ts
+++ b/x-pack/plugins/endpoint/public/applications/endpoint/models/policy_details_config.ts
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { UIPolicyConfig } from '../types';
+import { UIPolicyConfig } from '../../../../common/types';
/**
* A typed Object.entries() function where the keys and values are typed based on the given object
diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_details.test.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_details.test.ts
index 79e9de9c67352..feac8944f476b 100644
--- a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_details.test.ts
+++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_details.test.ts
@@ -14,16 +14,17 @@ import { coreMock } from 'src/core/public/mocks';
import { DepsStartMock, depsStartMock } from '../../mocks';
import { createBrowserHistory } from 'history';
import { mockAlertResultList } from './mock_alert_result_list';
+import { Immutable } from '../../../../../common/types';
describe('alert details tests', () => {
- let store: Store;
+ let store: Store, Immutable>;
let coreStart: ReturnType;
let depsStart: DepsStartMock;
let history: History;
/**
* A function that waits until a selector returns true.
*/
- let selectorIsTrue: (selector: (state: AlertListState) => boolean) => Promise;
+ let selectorIsTrue: (selector: (state: Immutable) => boolean) => Promise;
beforeEach(() => {
coreStart = coreMock.createStart();
depsStart = depsStartMock();
diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list.test.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list.test.ts
index b1cc2d46f614a..84281813312e0 100644
--- a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list.test.ts
+++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list.test.ts
@@ -12,20 +12,20 @@ import { alertMiddlewareFactory } from './middleware';
import { AppAction } from '../action';
import { coreMock } from 'src/core/public/mocks';
import { DepsStartMock, depsStartMock } from '../../mocks';
-import { AlertResultList } from '../../../../../common/types';
+import { AlertResultList, Immutable } from '../../../../../common/types';
import { isOnAlertPage } from './selectors';
import { createBrowserHistory } from 'history';
import { mockAlertResultList } from './mock_alert_result_list';
describe('alert list tests', () => {
- let store: Store;
+ let store: Store, Immutable>;
let coreStart: ReturnType;
let depsStart: DepsStartMock;
let history: History;
/**
* A function that waits until a selector returns true.
*/
- let selectorIsTrue: (selector: (state: AlertListState) => boolean) => Promise;
+ let selectorIsTrue: (selector: (state: Immutable) => boolean) => Promise;
beforeEach(() => {
coreStart = coreMock.createStart();
depsStart = depsStartMock();
diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list_pagination.test.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list_pagination.test.ts
index bb5893f14287b..4cc86e9c0449c 100644
--- a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list_pagination.test.ts
+++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list_pagination.test.ts
@@ -15,9 +15,10 @@ import { DepsStartMock, depsStartMock } from '../../mocks';
import { createBrowserHistory } from 'history';
import { uiQueryParams } from './selectors';
import { urlFromQueryParams } from '../../view/alerts/url_from_query_params';
+import { Immutable } from '../../../../../common/types';
describe('alert list pagination', () => {
- let store: Store;
+ let store: Store, Immutable>;
let coreStart: ReturnType;
let depsStart: DepsStartMock;
let history: History;
diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/reducer.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/reducer.ts
index 4430a4d39cf4a..52b91dcae7d70 100644
--- a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/reducer.ts
+++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/reducer.ts
@@ -4,11 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { Reducer } from 'redux';
-import { AlertListState } from '../../types';
+import { AlertListState, ImmutableReducer } from '../../types';
import { AppAction } from '../action';
+import { Immutable } from '../../../../../common/types';
-const initialState = (): AlertListState => {
+const initialState = (): Immutable => {
return {
alerts: [],
alertDetails: undefined,
@@ -22,7 +22,7 @@ const initialState = (): AlertListState => {
};
};
-export const alertListReducer: Reducer = (
+export const alertListReducer: ImmutableReducer = (
state = initialState(),
action
) => {
diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/selectors.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/selectors.ts
index 5e9b08c09c2c7..cc362c3701956 100644
--- a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/selectors.ts
+++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/selectors.ts
@@ -19,23 +19,23 @@ const createStructuredSelector: CreateStructuredSelector = createStructuredSelec
/**
* Returns the Alert Data array from state
*/
-export const alertListData = (state: AlertListState) => state.alerts;
+export const alertListData = (state: Immutable) => state.alerts;
-export const selectedAlertDetailsData = (state: AlertListState) => state.alertDetails;
+export const selectedAlertDetailsData = (state: Immutable) => state.alertDetails;
/**
* Returns the alert list pagination data from state
*/
export const alertListPagination = createStructuredSelector({
- pageIndex: (state: AlertListState) => state.pageIndex,
- pageSize: (state: AlertListState) => state.pageSize,
- total: (state: AlertListState) => state.total,
+ pageIndex: (state: Immutable) => state.pageIndex,
+ pageSize: (state: Immutable) => state.pageSize,
+ total: (state: Immutable) => state.total,
});
/**
* Returns a boolean based on whether or not the user is on the alerts page
*/
-export const isOnAlertPage = (state: AlertListState): boolean => {
+export const isOnAlertPage = (state: Immutable): boolean => {
return state.location ? state.location.pathname === '/alerts' : false;
};
@@ -44,10 +44,10 @@ export const isOnAlertPage = (state: AlertListState): boolean => {
* Used to calculate urls for links and such.
*/
export const uiQueryParams: (
- state: AlertListState
+ state: Immutable
) => Immutable = createSelector(
- (state: AlertListState) => state.location,
- (location: AlertListState['location']) => {
+ state => state.location,
+ (location: Immutable['location']) => {
const data: AlertingIndexUIQueryParams = {};
if (location) {
// Removes the `?` from the beginning of query string if it exists
@@ -82,7 +82,7 @@ export const uiQueryParams: (
* Parses the ui query params and returns a object that represents the query used by the SearchBar component.
* If the query url param is undefined, a default is returned.
*/
-export const searchBarQuery: (state: AlertListState) => Query = createSelector(
+export const searchBarQuery: (state: Immutable) => Query = createSelector(
uiQueryParams,
({ query }) => {
if (query !== undefined) {
@@ -97,21 +97,20 @@ export const searchBarQuery: (state: AlertListState) => Query = createSelector(
* Parses the ui query params and returns a rison encoded string that represents the search bar's date range.
* A default is provided if 'date_range' is not present in the url params.
*/
-export const encodedSearchBarDateRange: (state: AlertListState) => string = createSelector(
- uiQueryParams,
- ({ date_range: dateRange }) => {
- if (dateRange === undefined) {
- return encode({ from: 'now-24h', to: 'now' });
- } else {
- return dateRange;
- }
+export const encodedSearchBarDateRange: (
+ state: Immutable
+) => string = createSelector(uiQueryParams, ({ date_range: dateRange }) => {
+ if (dateRange === undefined) {
+ return encode({ from: 'now-24h', to: 'now' });
+ } else {
+ return dateRange;
}
-);
+});
/**
* Parses the ui query params and returns a object that represents the dateRange used by the SearchBar component.
*/
-export const searchBarDateRange: (state: AlertListState) => TimeRange = createSelector(
+export const searchBarDateRange: (state: Immutable) => TimeRange = createSelector(
encodedSearchBarDateRange,
encodedDateRange => {
return (decode(encodedDateRange) as unknown) as TimeRange;
@@ -122,7 +121,7 @@ export const searchBarDateRange: (state: AlertListState) => TimeRange = createSe
* Parses the ui query params and returns an array of filters used by the SearchBar component.
* If the 'filters' param is not present, a default is returned.
*/
-export const searchBarFilters: (state: AlertListState) => Filter[] = createSelector(
+export const searchBarFilters: (state: Immutable) => Filter[] = createSelector(
uiQueryParams,
({ filters }) => {
if (filters !== undefined) {
@@ -136,13 +135,14 @@ export const searchBarFilters: (state: AlertListState) => Filter[] = createSelec
/**
* Returns the indexPatterns used by the SearchBar component
*/
-export const searchBarIndexPatterns = (state: AlertListState) => state.searchBar.patterns;
+export const searchBarIndexPatterns = (state: Immutable) =>
+ state.searchBar.patterns;
/**
* query params to use when requesting alert data.
*/
export const apiQueryParams: (
- state: AlertListState
+ state: Immutable
) => Immutable = createSelector(
uiQueryParams,
encodedSearchBarDateRange,
@@ -161,7 +161,7 @@ export const apiQueryParams: (
* True if the user has selected an alert to see details about.
* Populated via the browsers query params.
*/
-export const hasSelectedAlert: (state: AlertListState) => boolean = createSelector(
+export const hasSelectedAlert: (state: Immutable) => boolean = createSelector(
uiQueryParams,
({ selected_alert: selectedAlert }) => selectedAlert !== undefined
);
diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts
index 4dafa68ddb647..21871ec8ca849 100644
--- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts
+++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts
@@ -27,14 +27,8 @@ interface UserPaginatedHostList {
payload: HostListPagination;
}
-// Why is FakeActionWithNoPayload here, see: https://github.com/elastic/endpoint-app-team/issues/273
-interface FakeActionWithNoPayload {
- type: 'fakeActionWithNoPayLoad';
-}
-
export type HostAction =
| ServerReturnedHostList
| ServerReturnedHostDetails
| ServerFailedToReturnHostDetails
- | UserPaginatedHostList
- | FakeActionWithNoPayload;
+ | UserPaginatedHostList;
diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts
index 8c8578426aa29..8f39baddda00e 100644
--- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts
+++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts
@@ -4,11 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { CoreStart, HttpSetup } from 'kibana/public';
-import { applyMiddleware, createStore, Dispatch, Store } from 'redux';
+import { applyMiddleware, createStore, Store } from 'redux';
import { coreMock } from '../../../../../../../../src/core/public/mocks';
import { History, createBrowserHistory } from 'history';
import { hostListReducer, hostMiddlewareFactory } from './index';
-import { HostResultList } from '../../../../../common/types';
+import { HostResultList, Immutable } from '../../../../../common/types';
import { HostListState } from '../../types';
import { AppAction } from '../action';
import { listData } from './selectors';
@@ -20,9 +20,10 @@ describe('host list middleware', () => {
let fakeCoreStart: jest.Mocked;
let depsStart: DepsStartMock;
let fakeHttpServices: jest.Mocked