diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 9a09ea1de6943..0949c5d742435 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -16,10 +16,11 @@
/src/plugins/discover/ @elastic/kibana-data-discovery
/x-pack/plugins/discover_enhanced/ @elastic/kibana-data-discovery
/test/functional/apps/discover/ @elastic/kibana-data-discovery
+/x-pack/plugins/graph/ @elastic/kibana-data-discovery
+/x-pack/test/functional/apps/graph @elastic/kibana-data-discovery
# Vis Editors
/x-pack/plugins/lens/ @elastic/kibana-vis-editors
-/x-pack/plugins/graph/ @elastic/kibana-vis-editors
/src/plugins/advanced_settings/ @elastic/kibana-vis-editors
/src/plugins/charts/ @elastic/kibana-vis-editors
/src/plugins/management/ @elastic/kibana-vis-editors
diff --git a/.github/workflows/sync-main-branch.yml b/.github/workflows/sync-main-branch.yml
index 63465602e8436..971ff0b9a6351 100644
--- a/.github/workflows/sync-main-branch.yml
+++ b/.github/workflows/sync-main-branch.yml
@@ -9,6 +9,7 @@ jobs:
sync_latest_from_upstream:
runs-on: ubuntu-latest
name: Sync latest commits from master branch
+ if: github.repository == 'elastic/kibana'
steps:
- name: Checkout target repo
diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc
index d2d543ff59d59..dfb62f23445ed 100644
--- a/docs/developer/plugin-list.asciidoc
+++ b/docs/developer/plugin-list.asciidoc
@@ -350,7 +350,7 @@ The plugin exposes the static DefaultEditorController class to consume.
|{kib-repo}blob/{branch}/x-pack/plugins/apm/readme.md[apm]
-|To access an elasticsearch instance that has live data you have two options:
+|Local setup documentation
|{kib-repo}blob/{branch}/x-pack/plugins/banners/README.md[banners]
diff --git a/docs/management/connectors/action-types/email.asciidoc b/docs/management/connectors/action-types/email.asciidoc
index 98d7b2591a572..131ff5ea5e9f6 100644
--- a/docs/management/connectors/action-types/email.asciidoc
+++ b/docs/management/connectors/action-types/email.asciidoc
@@ -107,7 +107,7 @@ For other email servers, you can check the list of well-known services that Node
[[elasticcloud]]
==== Sending email from Elastic Cloud
-IMPORTANT: These instructions require you to link:{cloud}/ec-watcher.html#ec-watcher-whitelist[whitelist] the email addresses that notifications get sent first.
+IMPORTANT: These instructions require you to link:{cloud}/ec-watcher.html#ec-watcher-whitelist[allowlist] the email addresses that notifications get sent.
Use the following connector settings to send email from Elastic Cloud:
diff --git a/docs/settings/logging-settings.asciidoc b/docs/settings/logging-settings.asciidoc
index aa38d54305eec..77f3bd90a911a 100644
--- a/docs/settings/logging-settings.asciidoc
+++ b/docs/settings/logging-settings.asciidoc
@@ -4,6 +4,16 @@
Logging settings
++++
+{kib} relies on three high-level entities to set the logging service: appenders, loggers, and root.
+
+- Appenders define where log messages are displayed (stdout or console) and their layout (`pattern` or `json`). They also allow you to specify if you want the logs stored and, if so, where (file on the disk).
+- Loggers define what logging settings, such as the level of verbosity and the appenders, to apply to a particular context. Each log entry context provides information about the service or plugin that emits it and any of its sub-parts, for example, `metrics.ops` or `elasticsearch.query`.
+- Root is a logger that applies to all the log entries in {kib}.
+
+Refer to the <> for common configuration use cases. To learn more about possible configuration values, go to {kibana-ref}/logging-service.html[{kib}'s Logging service].
+
+[[log-settings-compatibility]]
+==== Backwards compatibility
Compatibility with the legacy logging system is assured until the end of the `v7` version.
All log messages handled by `root` context (default) are forwarded to the legacy logging service.
The logging configuration is validated against the predefined schema and if there are
@@ -12,10 +22,12 @@ any issues with it, {kib} will fail to start with the detailed error message.
NOTE: When you switch to the new logging configuration, you will start seeing duplicate log entries in both formats.
These will be removed when the `default` appender is no longer required.
+[[log-settings-examples]]
+==== Examples
Here are some configuration examples for the most common logging use cases:
[[log-to-file-example]]
-==== Log to a file
+===== Log to a file
Log the default log format to a file instead of to stdout (the default).
@@ -33,10 +45,10 @@ logging:
----
[[log-in-json-ECS-example]]
-==== Log in json format
+===== Log in JSON format
-Log the default log format to json layout instead of pattern (the default).
-With `json` layout log messages will be formatted as JSON strings in https://www.elastic.co/guide/en/ecs/current/ecs-reference.html[ECS format] that includes a timestamp, log level, logger, message text and any other metadata that may be associated with the log message itself
+Log the default log format to JSON layout instead of pattern (the default).
+With `json` layout, log messages will be formatted as JSON strings in https://www.elastic.co/guide/en/ecs/current/ecs-reference.html[ECS format] that includes a timestamp, log level, logger, message text and any other metadata that may be associated with the log message itself.
[source,yaml]
----
@@ -51,7 +63,7 @@ logging:
----
[[log-with-meta-to-stdout]]
-==== Log with meta to stdout
+===== Log with meta to stdout
Include `%meta` in your pattern layout:
@@ -69,7 +81,7 @@ logging:
----
[[log-elasticsearch-queries]]
-==== Log {es} queries
+===== Log {es} queries
[source,yaml]
--
@@ -89,7 +101,7 @@ logging:
--
[[change-overall-log-level]]
-==== Change overall log level.
+===== Change overall log level
[source,yaml]
----
@@ -99,7 +111,7 @@ logging:
----
[[customize-specific-log-records]]
-==== Customize specific log records
+===== Customize specific log records
Here is a detailed configuration example that can be used to configure _loggers_, _appenders_ and _layouts_:
[source,yaml]
diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc
index 203339be638ab..78b776c85c937 100644
--- a/docs/setup/settings.asciidoc
+++ b/docs/setup/settings.asciidoc
@@ -295,12 +295,6 @@ is an alternative to `elasticsearch.username` and `elasticsearch.password`.
| `interpreter.enableInVisualize`
| Enables use of interpreter in Visualize. *Default: `true`*
-| `kibana.defaultAppId:`
- | deprecated:[7.9.0,This setting will be removed in Kibana 8.0.]
- Instead, use the <>.
- +
- The default application to load. *Default: `"home"`*
-
|[[kibana-index]] `kibana.index:`
| deprecated:[7.11.0,This setting will be removed in 8.0.] Multitenancy by
changing `kibana.index` will not be supported starting in 8.0. See
diff --git a/docs/user/alerting/rule-types/es-query.asciidoc b/docs/user/alerting/rule-types/es-query.asciidoc
index 5615c79a6c9c7..65d39ba170c3c 100644
--- a/docs/user/alerting/rule-types/es-query.asciidoc
+++ b/docs/user/alerting/rule-types/es-query.asciidoc
@@ -60,4 +60,32 @@ image::user/alerting/images/rule-types-es-query-valid.png[Test {es} query return
* An error message is shown if the query is invalid.
+
[role="screenshot"]
-image::user/alerting/images/rule-types-es-query-invalid.png[Test {es} query shows error when invalid]
\ No newline at end of file
+image::user/alerting/images/rule-types-es-query-invalid.png[Test {es} query shows error when invalid]
+
+[float]
+==== Match de-duplication
+
+The {es} query rule type performs de-duplication of document matches across rule executions. If you configure the rule with a schedule interval smaller than the time window, and a document matches a query in multiple rule executions, it will be alerted on only once.
+
+Suppose you have a rule configured to run every minute. The rule uses a time window of 1 hour and checks if there are more than 99 matches for the query. The {es} query rule type will do the following:
+
+[cols="3*<"]
+|===
+
+| `Execution 1 (0:00)`
+| Rule finds 113 matches in the last hour: `113 > 99`
+| Rule is active and user will be alerted.
+
+| `Execution 2 (0:01)`
+| Rule finds 127 matches in the last hour. 105 of the matches are duplicates that were alerted on in Execution 1, so you actually have 22 matches: `22 !> 99`
+| No alert.
+
+| `Execution 3 (0:02)`
+| Rule finds 159 matches in the last hour. 88 of the matches are duplicates that were alerted on in Execution 1, so you actually have 71 matches: `71 !> 99`
+| No alert.
+
+| `Execution 4 (0:03)`
+| Rule finds 190 matches in the last hour. 71 of them are duplicates that were alerted on in Exeuction 1, so you actually have 119 matches: `119 > 99`
+| Rule is active and user will be alerted.
+
+|===
\ No newline at end of file
diff --git a/package.json b/package.json
index e603190c72698..5aabfc66e4637 100644
--- a/package.json
+++ b/package.json
@@ -348,7 +348,7 @@
"react-moment-proptypes": "^1.7.0",
"react-monaco-editor": "^0.41.2",
"react-popper-tooltip": "^2.10.1",
- "react-query": "^3.21.0",
+ "react-query": "^3.21.1",
"react-redux": "^7.2.0",
"react-resizable": "^1.7.5",
"react-resize-detector": "^4.2.0",
diff --git a/packages/elastic-datemath/.babelrc b/packages/elastic-datemath/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/elastic-datemath/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-ace/.babelrc b/packages/kbn-ace/.babelrc
deleted file mode 100644
index 30ffbd24e1f18..0000000000000
--- a/packages/kbn-ace/.babelrc
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": [
- "src/ace/modes/x_json/worker/x_json.ace.worker.js"
- ]
-}
diff --git a/packages/kbn-ace/BUILD.bazel b/packages/kbn-ace/BUILD.bazel
index 5b9c38b16b53a..a13863b765d35 100644
--- a/packages/kbn-ace/BUILD.bazel
+++ b/packages/kbn-ace/BUILD.bazel
@@ -45,6 +45,8 @@ jsts_transpiler(
srcs = SRCS,
additional_args = [
"--copy-files",
+ "--ignore",
+ "**/*/src/ace/modes/x_json/worker/x_json.ace.worker.js",
"--quiet"
],
build_pkg_name = package_name(),
diff --git a/packages/kbn-alerts/.babelrc b/packages/kbn-alerts/.babelrc
deleted file mode 100644
index 40a198521b903..0000000000000
--- a/packages/kbn-alerts/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-alerts/.babelrc.browser b/packages/kbn-alerts/.babelrc.browser
deleted file mode 100644
index 71bbfbcd6eb2f..0000000000000
--- a/packages/kbn-alerts/.babelrc.browser
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-alerts/BUILD.bazel b/packages/kbn-alerts/BUILD.bazel
index a571380202cd6..91c575346fff7 100644
--- a/packages/kbn-alerts/BUILD.bazel
+++ b/packages/kbn-alerts/BUILD.bazel
@@ -57,7 +57,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-analytics/.babelrc b/packages/kbn-analytics/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-analytics/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-analytics/.babelrc.browser b/packages/kbn-analytics/.babelrc.browser
deleted file mode 100644
index dc6a77bbe0bcd..0000000000000
--- a/packages/kbn-analytics/.babelrc.browser
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"]
-}
diff --git a/packages/kbn-analytics/BUILD.bazel b/packages/kbn-analytics/BUILD.bazel
index ca8cdcbffbb52..cc65746e890ce 100644
--- a/packages/kbn-analytics/BUILD.bazel
+++ b/packages/kbn-analytics/BUILD.bazel
@@ -42,7 +42,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-apm-config-loader/.babelrc b/packages/kbn-apm-config-loader/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-apm-config-loader/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-apm-utils/.babelrc b/packages/kbn-apm-utils/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-apm-utils/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-babel-code-parser/.babelrc b/packages/kbn-babel-code-parser/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-babel-code-parser/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-cli-dev-mode/.babelrc b/packages/kbn-cli-dev-mode/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-cli-dev-mode/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-config-schema/.babelrc b/packages/kbn-config-schema/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-config-schema/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-config/.babelrc b/packages/kbn-config/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-config/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-crypto/.babelrc b/packages/kbn-crypto/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-crypto/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-dev-utils/.babelrc b/packages/kbn-dev-utils/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-dev-utils/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-docs-utils/.babelrc b/packages/kbn-docs-utils/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-docs-utils/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-es-archiver/.babelrc b/packages/kbn-es-archiver/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-es-archiver/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-es-query/.babelrc b/packages/kbn-es-query/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-es-query/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-es-query/.babelrc.browser b/packages/kbn-es-query/.babelrc.browser
deleted file mode 100644
index dc6a77bbe0bcd..0000000000000
--- a/packages/kbn-es-query/.babelrc.browser
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"]
-}
diff --git a/packages/kbn-es-query/BUILD.bazel b/packages/kbn-es-query/BUILD.bazel
index d4a531d308f6e..b3d861d937c8b 100644
--- a/packages/kbn-es-query/BUILD.bazel
+++ b/packages/kbn-es-query/BUILD.bazel
@@ -76,7 +76,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-es/.babelrc b/packages/kbn-es/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-es/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-field-types/.babelrc b/packages/kbn-field-types/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-field-types/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-i18n/.babelrc b/packages/kbn-i18n/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-i18n/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-i18n/.babelrc.browser b/packages/kbn-i18n/.babelrc.browser
deleted file mode 100644
index dc6a77bbe0bcd..0000000000000
--- a/packages/kbn-i18n/.babelrc.browser
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"]
-}
diff --git a/packages/kbn-i18n/BUILD.bazel b/packages/kbn-i18n/BUILD.bazel
index 62d5fb1d75a46..49d5603b2c516 100644
--- a/packages/kbn-i18n/BUILD.bazel
+++ b/packages/kbn-i18n/BUILD.bazel
@@ -65,7 +65,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-interpreter/.babelrc b/packages/kbn-interpreter/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-interpreter/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-io-ts-utils/.babelrc b/packages/kbn-io-ts-utils/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-io-ts-utils/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-legacy-logging/.babelrc b/packages/kbn-legacy-logging/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-legacy-logging/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-logging/.babelrc b/packages/kbn-logging/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-logging/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-mapbox-gl/.babelrc b/packages/kbn-mapbox-gl/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-mapbox-gl/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-monaco/.babelrc b/packages/kbn-monaco/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-monaco/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-monaco/.babelrc.browser b/packages/kbn-monaco/.babelrc.browser
deleted file mode 100644
index dc6a77bbe0bcd..0000000000000
--- a/packages/kbn-monaco/.babelrc.browser
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"]
-}
diff --git a/packages/kbn-monaco/BUILD.bazel b/packages/kbn-monaco/BUILD.bazel
index 3656210cb6b1b..d2d9bf3f9a00c 100644
--- a/packages/kbn-monaco/BUILD.bazel
+++ b/packages/kbn-monaco/BUILD.bazel
@@ -56,7 +56,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
webpack(
diff --git a/packages/kbn-optimizer/.babelrc b/packages/kbn-optimizer/.babelrc
deleted file mode 100644
index 1685d1644d94a..0000000000000
--- a/packages/kbn-optimizer/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.js"]
-}
diff --git a/packages/kbn-plugin-generator/.babelrc b/packages/kbn-plugin-generator/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-plugin-generator/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-plugin-helpers/.babelrc b/packages/kbn-plugin-helpers/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-plugin-helpers/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-rule-data-utils/.babelrc b/packages/kbn-rule-data-utils/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-rule-data-utils/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-securitysolution-autocomplete/.babelrc b/packages/kbn-securitysolution-autocomplete/.babelrc
deleted file mode 100644
index 40a198521b903..0000000000000
--- a/packages/kbn-securitysolution-autocomplete/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-autocomplete/.babelrc.browser b/packages/kbn-securitysolution-autocomplete/.babelrc.browser
deleted file mode 100644
index 71bbfbcd6eb2f..0000000000000
--- a/packages/kbn-securitysolution-autocomplete/.babelrc.browser
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-autocomplete/BUILD.bazel b/packages/kbn-securitysolution-autocomplete/BUILD.bazel
index 53cd7b4f8d3e1..ac90a0479ce2a 100644
--- a/packages/kbn-securitysolution-autocomplete/BUILD.bazel
+++ b/packages/kbn-securitysolution-autocomplete/BUILD.bazel
@@ -72,7 +72,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-securitysolution-es-utils/.babelrc b/packages/kbn-securitysolution-es-utils/.babelrc
deleted file mode 100644
index 40a198521b903..0000000000000
--- a/packages/kbn-securitysolution-es-utils/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-hook-utils/.babelrc b/packages/kbn-securitysolution-hook-utils/.babelrc
deleted file mode 100644
index b17a19d6faf3f..0000000000000
--- a/packages/kbn-securitysolution-hook-utils/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-hook-utils/.babelrc.browser b/packages/kbn-securitysolution-hook-utils/.babelrc.browser
deleted file mode 100644
index 71bbfbcd6eb2f..0000000000000
--- a/packages/kbn-securitysolution-hook-utils/.babelrc.browser
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-hook-utils/BUILD.bazel b/packages/kbn-securitysolution-hook-utils/BUILD.bazel
index de007b34eeb21..bc7fd3bce1412 100644
--- a/packages/kbn-securitysolution-hook-utils/BUILD.bazel
+++ b/packages/kbn-securitysolution-hook-utils/BUILD.bazel
@@ -54,7 +54,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/.babelrc b/packages/kbn-securitysolution-io-ts-alerting-types/.babelrc
deleted file mode 100644
index b17a19d6faf3f..0000000000000
--- a/packages/kbn-securitysolution-io-ts-alerting-types/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/.babelrc.browser b/packages/kbn-securitysolution-io-ts-alerting-types/.babelrc.browser
deleted file mode 100644
index 71bbfbcd6eb2f..0000000000000
--- a/packages/kbn-securitysolution-io-ts-alerting-types/.babelrc.browser
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel b/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel
index 940c6d589da11..cdee3a2f92540 100644
--- a/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel
+++ b/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel
@@ -55,7 +55,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-securitysolution-io-ts-list-types/.babelrc b/packages/kbn-securitysolution-io-ts-list-types/.babelrc
deleted file mode 100644
index 40a198521b903..0000000000000
--- a/packages/kbn-securitysolution-io-ts-list-types/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-io-ts-list-types/.babelrc.browser b/packages/kbn-securitysolution-io-ts-list-types/.babelrc.browser
deleted file mode 100644
index 71bbfbcd6eb2f..0000000000000
--- a/packages/kbn-securitysolution-io-ts-list-types/.babelrc.browser
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel b/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel
index 07ed552cdc408..ff4f2e80cbd37 100644
--- a/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel
+++ b/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel
@@ -53,7 +53,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts b/packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts
index 1909bcb1bcc2e..31f763101c258 100644
--- a/packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts
+++ b/packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts
@@ -40,7 +40,7 @@ export interface UseExceptionListsProps {
http: HttpStart;
namespaceTypes: NamespaceType[];
notifications: NotificationsStart;
- pagination?: Pagination;
+ initialPagination?: Pagination;
showTrustedApps: boolean;
showEventFilters: boolean;
}
diff --git a/packages/kbn-securitysolution-io-ts-types/.babelrc b/packages/kbn-securitysolution-io-ts-types/.babelrc
deleted file mode 100644
index 40a198521b903..0000000000000
--- a/packages/kbn-securitysolution-io-ts-types/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-io-ts-types/.babelrc.browser b/packages/kbn-securitysolution-io-ts-types/.babelrc.browser
deleted file mode 100644
index 71bbfbcd6eb2f..0000000000000
--- a/packages/kbn-securitysolution-io-ts-types/.babelrc.browser
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-io-ts-types/BUILD.bazel b/packages/kbn-securitysolution-io-ts-types/BUILD.bazel
index adabf9708a59f..fe2247ac0b614 100644
--- a/packages/kbn-securitysolution-io-ts-types/BUILD.bazel
+++ b/packages/kbn-securitysolution-io-ts-types/BUILD.bazel
@@ -53,7 +53,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-securitysolution-io-ts-utils/.babelrc b/packages/kbn-securitysolution-io-ts-utils/.babelrc
deleted file mode 100644
index 40a198521b903..0000000000000
--- a/packages/kbn-securitysolution-io-ts-utils/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-io-ts-utils/.babelrc.browser b/packages/kbn-securitysolution-io-ts-utils/.babelrc.browser
deleted file mode 100644
index 71bbfbcd6eb2f..0000000000000
--- a/packages/kbn-securitysolution-io-ts-utils/.babelrc.browser
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-io-ts-utils/BUILD.bazel b/packages/kbn-securitysolution-io-ts-utils/BUILD.bazel
index 346bd19451abd..24819bdd16a33 100644
--- a/packages/kbn-securitysolution-io-ts-utils/BUILD.bazel
+++ b/packages/kbn-securitysolution-io-ts-utils/BUILD.bazel
@@ -57,7 +57,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-securitysolution-list-api/.babelrc b/packages/kbn-securitysolution-list-api/.babelrc
deleted file mode 100644
index 40a198521b903..0000000000000
--- a/packages/kbn-securitysolution-list-api/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-list-api/.babelrc.browser b/packages/kbn-securitysolution-list-api/.babelrc.browser
deleted file mode 100644
index 71bbfbcd6eb2f..0000000000000
--- a/packages/kbn-securitysolution-list-api/.babelrc.browser
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-list-api/BUILD.bazel b/packages/kbn-securitysolution-list-api/BUILD.bazel
index 6858a9389119f..52a134456cdd9 100644
--- a/packages/kbn-securitysolution-list-api/BUILD.bazel
+++ b/packages/kbn-securitysolution-list-api/BUILD.bazel
@@ -56,7 +56,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-securitysolution-list-constants/.babelrc b/packages/kbn-securitysolution-list-constants/.babelrc
deleted file mode 100644
index 40a198521b903..0000000000000
--- a/packages/kbn-securitysolution-list-constants/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-list-constants/.babelrc.browser b/packages/kbn-securitysolution-list-constants/.babelrc.browser
deleted file mode 100644
index 71bbfbcd6eb2f..0000000000000
--- a/packages/kbn-securitysolution-list-constants/.babelrc.browser
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-list-constants/BUILD.bazel b/packages/kbn-securitysolution-list-constants/BUILD.bazel
index 9b3de9520f6a1..db4dd94091abf 100644
--- a/packages/kbn-securitysolution-list-constants/BUILD.bazel
+++ b/packages/kbn-securitysolution-list-constants/BUILD.bazel
@@ -45,7 +45,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-securitysolution-list-hooks/.babelrc b/packages/kbn-securitysolution-list-hooks/.babelrc
deleted file mode 100644
index 40a198521b903..0000000000000
--- a/packages/kbn-securitysolution-list-hooks/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-list-hooks/.babelrc.browser b/packages/kbn-securitysolution-list-hooks/.babelrc.browser
deleted file mode 100644
index 71bbfbcd6eb2f..0000000000000
--- a/packages/kbn-securitysolution-list-hooks/.babelrc.browser
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-list-hooks/BUILD.bazel b/packages/kbn-securitysolution-list-hooks/BUILD.bazel
index ba8c579bb97de..2a9666bd1429e 100644
--- a/packages/kbn-securitysolution-list-hooks/BUILD.bazel
+++ b/packages/kbn-securitysolution-list-hooks/BUILD.bazel
@@ -62,7 +62,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-securitysolution-list-hooks/src/use_exception_lists/index.ts b/packages/kbn-securitysolution-list-hooks/src/use_exception_lists/index.ts
index 0bd4c6c705668..722a7918c4127 100644
--- a/packages/kbn-securitysolution-list-hooks/src/use_exception_lists/index.ts
+++ b/packages/kbn-securitysolution-list-hooks/src/use_exception_lists/index.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { useEffect, useMemo, useRef, useState } from 'react';
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import type {
ExceptionListSchema,
UseExceptionListsProps,
@@ -17,7 +17,19 @@ import { fetchExceptionLists } from '@kbn/securitysolution-list-api';
import { getFilters } from '@kbn/securitysolution-list-utils';
export type Func = () => void;
-export type ReturnExceptionLists = [boolean, ExceptionListSchema[], Pagination, Func | null];
+export type ReturnExceptionLists = [
+ loading: boolean,
+ exceptionLists: ExceptionListSchema[],
+ pagination: Pagination,
+ setPagination: React.Dispatch>,
+ fetchLists: Func | null
+];
+
+const DEFAULT_PAGINATION = {
+ page: 1,
+ perPage: 20,
+ total: 0,
+};
/**
* Hook for fetching ExceptionLists
@@ -29,17 +41,13 @@ export type ReturnExceptionLists = [boolean, ExceptionListSchema[], Pagination,
* @param notifications kibana service for displaying toasters
* @param showTrustedApps boolean - include/exclude trusted app lists
* @param showEventFilters boolean - include/exclude event filters lists
- * @param pagination
+ * @param initialPagination
*
*/
export const useExceptionLists = ({
errorMessage,
http,
- pagination = {
- page: 1,
- perPage: 20,
- total: 0,
- },
+ initialPagination = DEFAULT_PAGINATION,
filterOptions = {},
namespaceTypes,
notifications,
@@ -47,9 +55,9 @@ export const useExceptionLists = ({
showEventFilters = false,
}: UseExceptionListsProps): ReturnExceptionLists => {
const [exceptionLists, setExceptionLists] = useState([]);
- const [paginationInfo, setPagination] = useState(pagination);
+ const [pagination, setPagination] = useState(initialPagination);
const [loading, setLoading] = useState(true);
- const fetchExceptionListsRef = useRef(null);
+ const abortCtrlRef = useRef();
const namespaceTypesAsString = useMemo(() => namespaceTypes.join(','), [namespaceTypes]);
const filters = useMemo(
@@ -58,66 +66,57 @@ export const useExceptionLists = ({
[namespaceTypes, filterOptions, showTrustedApps, showEventFilters]
);
- useEffect(() => {
- let isSubscribed = true;
- const abortCtrl = new AbortController();
+ const fetchData = useCallback(async (): Promise => {
+ try {
+ setLoading(true);
- const fetchData = async (): Promise => {
- try {
- setLoading(true);
+ abortCtrlRef.current = new AbortController();
- const { page, per_page: perPage, total, data } = await fetchExceptionLists({
- filters,
- http,
- namespaceTypes: namespaceTypesAsString,
- pagination: {
- page: pagination.page,
- perPage: pagination.perPage,
- },
- signal: abortCtrl.signal,
- });
+ const { page, per_page: perPage, total, data } = await fetchExceptionLists({
+ filters,
+ http,
+ namespaceTypes: namespaceTypesAsString,
+ pagination: {
+ page: pagination.page,
+ perPage: pagination.perPage,
+ },
+ signal: abortCtrlRef.current.signal,
+ });
- if (isSubscribed) {
- setPagination({
- page,
- perPage,
- total,
- });
- setExceptionLists(data);
- setLoading(false);
- }
- } catch (error) {
- if (isSubscribed) {
- notifications.toasts.addError(error, {
- title: errorMessage,
- });
- setExceptionLists([]);
- setPagination({
- page: 1,
- perPage: 20,
- total: 0,
- });
- setLoading(false);
- }
+ setPagination({
+ page,
+ perPage,
+ total,
+ });
+ setExceptionLists(data);
+ setLoading(false);
+ } catch (error) {
+ if (error.name !== 'AbortError') {
+ notifications.toasts.addError(error, {
+ title: errorMessage,
+ });
+ setExceptionLists([]);
+ setPagination(DEFAULT_PAGINATION);
+ setLoading(false);
}
- };
-
- fetchData();
-
- fetchExceptionListsRef.current = fetchData;
- return (): void => {
- isSubscribed = false;
- abortCtrl.abort();
- };
+ }
}, [
errorMessage,
- notifications,
- pagination.page,
- pagination.perPage,
filters,
- namespaceTypesAsString,
http,
+ namespaceTypesAsString,
+ notifications.toasts,
+ pagination.page,
+ pagination.perPage,
]);
- return [loading, exceptionLists, paginationInfo, fetchExceptionListsRef.current];
+ useEffect(() => {
+ fetchData();
+
+ return (): void => {
+ abortCtrlRef.current?.abort();
+ };
+ }, [fetchData]);
+
+ return [loading, exceptionLists, pagination, setPagination, fetchData];
};
diff --git a/packages/kbn-securitysolution-list-utils/.babelrc b/packages/kbn-securitysolution-list-utils/.babelrc
deleted file mode 100644
index 40a198521b903..0000000000000
--- a/packages/kbn-securitysolution-list-utils/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-list-utils/.babelrc.browser b/packages/kbn-securitysolution-list-utils/.babelrc.browser
deleted file mode 100644
index 71bbfbcd6eb2f..0000000000000
--- a/packages/kbn-securitysolution-list-utils/.babelrc.browser
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-list-utils/BUILD.bazel b/packages/kbn-securitysolution-list-utils/BUILD.bazel
index 4701723286eff..eb33eb1a03b66 100644
--- a/packages/kbn-securitysolution-list-utils/BUILD.bazel
+++ b/packages/kbn-securitysolution-list-utils/BUILD.bazel
@@ -58,7 +58,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-securitysolution-t-grid/.babelrc b/packages/kbn-securitysolution-t-grid/.babelrc
deleted file mode 100644
index 40a198521b903..0000000000000
--- a/packages/kbn-securitysolution-t-grid/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-t-grid/.babelrc.browser b/packages/kbn-securitysolution-t-grid/.babelrc.browser
deleted file mode 100644
index 71bbfbcd6eb2f..0000000000000
--- a/packages/kbn-securitysolution-t-grid/.babelrc.browser
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-securitysolution-t-grid/BUILD.bazel b/packages/kbn-securitysolution-t-grid/BUILD.bazel
index f9a6a5d7934ad..dd4e73af95720 100644
--- a/packages/kbn-securitysolution-t-grid/BUILD.bazel
+++ b/packages/kbn-securitysolution-t-grid/BUILD.bazel
@@ -54,7 +54,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-securitysolution-utils/.babelrc b/packages/kbn-securitysolution-utils/.babelrc
deleted file mode 100644
index 40a198521b903..0000000000000
--- a/packages/kbn-securitysolution-utils/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.ts", "**/*.test.tsx"]
-}
diff --git a/packages/kbn-server-http-tools/.babelrc b/packages/kbn-server-http-tools/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-server-http-tools/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-server-route-repository/.babelrc b/packages/kbn-server-route-repository/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-server-route-repository/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-std/.babelrc b/packages/kbn-std/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-std/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-storybook/.babelrc b/packages/kbn-storybook/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-storybook/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-telemetry-tools/.babelrc b/packages/kbn-telemetry-tools/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-telemetry-tools/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-test/.babelrc b/packages/kbn-test/.babelrc
deleted file mode 100644
index 1685d1644d94a..0000000000000
--- a/packages/kbn-test/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"],
- "ignore": ["**/*.test.js"]
-}
diff --git a/packages/kbn-tinymath/babel.config.js b/packages/kbn-tinymath/babel.config.js
deleted file mode 100644
index b4a118df51af5..0000000000000
--- a/packages/kbn-tinymath/babel.config.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-module.exports = {
- env: {
- web: {
- presets: ['@kbn/babel-preset/webpack_preset'],
- },
- node: {
- presets: ['@kbn/babel-preset/node_preset'],
- },
- },
- ignore: ['**/*.test.ts', '**/*.test.tsx'],
-};
diff --git a/packages/kbn-typed-react-router-config/.babelrc b/packages/kbn-typed-react-router-config/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-typed-react-router-config/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-typed-react-router-config/.babelrc.browser b/packages/kbn-typed-react-router-config/.babelrc.browser
deleted file mode 100644
index dc6a77bbe0bcd..0000000000000
--- a/packages/kbn-typed-react-router-config/.babelrc.browser
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/webpack_preset"]
-}
diff --git a/packages/kbn-typed-react-router-config/BUILD.bazel b/packages/kbn-typed-react-router-config/BUILD.bazel
index be346f8321fad..7fccc53bd7449 100644
--- a/packages/kbn-typed-react-router-config/BUILD.bazel
+++ b/packages/kbn-typed-react-router-config/BUILD.bazel
@@ -56,7 +56,7 @@ jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
- config_file = ".babelrc.browser"
+ web = True,
)
ts_config(
diff --git a/packages/kbn-ui-shared-deps/.babelrc b/packages/kbn-ui-shared-deps/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-ui-shared-deps/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-utility-types/.babelrc b/packages/kbn-utility-types/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-utility-types/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/packages/kbn-utils/.babelrc b/packages/kbn-utils/.babelrc
deleted file mode 100644
index 7da72d1779128..0000000000000
--- a/packages/kbn-utils/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@kbn/babel-preset/node_preset"]
-}
diff --git a/src/core/server/saved_objects/migrationsv2/test_helpers/retry.test.ts b/src/core/server/saved_objects/migrationsv2/test_helpers/retry.test.ts
index 246f61c71ae4d..ff5bf3d01c641 100644
--- a/src/core/server/saved_objects/migrationsv2/test_helpers/retry.test.ts
+++ b/src/core/server/saved_objects/migrationsv2/test_helpers/retry.test.ts
@@ -8,7 +8,8 @@
import { retryAsync } from './retry_async';
-describe('retry', () => {
+// FLAKY: https://github.com/elastic/kibana/issues/110970
+describe.skip('retry', () => {
it('retries throwing functions until they succeed', async () => {
let i = 0;
await expect(
diff --git a/src/dev/bazel/jsts_transpiler.bzl b/src/dev/bazel/jsts_transpiler.bzl
index 03033bbfa83f8..5116c73adb3c7 100644
--- a/src/dev/bazel/jsts_transpiler.bzl
+++ b/src/dev/bazel/jsts_transpiler.bzl
@@ -2,28 +2,42 @@
load("@npm//@babel/cli:index.bzl", _babel = "babel")
-def jsts_transpiler(name, srcs, build_pkg_name, root_input_dir = "src", config_file = ".babelrc", additional_args = ["--quiet"], **kwargs):
+def jsts_transpiler(name, srcs, build_pkg_name, web = False, root_input_dir = "src", additional_args = ["--quiet"], **kwargs):
"""A macro around the autogenerated babel rule.
Args:
name: target name
srcs: list of sources
+ build_pkg_name: package name into the build folder
+ web: setup the correct presets to consume the outputs in the browser, defaults to "False" and optimizes for node
root_input_dir: defines the root input dir to transpile files from, defaults to "src"
- config_file: transpiler config file, it defaults to a package local .babelrc
additional_args: Any additional extra arguments, defaults to --quiet
**kwargs: the rest
"""
+
+ inline_presets = [
+ "--presets",
+ ]
+
+ if web:
+ inline_presets += [
+ "@kbn/babel-preset/webpack_preset",
+ ]
+ else:
+ inline_presets += [
+ "@kbn/babel-preset/node_preset",
+ ]
+
args = [
"./%s/%s" % (build_pkg_name, root_input_dir),
- "--config-file",
- "./%s/%s" % (build_pkg_name, config_file),
"--out-dir",
"$(@D)",
+ "--no-babelrc",
"--extensions",
".ts,.tsx,.js",
- ] + additional_args
+ ] + inline_presets + additional_args
- data = [config_file] + srcs + [
+ data = srcs + [
"//packages/kbn-babel-preset",
]
diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker
index 4bb89e1b7e606..adf0be3b5aa54 100755
--- a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker
+++ b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker
@@ -76,7 +76,6 @@ kibana_vars=(
interpreter.enableInVisualize
kibana.autocompleteTerminateAfter
kibana.autocompleteTimeout
- kibana.defaultAppId
kibana.index
logging.appenders
logging.appenders.console
diff --git a/src/plugins/discover/public/application/apps/not_found/not_found_route.tsx b/src/plugins/discover/public/application/apps/not_found/not_found_route.tsx
index ff515f27201a4..cd16a820cc8f7 100644
--- a/src/plugins/discover/public/application/apps/not_found/not_found_route.tsx
+++ b/src/plugins/discover/public/application/apps/not_found/not_found_route.tsx
@@ -28,10 +28,7 @@ export function NotFoundRoute(props: NotFoundRouteProps) {
useEffect(() => {
const path = window.location.hash.substr(1);
getUrlTracker().restorePreviousUrl();
- const { navigated } = urlForwarding.navigateToLegacyKibanaUrl(path);
- if (!navigated) {
- urlForwarding.navigateToDefaultApp();
- }
+ urlForwarding.navigateToLegacyKibanaUrl(path);
const bannerMessage = i18n.translate('discover.noMatchRoute.bannerTitleText', {
defaultMessage: 'Page not found',
diff --git a/src/plugins/embeddable/common/types.ts b/src/plugins/embeddable/common/types.ts
index 22d8672e59a37..430b59bc62242 100644
--- a/src/plugins/embeddable/common/types.ts
+++ b/src/plugins/embeddable/common/types.ts
@@ -12,6 +12,7 @@ import { PersistableStateService } from '../../kibana_utils/common';
export enum ViewMode {
EDIT = 'edit',
+ PREVIEW = 'preview',
VIEW = 'view',
}
diff --git a/src/plugins/expressions/common/expression_renderers/types.ts b/src/plugins/expressions/common/expression_renderers/types.ts
index 239cff6143ae7..8547c1a1bec92 100644
--- a/src/plugins/expressions/common/expression_renderers/types.ts
+++ b/src/plugins/expressions/common/expression_renderers/types.ts
@@ -53,12 +53,11 @@ export type AnyExpressionRenderDefinition = ExpressionRenderDefinition;
* This value can be set from a consumer embedding an expression renderer and is accessible
* from within the active render function as part of the handlers.
* The following modes are supported:
- * * display (default): The chart is rendered in a container with the main purpose of viewing the chart (e.g. in a container like dashboard or canvas)
+ * * view (default): The chart is rendered in a container with the main purpose of viewing the chart (e.g. in a container like dashboard or canvas)
* * preview: The chart is rendered in very restricted space (below 100px width and height) and should only show a rough outline
* * edit: The chart is rendered within an editor and configuration elements within the chart should be displayed
- * * noInteractivity: The chart is rendered in a non-interactive environment and should not provide any affordances for interaction like brushing
*/
-export type RenderMode = 'noInteractivity' | 'edit' | 'preview' | 'display';
+export type RenderMode = 'edit' | 'preview' | 'view';
export interface IInterpreterRenderHandlers {
/**
@@ -71,6 +70,12 @@ export interface IInterpreterRenderHandlers {
event: (event: any) => void;
hasCompatibleActions?: (event: any) => Promise;
getRenderMode: () => RenderMode;
+
+ /**
+ * The chart is rendered in a non-interactive environment and should not provide any affordances for interaction like brushing.
+ */
+ isInteractive: () => boolean;
+
isSyncColorsEnabled: () => boolean;
/**
* This uiState interface is actually `PersistedState` from the visualizations plugin,
diff --git a/src/plugins/expressions/public/loader.ts b/src/plugins/expressions/public/loader.ts
index d0f60eb294060..3ab7473d8d735 100644
--- a/src/plugins/expressions/public/loader.ts
+++ b/src/plugins/expressions/public/loader.ts
@@ -53,6 +53,7 @@ export class ExpressionLoader {
);
this.renderHandler = new ExpressionRenderHandler(element, {
+ interactive: params?.interactive,
onRenderError: params && params.onRenderError,
renderMode: params?.renderMode,
syncColors: params?.syncColors,
diff --git a/src/plugins/expressions/public/react_expression_renderer.tsx b/src/plugins/expressions/public/react_expression_renderer.tsx
index 719af1b39f89e..2640be16eae46 100644
--- a/src/plugins/expressions/public/react_expression_renderer.tsx
+++ b/src/plugins/expressions/public/react_expression_renderer.tsx
@@ -171,6 +171,7 @@ export const ReactExpressionRenderer = ({
}, [
hasCustomRenderErrorHandler,
onEvent,
+ expressionLoaderOptions.interactive,
expressionLoaderOptions.renderMode,
expressionLoaderOptions.syncColors,
]);
diff --git a/src/plugins/expressions/public/render.ts b/src/plugins/expressions/public/render.ts
index e7a00867c1005..e9a65d1e8f12e 100644
--- a/src/plugins/expressions/public/render.ts
+++ b/src/plugins/expressions/public/render.ts
@@ -21,6 +21,7 @@ export interface ExpressionRenderHandlerParams {
onRenderError?: RenderErrorHandlerFnType;
renderMode?: RenderMode;
syncColors?: boolean;
+ interactive?: boolean;
hasCompatibleActions?: (event: ExpressionRendererEvent) => Promise;
}
@@ -54,6 +55,7 @@ export class ExpressionRenderHandler {
onRenderError,
renderMode,
syncColors,
+ interactive,
hasCompatibleActions = async () => false,
}: ExpressionRenderHandlerParams = {}
) {
@@ -90,11 +92,14 @@ export class ExpressionRenderHandler {
this.eventsSubject.next(data);
},
getRenderMode: () => {
- return renderMode || 'display';
+ return renderMode || 'view';
},
isSyncColorsEnabled: () => {
return syncColors || false;
},
+ isInteractive: () => {
+ return interactive ?? true;
+ },
hasCompatibleActions,
};
}
diff --git a/src/plugins/expressions/public/types/index.ts b/src/plugins/expressions/public/types/index.ts
index 5a2198bb4f2e5..172f322f8892a 100644
--- a/src/plugins/expressions/public/types/index.ts
+++ b/src/plugins/expressions/public/types/index.ts
@@ -44,6 +44,7 @@ export interface IExpressionLoaderParams {
customRenderers?: [];
uiState?: unknown;
inspectorAdapters?: Adapters;
+ interactive?: boolean;
onRenderError?: RenderErrorHandlerFnType;
searchSessionId?: string;
renderMode?: RenderMode;
diff --git a/src/plugins/home/public/application/components/home_app.js b/src/plugins/home/public/application/components/home_app.js
index ef70dac20d3cc..94413e6af390f 100644
--- a/src/plugins/home/public/application/components/home_app.js
+++ b/src/plugins/home/public/application/components/home_app.js
@@ -12,19 +12,10 @@ import PropTypes from 'prop-types';
import { Home } from './home';
import { TutorialDirectory } from './tutorial_directory';
import { Tutorial } from './tutorial/tutorial';
-import { HashRouter as Router, Switch, Route } from 'react-router-dom';
+import { HashRouter as Router, Switch, Route, Redirect } from 'react-router-dom';
import { getTutorial } from '../load_tutorials';
import { replaceTemplateStrings } from './tutorial/replace_template_strings';
import { getServices } from '../kibana_services';
-import useMount from 'react-use/lib/useMount';
-
-const RedirectToDefaultApp = () => {
- useMount(() => {
- const { urlForwarding } = getServices();
- urlForwarding.navigateToDefaultApp();
- });
- return null;
-};
export function HomeApp({ directories, solutions }) {
const {
@@ -78,7 +69,7 @@ export function HomeApp({ directories, solutions }) {
hasUserIndexPattern={() => indexPatternService.hasUserIndexPattern()}
/>
-
+
diff --git a/src/plugins/home/public/plugin.ts b/src/plugins/home/public/plugin.ts
index 7dd1d8728ad7f..f6a1566b267ac 100644
--- a/src/plugins/home/public/plugin.ts
+++ b/src/plugins/home/public/plugin.ts
@@ -14,7 +14,6 @@ import {
PluginInitializerContext,
} from 'kibana/public';
import { i18n } from '@kbn/i18n';
-import { first } from 'rxjs/operators';
import {
EnvironmentService,
@@ -137,27 +136,9 @@ export class HomePublicPlugin
};
}
- public start(
- { application: { capabilities, currentAppId$ }, http }: CoreStart,
- { urlForwarding }: HomePluginStartDependencies
- ) {
+ public start({ application: { capabilities } }: CoreStart) {
this.featuresCatalogueRegistry.start({ capabilities });
- // If the home app is the initial location when loading Kibana...
- if (
- window.location.pathname === http.basePath.prepend(HOME_APP_BASE_PATH) &&
- window.location.hash === ''
- ) {
- // ...wait for the app to mount initially and then...
- currentAppId$.pipe(first()).subscribe((appId) => {
- if (appId === 'home') {
- // ...navigate to default app set by `kibana.defaultAppId`.
- // This doesn't do anything as along as the default settings are kept.
- urlForwarding.navigateToDefaultApp({ overwriteHash: false });
- }
- });
- }
-
return { featureCatalogue: this.featuresCatalogueRegistry };
}
}
diff --git a/src/plugins/kibana_legacy/config.ts b/src/plugins/kibana_legacy/config.ts
deleted file mode 100644
index 91083a554bce1..0000000000000
--- a/src/plugins/kibana_legacy/config.ts
+++ /dev/null
@@ -1,15 +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
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { schema, TypeOf } from '@kbn/config-schema';
-
-export const configSchema = schema.object({
- defaultAppId: schema.string({ defaultValue: 'home' }),
-});
-
-export type ConfigSchema = TypeOf;
diff --git a/src/plugins/kibana_legacy/kibana.json b/src/plugins/kibana_legacy/kibana.json
index b1d7b10f9527a..afca886ad9376 100644
--- a/src/plugins/kibana_legacy/kibana.json
+++ b/src/plugins/kibana_legacy/kibana.json
@@ -1,7 +1,7 @@
{
"id": "kibanaLegacy",
"version": "kibana",
- "server": true,
+ "server": false,
"ui": true,
"owner": {
"name": "Vis Editors",
diff --git a/src/plugins/kibana_legacy/public/index.ts b/src/plugins/kibana_legacy/public/index.ts
index fa04b192cd177..13271532881cb 100644
--- a/src/plugins/kibana_legacy/public/index.ts
+++ b/src/plugins/kibana_legacy/public/index.ts
@@ -9,11 +9,9 @@
// TODO: https://github.com/elastic/kibana/issues/110891
/* eslint-disable @kbn/eslint/no_export_all */
-import { PluginInitializerContext } from 'kibana/public';
import { KibanaLegacyPlugin } from './plugin';
-export const plugin = (initializerContext: PluginInitializerContext) =>
- new KibanaLegacyPlugin(initializerContext);
+export const plugin = () => new KibanaLegacyPlugin();
export * from './plugin';
diff --git a/src/plugins/kibana_legacy/public/mocks.ts b/src/plugins/kibana_legacy/public/mocks.ts
index 9f79daf0f3505..510e59c7ff190 100644
--- a/src/plugins/kibana_legacy/public/mocks.ts
+++ b/src/plugins/kibana_legacy/public/mocks.ts
@@ -14,9 +14,6 @@ export type Start = jest.Mocked>;
const createSetupContract = (): Setup => ({});
const createStartContract = (): Start => ({
- config: {
- defaultAppId: 'home',
- },
loadFontAwesome: jest.fn(),
loadAngularBootstrap: jest.fn(),
});
diff --git a/src/plugins/kibana_legacy/public/plugin.ts b/src/plugins/kibana_legacy/public/plugin.ts
index af22ceadaa9e1..e5244c110ad20 100644
--- a/src/plugins/kibana_legacy/public/plugin.ts
+++ b/src/plugins/kibana_legacy/public/plugin.ts
@@ -6,18 +6,15 @@
* Side Public License, v 1.
*/
-import { PluginInitializerContext, CoreStart, CoreSetup } from 'kibana/public';
-import { ConfigSchema } from '../config';
+import { CoreStart, CoreSetup } from 'kibana/public';
import { injectHeaderStyle } from './utils/inject_header_style';
export class KibanaLegacyPlugin {
- constructor(private readonly initializerContext: PluginInitializerContext) {}
-
public setup(core: CoreSetup<{}, KibanaLegacyStart>) {
return {};
}
- public start({ application, http: { basePath }, uiSettings }: CoreStart) {
+ public start({ uiSettings }: CoreStart) {
injectHeaderStyle(uiSettings);
return {
/**
@@ -35,11 +32,6 @@ export class KibanaLegacyPlugin {
const { initAngularBootstrap } = await import('./angular_bootstrap');
initAngularBootstrap();
},
- /**
- * @deprecated
- * Just exported for wiring up with dashboard mode, should not be used.
- */
- config: this.initializerContext.config.get(),
};
}
}
diff --git a/src/plugins/kibana_legacy/server/index.ts b/src/plugins/kibana_legacy/server/index.ts
deleted file mode 100644
index 90c9c2888c9da..0000000000000
--- a/src/plugins/kibana_legacy/server/index.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import type { CoreSetup, CoreStart, PluginConfigDescriptor } from 'kibana/server';
-import { get } from 'lodash';
-
-import { configSchema, ConfigSchema } from '../config';
-
-export const config: PluginConfigDescriptor = {
- exposeToBrowser: {
- defaultAppId: true,
- },
- schema: configSchema,
- deprecations: ({ renameFromRoot }) => [
- // TODO: Remove deprecation once defaultAppId is deleted
- renameFromRoot('kibana.defaultAppId', 'kibana_legacy.defaultAppId', { silent: true }),
- (completeConfig, rootPath, addDeprecation) => {
- if (
- get(completeConfig, 'kibana.defaultAppId') === undefined &&
- get(completeConfig, 'kibana_legacy.defaultAppId') === undefined
- ) {
- return;
- }
- addDeprecation({
- message: `kibana.defaultAppId is deprecated and will be removed in 8.0. Please use the \`defaultRoute\` advanced setting instead`,
- correctiveActions: {
- manualSteps: [
- 'Go to Stack Management > Advanced Settings',
- 'Update the "defaultRoute" setting under the General section',
- 'Remove "kibana.defaultAppId" from the kibana.yml config file',
- ],
- },
- });
- },
- ],
-};
-
-class Plugin {
- public setup(core: CoreSetup) {}
-
- public start(core: CoreStart) {}
-}
-
-export const plugin = () => new Plugin();
diff --git a/src/plugins/presentation_util/public/__stories__/render.tsx b/src/plugins/presentation_util/public/__stories__/render.tsx
index 2588d2e3294ae..76725d08956bd 100644
--- a/src/plugins/presentation_util/public/__stories__/render.tsx
+++ b/src/plugins/presentation_util/public/__stories__/render.tsx
@@ -11,8 +11,9 @@ import React, { useRef, useEffect } from 'react';
import { ExpressionRenderDefinition, IInterpreterRenderHandlers } from 'src/plugins/expressions';
export const defaultHandlers: IInterpreterRenderHandlers = {
- getRenderMode: () => 'display',
+ getRenderMode: () => 'view',
isSyncColorsEnabled: () => false,
+ isInteractive: () => true,
done: action('done'),
onDestroy: action('onDestroy'),
reload: action('reload'),
diff --git a/src/plugins/url_forwarding/kibana.json b/src/plugins/url_forwarding/kibana.json
index a8b0571230b72..3e48cf73de5ef 100644
--- a/src/plugins/url_forwarding/kibana.json
+++ b/src/plugins/url_forwarding/kibana.json
@@ -6,6 +6,5 @@
"owner": {
"name": "Vis Editors",
"githubTeam": "kibana-vis-editors"
- },
- "requiredPlugins": ["kibanaLegacy"]
+ }
}
diff --git a/src/plugins/url_forwarding/public/forward_app/forward_app.test.ts b/src/plugins/url_forwarding/public/forward_app/forward_app.test.ts
new file mode 100644
index 0000000000000..c45bde0d67891
--- /dev/null
+++ b/src/plugins/url_forwarding/public/forward_app/forward_app.test.ts
@@ -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
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+import type { Location } from 'history';
+import type { AppMountParameters, CoreSetup, ScopedHistory } from 'kibana/public';
+import { coreMock } from '../../../../core/public/mocks';
+import type { UrlForwardingStart } from '../plugin';
+import { createLegacyUrlForwardApp } from './forward_app';
+
+function createAppMountParams(hash: string): AppMountParameters {
+ return {
+ history: {
+ location: {
+ hash,
+ } as Location,
+ } as ScopedHistory,
+ } as AppMountParameters;
+}
+
+describe('forward_app', () => {
+ let coreSetup: CoreSetup<{}, UrlForwardingStart>;
+ let coreStart: ReturnType;
+
+ beforeEach(() => {
+ coreSetup = coreMock.createSetup({ basePath: '/base/path' });
+ coreStart = coreMock.createStart({ basePath: '/base/path' });
+ coreSetup.getStartServices = () => Promise.resolve([coreStart, {}, {} as any]);
+ });
+
+ it('should forward to defaultRoute if hash is not a known redirect', async () => {
+ coreStart.uiSettings.get.mockImplementation((key) => {
+ if (key === 'defaultRoute') return '/app/defaultApp';
+ throw new Error('Mock implementation missing');
+ });
+
+ const app = createLegacyUrlForwardApp(coreSetup, [
+ { legacyAppId: 'discover', newAppId: 'discover', rewritePath: (p) => p },
+ ]);
+ await app.mount(createAppMountParams('#/foobar'));
+ expect(coreStart.application.navigateToUrl).toHaveBeenCalledWith('/base/path/app/defaultApp');
+ });
+
+ it('should not forward to defaultRoute if hash path is a known redirect', async () => {
+ const app = createLegacyUrlForwardApp(coreSetup, [
+ { legacyAppId: 'discover', newAppId: 'discover', rewritePath: (p) => p },
+ ]);
+ await app.mount(createAppMountParams('#/discover'));
+ expect(coreStart.application.navigateToUrl).not.toHaveBeenCalled();
+ });
+});
diff --git a/src/plugins/url_forwarding/public/forward_app/forward_app.ts b/src/plugins/url_forwarding/public/forward_app/forward_app.ts
index 96c4fab5f3331..3a66e207f8c26 100644
--- a/src/plugins/url_forwarding/public/forward_app/forward_app.ts
+++ b/src/plugins/url_forwarding/public/forward_app/forward_app.ts
@@ -23,23 +23,18 @@ export const createLegacyUrlForwardApp = (
async mount(params: AppMountParameters) {
const hash = params.history.location.hash.substr(1);
- if (!hash) {
- const [, , kibanaLegacyStart] = await core.getStartServices();
- kibanaLegacyStart.navigateToDefaultApp();
- }
-
const [
{
application,
+ uiSettings,
http: { basePath },
},
] = await core.getStartServices();
- const result = await navigateToLegacyKibanaUrl(hash, forwards, basePath, application);
-
- if (!result.navigated) {
- const [, , kibanaLegacyStart] = await core.getStartServices();
- kibanaLegacyStart.navigateToDefaultApp();
+ const { navigated } = navigateToLegacyKibanaUrl(hash, forwards, basePath, application);
+ if (!navigated) {
+ const defaultRoute = uiSettings.get('defaultRoute');
+ application.navigateToUrl(basePath.prepend(defaultRoute));
}
return () => {};
diff --git a/src/plugins/url_forwarding/public/mocks.ts b/src/plugins/url_forwarding/public/mocks.ts
index 67b521b9d697d..582bb004b655e 100644
--- a/src/plugins/url_forwarding/public/mocks.ts
+++ b/src/plugins/url_forwarding/public/mocks.ts
@@ -17,7 +17,6 @@ const createSetupContract = (): Setup => ({
const createStartContract = (): Start => ({
getForwards: jest.fn(),
- navigateToDefaultApp: jest.fn(),
navigateToLegacyKibanaUrl: jest.fn(),
});
diff --git a/src/plugins/url_forwarding/public/navigate_to_default_app.ts b/src/plugins/url_forwarding/public/navigate_to_default_app.ts
deleted file mode 100644
index 0c934ac9c6844..0000000000000
--- a/src/plugins/url_forwarding/public/navigate_to_default_app.ts
+++ /dev/null
@@ -1,39 +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
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { ApplicationStart, IBasePath } from 'kibana/public';
-import { ForwardDefinition } from './plugin';
-
-export function navigateToDefaultApp(
- defaultAppId: string,
- forwards: ForwardDefinition[],
- application: ApplicationStart,
- basePath: IBasePath,
- currentAppId: string | undefined,
- overwriteHash: boolean
-) {
- // navigate to the respective path in the legacy kibana plugin by default (for unmigrated plugins)
- let targetAppId = 'kibana';
- let targetAppPath = `#/${defaultAppId}`;
-
- // try to find an existing redirect for the target path if possible
- // this avoids having to load the legacy app just to get redirected to a core application again afterwards
- const relevantForward = forwards.find((forward) => defaultAppId.startsWith(forward.legacyAppId));
- if (relevantForward) {
- targetAppPath = relevantForward.rewritePath(`/${defaultAppId}`);
- targetAppId = relevantForward.newAppId;
- }
-
- // when the correct app is already loaded, just set the hash to the right value
- // otherwise use navigateToApp (or setting href in case of kibana app)
- if (currentAppId !== targetAppId) {
- application.navigateToApp(targetAppId, { path: targetAppPath, replace: true });
- } else if (overwriteHash) {
- window.location.hash = targetAppPath;
- }
-}
diff --git a/src/plugins/url_forwarding/public/plugin.ts b/src/plugins/url_forwarding/public/plugin.ts
index 1151e853f28ba..ee56ba73eb24e 100644
--- a/src/plugins/url_forwarding/public/plugin.ts
+++ b/src/plugins/url_forwarding/public/plugin.ts
@@ -7,9 +7,6 @@
*/
import { CoreStart, CoreSetup } from 'kibana/public';
-import { KibanaLegacyStart } from 'src/plugins/kibana_legacy/public';
-import { Subscription } from 'rxjs';
-import { navigateToDefaultApp } from './navigate_to_default_app';
import { createLegacyUrlForwardApp } from './forward_app';
import { navigateToLegacyKibanaUrl } from './forward_app/navigate_to_legacy_kibana_url';
@@ -21,8 +18,6 @@ export interface ForwardDefinition {
export class UrlForwardingPlugin {
private forwardDefinitions: ForwardDefinition[] = [];
- private currentAppId: string | undefined;
- private currentAppIdSubscription: Subscription | undefined;
public setup(core: CoreSetup<{}, UrlForwardingStart>) {
core.application.register(createLegacyUrlForwardApp(core, this.forwardDefinitions));
@@ -71,30 +66,8 @@ export class UrlForwardingPlugin {
};
}
- public start(
- { application, http: { basePath }, uiSettings }: CoreStart,
- { kibanaLegacy }: { kibanaLegacy: KibanaLegacyStart }
- ) {
- this.currentAppIdSubscription = application.currentAppId$.subscribe((currentAppId) => {
- this.currentAppId = currentAppId;
- });
+ public start({ application, http: { basePath } }: CoreStart) {
return {
- /**
- * Navigates to the app defined as kibana.defaultAppId.
- * This takes redirects into account and uses the right mechanism to navigate.
- */
- navigateToDefaultApp: (
- { overwriteHash }: { overwriteHash: boolean } = { overwriteHash: true }
- ) => {
- navigateToDefaultApp(
- kibanaLegacy.config.defaultAppId,
- this.forwardDefinitions,
- application,
- basePath,
- this.currentAppId,
- overwriteHash
- );
- },
/**
* Resolves the provided hash using the registered forwards and navigates to the target app.
* If a navigation happened, `{ navigated: true }` will be returned.
@@ -111,12 +84,6 @@ export class UrlForwardingPlugin {
getForwards: () => this.forwardDefinitions,
};
}
-
- public stop() {
- if (this.currentAppIdSubscription) {
- this.currentAppIdSubscription.unsubscribe();
- }
- }
}
export type UrlForwardingSetup = ReturnType;
diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts
index b71542a8beeea..78230a8961967 100644
--- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts
+++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts
@@ -402,6 +402,7 @@ export class VisualizeEmbeddable
searchSessionId: this.input.searchSessionId,
syncColors: this.input.syncColors,
uiState: this.vis.uiState,
+ interactive: !this.input.disableTriggers,
inspectorAdapters: this.inspectorAdapters,
executionContext: context,
};
diff --git a/test/functional/apps/home/_home.js b/test/functional/apps/home/_home.js
index 24e672463964d..e3ca3f6761113 100644
--- a/test/functional/apps/home/_home.js
+++ b/test/functional/apps/home/_home.js
@@ -26,7 +26,7 @@ export default function ({ getService, getPageObjects }) {
});
it('clicking on console on homepage should take you to console app', async () => {
- await PageObjects.common.navigateToUrl('home');
+ await PageObjects.common.navigateToApp('home');
await testSubjects.click('homeDevTools');
const url = await browser.getCurrentUrl();
expect(url.includes('/app/dev_tools#/console')).to.be(true);
diff --git a/x-pack/plugins/apm/dev_docs/feature_flags.md b/x-pack/plugins/apm/dev_docs/feature_flags.md
new file mode 100644
index 0000000000000..9f722dd5eac5a
--- /dev/null
+++ b/x-pack/plugins/apm/dev_docs/feature_flags.md
@@ -0,0 +1,14 @@
+## Feature flags
+
+To set up a flagged feature, add the name of the feature key (`apm:myFeature`) to [commmon/ui_settings_keys.ts](./common/ui_settings_keys.ts) and the feature parameters to [server/ui_settings.ts](./server/ui_settings.ts).
+
+Test for the feature like:
+
+```js
+import { myFeatureEnabled } from '../ui_settings_keys';
+if (core.uiSettings.get(myFeatureEnabled)) {
+ doStuff();
+}
+```
+
+Settings can be managed in Kibana under Stack Management > Advanced Settings > Observability.
\ No newline at end of file
diff --git a/x-pack/plugins/apm/dev_docs/linting.md b/x-pack/plugins/apm/dev_docs/linting.md
new file mode 100644
index 0000000000000..a4fd3094f121c
--- /dev/null
+++ b/x-pack/plugins/apm/dev_docs/linting.md
@@ -0,0 +1,22 @@
+## Linting
+
+_Note: Run the following commands from the root of Kibana._
+
+### Typescript
+
+```
+node scripts/type_check.js --project x-pack/plugins/apm/tsconfig.json
+```
+
+### Prettier
+
+```
+yarn prettier "./x-pack/plugins/apm/**/*.{tsx,ts,js}" --write
+```
+
+### ESLint
+
+```
+node scripts/eslint.js x-pack/legacy/plugins/apm
+```
+diff --git a/x-pack/plugins/apm/dev_docs/feature_flags.md b/x-pack/plugins/apm/dev_docs/feature_flags.md
diff --git a/x-pack/plugins/apm/dev_docs/local_setup.md b/x-pack/plugins/apm/dev_docs/local_setup.md
new file mode 100644
index 0000000000000..d977f44445148
--- /dev/null
+++ b/x-pack/plugins/apm/dev_docs/local_setup.md
@@ -0,0 +1,50 @@
+## Local environment setup
+
+### Kibana
+
+```
+git clone git@github.com:elastic/kibana.git
+cd kibana/
+yarn kbn bootstrap
+yarn start --no-base-path
+```
+
+### APM Server, Elasticsearch and data
+
+To access an elasticsearch instance that has live data you have two options:
+
+#### A. Connect to Elasticsearch on Cloud (internal devs only)
+
+Find the credentials for the cluster [here](https://github.com/elastic/apm-dev/blob/master/docs/credentials/apm-ui-clusters.md#apmelstcco)
+
+#### B. Start Elastic Stack and APM data generators
+
+```
+git clone git@github.com:elastic/apm-integration-testing.git
+cd apm-integration-testing/
+./scripts/compose.py start master --all --no-kibana
+```
+
+_Docker Compose is required_
+
+### Setup default APM users
+
+APM behaves differently depending on which the role and permissions a logged in user has. To create the users run:
+
+```sh
+node x-pack/plugins/apm/scripts/create-apm-users-and-roles.js --username admin --password changeme --kibana-url http://localhost:5601 --role-suffix
+```
+
+This will create:
+
+**apm_read_user**: Read only user
+
+**apm_power_user**: Read+write user.
+
+## Debugging Elasticsearch queries
+
+All APM api endpoints accept `_inspect=true` as a query param that will result in the underlying ES query being outputted in the Kibana backend process.
+
+Example:
+`/api/apm/services/my_service?_inspect=true`
+diff --git a/x-pack/plugins/apm/dev_docs/linting.md b/x-pack/plugins/apm/dev_docs/linting.md
diff --git a/x-pack/plugins/apm/dev_docs/testing.md b/x-pack/plugins/apm/dev_docs/testing.md
new file mode 100644
index 0000000000000..93f32111048c1
--- /dev/null
+++ b/x-pack/plugins/apm/dev_docs/testing.md
@@ -0,0 +1,66 @@
+# Testing
+
+## Unit Tests (Jest)
+
+```
+node scripts/test/jest [--watch] [--updateSnapshot]
+```
+
+#### Coverage
+
+HTML coverage report can be found in target/coverage/jest after tests have run.
+
+```
+open target/coverage/jest/index.html
+```
+
+---
+
+## API Tests
+
+API tests are separated in two suites:
+
+- a basic license test suite [default]
+- a trial license test suite (the equivalent of gold+)
+
+```
+node scripts/test/api [--trial] [--help]
+```
+
+The API tests are located in `x-pack/test/apm_api_integration/`.
+
+**API Test tips**
+
+- For debugging access Elasticsearch on http://localhost:9220 (`elastic` / `changeme`)
+- To update snapshots append `--updateSnapshots` to the functional_test_runner command
+
+---
+
+## E2E Tests (Cypress)
+
+```
+node scripts/test/e2e [--trial] [--help]
+```
+
+The E2E tests are located [here](../../ftr_e2e)
+
+---
+
+## Functional tests (Security and Correlations tests)
+TODO: We could try moving this tests to the new e2e tests located at `x-pack/plugins/apm/ftr_e2e`.
+
+**Start server**
+
+```
+node scripts/functional_tests_server --config x-pack/test/functional/config.js
+```
+
+**Run tests**
+
+```
+node scripts/functional_test_runner --config x-pack/test/functional/config.js --grep='APM specs'
+```
+
+APM tests are located in `x-pack/test/functional/apps/apm`.
+For debugging access Elasticsearch on http://localhost:9220` (elastic/changeme)
+diff --git a/x-pack/plugins/apm/scripts/test/README.md b/x-pack/plugins/apm/scripts/test/README.md
diff --git a/x-pack/plugins/apm/readme.md b/x-pack/plugins/apm/readme.md
index a331bb4e9f116..fe7e77d28986c 100644
--- a/x-pack/plugins/apm/readme.md
+++ b/x-pack/plugins/apm/readme.md
@@ -2,105 +2,28 @@
## Local environment setup
-### Kibana
-
-```
-git clone git@github.com:elastic/kibana.git
-cd kibana/
-yarn kbn bootstrap
-yarn start --no-base-path
-```
-
-### APM Server, Elasticsearch and data
-
-To access an elasticsearch instance that has live data you have two options:
-
-#### A. Connect to Elasticsearch on Cloud (internal devs only)
-
-Find the credentials for the cluster [here](https://github.com/elastic/apm-dev/blob/master/docs/credentials/apm-ui-clusters.md#apmelstcco)
-
-#### B. Start Elastic Stack and APM data generators
-
-```
-git clone git@github.com:elastic/apm-integration-testing.git
-cd apm-integration-testing/
-./scripts/compose.py start master --all --no-kibana
-```
-
-_Docker Compose is required_
+[Local setup documentation](./dev_docs/local_setup.md)
## Testing
-Go to [tests documentation](./scripts/test/README.md)
+[Testing documentation](./dev_docs/testing.md)
## Linting
-_Note: Run the following commands from `kibana/`._
-
-### Typescript
-
-```
-node scripts/type_check.js --project x-pack/plugins/apm/tsconfig.json
-```
-
-### Prettier
-
-```
-yarn prettier "./x-pack/plugins/apm/**/*.{tsx,ts,js}" --write
-```
-
-### ESLint
-
-```
-node scripts/eslint.js x-pack/legacy/plugins/apm
-```
-
-## Setup default APM users
-
-APM behaves differently depending on which the role and permissions a logged in user has. To create the users run:
-
-```sh
-node x-pack/plugins/apm/scripts/create-apm-users-and-roles.js --username admin --password changeme --kibana-url http://localhost:5601 --role-suffix
-```
-
-This will create:
-
-**apm_read_user**: Read only user
-
-**apm_power_user**: Read+write user.
-
-## Debugging Elasticsearch queries
-
-All APM api endpoints accept `_inspect=true` as a query param that will result in the underlying ES query being outputted in the Kibana backend process.
-
-Example:
-`/api/apm/services/my_service?_inspect=true`
+[Linting documentation](./dev_docs/linting.md)
## Storybook
-Start the [Storybook](https://storybook.js.org/) development environment with
-`yarn storybook apm`. All files with a .stories.tsx extension will be loaded.
-You can access the development environment at http://localhost:9001.
-
-## Experimental features settings
-
-To set up a flagged feature, add the name of the feature key (`apm:myFeature`) to [commmon/ui_settings_keys.ts](./common/ui_settings_keys.ts) and the feature parameters to [server/ui_settings.ts](./server/ui_settings.ts).
-
-Test for the feature like:
-
-```js
-import { myFeatureEnabled } from '../ui_settings_keys';
-if (core.uiSettings.get(myFeatureEnabled)) {
- doStuff();
-}
+**Start**
+```
+yarn storybook apm
```
-Settings can be managed in Kibana under Stack Management > Advanced Settings > Observability.
+All files with a .stories.tsx extension will be loaded. You can access the development environment at http://localhost:9001.
## Further resources
-
-- [Cypress integration tests](./e2e/README.md)
- [VSCode setup instructions](./dev_docs/vscode_setup.md)
- [Github PR commands](./dev_docs/github_commands.md)
- [Routing and Linking](./dev_docs/routing_and_linking.md)
- [Telemetry](./dev_docs/telemetry.md)
+- [Features flags](./dev_docs/feature_flags.md)
diff --git a/x-pack/plugins/apm/scripts/test/README.md b/x-pack/plugins/apm/scripts/test/README.md
index b241b2efdfd99..2b5e4212ea08f 100644
--- a/x-pack/plugins/apm/scripts/test/README.md
+++ b/x-pack/plugins/apm/scripts/test/README.md
@@ -1,63 +1 @@
-## Unit Tests (Jest)
-
-```
-node scripts/tests/jest [--watch] [--updateSnapshot]
-```
-
-#### Coverage
-
-HTML coverage report can be found in target/coverage/jest after tests have run.
-
-```
-open target/coverage/jest/index.html
-```
-
----
-
-## API Tests
-
-API tests are separated in two suites:
-
-- a basic license test suite [default]
-- a trial license test suite (the equivalent of gold+)
-
-```
-node scripts/tests/api [--trial] [--help]
-```
-
-The API tests are located in `x-pack/test/apm_api_integration/`.
-
-**API Test tips**
-
-- For debugging access Elasticsearch on http://localhost:9220` (elastic/changeme)
-- To update snapshots append `--updateSnapshots` to the functional_test_runner command
-
----
-
-## E2E Tests (Cypress)
-
-```
-node scripts/tests/e2e [--trial] [--help]
-```
-
-The E2E tests are located [here](../../ftr_e2e)
-
----
-
-## Functional tests (Security and Correlations tests)
-TODO: We could try moving this tests to the new e2e tests located at `x-pack/plugins/apm/ftr_e2e`.
-
-**Start server**
-
-```
-node scripts/functional_tests_server --config x-pack/test/functional/config.js
-```
-
-**Run tests**
-
-```
-node scripts/functional_test_runner --config x-pack/test/functional/config.js --grep='APM specs'
-```
-
-APM tests are located in `x-pack/test/functional/apps/apm`.
-For debugging access Elasticsearch on http://localhost:9220` (elastic/changeme)
+Go to [testing documentation](../../dev_docs/testing.md)
\ No newline at end of file
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts
index bd844dd3335ef..082a69a874cae 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts
@@ -85,7 +85,6 @@ export function savedLens(): ExpressionFunctionDefinition<
title: args.title === null ? undefined : args.title,
disableTriggers: true,
palette: args.palette,
- renderMode: 'noInteractivity',
},
embeddableType: EmbeddableTypes.lens,
generatedAt: Date.now(),
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/__stories__/render.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/__stories__/render.tsx
index d87c24b1b7e86..643d7cdedc50d 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/__stories__/render.tsx
+++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/__stories__/render.tsx
@@ -13,8 +13,9 @@ export const defaultHandlers: RendererHandlers = {
destroy: () => action('destroy'),
getElementId: () => 'element-id',
getFilter: () => 'filter',
- getRenderMode: () => 'display',
+ getRenderMode: () => 'view',
isSyncColorsEnabled: () => false,
+ isInteractive: () => true,
onComplete: (fn) => undefined,
onEmbeddableDestroyed: action('onEmbeddableDestroyed'),
onEmbeddableInputChange: action('onEmbeddableInputChange'),
diff --git a/x-pack/plugins/canvas/public/lib/create_handlers.ts b/x-pack/plugins/canvas/public/lib/create_handlers.ts
index dfc4387bcbf92..3734b1bf53051 100644
--- a/x-pack/plugins/canvas/public/lib/create_handlers.ts
+++ b/x-pack/plugins/canvas/public/lib/create_handlers.ts
@@ -26,8 +26,9 @@ export const createBaseHandlers = (): IInterpreterRenderHandlers => ({
update() {},
event() {},
onDestroy() {},
- getRenderMode: () => 'display',
+ getRenderMode: () => 'view',
isSyncColorsEnabled: () => false,
+ isInteractive: () => true,
});
export const createHandlers = (baseHandlers = createBaseHandlers()): RendererHandlers => ({
diff --git a/x-pack/plugins/cases/public/components/connectors/jira/use_get_fields_by_issue_type.tsx b/x-pack/plugins/cases/public/components/connectors/jira/use_get_fields_by_issue_type.tsx
index a4958d91c88aa..686df1022a0d7 100644
--- a/x-pack/plugins/cases/public/components/connectors/jira/use_get_fields_by_issue_type.tsx
+++ b/x-pack/plugins/cases/public/components/connectors/jira/use_get_fields_by_issue_type.tsx
@@ -57,8 +57,8 @@ export const useGetFieldsByIssueType = ({
});
if (!didCancel.current) {
- setIsLoading(false);
setFields(res.data ?? {});
+ setIsLoading(false);
if (res.status && res.status === 'error') {
toastNotifications.addDanger({
title: i18n.FIELDS_API_ERROR,
diff --git a/x-pack/plugins/cases/public/components/connectors/jira/use_get_issue_types.tsx b/x-pack/plugins/cases/public/components/connectors/jira/use_get_issue_types.tsx
index 447491d2a2fff..0d7073f3bf2d4 100644
--- a/x-pack/plugins/cases/public/components/connectors/jira/use_get_issue_types.tsx
+++ b/x-pack/plugins/cases/public/components/connectors/jira/use_get_issue_types.tsx
@@ -56,13 +56,14 @@ export const useGetIssueTypes = ({
});
if (!didCancel.current) {
- setIsLoading(false);
const asOptions = (res.data ?? []).map((type) => ({
text: type.name ?? '',
value: type.id ?? '',
}));
+
setIssueTypes(res.data ?? []);
handleIssueType(asOptions);
+ setIsLoading(false);
if (res.status && res.status === 'error') {
toastNotifications.addDanger({
title: i18n.ISSUE_TYPES_API_ERROR,
diff --git a/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx b/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx
index fb45bf6ac3ae0..eec84cdd8d90f 100644
--- a/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx
+++ b/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx
@@ -7,16 +7,14 @@
import React from 'react';
import { mount } from 'enzyme';
-import { waitFor } from '@testing-library/react';
+import { render, waitFor, screen } from '@testing-library/react';
import { EditConnector, EditConnectorProps } from './index';
-import { getFormMock, useFormMock } from '../__mock__/form';
import { TestProviders } from '../../common/mock';
import { connectorsMock } from '../../containers/configure/mock';
import { basicCase, basicPush, caseUserActions } from '../../containers/mock';
import { useKibana } from '../../common/lib/kibana';
-jest.mock('../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form');
jest.mock('../../common/lib/kibana');
const useKibanaMock = useKibana as jest.Mocked;
@@ -50,17 +48,32 @@ const defaultProps: EditConnectorProps = {
};
describe('EditConnector ', () => {
- const sampleConnector = '123';
- const formHookMock = getFormMock({ connectorId: sampleConnector });
beforeEach(() => {
jest.clearAllMocks();
- useFormMock.mockImplementation(() => ({ form: formHookMock }));
useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({
actionTypeTitle: '.servicenow',
iconClass: 'logoSecurity',
});
});
+ it('Renders servicenow connector from case initially', async () => {
+ const serviceNowProps = {
+ ...defaultProps,
+ caseData: {
+ ...defaultProps.caseData,
+ connector: { ...defaultProps.caseData.connector, id: 'servicenow-1' },
+ },
+ };
+
+ render(
+
+
+
+ );
+
+ expect(await screen.findByText('My Connector')).toBeInTheDocument();
+ });
+
it('Renders no connector, and then edit', async () => {
const wrapper = mount(
@@ -98,58 +111,81 @@ describe('EditConnector ', () => {
expect(wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().exists()).toBeTruthy();
wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().simulate('click');
- await waitFor(() => expect(onSubmit.mock.calls[0][0]).toBe(sampleConnector));
+ await waitFor(() => expect(onSubmit.mock.calls[0][0]).toBe('resilient-2'));
});
it('Revert to initial external service on error', async () => {
onSubmit.mockImplementation((connector, onSuccess, onError) => {
onError(new Error('An error has occurred'));
});
+
+ const props = {
+ ...defaultProps,
+ caseData: {
+ ...defaultProps.caseData,
+ connector: { ...defaultProps.caseData.connector, id: 'servicenow-1' },
+ },
+ };
+
const wrapper = mount(
-
+
);
- wrapper.find('[data-test-subj="connector-edit"] button').simulate('click');
+ wrapper.find('[data-test-subj="connector-edit"] button').simulate('click');
wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click');
- wrapper.update();
- wrapper.find('button[data-test-subj="dropdown-connector-resilient-2"]').simulate('click');
- wrapper.update();
-
- expect(wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().exists()).toBeTruthy();
+ await waitFor(() => {
+ wrapper.update();
+ wrapper.find('button[data-test-subj="dropdown-connector-resilient-2"]').simulate('click');
+ wrapper.update();
+ expect(
+ wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().exists()
+ ).toBeTruthy();
+ wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().simulate('click');
+ });
- wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().simulate('click');
await waitFor(() => {
wrapper.update();
- expect(formHookMock.setFieldValue).toHaveBeenCalledWith('connectorId', 'none');
+ expect(wrapper.find(`[data-test-subj="edit-connectors-submit"]`).exists()).toBeFalsy();
});
+
+ /**
+ * If an error is being throw on submit the selected connector should
+ * be reverted to the initial one. In our test the initial one is the .servicenow-1
+ * connector. The title of the .servicenow-1 connector is My Connector.
+ */
+ expect(wrapper.text().includes('My Connector')).toBeTruthy();
});
it('Resets selector on cancel', async () => {
const props = {
...defaultProps,
+ caseData: {
+ ...defaultProps.caseData,
+ connector: { ...defaultProps.caseData.connector, id: 'servicenow-1' },
+ },
};
+
const wrapper = mount(
);
- wrapper.find('[data-test-subj="connector-edit"] button').simulate('click');
+ wrapper.find('[data-test-subj="connector-edit"] button').simulate('click');
wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click');
wrapper.update();
wrapper.find('button[data-test-subj="dropdown-connector-resilient-2"]').simulate('click');
wrapper.update();
-
wrapper.find(`[data-test-subj="edit-connectors-cancel"]`).last().simulate('click');
+
await waitFor(() => {
wrapper.update();
- expect(formHookMock.setFieldValue).toBeCalledWith(
- 'connectorId',
- defaultProps.caseData.connector.id
- );
+ expect(wrapper.find(`[data-test-subj="edit-connectors-submit"]`).exists()).toBeFalsy();
});
+
+ expect(wrapper.text().includes('My Connector')).toBeTruthy();
});
it('Renders loading spinner', async () => {
diff --git a/x-pack/plugins/cases/public/components/edit_connector/index.tsx b/x-pack/plugins/cases/public/components/edit_connector/index.tsx
index df7855fb9ce33..70845f28e1f6b 100644
--- a/x-pack/plugins/cases/public/components/edit_connector/index.tsx
+++ b/x-pack/plugins/cases/public/components/edit_connector/index.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { useCallback, useReducer } from 'react';
+import React, { useCallback, useEffect, useReducer } from 'react';
import deepEqual from 'fast-deep-equal';
import {
EuiText,
@@ -144,17 +144,43 @@ export const EditConnector = React.memo(
{ ...initialState, fields: caseFields }
);
+ useEffect(() => {
+ // Initialize the current connector with the connector information attached to the case if we can find that
+ // connector in the retrieved connectors from the API call
+ if (!isLoading) {
+ dispatch({
+ type: 'SET_CURRENT_CONNECTOR',
+ payload: getConnectorById(caseData.connector.id, connectors),
+ });
+
+ // Set the fields initially to whatever is present in the case, this should match with
+ // the latest user action for an update connector as well
+ dispatch({
+ type: 'SET_FIELDS',
+ payload: caseFields,
+ });
+ }
+ }, [caseData.connector.id, connectors, isLoading, caseFields]);
+
+ /**
+ * There is a race condition with this callback. At some point during the initial mounting of this component, this
+ * callback will be called. There are a couple problems with this:
+ *
+ * 1. If the call occurs before the above useEffect does its dispatches (aka while the connectors are still loading) this will
+ * result in setting the current connector to null when in fact we might have a valid connector. It could also
+ * cause issues when setting the fields because if there are no user actions then the getConnectorFieldsFromUserActions
+ * will return null even when the caseData.connector.fields is valid and populated.
+ *
+ * 2. If the call occurs after the above useEffect then the currentConnector should === newConnectorId
+ *
+ * As far as I know dispatch is synchronous so if the useEffect runs first it should successfully set currentConnector. If
+ * onChangeConnector runs first and sets stuff to null, then when useEffect runs it'll switch everything back to what we need it to be
+ * initially.
+ */
const onChangeConnector = useCallback(
(newConnectorId) => {
- // Init
- if (currentConnector == null) {
- dispatch({
- type: 'SET_CURRENT_CONNECTOR',
- payload: getConnectorById(newConnectorId, connectors),
- });
- }
- // change connect on dropdown action
- else if (currentConnector.id !== newConnectorId) {
+ // change connector on dropdown action
+ if (currentConnector?.id !== newConnectorId) {
dispatch({
type: 'SET_CURRENT_CONNECTOR',
payload: getConnectorById(newConnectorId, connectors),
@@ -163,14 +189,9 @@ export const EditConnector = React.memo(
type: 'SET_FIELDS',
payload: getConnectorFieldsFromUserActions(newConnectorId, userActions ?? []),
});
- } else if (fields === null) {
- dispatch({
- type: 'SET_FIELDS',
- payload: getConnectorFieldsFromUserActions(newConnectorId, userActions ?? []),
- });
}
},
- [currentConnector, fields, userActions, connectors]
+ [currentConnector, userActions, connectors]
);
const onFieldsChange = useCallback(
diff --git a/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/processor.tsx b/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/processor.tsx
index 18315b1611c56..d0e816a06c7df 100644
--- a/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/processor.tsx
+++ b/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/processor.tsx
@@ -48,7 +48,7 @@ const LensMarkDownRendererComponent: React.FC = ({
style={{ height: LENS_VISUALIZATION_HEIGHT }}
timeRange={timeRange}
attributes={attributes}
- renderMode="display"
+ renderMode="view"
/>
diff --git a/x-pack/plugins/graph/kibana.json b/x-pack/plugins/graph/kibana.json
index 463893e2425ac..cc732e67995ba 100644
--- a/x-pack/plugins/graph/kibana.json
+++ b/x-pack/plugins/graph/kibana.json
@@ -9,7 +9,7 @@
"configPath": ["xpack", "graph"],
"requiredBundles": ["kibanaUtils", "kibanaReact", "home"],
"owner": {
- "name": "Vis Editors",
- "githubTeam": "kibana-vis-editors"
+ "name": "Data Discovery",
+ "githubTeam": "kibana-data-discovery"
}
}
diff --git a/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.test.tsx b/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.test.tsx
index a0d137b90e84c..c156b870e7aa3 100644
--- a/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.test.tsx
+++ b/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.test.tsx
@@ -151,7 +151,7 @@ describe('DatatableComponent', () => {
dispatchEvent={onDispatchEvent}
getType={jest.fn()}
rowHasRowClickTriggerActions={[false, false, false]}
- renderMode="display"
+ renderMode="view"
paletteService={chartPluginMock.createPaletteRegistry()}
uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient}
/>
@@ -427,7 +427,7 @@ describe('DatatableComponent', () => {
formatFactory={() => ({ convert: (x) => x } as IFieldFormat)}
dispatchEvent={onDispatchEvent}
getType={jest.fn()}
- renderMode="display"
+ renderMode="view"
paletteService={chartPluginMock.createPaletteRegistry()}
uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient}
/>
@@ -457,7 +457,7 @@ describe('DatatableComponent', () => {
formatFactory={() => ({ convert: (x) => x } as IFieldFormat)}
dispatchEvent={onDispatchEvent}
getType={jest.fn()}
- renderMode="display"
+ renderMode="view"
paletteService={chartPluginMock.createPaletteRegistry()}
uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient}
/>
@@ -485,7 +485,7 @@ describe('DatatableComponent', () => {
formatFactory={() => ({ convert: (x) => x } as IFieldFormat)}
dispatchEvent={onDispatchEvent}
getType={jest.fn()}
- renderMode="display"
+ renderMode="view"
paletteService={chartPluginMock.createPaletteRegistry()}
uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient}
/>
@@ -546,7 +546,7 @@ describe('DatatableComponent', () => {
formatFactory={() => ({ convert: (x) => x } as IFieldFormat)}
dispatchEvent={onDispatchEvent}
getType={jest.fn()}
- renderMode="display"
+ renderMode="view"
paletteService={chartPluginMock.createPaletteRegistry()}
uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient}
/>
@@ -581,7 +581,7 @@ describe('DatatableComponent', () => {
formatFactory={() => ({ convert: (x) => x } as IFieldFormat)}
dispatchEvent={onDispatchEvent}
getType={jest.fn()}
- renderMode="display"
+ renderMode="view"
paletteService={chartPluginMock.createPaletteRegistry()}
uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient}
/>
@@ -616,7 +616,7 @@ describe('DatatableComponent', () => {
formatFactory={() => ({ convert: (x) => x } as IFieldFormat)}
dispatchEvent={onDispatchEvent}
getType={jest.fn()}
- renderMode="display"
+ renderMode="view"
paletteService={chartPluginMock.createPaletteRegistry()}
uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient}
/>
@@ -650,7 +650,7 @@ describe('DatatableComponent', () => {
formatFactory={() => ({ convert: (x) => x } as IFieldFormat)}
dispatchEvent={onDispatchEvent}
getType={jest.fn()}
- renderMode="display"
+ renderMode="view"
paletteService={chartPluginMock.createPaletteRegistry()}
uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient}
/>
diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.test.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.test.tsx
index a0831e8a73b57..be20118ba2941 100644
--- a/x-pack/plugins/lens/public/embeddable/embeddable.test.tsx
+++ b/x-pack/plugins/lens/public/embeddable/embeddable.test.tsx
@@ -566,7 +566,8 @@ describe('embeddable', () => {
timeRange,
query,
filters,
- renderMode: 'noInteractivity',
+ renderMode: 'view',
+ disableTriggers: true,
} as LensEmbeddableInput;
const embeddable = new Embeddable(
@@ -599,7 +600,12 @@ describe('embeddable', () => {
await embeddable.initializeSavedVis(input);
embeddable.render(mountpoint);
- expect(expressionRenderer.mock.calls[0][0].renderMode).toEqual('noInteractivity');
+ expect(expressionRenderer.mock.calls[0][0]).toEqual(
+ expect.objectContaining({
+ interactive: false,
+ renderMode: 'view',
+ })
+ );
});
it('should merge external context with query and filters of the saved object', async () => {
diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx
index 7e87dd3076faa..d10423c76686c 100644
--- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx
+++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx
@@ -361,6 +361,7 @@ export class Embeddable
searchSessionId={this.externalSearchContext.searchSessionId}
handleEvent={this.handleEvent}
onData$={this.updateActiveData}
+ interactive={!input.disableTriggers}
renderMode={input.renderMode}
syncColors={input.syncColors}
hasCompatibleActions={this.hasCompatibleActions}
diff --git a/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx b/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx
index 1116b4a0d3963..c827fe74cc52b 100644
--- a/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx
+++ b/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx
@@ -38,6 +38,7 @@ export interface ExpressionWrapperProps {
expression: string | null;
errors: ErrorMessage[] | undefined;
variables?: Record;
+ interactive?: boolean;
searchContext: ExecutionContextSearch;
searchSessionId?: string;
handleEvent: (event: ExpressionRendererEvent) => void;
@@ -113,6 +114,7 @@ export function ExpressionWrapper({
searchContext,
variables,
handleEvent,
+ interactive,
searchSessionId,
onData$,
renderMode,
@@ -137,6 +139,7 @@ export function ExpressionWrapper({
padding="s"
variables={variables}
expression={expression}
+ interactive={interactive}
searchContext={searchContext}
searchSessionId={searchSessionId}
onData$={onData$}
diff --git a/x-pack/plugins/lens/public/pie_visualization/expression.tsx b/x-pack/plugins/lens/public/pie_visualization/expression.tsx
index 50dc0e2a296be..d26289450bd0f 100644
--- a/x-pack/plugins/lens/public/pie_visualization/expression.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/expression.tsx
@@ -42,6 +42,7 @@ export const getPieRenderer = (dependencies: {
{...config}
formatFactory={dependencies.formatFactory}
chartsThemeService={dependencies.chartsThemeService}
+ interactive={handlers.isInteractive()}
paletteService={dependencies.paletteService}
onClickValue={onClickValue}
renderMode={handlers.getRenderMode()}
diff --git a/x-pack/plugins/lens/public/pie_visualization/render_function.test.tsx b/x-pack/plugins/lens/public/pie_visualization/render_function.test.tsx
index 93f16c49061e4..209d7ff652ea1 100644
--- a/x-pack/plugins/lens/public/pie_visualization/render_function.test.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/render_function.test.tsx
@@ -77,7 +77,7 @@ describe('PieVisualization component', () => {
onClickValue: jest.fn(),
chartsThemeService,
paletteService: chartPluginMock.createPaletteRegistry(),
- renderMode: 'display' as const,
+ renderMode: 'view' as const,
syncColors: false,
};
}
@@ -302,10 +302,10 @@ describe('PieVisualization component', () => {
`);
});
- test('does not set click listener on noInteractivity render mode', () => {
+ test('does not set click listener on non-interactive mode', () => {
const defaultArgs = getDefaultArgs();
const component = shallow(
-
+
);
expect(component.find(Settings).first().prop('onElementClick')).toBeUndefined();
});
diff --git a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
index 41b96ff4324ae..a0a845dc96007 100644
--- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
+++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx
@@ -55,6 +55,7 @@ export function PieComponent(
props: PieExpressionProps & {
formatFactory: FormatFactory;
chartsThemeService: ChartsPluginSetup['theme'];
+ interactive?: boolean;
paletteService: PaletteRegistry;
onClickValue: (data: LensFilterEvent['data']) => void;
renderMode: RenderMode;
@@ -289,9 +290,7 @@ export function PieComponent(
}
legendPosition={legendPosition || Position.Right}
legendMaxDepth={nestedLegend ? undefined : 1 /* Color is based only on first layer */}
- onElementClick={
- props.renderMode !== 'noInteractivity' ? onElementClickHandler : undefined
- }
+ onElementClick={props.interactive ?? true ? onElementClickHandler : undefined}
legendAction={getLegendAction(firstTable, onClickValue)}
theme={{
...chartTheme,
diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx
index aa2a0b42864e6..671db4653a88a 100644
--- a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx
+++ b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx
@@ -481,7 +481,7 @@ describe('xy_expression', () => {
defaultProps = {
formatFactory: getFormatSpy,
timeZone: 'UTC',
- renderMode: 'display',
+ renderMode: 'view',
chartsThemeService,
chartsActiveCursorService,
paletteService,
@@ -1065,11 +1065,11 @@ describe('xy_expression', () => {
});
});
- test('onBrushEnd is not set on noInteractivity mode', () => {
+ test('onBrushEnd is not set on non-interactive mode', () => {
const { args, data } = sampleArgs();
const wrapper = mountWithIntl(
-
+
);
expect(wrapper.find(Settings).first().prop('onBrushEnd')).toBeUndefined();
@@ -1335,11 +1335,11 @@ describe('xy_expression', () => {
});
});
- test('onElementClick is not triggering event on noInteractivity mode', () => {
+ test('onElementClick is not triggering event on non-interactive mode', () => {
const { args, data } = sampleArgs();
const wrapper = mountWithIntl(
-
+
);
expect(wrapper.find(Settings).first().prop('onElementClick')).toBeUndefined();
diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx
index 4eaebeb98a5a1..b7f1a9dabf3c7 100644
--- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx
+++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx
@@ -81,6 +81,7 @@ export type XYChartRenderProps = XYChartProps & {
formatFactory: FormatFactory;
timeZone: string;
minInterval: number | undefined;
+ interactive?: boolean;
onClickValue: (data: LensFilterEvent['data']) => void;
onSelectRange: (data: LensBrushEvent['data']) => void;
renderMode: RenderMode;
@@ -148,6 +149,7 @@ export const getXyChartRenderer = (dependencies: {
paletteService={dependencies.paletteService}
timeZone={dependencies.timeZone}
minInterval={calculateMinInterval(config)}
+ interactive={handlers.isInteractive()}
onClickValue={onClickValue}
onSelectRange={onSelectRange}
renderMode={handlers.getRenderMode()}
@@ -221,7 +223,7 @@ export function XYChart({
minInterval,
onClickValue,
onSelectRange,
- renderMode,
+ interactive = true,
syncColors,
}: XYChartRenderProps) {
const {
@@ -516,8 +518,8 @@ export function XYChart({
}}
rotation={shouldRotate ? 90 : 0}
xDomain={xDomain}
- onBrushEnd={renderMode !== 'noInteractivity' ? brushHandler : undefined}
- onElementClick={renderMode !== 'noInteractivity' ? clickHandler : undefined}
+ onBrushEnd={interactive ? brushHandler : undefined}
+ onElementClick={interactive ? clickHandler : undefined}
legendAction={getLegendAction(
filteredLayers,
data.tables,
diff --git a/x-pack/plugins/lists/common/schemas/response/found_exception_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/response/found_exception_list_schema.mock.ts
index e3611120348f4..e5e41b5fe4a85 100644
--- a/x-pack/plugins/lists/common/schemas/response/found_exception_list_schema.mock.ts
+++ b/x-pack/plugins/lists/common/schemas/response/found_exception_list_schema.mock.ts
@@ -12,6 +12,6 @@ import { getExceptionListSchemaMock } from './exception_list_schema.mock';
export const getFoundExceptionListSchemaMock = (): FoundExceptionListSchema => ({
data: [getExceptionListSchemaMock()],
page: 1,
- per_page: 1,
+ per_page: 20,
total: 1,
});
diff --git a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_lists.test.ts b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_lists.test.ts
index 4987de321c556..810fcaa15494f 100644
--- a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_lists.test.ts
+++ b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_lists.test.ts
@@ -41,13 +41,13 @@ describe('useExceptionLists', () => {
errorMessage: 'Uh oh',
filterOptions: {},
http: mockKibanaHttpService,
- namespaceTypes: ['single', 'agnostic'],
- notifications: mockKibanaNotificationsService,
- pagination: {
+ initialPagination: {
page: 1,
perPage: 20,
total: 0,
},
+ namespaceTypes: ['single', 'agnostic'],
+ notifications: mockKibanaNotificationsService,
showEventFilters: false,
showTrustedApps: false,
})
@@ -62,7 +62,8 @@ describe('useExceptionLists', () => {
perPage: 20,
total: 0,
},
- null,
+ expect.any(Function),
+ expect.any(Function),
]);
});
});
@@ -77,13 +78,13 @@ describe('useExceptionLists', () => {
errorMessage: 'Uh oh',
filterOptions: {},
http: mockKibanaHttpService,
- namespaceTypes: ['single', 'agnostic'],
- notifications: mockKibanaNotificationsService,
- pagination: {
+ initialPagination: {
page: 1,
perPage: 20,
total: 0,
},
+ namespaceTypes: ['single', 'agnostic'],
+ notifications: mockKibanaNotificationsService,
showEventFilters: false,
showTrustedApps: false,
})
@@ -100,10 +101,11 @@ describe('useExceptionLists', () => {
expectedListItemsResult,
{
page: 1,
- perPage: 1,
+ perPage: 20,
total: 1,
},
- result.current[3],
+ expect.any(Function),
+ expect.any(Function),
]);
});
});
@@ -117,13 +119,13 @@ describe('useExceptionLists', () => {
errorMessage: 'Uh oh',
filterOptions: {},
http: mockKibanaHttpService,
- namespaceTypes: ['single', 'agnostic'],
- notifications: mockKibanaNotificationsService,
- pagination: {
+ initialPagination: {
page: 1,
perPage: 20,
total: 0,
},
+ namespaceTypes: ['single', 'agnostic'],
+ notifications: mockKibanaNotificationsService,
showEventFilters: false,
showTrustedApps: true,
})
@@ -153,13 +155,13 @@ describe('useExceptionLists', () => {
errorMessage: 'Uh oh',
filterOptions: {},
http: mockKibanaHttpService,
- namespaceTypes: ['single', 'agnostic'],
- notifications: mockKibanaNotificationsService,
- pagination: {
+ initialPagination: {
page: 1,
perPage: 20,
total: 0,
},
+ namespaceTypes: ['single', 'agnostic'],
+ notifications: mockKibanaNotificationsService,
showEventFilters: false,
showTrustedApps: false,
})
@@ -189,13 +191,13 @@ describe('useExceptionLists', () => {
errorMessage: 'Uh oh',
filterOptions: {},
http: mockKibanaHttpService,
- namespaceTypes: ['single', 'agnostic'],
- notifications: mockKibanaNotificationsService,
- pagination: {
+ initialPagination: {
page: 1,
perPage: 20,
total: 0,
},
+ namespaceTypes: ['single', 'agnostic'],
+ notifications: mockKibanaNotificationsService,
showEventFilters: true,
showTrustedApps: false,
})
@@ -225,13 +227,13 @@ describe('useExceptionLists', () => {
errorMessage: 'Uh oh',
filterOptions: {},
http: mockKibanaHttpService,
- namespaceTypes: ['single', 'agnostic'],
- notifications: mockKibanaNotificationsService,
- pagination: {
+ initialPagination: {
page: 1,
perPage: 20,
total: 0,
},
+ namespaceTypes: ['single', 'agnostic'],
+ notifications: mockKibanaNotificationsService,
showEventFilters: false,
showTrustedApps: false,
})
@@ -264,13 +266,13 @@ describe('useExceptionLists', () => {
name: 'Sample Endpoint',
},
http: mockKibanaHttpService,
- namespaceTypes: ['single', 'agnostic'],
- notifications: mockKibanaNotificationsService,
- pagination: {
+ initialPagination: {
page: 1,
perPage: 20,
total: 0,
},
+ namespaceTypes: ['single', 'agnostic'],
+ notifications: mockKibanaNotificationsService,
showEventFilters: false,
showTrustedApps: false,
})
@@ -302,9 +304,9 @@ describe('useExceptionLists', () => {
errorMessage,
filterOptions,
http,
+ initialPagination,
namespaceTypes,
notifications,
- pagination,
showEventFilters,
showTrustedApps,
}) =>
@@ -312,9 +314,9 @@ describe('useExceptionLists', () => {
errorMessage,
filterOptions,
http,
+ initialPagination,
namespaceTypes,
notifications,
- pagination,
showEventFilters,
showTrustedApps,
}),
@@ -323,13 +325,13 @@ describe('useExceptionLists', () => {
errorMessage: 'Uh oh',
filterOptions: {},
http: mockKibanaHttpService,
- namespaceTypes: ['single'],
- notifications: mockKibanaNotificationsService,
- pagination: {
+ initialPagination: {
page: 1,
perPage: 20,
total: 0,
},
+ namespaceTypes: ['single'],
+ notifications: mockKibanaNotificationsService,
showEventFilters: false,
showTrustedApps: false,
},
@@ -344,13 +346,13 @@ describe('useExceptionLists', () => {
errorMessage: 'Uh oh',
filterOptions: {},
http: mockKibanaHttpService,
- namespaceTypes: ['single', 'agnostic'],
- notifications: mockKibanaNotificationsService,
- pagination: {
+ initialPagination: {
page: 1,
perPage: 20,
total: 0,
},
+ namespaceTypes: ['single', 'agnostic'],
+ notifications: mockKibanaNotificationsService,
showEventFilters: false,
showTrustedApps: false,
});
@@ -372,13 +374,13 @@ describe('useExceptionLists', () => {
errorMessage: 'Uh oh',
filterOptions: {},
http: mockKibanaHttpService,
- namespaceTypes: ['single', 'agnostic'],
- notifications: mockKibanaNotificationsService,
- pagination: {
+ initialPagination: {
page: 1,
perPage: 20,
total: 0,
},
+ namespaceTypes: ['single', 'agnostic'],
+ notifications: mockKibanaNotificationsService,
showEventFilters: false,
showTrustedApps: false,
})
@@ -390,8 +392,8 @@ describe('useExceptionLists', () => {
expect(typeof result.current[3]).toEqual('function');
- if (result.current[3] != null) {
- result.current[3]();
+ if (result.current[4] != null) {
+ result.current[4]();
}
// NOTE: Only need one call here because hook already initilaized
await waitForNextUpdate();
@@ -411,13 +413,13 @@ describe('useExceptionLists', () => {
errorMessage: 'Uh oh',
filterOptions: {},
http: mockKibanaHttpService,
- namespaceTypes: ['single', 'agnostic'],
- notifications: mockKibanaNotificationsService,
- pagination: {
+ initialPagination: {
page: 1,
perPage: 20,
total: 0,
},
+ namespaceTypes: ['single', 'agnostic'],
+ notifications: mockKibanaNotificationsService,
showEventFilters: false,
showTrustedApps: false,
})
diff --git a/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx b/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx
index 0c150773d22be..bc00c6a258a07 100644
--- a/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx
+++ b/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx
@@ -280,10 +280,10 @@ export const SwimlaneContainer: FC = ({
return { x: selection.times.map((v) => v * 1000), y: selection.lanes };
}, [selection, swimlaneData, swimlaneType]);
- const swimLaneConfig: HeatmapSpec['config'] = useMemo(() => {
+ const swimLaneConfig = useMemo(() => {
if (!showSwimlane) return {};
- return {
+ const config: HeatmapSpec['config'] = {
onBrushEnd: (e: HeatmapBrushEvent) => {
if (!e.cells.length) return;
@@ -318,7 +318,7 @@ export const SwimlaneContainer: FC = ({
yAxisLabel: {
visible: true,
width: Y_AXIS_LABEL_WIDTH,
- fill: euiTheme.euiTextSubduedColor,
+ textColor: euiTheme.euiTextSubduedColor,
padding: Y_AXIS_LABEL_PADDING,
formatter: (laneLabel: string) => {
return laneLabel === '' ? EMPTY_FIELD_VALUE_LABEL : laneLabel;
@@ -327,7 +327,7 @@ export const SwimlaneContainer: FC = ({
},
xAxisLabel: {
visible: true,
- fill: euiTheme.euiTextSubduedColor,
+ textColor: euiTheme.euiTextSubduedColor,
formatter: (v: number) => {
timeBuckets.setInterval(`${swimlaneData.interval}s`);
const scaledDateFormat = timeBuckets.getScaledDateFormat();
@@ -346,6 +346,8 @@ export const SwimlaneContainer: FC = ({
...(showLegend ? { maxLegendHeight: LEGEND_HEIGHT } : {}),
timeZone: 'UTC',
};
+
+ return config;
}, [
showSwimlane,
swimlaneType,
diff --git a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts
index 7a81a7ecb1e34..32c6aeb6b7553 100644
--- a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts
+++ b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts
@@ -590,7 +590,7 @@ export class AnomalyExplorerChartsService {
return mlResultsService
.getMetricData(
Array.isArray(config.datafeedConfig.indices)
- ? config.datafeedConfig.indices[0]
+ ? config.datafeedConfig.indices.join()
: config.datafeedConfig.indices,
entityFields,
datafeedQuery,
@@ -777,7 +777,7 @@ export class AnomalyExplorerChartsService {
return mlResultsService
.getEventDistributionData(
Array.isArray(config.datafeedConfig.indices)
- ? config.datafeedConfig.indices[0]
+ ? config.datafeedConfig.indices.join()
: config.datafeedConfig.indices,
splitField,
filterField,
diff --git a/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx b/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx
index 2c80c874e89fa..6d0477b22edee 100644
--- a/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx
+++ b/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx
@@ -6,28 +6,16 @@
*/
import { useQuery } from 'react-query';
-
-import { i18n } from '@kbn/i18n';
import { useKibana } from '../common/lib/kibana';
-import { useErrorToast } from '../common/hooks/use_error_toast';
export const useActionResultsPrivileges = () => {
const { http } = useKibana().services;
- const setErrorToast = useErrorToast();
return useQuery(
['actionResultsPrivileges'],
() => http.get('/internal/osquery/privileges_check'),
{
keepPreviousData: true,
- select: (response) => response?.has_all_requested ?? false,
- onSuccess: () => setErrorToast(),
- onError: (error: Error) =>
- setErrorToast(error, {
- title: i18n.translate('xpack.osquery.action_results_privileges.fetchError', {
- defaultMessage: 'Error while fetching action results privileges',
- }),
- }),
}
);
};
diff --git a/x-pack/plugins/osquery/public/common/page_paths.ts b/x-pack/plugins/osquery/public/common/page_paths.ts
index 0e0d8310ae8be..8df1006da181a 100644
--- a/x-pack/plugins/osquery/public/common/page_paths.ts
+++ b/x-pack/plugins/osquery/public/common/page_paths.ts
@@ -27,8 +27,6 @@ export interface DynamicPagePathValues {
[key: string]: string;
}
-export const BASE_PATH = '/app/fleet';
-
// If routing paths are changed here, please also check to see if
// `pagePathGetters()`, below, needs any modifications
export const PAGE_ROUTING_PATHS = {
diff --git a/x-pack/plugins/osquery/public/components/app.tsx b/x-pack/plugins/osquery/public/components/app.tsx
index 44407139ab492..33fb6ac6a2adf 100644
--- a/x-pack/plugins/osquery/public/components/app.tsx
+++ b/x-pack/plugins/osquery/public/components/app.tsx
@@ -5,6 +5,8 @@
* 2.0.
*/
+/* eslint-disable react-hooks/rules-of-hooks */
+
import React, { useMemo } from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiTabs, EuiTab } from '@elastic/eui';
@@ -14,10 +16,17 @@ import { Container, Nav, Wrapper } from './layouts';
import { OsqueryAppRoutes } from '../routes';
import { useRouterNavigate } from '../common/lib/kibana';
import { ManageIntegrationLink } from './manage_integration_link';
+import { useOsqueryIntegrationStatus } from '../common/hooks';
+import { OsqueryAppEmptyState } from './empty_state';
const OsqueryAppComponent = () => {
const location = useLocation();
const section = useMemo(() => location.pathname.split('/')[1] ?? 'overview', [location.pathname]);
+ const { data: osqueryIntegration, isFetched } = useOsqueryIntegrationStatus();
+
+ if (isFetched && osqueryIntegration.install_status !== 'installed') {
+ return ;
+ }
return (
diff --git a/x-pack/plugins/osquery/public/components/empty_state.tsx b/x-pack/plugins/osquery/public/components/empty_state.tsx
new file mode 100644
index 0000000000000..1ee0d496c0ddc
--- /dev/null
+++ b/x-pack/plugins/osquery/public/components/empty_state.tsx
@@ -0,0 +1,86 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React, { useCallback, useMemo } from 'react';
+import { FormattedMessage } from '@kbn/i18n/react';
+import { EuiButton } from '@elastic/eui';
+
+import { KibanaPageTemplate } from '../../../../../src/plugins/kibana_react/public';
+import { INTEGRATIONS_PLUGIN_ID } from '../../../fleet/common';
+import { pagePathGetters } from '../../../fleet/public';
+import { isModifiedEvent, isLeftClickEvent, useKibana } from '../common/lib/kibana';
+import { OsqueryIcon } from './osquery_icon';
+import { useBreadcrumbs } from '../common/hooks/use_breadcrumbs';
+import { OSQUERY_INTEGRATION_NAME } from '../../common';
+
+const OsqueryAppEmptyStateComponent = () => {
+ useBreadcrumbs('base');
+
+ const {
+ application: { getUrlForApp, navigateToApp },
+ } = useKibana().services;
+
+ const integrationHref = useMemo(() => {
+ return getUrlForApp(INTEGRATIONS_PLUGIN_ID, {
+ path: pagePathGetters.integration_details_overview({
+ pkgkey: OSQUERY_INTEGRATION_NAME,
+ })[1],
+ });
+ }, [getUrlForApp]);
+
+ const integrationClick = useCallback(
+ (event) => {
+ if (!isModifiedEvent(event) && isLeftClickEvent(event)) {
+ event.preventDefault();
+ return navigateToApp(INTEGRATIONS_PLUGIN_ID, {
+ path: pagePathGetters.integration_details_overview({
+ pkgkey: OSQUERY_INTEGRATION_NAME,
+ })[1],
+ });
+ }
+ },
+ [navigateToApp]
+ );
+
+ const pageHeader = useMemo(
+ () => ({
+ iconType: OsqueryIcon,
+ pageTitle: (
+
+ ),
+ description: (
+
+ ),
+ rightSideItems: [
+ // eslint-disable-next-line @elastic/eui/href-or-on-click
+
+
+ ,
+ ],
+ }),
+ [integrationClick, integrationHref]
+ );
+
+ return ;
+};
+
+export const OsqueryAppEmptyState = React.memo(OsqueryAppEmptyStateComponent);
diff --git a/x-pack/plugins/osquery/public/components/manage_integration_link.tsx b/x-pack/plugins/osquery/public/components/manage_integration_link.tsx
index 44b923860e1a8..32779ded46c50 100644
--- a/x-pack/plugins/osquery/public/components/manage_integration_link.tsx
+++ b/x-pack/plugins/osquery/public/components/manage_integration_link.tsx
@@ -24,11 +24,9 @@ const ManageIntegrationLinkComponent = () => {
const integrationHref = useMemo(() => {
if (osqueryIntegration) {
return getUrlForApp(INTEGRATIONS_PLUGIN_ID, {
- path:
- '#' +
- pagePathGetters.integration_details_policies({
- pkgkey: `${osqueryIntegration.name}-${osqueryIntegration.version}`,
- })[1],
+ path: pagePathGetters.integration_details_policies({
+ pkgkey: `${osqueryIntegration.name}-${osqueryIntegration.version}`,
+ })[1],
});
}
}, [getUrlForApp, osqueryIntegration]);
@@ -39,11 +37,9 @@ const ManageIntegrationLinkComponent = () => {
event.preventDefault();
if (osqueryIntegration) {
return navigateToApp(INTEGRATIONS_PLUGIN_ID, {
- path:
- '#' +
- pagePathGetters.integration_details_policies({
- pkgkey: `${osqueryIntegration.name}-${osqueryIntegration.version}`,
- })[1],
+ path: pagePathGetters.integration_details_policies({
+ pkgkey: `${osqueryIntegration.name}-${osqueryIntegration.version}`,
+ })[1],
});
}
}
diff --git a/x-pack/plugins/osquery/public/live_queries/form/index.tsx b/x-pack/plugins/osquery/public/live_queries/form/index.tsx
index 987be904c87e6..69b02dee8b9f7 100644
--- a/x-pack/plugins/osquery/public/live_queries/form/index.tsx
+++ b/x-pack/plugins/osquery/public/live_queries/form/index.tsx
@@ -114,7 +114,7 @@ const LiveQueryFormComponent: React.FC = ({
),
});
- const { setFieldValue, submit } = form;
+ const { setFieldValue, submit, isSubmitting } = form;
const actionId = useMemo(() => data?.actions[0].action_id, [data?.actions]);
const agentIds = useMemo(() => data?.actions[0].agents, [data?.actions]);
@@ -185,7 +185,10 @@ const LiveQueryFormComponent: React.FC = ({
)}
-
+
= ({
>
),
[
- agentSelected,
- permissions.writeSavedQueries,
- handleShowSaveQueryFlout,
queryComponentProps,
+ singleAgentMode,
+ permissions.writeSavedQueries,
+ agentSelected,
queryValueProvided,
resultsStatus,
- singleAgentMode,
+ handleShowSaveQueryFlout,
+ isSubmitting,
submit,
]
);
diff --git a/x-pack/plugins/osquery/public/packs/common/add_pack_query.tsx b/x-pack/plugins/osquery/public/packs/common/add_pack_query.tsx
index 2d58e2dfe9522..d1115898b4e40 100644
--- a/x-pack/plugins/osquery/public/packs/common/add_pack_query.tsx
+++ b/x-pack/plugins/osquery/public/packs/common/add_pack_query.tsx
@@ -51,7 +51,7 @@ const AddPackQueryFormComponent = ({ handleSubmit }) => {
},
},
});
- const { submit } = form;
+ const { submit, isSubmitting } = form;
const createSavedQueryMutation = useMutation(
(payload) => http.post(`/internal/osquery/saved_query`, { body: JSON.stringify(payload) }),
@@ -108,7 +108,7 @@ const AddPackQueryFormComponent = ({ handleSubmit }) => {
-
+
{'Add query'}
diff --git a/x-pack/plugins/osquery/public/packs/common/pack_form.tsx b/x-pack/plugins/osquery/public/packs/common/pack_form.tsx
index 86d4d8dff6ba6..ab0984e808943 100644
--- a/x-pack/plugins/osquery/public/packs/common/pack_form.tsx
+++ b/x-pack/plugins/osquery/public/packs/common/pack_form.tsx
@@ -40,7 +40,7 @@ const PackFormComponent = ({ data, handleSubmit }) => {
},
},
});
- const { submit } = form;
+ const { submit, isSubmitting } = form;
return (
diff --git a/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx b/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx
index a7596575b90c4..617d83821d08d 100644
--- a/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx
+++ b/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx
@@ -38,6 +38,7 @@ const EditSavedQueryFormComponent: React.FC = ({
defaultValue,
handleSubmit,
});
+ const { submit, isSubmitting } = form;
return (
= ({
defaultValue,
handleSubmit,
});
+ const { submit, isSubmitting } = form;
return (
{
const { data } = useScheduledQueryGroup({ scheduledQueryGroupId });
- useBreadcrumbs('scheduled_query_group_edit', { scheduledQueryGroupName: data?.name ?? '' });
+ useBreadcrumbs('scheduled_query_group_edit', {
+ scheduledQueryGroupId: data?.id ?? '',
+ scheduledQueryGroupName: data?.name ?? '',
+ });
const LeftColumn = useMemo(
() => (
diff --git a/x-pack/plugins/osquery/public/saved_queries/constants.ts b/x-pack/plugins/osquery/public/saved_queries/constants.ts
index 69ca805e3e8fa..8edcfd00d1788 100644
--- a/x-pack/plugins/osquery/public/saved_queries/constants.ts
+++ b/x-pack/plugins/osquery/public/saved_queries/constants.ts
@@ -6,3 +6,4 @@
*/
export const SAVED_QUERIES_ID = 'savedQueryList';
+export const SAVED_QUERY_ID = 'savedQuery';
diff --git a/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx b/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx
index 6d14943a6bc84..8c35a359a9baf 100644
--- a/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx
+++ b/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx
@@ -42,6 +42,7 @@ const SavedQueryFlyoutComponent: React.FC = ({ defaultValue
defaultValue,
handleSubmit,
});
+ const { submit, isSubmitting } = form;
return (
@@ -72,7 +73,7 @@ const SavedQueryFlyoutComponent: React.FC = ({ defaultValue
-
+
{
queryClient.invalidateQueries(SAVED_QUERIES_ID);
+ queryClient.invalidateQueries([SAVED_QUERY_ID, { savedQueryId }]);
navigateToApp(PLUGIN_ID, { path: pagePathGetters.saved_queries() });
toasts.addSuccess(
i18n.translate('xpack.osquery.editSavedQuery.successToastMessageText', {
diff --git a/x-pack/plugins/osquery/public/scheduled_query_groups/form/index.tsx b/x-pack/plugins/osquery/public/scheduled_query_groups/form/index.tsx
index 685960ecd202e..3598a9fd2e44c 100644
--- a/x-pack/plugins/osquery/public/scheduled_query_groups/form/index.tsx
+++ b/x-pack/plugins/osquery/public/scheduled_query_groups/form/index.tsx
@@ -88,7 +88,7 @@ const ScheduledQueryGroupFormComponent: React.FC =
`scheduled_query_groups/${editMode ? defaultValue?.id : ''}`
);
- const { isLoading, mutateAsync } = useMutation(
+ const { mutateAsync } = useMutation(
(payload: Record) =>
editMode && defaultValue?.id
? http.put(packagePolicyRouteService.getUpdatePath(defaultValue.id), {
@@ -248,7 +248,7 @@ const ScheduledQueryGroupFormComponent: React.FC =
),
});
- const { setFieldValue, submit } = form;
+ const { setFieldValue, submit, isSubmitting } = form;
const policyIdEuiFieldProps = useMemo(
() => ({ isDisabled: !!defaultValue, options: agentPolicyOptions }),
@@ -368,7 +368,7 @@ const ScheduledQueryGroupFormComponent: React.FC =
(
)
)(args);
- if (fieldRequiredError && (!!(!editForm && args.formData.value?.field.length) || editForm)) {
+ // @ts-expect-error update types
+ if (fieldRequiredError && ((!editForm && args.formData['value.field'].length) || editForm)) {
return fieldRequiredError;
}
diff --git a/x-pack/plugins/osquery/public/scheduled_query_groups/queries/query_flyout.tsx b/x-pack/plugins/osquery/public/scheduled_query_groups/queries/query_flyout.tsx
index cae9711694f29..d38c1b2118f24 100644
--- a/x-pack/plugins/osquery/public/scheduled_query_groups/queries/query_flyout.tsx
+++ b/x-pack/plugins/osquery/public/scheduled_query_groups/queries/query_flyout.tsx
@@ -5,6 +5,7 @@
* 2.0.
*/
+import { isEmpty } from 'lodash';
import {
EuiCallOut,
EuiFlyout,
@@ -66,7 +67,7 @@ const QueryFlyoutComponent: React.FC = ({
if (isValid && ecsFieldValue) {
onSave({
...payload,
- ecs_mapping: ecsFieldValue,
+ ...(isEmpty(ecsFieldValue) ? {} : { ecs_mapping: ecsFieldValue }),
});
onClose();
}
@@ -81,7 +82,7 @@ const QueryFlyoutComponent: React.FC = ({
[integrationPackageVersion]
);
- const { submit, setFieldValue, reset } = form;
+ const { submit, setFieldValue, reset, isSubmitting } = form;
const [{ query }] = useFormData({
form,
@@ -245,7 +246,7 @@ const QueryFlyoutComponent: React.FC = ({
-
+
= ({
toggleErrors,
expanded,
}) => {
+ const data = useKibana().services.data;
+ const [logsIndexPattern, setLogsIndexPattern] = useState(undefined);
+
const { data: lastResultsData, isFetched } = useScheduledQueryGroupQueryLastResults({
actionId,
agentIds,
interval,
+ logsIndexPattern,
});
const { data: errorsData, isFetched: errorsFetched } = useScheduledQueryGroupQueryErrors({
actionId,
agentIds,
interval,
+ logsIndexPattern,
});
const handleErrorsToggle = useCallback(() => toggleErrors({ queryId, interval }), [
@@ -409,20 +414,41 @@ const ScheduledQueryLastResults: React.FC = ({
toggleErrors,
]);
+ useEffect(() => {
+ const fetchLogsIndexPattern = async () => {
+ const indexPattern = await data.indexPatterns.find('logs-*');
+
+ setLogsIndexPattern(indexPattern[0]);
+ };
+ fetchLogsIndexPattern();
+ }, [data.indexPatterns]);
+
if (!isFetched || !errorsFetched) {
return ;
}
- if (!lastResultsData) {
+ if (!lastResultsData && !errorsData?.total) {
return <>{'-'}>;
}
return (
- {lastResultsData.first_event_ingested_time?.value ? (
-
- <>{moment(lastResultsData.first_event_ingested_time?.value).fromNow()}>
+ {lastResultsData?.['@timestamp'] ? (
+
+ {' '}
+
+ >
+ }
+ >
+
) : (
'-'
@@ -432,10 +458,17 @@ const ScheduledQueryLastResults: React.FC = ({
- {lastResultsData?.doc_count ?? 0}
+ {lastResultsData?.docCount ?? 0}
- {'Documents'}
+
+
+
@@ -443,10 +476,17 @@ const ScheduledQueryLastResults: React.FC = ({
- {lastResultsData?.unique_agents?.value ?? 0}
+ {lastResultsData?.uniqueAgentsCount ?? 0}
- {'Agents'}
+
+
+
@@ -458,7 +498,15 @@ const ScheduledQueryLastResults: React.FC = ({
- {'Errors'}
+
+ {' '}
+
+
{
const data = useKibana().services.data;
@@ -28,9 +30,8 @@ export const useScheduledQueryGroupQueryErrors = ({
return useQuery(
['scheduledQueryErrors', { actionId, interval }],
async () => {
- const indexPattern = await data.indexPatterns.find('logs-*');
const searchSource = await data.search.searchSource.create({
- index: indexPattern[0],
+ index: logsIndexPattern,
fields: ['*'],
sort: [
{
@@ -80,7 +81,7 @@ export const useScheduledQueryGroupQueryErrors = ({
},
{
keepPreviousData: true,
- enabled: !!(!skip && actionId && interval && agentIds?.length),
+ enabled: !!(!skip && actionId && interval && agentIds?.length && logsIndexPattern),
select: (response) => response.rawResponse.hits ?? [],
refetchOnReconnect: false,
refetchOnWindowFocus: false,
diff --git a/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts b/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts
index f972640e25986..7cfd6be461e05 100644
--- a/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts
+++ b/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts
@@ -6,13 +6,14 @@
*/
import { useQuery } from 'react-query';
-
+import { IndexPattern } from '../../../../../src/plugins/data/common';
import { useKibana } from '../common/lib/kibana';
interface UseScheduledQueryGroupQueryLastResultsProps {
actionId: string;
agentIds?: string[];
interval: number;
+ logsIndexPattern?: IndexPattern;
skip?: boolean;
}
@@ -20,6 +21,7 @@ export const useScheduledQueryGroupQueryLastResults = ({
actionId,
agentIds,
interval,
+ logsIndexPattern,
skip = false,
}: UseScheduledQueryGroupQueryLastResultsProps) => {
const data = useKibana().services.data;
@@ -27,23 +29,9 @@ export const useScheduledQueryGroupQueryLastResults = ({
return useQuery(
['scheduledQueryLastResults', { actionId }],
async () => {
- const indexPattern = await data.indexPatterns.find('logs-*');
- const searchSource = await data.search.searchSource.create({
- index: indexPattern[0],
- size: 0,
- aggs: {
- runs: {
- terms: {
- field: 'response_id',
- order: { first_event_ingested_time: 'desc' },
- size: 1,
- },
- aggs: {
- first_event_ingested_time: { min: { field: '@timestamp' } },
- unique_agents: { cardinality: { field: 'agent.id' } },
- },
- },
- },
+ const lastResultsSearchSource = await data.search.searchSource.create({
+ index: logsIndexPattern,
+ size: 1,
query: {
// @ts-expect-error update types
bool: {
@@ -59,26 +47,62 @@ export const useScheduledQueryGroupQueryLastResults = ({
action_id: actionId,
},
},
- {
- range: {
- '@timestamp': {
- gte: `now-${interval * 2}s`,
- lte: 'now',
- },
- },
- },
],
},
},
});
- return searchSource.fetch$().toPromise();
+ const lastResultsResponse = await lastResultsSearchSource.fetch$().toPromise();
+
+ const responseId = lastResultsResponse.rawResponse?.hits?.hits[0]?._source?.response_id;
+
+ if (responseId) {
+ const aggsSearchSource = await data.search.searchSource.create({
+ index: logsIndexPattern,
+ size: 0,
+ aggs: {
+ unique_agents: { cardinality: { field: 'agent.id' } },
+ },
+ query: {
+ // @ts-expect-error update types
+ bool: {
+ should: agentIds?.map((agentId) => ({
+ match_phrase: {
+ 'agent.id': agentId,
+ },
+ })),
+ minimum_should_match: 1,
+ filter: [
+ {
+ match_phrase: {
+ action_id: actionId,
+ },
+ },
+ {
+ match_phrase: {
+ response_id: responseId,
+ },
+ },
+ ],
+ },
+ },
+ });
+
+ const aggsResponse = await aggsSearchSource.fetch$().toPromise();
+
+ return {
+ '@timestamp': lastResultsResponse.rawResponse?.hits?.hits[0]?.fields?.['@timestamp'],
+ // @ts-expect-error update types
+ uniqueAgentsCount: aggsResponse.rawResponse.aggregations?.unique_agents?.value,
+ docCount: aggsResponse.rawResponse?.hits?.total,
+ };
+ }
+
+ return null;
},
{
keepPreviousData: true,
- enabled: !!(!skip && actionId && interval && agentIds?.length),
- // @ts-expect-error update types
- select: (response) => response.rawResponse.aggregations?.runs?.buckets[0] ?? [],
+ enabled: !!(!skip && actionId && interval && agentIds?.length && logsIndexPattern),
refetchOnReconnect: false,
refetchOnWindowFocus: false,
}
diff --git a/x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts b/x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts
index 80c335c1c46d3..d9683d23deb13 100644
--- a/x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts
+++ b/x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts
@@ -9,7 +9,6 @@ import { OSQUERY_INTEGRATION_NAME, PLUGIN_ID } from '../../../common';
import { IRouter } from '../../../../../../src/core/server';
import { OsqueryAppContext } from '../../lib/osquery_app_context_services';
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const privilegesCheckRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => {
router.get(
{
@@ -20,23 +19,26 @@ export const privilegesCheckRoute = (router: IRouter, osqueryContext: OsqueryApp
},
},
async (context, request, response) => {
- const esClient = context.core.elasticsearch.client.asCurrentUser;
-
- const privileges = (
- await esClient.security.hasPrivileges({
- body: {
- index: [
- {
- names: [`logs-${OSQUERY_INTEGRATION_NAME}.result*`],
- privileges: ['read'],
- },
- ],
+ if (osqueryContext.security.authz.mode.useRbacForRequest(request)) {
+ const checkPrivileges = osqueryContext.security.authz.checkPrivilegesDynamicallyWithRequest(
+ request
+ );
+ const { hasAllRequested } = await checkPrivileges({
+ elasticsearch: {
+ cluster: [],
+ index: {
+ [`logs-${OSQUERY_INTEGRATION_NAME}.result*`]: ['read'],
+ },
},
- })
- ).body;
+ });
+
+ return response.ok({
+ body: `${hasAllRequested}`,
+ });
+ }
return response.ok({
- body: privileges,
+ body: 'true',
});
}
);
diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx
index 582ca0252604c..1ef3c3d3c5414 100644
--- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx
+++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx
@@ -15,8 +15,9 @@ import { FormatUrl } from '../../../../../../common/components/link_to';
import * as i18n from './translations';
import { ExceptionListInfo } from './use_all_exception_lists';
import { ExceptionOverflowDisplay } from './exceptions_overflow_display';
+import { ExceptionsTableItem } from './types';
-export type AllExceptionListsColumns = EuiBasicTableColumn;
+export type AllExceptionListsColumns = EuiBasicTableColumn;
export const getAllExceptionListsColumns = (
onExport: (arg: { id: string; listId: string; namespaceType: NamespaceType }) => () => void,
diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx
index 206976e6c0c1a..23bf634cb1081 100644
--- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx
+++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx
@@ -7,6 +7,7 @@
import React, { useMemo, useEffect, useCallback, useState } from 'react';
import {
+ CriteriaWithPagination,
EuiBasicTable,
EuiEmptyPrompt,
EuiLoadingContent,
@@ -37,6 +38,7 @@ import { SecurityPageName } from '../../../../../../../common/constants';
import { useUserData } from '../../../../../components/user_info';
import { userHasPermissions } from '../../helpers';
import { useListsConfig } from '../../../../../containers/detection_engine/lists/use_lists_config';
+import { ExceptionsTableItem } from './types';
export type Func = () => Promise;
@@ -74,7 +76,13 @@ export const ExceptionListsTable = React.memo(() => {
exceptionReferenceModalInitialState
);
const [filters, setFilters] = useState(undefined);
- const [loadingExceptions, exceptions, pagination, refreshExceptions] = useExceptionLists({
+ const [
+ loadingExceptions,
+ exceptions,
+ pagination,
+ setPagination,
+ refreshExceptions,
+ ] = useExceptionLists({
errorMessage: i18n.ERROR_EXCEPTION_LISTS,
filterOptions: filters,
http,
@@ -125,7 +133,7 @@ export const ExceptionListsTable = React.memo(() => {
try {
setDeletingListIds((ids) => [...ids, id]);
if (refreshExceptions != null) {
- await refreshExceptions();
+ refreshExceptions();
}
if (exceptionsListsRef[id] != null && exceptionsListsRef[id].rules.length === 0) {
@@ -153,7 +161,7 @@ export const ExceptionListsTable = React.memo(() => {
} catch (error) {
handleDeleteError(error);
} finally {
- setDeletingListIds((ids) => [...ids.filter((_id) => _id !== id)]);
+ setDeletingListIds((ids) => ids.filter((_id) => _id !== id));
}
},
[
@@ -326,11 +334,27 @@ export const ExceptionListsTable = React.memo(() => {
setExportDownload({});
}, []);
- const tableItems = (exceptionListsWithRuleRefs ?? []).map((item) => ({
- ...item,
- isDeleting: deletingListIds.includes(item.id),
- isExporting: exportingListIds.includes(item.id),
- }));
+ const tableItems = useMemo(
+ () =>
+ (exceptionListsWithRuleRefs ?? []).map((item) => ({
+ ...item,
+ isDeleting: deletingListIds.includes(item.id),
+ isExporting: exportingListIds.includes(item.id),
+ })),
+ [deletingListIds, exceptionListsWithRuleRefs, exportingListIds]
+ );
+
+ const handlePaginationChange = useCallback(
+ (criteria: CriteriaWithPagination) => {
+ const { index, size } = criteria.page;
+ setPagination((currentPagination) => ({
+ ...currentPagination,
+ perPage: size,
+ page: index + 1,
+ }));
+ },
+ [setPagination]
+ );
return (
<>
@@ -367,14 +391,14 @@ export const ExceptionListsTable = React.memo(() => {
numberSelectedItems={0}
onRefresh={handleRefresh}
/>
-
data-test-subj="exceptions-table"
columns={exceptionsColumns}
isSelectable={hasPermissions}
itemId="id"
items={tableItems}
noItemsMessage={emptyPrompt}
- onChange={() => {}}
+ onChange={handlePaginationChange}
pagination={paginationMemo}
/>
>
@@ -400,3 +424,5 @@ export const ExceptionListsTable = React.memo(() => {
>
);
});
+
+ExceptionListsTable.displayName = 'ExceptionListsTable';
diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/types.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/types.ts
new file mode 100644
index 0000000000000..d7cbb924071f2
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/types.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { ExceptionListInfo } from './use_all_exception_lists';
+
+export interface ExceptionsTableItem extends ExceptionListInfo {
+ isDeleting: boolean;
+ isExporting: boolean;
+}
diff --git a/x-pack/plugins/uptime/server/kibana.index.ts b/x-pack/plugins/uptime/server/kibana.index.ts
index c303c78273331..3b1001daf0515 100644
--- a/x-pack/plugins/uptime/server/kibana.index.ts
+++ b/x-pack/plugins/uptime/server/kibana.index.ts
@@ -46,7 +46,11 @@ export const initServerWithKibana = (
management: {
insightsAndAlerting: ['triggersActions'],
},
- alerting: ['xpack.uptime.alerts.tls', 'xpack.uptime.alerts.monitorStatus'],
+ alerting: [
+ 'xpack.uptime.alerts.tls',
+ 'xpack.uptime.alerts.monitorStatus',
+ 'xpack.uptime.alerts.durationAnomaly',
+ ],
privileges: {
all: {
app: ['uptime', 'kibana'],
@@ -58,10 +62,18 @@ export const initServerWithKibana = (
},
alerting: {
rule: {
- all: ['xpack.uptime.alerts.tls', 'xpack.uptime.alerts.monitorStatus'],
+ all: [
+ 'xpack.uptime.alerts.tls',
+ 'xpack.uptime.alerts.monitorStatus',
+ 'xpack.uptime.alerts.durationAnomaly',
+ ],
},
alert: {
- all: ['xpack.uptime.alerts.tls', 'xpack.uptime.alerts.monitorStatus'],
+ all: [
+ 'xpack.uptime.alerts.tls',
+ 'xpack.uptime.alerts.monitorStatus',
+ 'xpack.uptime.alerts.durationAnomaly',
+ ],
},
},
management: {
@@ -79,10 +91,18 @@ export const initServerWithKibana = (
},
alerting: {
rule: {
- read: ['xpack.uptime.alerts.tls', 'xpack.uptime.alerts.monitorStatus'],
+ read: [
+ 'xpack.uptime.alerts.tls',
+ 'xpack.uptime.alerts.monitorStatus',
+ 'xpack.uptime.alerts.durationAnomaly',
+ ],
},
alert: {
- read: ['xpack.uptime.alerts.tls', 'xpack.uptime.alerts.monitorStatus'],
+ read: [
+ 'xpack.uptime.alerts.tls',
+ 'xpack.uptime.alerts.monitorStatus',
+ 'xpack.uptime.alerts.durationAnomaly',
+ ],
},
},
management: {
diff --git a/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors_fleet.ts b/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors_fleet.ts
index 768b65453fabc..49fcdb8eba4f1 100644
--- a/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors_fleet.ts
+++ b/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors_fleet.ts
@@ -14,7 +14,8 @@ export default function ({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const client = getService('es');
- describe('telemetry collectors fleet', () => {
+ // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/111240
+ describe.skip('telemetry collectors fleet', () => {
before('generating data', async () => {
await getService('esArchiver').load(
'x-pack/test/functional/es_archives/uptime/blank_data_stream'
diff --git a/yarn.lock b/yarn.lock
index 4d49a2f06e1e9..f0a1ff1278f4e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -23379,10 +23379,10 @@ react-popper@^2.2.4:
react-fast-compare "^3.0.1"
warning "^4.0.2"
-react-query@^3.21.0:
- version "3.21.0"
- resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.21.0.tgz#2e099a7906c38eeeb750e8b9b12121a21fa8d9ef"
- integrity sha512-5rY5J8OD9f4EdkytjSsdCO+pqbJWKwSIMETfh/UyxqyjLURHE0IhlB+IPNPrzzu/dzK0rRxi5p0IkcCdSfizDQ==
+react-query@^3.21.1:
+ version "3.21.1"
+ resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.21.1.tgz#8fe4df90bf6c6a93e0552ea9baff211d1b28f6e0"
+ integrity sha512-aKFLfNJc/m21JBXJk7sR9tDUYPjotWA4EHAKvbZ++GgxaY+eI0tqBxXmGBuJo0Pisis1W4pZWlZgoRv9yE8yjA==
dependencies:
"@babel/runtime" "^7.5.5"
broadcast-channel "^3.4.1"