diff --git a/.ci/Dockerfile b/.ci/Dockerfile
index cf827fc0ed08f..8a972c65f8412 100644
--- a/.ci/Dockerfile
+++ b/.ci/Dockerfile
@@ -1,7 +1,7 @@
# NOTE: This Dockerfile is ONLY used to run certain tasks in CI. It is not used to run Kibana or as a distributable.
# If you're looking for the Kibana Docker image distributable, please see: src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts
-ARG NODE_VERSION=14.15.2
+ARG NODE_VERSION=14.15.3
FROM node:${NODE_VERSION} AS base
diff --git a/.ci/teamcity/bootstrap.sh b/.ci/teamcity/bootstrap.sh
index adb884ca064ba..fc57811bb2077 100755
--- a/.ci/teamcity/bootstrap.sh
+++ b/.ci/teamcity/bootstrap.sh
@@ -7,7 +7,7 @@ source "$(dirname "${0}")/util.sh"
tc_start_block "Bootstrap"
tc_start_block "yarn install and kbn bootstrap"
-verify_no_git_changes yarn kbn bootstrap --prefer-offline
+verify_no_git_changes yarn kbn bootstrap
tc_end_block "yarn install and kbn bootstrap"
tc_start_block "build kbn-pm"
diff --git a/.ci/teamcity/checks/bundle_limits.sh b/.ci/teamcity/checks/bundle_limits.sh
index 3f7daef6d0473..751ec5a03ee7b 100755
--- a/.ci/teamcity/checks/bundle_limits.sh
+++ b/.ci/teamcity/checks/bundle_limits.sh
@@ -4,4 +4,5 @@ set -euo pipefail
source "$(dirname "${0}")/../util.sh"
-node scripts/build_kibana_platform_plugins --validate-limits
+checks-reporter-with-killswitch "Check Bundle Limits" \
+ node scripts/build_kibana_platform_plugins --validate-limits
diff --git a/.ci/teamcity/checks/commit.sh b/.ci/teamcity/checks/commit.sh
new file mode 100755
index 0000000000000..387ec0c126785
--- /dev/null
+++ b/.ci/teamcity/checks/commit.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+source "$(dirname "${0}")/../util.sh"
+
+# Runs pre-commit hook script for the files touched in the last commit.
+# That way we can ensure a set of quick commit checks earlier as we removed
+# the pre-commit hook installation by default.
+# If files are more than 200 we will skip it and just use
+# the further ci steps that already check linting and file casing for the entire repo.
+checks-reporter-with-killswitch "Quick commit checks" \
+ "$(dirname "${0}")/commit_check_runner.sh"
diff --git a/.ci/teamcity/checks/commit_check_runner.sh b/.ci/teamcity/checks/commit_check_runner.sh
new file mode 100755
index 0000000000000..f2a4a20568215
--- /dev/null
+++ b/.ci/teamcity/checks/commit_check_runner.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+echo "!!!!!!!! ATTENTION !!!!!!!!
+That check is intended to provide earlier CI feedback after we remove the automatic install for the local pre-commit hook.
+If you want, you can still manually install the pre-commit hook locally by running 'node scripts/register_git_hook locally'
+!!!!!!!!!!!!!!!!!!!!!!!!!!!
+"
+
+node scripts/precommit_hook.js --ref HEAD~1..HEAD --max-files 200 --verbose
diff --git a/.ci/teamcity/checks/jest_configs.sh b/.ci/teamcity/checks/jest_configs.sh
new file mode 100755
index 0000000000000..6703ffffb5651
--- /dev/null
+++ b/.ci/teamcity/checks/jest_configs.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+source "$(dirname "${0}")/../util.sh"
+
+checks-reporter-with-killswitch "Check Jest Configs" \
+ node scripts/check_jest_configs
diff --git a/.ci/teamcity/checks/plugins_with_circular_deps.sh b/.ci/teamcity/checks/plugins_with_circular_deps.sh
new file mode 100755
index 0000000000000..5acc4b2ae351b
--- /dev/null
+++ b/.ci/teamcity/checks/plugins_with_circular_deps.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+source "$(dirname "${0}")/../util.sh"
+
+checks-reporter-with-killswitch "Check Plugins With Circular Dependencies" \
+ node scripts/find_plugins_with_circular_deps
diff --git a/.ci/teamcity/oss/plugin_functional.sh b/.ci/teamcity/oss/plugin_functional.sh
index 5d1ecbcbd48ee..3570bf01e49c4 100755
--- a/.ci/teamcity/oss/plugin_functional.sh
+++ b/.ci/teamcity/oss/plugin_functional.sh
@@ -13,6 +13,21 @@ if [[ ! -d "target" ]]; then
fi
cd -
-./test/scripts/test/plugin_functional.sh
-./test/scripts/test/example_functional.sh
-./test/scripts/test/interpreter_functional.sh
+checks-reporter-with-killswitch "Plugin Functional Tests" \
+ node scripts/functional_tests \
+ --config test/plugin_functional/config.ts \
+ --bail \
+ --debug
+
+checks-reporter-with-killswitch "Example Functional Tests" \
+ node scripts/functional_tests \
+ --config test/examples/config.js \
+ --bail \
+ --debug
+
+checks-reporter-with-killswitch "Interpreter Functional Tests" \
+ node scripts/functional_tests \
+ --config test/interpreter_functional/config.ts \
+ --bail \
+ --debug \
+ --kibana-install-dir "$KIBANA_INSTALL_DIR"
diff --git a/.ci/teamcity/setup_env.sh b/.ci/teamcity/setup_env.sh
index f662d36247a2f..982d129dae2a6 100755
--- a/.ci/teamcity/setup_env.sh
+++ b/.ci/teamcity/setup_env.sh
@@ -25,12 +25,14 @@ tc_set_env FORCE_COLOR 1
tc_set_env TEST_BROWSER_HEADLESS 1
tc_set_env ELASTIC_APM_ENVIRONMENT ci
+tc_set_env ELASTIC_APM_TRANSACTION_SAMPLE_RATE 0.1
if [[ "${KIBANA_CI_REPORTER_KEY_BASE64-}" ]]; then
tc_set_env KIBANA_CI_REPORTER_KEY "$(echo "$KIBANA_CI_REPORTER_KEY_BASE64" | base64 -d)"
fi
if is_pr; then
+ tc_set_env ELASTIC_APM_ACTIVE false
tc_set_env CHECKS_REPORTER_ACTIVE true
# These can be removed once we're not supporting Jenkins and TeamCity at the same time
@@ -39,6 +41,7 @@ if is_pr; then
tc_set_env ghprbActualCommit "$GITHUB_PR_TRIGGERED_SHA"
tc_set_env BUILD_URL "$TEAMCITY_BUILD_URL"
else
+ tc_set_env ELASTIC_APM_ACTIVE true
tc_set_env CHECKS_REPORTER_ACTIVE false
fi
diff --git a/.node-version b/.node-version
index 420568d75691b..19c4c189d3640 100644
--- a/.node-version
+++ b/.node-version
@@ -1 +1 @@
-14.15.2
+14.15.3
diff --git a/.nvmrc b/.nvmrc
index 420568d75691b..19c4c189d3640 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-14.15.2
+14.15.3
diff --git a/.teamcity/pom.xml b/.teamcity/pom.xml
index 5fa068d0a92e0..e6ec1f1c043c2 100644
--- a/.teamcity/pom.xml
+++ b/.teamcity/pom.xml
@@ -46,6 +46,14 @@
true
+
+ teamcity
+ https://artifactory.elstc.co/artifactory/teamcity
+
+ true
+ always
+
+
@@ -53,6 +61,10 @@
JetBrains
https://download.jetbrains.com/teamcity-repository
+
+ teamcity
+ https://artifactory.elstc.co/artifactory/teamcity
+
@@ -124,5 +136,10 @@
junit
4.13
+
+ co.elastic.teamcity
+ teamcity-common
+ 1.0.0-SNAPSHOT
+
diff --git a/.teamcity/settings.kts b/.teamcity/settings.kts
index ec1b1c6eb94ef..28108d019327b 100644
--- a/.teamcity/settings.kts
+++ b/.teamcity/settings.kts
@@ -2,7 +2,7 @@ import jetbrains.buildServer.configs.kotlin.v2019_2.*
import projects.Kibana
import projects.KibanaConfiguration
-version = "2020.1"
+version = "2020.2"
val config = KibanaConfiguration {
agentNetwork = DslContext.getParameter("agentNetwork", "teamcity")
diff --git a/.teamcity/src/Agents.kt b/.teamcity/src/Agents.kt
new file mode 100644
index 0000000000000..557cce80d0f55
--- /dev/null
+++ b/.teamcity/src/Agents.kt
@@ -0,0 +1,28 @@
+import co.elastic.teamcity.common.GoogleCloudAgent
+import co.elastic.teamcity.common.GoogleCloudAgentDiskType
+import co.elastic.teamcity.common.GoogleCloudProfile
+
+private val sizes = listOf("2", "4", "8", "16")
+
+val StandardAgents = sizes.map { size -> size to GoogleCloudAgent {
+ sourceImageFamily = "elastic-kibana-ci-ubuntu-1804-lts"
+ agentPrefix = "kibana-standard-$size-"
+ machineType = "n2-standard-$size"
+ diskSizeGb = 75
+ diskType = GoogleCloudAgentDiskType.SSD
+} }.toMap()
+
+val BuildAgent = GoogleCloudAgent {
+ sourceImageFamily = "elastic-kibana-ci-ubuntu-1804-lts"
+ agentPrefix = "kibana-c2-16-"
+ machineType = "c2-standard-16"
+ diskSizeGb = 250
+ diskType = GoogleCloudAgentDiskType.SSD
+}
+
+val CloudProfile = GoogleCloudProfile {
+ accessKeyId = "447fdd4d-7129-46b7-9822-2e57658c7422"
+
+ agents(StandardAgents)
+ agent(BuildAgent)
+}
diff --git a/.teamcity/src/Extensions.kt b/.teamcity/src/Extensions.kt
index 120b333d43e72..2942a6385f13f 100644
--- a/.teamcity/src/Extensions.kt
+++ b/.teamcity/src/Extensions.kt
@@ -1,9 +1,7 @@
+import co.elastic.teamcity.common.requireAgent
import jetbrains.buildServer.configs.kotlin.v2019_2.*
-import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.notifications
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.ScriptBuildStep
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.script
-import jetbrains.buildServer.configs.kotlin.v2019_2.ui.insert
-import projects.kibanaConfiguration
fun BuildFeatures.junit(dirs: String = "target/**/TEST-*.xml") {
feature {
@@ -13,40 +11,8 @@ fun BuildFeatures.junit(dirs: String = "target/**/TEST-*.xml") {
}
}
-fun ProjectFeatures.kibanaAgent(init: ProjectFeature.() -> Unit) {
- feature {
- type = "CloudImage"
- param("network", kibanaConfiguration.agentNetwork)
- param("subnet", kibanaConfiguration.agentSubnet)
- param("growingId", "true")
- param("agent_pool_id", "-2")
- param("preemptible", "false")
- param("sourceProject", "elastic-images-prod")
- param("sourceImageFamily", "elastic-kibana-ci-ubuntu-1804-lts")
- param("zone", "us-central1-a")
- param("profileId", "kibana")
- param("diskType", "pd-ssd")
- param("machineCustom", "false")
- param("maxInstances", "200")
- param("imageType", "ImageFamily")
- param("diskSizeGb", "75") // TODO
- init()
- }
-}
-
-fun ProjectFeatures.kibanaAgent(size: String, init: ProjectFeature.() -> Unit = {}) {
- kibanaAgent {
- id = "KIBANA_STANDARD_$size"
- param("source-id", "kibana-standard-$size-")
- param("machineType", "n2-standard-$size")
- init()
- }
-}
-
fun BuildType.kibanaAgent(size: String) {
- requirements {
- startsWith("teamcity.agent.name", "kibana-standard-$size-", "RQ_AGENT_NAME")
- }
+ requireAgent(StandardAgents[size]!!)
}
fun BuildType.kibanaAgent(size: Int) {
diff --git a/.teamcity/src/builds/Checks.kt b/.teamcity/src/builds/Checks.kt
index 1228ea4d94f4c..37336316c4c91 100644
--- a/.teamcity/src/builds/Checks.kt
+++ b/.teamcity/src/builds/Checks.kt
@@ -11,16 +11,18 @@ object Checks : BuildType({
kibanaAgent(4)
val checkScripts = mapOf(
+ "Quick Commit Checks" to ".ci/teamcity/checks/commit.sh",
"Check Telemetry Schema" to ".ci/teamcity/checks/telemetry.sh",
"Check TypeScript Projects" to ".ci/teamcity/checks/ts_projects.sh",
"Check File Casing" to ".ci/teamcity/checks/file_casing.sh",
"Check Licenses" to ".ci/teamcity/checks/licenses.sh",
"Verify NOTICE" to ".ci/teamcity/checks/verify_notice.sh",
- "Test Hardening" to ".ci/teamcity/checks/test_hardening.sh",
"Check Types" to ".ci/teamcity/checks/type_check.sh",
+ "Check Jest Configs" to ".ci/teamcity/checks/jest_configs.sh",
"Check Doc API Changes" to ".ci/teamcity/checks/doc_api_changes.sh",
"Check Bundle Limits" to ".ci/teamcity/checks/bundle_limits.sh",
- "Check i18n" to ".ci/teamcity/checks/i18n.sh"
+ "Check i18n" to ".ci/teamcity/checks/i18n.sh",
+ "Check Plugins With Circular Dependencies" to ".ci/teamcity/checks/plugins_with_circular_deps.sh"
)
steps {
diff --git a/.teamcity/src/builds/default/DefaultCiGroup.kt b/.teamcity/src/builds/default/DefaultCiGroup.kt
index 7dbe9cd0ba84c..2c3b0d348591e 100755
--- a/.teamcity/src/builds/default/DefaultCiGroup.kt
+++ b/.teamcity/src/builds/default/DefaultCiGroup.kt
@@ -1,5 +1,7 @@
package builds.default
+import StandardAgents
+import co.elastic.teamcity.common.requireAgent
import jetbrains.buildServer.configs.kotlin.v2019_2.*
import runbld
@@ -11,5 +13,7 @@ class DefaultCiGroup(val ciGroup: Int = 0, init: BuildType.() -> Unit = {}) : De
runbld("Default CI Group $ciGroup", "./.ci/teamcity/default/ci_group.sh $ciGroup")
}
+ requireAgent(StandardAgents["4"]!!)
+
init()
})
diff --git a/.teamcity/src/builds/default/DefaultCiGroups.kt b/.teamcity/src/builds/default/DefaultCiGroups.kt
index 6f1d45598c92e..4f39283149e73 100644
--- a/.teamcity/src/builds/default/DefaultCiGroups.kt
+++ b/.teamcity/src/builds/default/DefaultCiGroups.kt
@@ -3,7 +3,7 @@ package builds.default
import dependsOn
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
-const val DEFAULT_CI_GROUP_COUNT = 10
+const val DEFAULT_CI_GROUP_COUNT = 11
val defaultCiGroups = (1..DEFAULT_CI_GROUP_COUNT).map { DefaultCiGroup(it) }
object DefaultCiGroups : BuildType({
diff --git a/.teamcity/src/builds/es_snapshots/Verify.kt b/.teamcity/src/builds/es_snapshots/Verify.kt
index c778814af536c..4c0307e9eca55 100644
--- a/.teamcity/src/builds/es_snapshots/Verify.kt
+++ b/.teamcity/src/builds/es_snapshots/Verify.kt
@@ -6,7 +6,7 @@ import builds.default.defaultCiGroups
import builds.oss.OssBuild
import builds.oss.OssPluginFunctional
import builds.oss.ossCiGroups
-import builds.test.ApiServerIntegration
+import builds.oss.OssApiServerIntegration
import builds.test.JestIntegration
import dependsOn
import jetbrains.buildServer.configs.kotlin.v2019_2.*
@@ -49,7 +49,7 @@ val defaultBuildsToClone = listOf(
val defaultCloned = defaultBuildsToClone.map { cloneForVerify(it) }
val integrationsBuildsToClone = listOf(
- ApiServerIntegration,
+ OssApiServerIntegration,
JestIntegration
)
diff --git a/.teamcity/src/builds/test/ApiServerIntegration.kt b/.teamcity/src/builds/oss/OssApiServerIntegration.kt
similarity index 62%
rename from .teamcity/src/builds/test/ApiServerIntegration.kt
rename to .teamcity/src/builds/oss/OssApiServerIntegration.kt
index ca58b628cbd22..a04512fb2aba5 100644
--- a/.teamcity/src/builds/test/ApiServerIntegration.kt
+++ b/.teamcity/src/builds/oss/OssApiServerIntegration.kt
@@ -1,10 +1,8 @@
-package builds.test
+package builds.oss
-import addTestSettings
-import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
import runbld
-object ApiServerIntegration : BuildType({
+object OssApiServerIntegration : OssFunctionalBase({
name = "API/Server Integration"
description = "Executes API and Server Integration Tests"
@@ -12,6 +10,4 @@ object ApiServerIntegration : BuildType({
runbld("API Integration", "./.ci/teamcity/oss/api_integration.sh")
runbld("Server Integration", "./.ci/teamcity/oss/server_integration.sh")
}
-
- addTestSettings()
})
diff --git a/.teamcity/src/builds/test/AllTests.kt b/.teamcity/src/builds/test/AllTests.kt
index d1b5898d1a5f5..9506d98cbe50e 100644
--- a/.teamcity/src/builds/test/AllTests.kt
+++ b/.teamcity/src/builds/test/AllTests.kt
@@ -1,5 +1,6 @@
package builds.test
+import builds.oss.OssApiServerIntegration
import dependsOn
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
@@ -8,5 +9,5 @@ object AllTests : BuildType({
description = "All Non-Functional Tests"
type = Type.COMPOSITE
- dependsOn(QuickTests, Jest, XPackJest, JestIntegration, ApiServerIntegration)
+ dependsOn(QuickTests, Jest, XPackJest, JestIntegration, OssApiServerIntegration)
})
diff --git a/.teamcity/src/builds/test/QuickTests.kt b/.teamcity/src/builds/test/QuickTests.kt
index 5b1d2541480ad..a294fce9599c3 100644
--- a/.teamcity/src/builds/test/QuickTests.kt
+++ b/.teamcity/src/builds/test/QuickTests.kt
@@ -12,7 +12,7 @@ object QuickTests : BuildType({
kibanaAgent(2)
val testScripts = mapOf(
- "Test Hardening" to ".ci/teamcity/checkes/test_hardening.sh",
+ "Test Hardening" to ".ci/teamcity/checks/test_hardening.sh",
"Test Projects" to ".ci/teamcity/tests/test_projects.sh",
"Mocha Tests" to ".ci/teamcity/tests/mocha.sh"
)
diff --git a/.teamcity/src/projects/Kibana.kt b/.teamcity/src/projects/Kibana.kt
index 20c30eedf5b91..1878f49debe8c 100644
--- a/.teamcity/src/projects/Kibana.kt
+++ b/.teamcity/src/projects/Kibana.kt
@@ -5,9 +5,10 @@ import builds.*
import builds.default.*
import builds.oss.*
import builds.test.*
+import CloudProfile
+import co.elastic.teamcity.common.googleCloudProfile
import jetbrains.buildServer.configs.kotlin.v2019_2.*
import jetbrains.buildServer.configs.kotlin.v2019_2.projectFeatures.slackConnection
-import kibanaAgent
import templates.KibanaTemplate
import templates.DefaultTemplate
import vcs.Elasticsearch
@@ -31,7 +32,7 @@ fun Kibana(config: KibanaConfiguration = KibanaConfiguration()) : Project {
param("teamcity.ui.settings.readOnly", "true")
// https://github.com/JetBrains/teamcity-webhooks
- param("teamcity.internal.webhooks.enable", "true")
+ param("teamcity.internal.webhooks.enable", "false")
param("teamcity.internal.webhooks.events", "BUILD_STARTED;BUILD_FINISHED;BUILD_INTERRUPTED;CHANGES_LOADED;BUILD_TYPE_ADDED_TO_QUEUE;BUILD_PROBLEMS_CHANGED")
param("teamcity.internal.webhooks.url", "https://ci-stats.kibana.dev/_teamcity_webhook")
param("teamcity.internal.webhooks.username", "automation")
@@ -46,36 +47,9 @@ fun Kibana(config: KibanaConfiguration = KibanaConfiguration()) : Project {
defaultTemplate = DefaultTemplate
- features {
- val sizes = listOf("2", "4", "8", "16")
- for (size in sizes) {
- kibanaAgent(size)
- }
-
- kibanaAgent {
- id = "KIBANA_C2_16"
- param("source-id", "kibana-c2-16-")
- param("machineType", "c2-standard-16")
- }
-
- feature {
- id = "kibana"
- type = "CloudProfile"
- param("agentPushPreset", "")
- param("profileId", "kibana")
- param("profileServerUrl", "")
- param("name", "kibana")
- param("total-work-time", "")
- param("credentialsType", "key")
- param("description", "")
- param("next-hour", "")
- param("cloud-code", "google")
- param("terminate-after-build", "true")
- param("terminate-idle-time", "30")
- param("enabled", "true")
- param("secure:accessKey", "credentialsJSON:447fdd4d-7129-46b7-9822-2e57658c7422")
- }
+ googleCloudProfile(CloudProfile)
+ features {
slackConnection {
id = "KIBANA_SLACK"
displayName = "Kibana Slack"
@@ -106,7 +80,6 @@ fun Kibana(config: KibanaConfiguration = KibanaConfiguration()) : Project {
buildType(JestIntegration)
}
- buildType(ApiServerIntegration)
buildType(QuickTests)
buildType(AllTests)
}
@@ -125,6 +98,7 @@ fun Kibana(config: KibanaConfiguration = KibanaConfiguration()) : Project {
buildType(OssFirefox)
buildType(OssAccessibility)
buildType(OssPluginFunctional)
+ buildType(OssApiServerIntegration)
subProject {
id("CIGroups")
diff --git a/.teamcity/src/templates/DefaultTemplate.kt b/.teamcity/src/templates/DefaultTemplate.kt
index 762218b72ab10..1f7f364600e21 100644
--- a/.teamcity/src/templates/DefaultTemplate.kt
+++ b/.teamcity/src/templates/DefaultTemplate.kt
@@ -1,15 +1,14 @@
package templates
+import StandardAgents
+import co.elastic.teamcity.common.requireAgent
import jetbrains.buildServer.configs.kotlin.v2019_2.Template
import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.perfmon
object DefaultTemplate : Template({
name = "Default Template"
- requirements {
- equals("system.cloud.profile_id", "kibana", "RQ_CLOUD_PROFILE_ID")
- startsWith("teamcity.agent.name", "kibana-standard-2-", "RQ_AGENT_NAME")
- }
+ requireAgent(StandardAgents["2"]!!)
params {
param("env.HOME", "/var/lib/jenkins") // TODO once the agent images are sorted out
diff --git a/.teamcity/src/templates/KibanaTemplate.kt b/.teamcity/src/templates/KibanaTemplate.kt
index 117c30ddb86e3..83fe4fdaa1edd 100644
--- a/.teamcity/src/templates/KibanaTemplate.kt
+++ b/.teamcity/src/templates/KibanaTemplate.kt
@@ -1,5 +1,7 @@
package templates
+import StandardAgents
+import co.elastic.teamcity.common.requireAgent
import vcs.Kibana
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildStep
import jetbrains.buildServer.configs.kotlin.v2019_2.ParameterDisplay
@@ -21,10 +23,7 @@ object KibanaTemplate : Template({
// checkoutDir = "/dev/shm/%system.teamcity.buildType.id%/%system.build.number%/kibana"
}
- requirements {
- equals("system.cloud.profile_id", "kibana", "RQ_CLOUD_PROFILE_ID")
- startsWith("teamcity.agent.name", "kibana-standard-2-", "RQ_AGENT_NAME")
- }
+ requireAgent(StandardAgents["2"]!!)
features {
perfmon { }
@@ -41,7 +40,7 @@ object KibanaTemplate : Template({
}
failureConditions {
- executionTimeoutMin = 120
+ executionTimeoutMin = 160
testFailure = false
}
diff --git a/.teamcity/tests/projects/KibanaTest.kt b/.teamcity/tests/projects/KibanaTest.kt
index 677effec5be65..311c15a1da7cb 100644
--- a/.teamcity/tests/projects/KibanaTest.kt
+++ b/.teamcity/tests/projects/KibanaTest.kt
@@ -1,5 +1,7 @@
package projects
+import jetbrains.buildServer.configs.kotlin.v2019_2.AbsoluteId
+import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
import org.junit.Assert.*
import org.junit.Test
@@ -18,10 +20,11 @@ class KibanaTest {
@Test
fun test_CloudImages_Exist() {
+ DslContext.projectId = AbsoluteId("My Project")
val project = Kibana(TestConfig)
assertTrue(project.features.items.any {
- it.type == "CloudImage" && it.params.any { param -> param.name == "network" && param.value == "network"}
+ it.type == "CloudImage" && it.params.any { param -> param.name == "network" && param.value == "teamcity" }
})
}
}
diff --git a/docs/development/core/server/kibana-plugin-core-server.legacyelasticsearcherror.md b/docs/development/core/server/kibana-plugin-core-server.legacyelasticsearcherror.md
index 40fc1a8e05a68..7c53356615ee9 100644
--- a/docs/development/core/server/kibana-plugin-core-server.legacyelasticsearcherror.md
+++ b/docs/development/core/server/kibana-plugin-core-server.legacyelasticsearcherror.md
@@ -9,7 +9,7 @@
Signature:
```typescript
-export interface LegacyElasticsearchError extends Boom
+export interface LegacyElasticsearchError extends Boom.Boom
```
## Properties
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.apply_filter_trigger.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.apply_filter_trigger.md
new file mode 100644
index 0000000000000..aaed18b3b8890
--- /dev/null
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.apply_filter_trigger.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [APPLY\_FILTER\_TRIGGER](./kibana-plugin-plugins-data-public.apply_filter_trigger.md)
+
+## APPLY\_FILTER\_TRIGGER variable
+
+Signature:
+
+```typescript
+APPLY_FILTER_TRIGGER = "FILTER_TRIGGER"
+```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.applyglobalfilteractioncontext.embeddable.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.applyglobalfilteractioncontext.embeddable.md
index 027ae4209b77f..dbeeeb9979aae 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.applyglobalfilteractioncontext.embeddable.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.applyglobalfilteractioncontext.embeddable.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-embeddable?: IEmbeddable;
+embeddable?: unknown;
```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.applyglobalfilteractioncontext.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.applyglobalfilteractioncontext.md
index 62817cd0a1e33..2f844b6844645 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.applyglobalfilteractioncontext.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.applyglobalfilteractioncontext.md
@@ -14,7 +14,7 @@ export interface ApplyGlobalFilterActionContext
| Property | Type | Description |
| --- | --- | --- |
-| [embeddable](./kibana-plugin-plugins-data-public.applyglobalfilteractioncontext.embeddable.md) | IEmbeddable
| |
+| [embeddable](./kibana-plugin-plugins-data-public.applyglobalfilteractioncontext.embeddable.md) | unknown
| |
| [filters](./kibana-plugin-plugins-data-public.applyglobalfilteractioncontext.filters.md) | Filter[]
| |
| [timeFieldName](./kibana-plugin-plugins-data-public.applyglobalfilteractioncontext.timefieldname.md) | string
| |
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.allownoindex.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.allownoindex.md
new file mode 100644
index 0000000000000..5e397d11b0a89
--- /dev/null
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.allownoindex.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) > [allowNoIndex](./kibana-plugin-plugins-data-public.indexpattern.allownoindex.md)
+
+## IndexPattern.allowNoIndex property
+
+prevents errors when index pattern exists before indices
+
+Signature:
+
+```typescript
+readonly allowNoIndex: boolean;
+```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getassavedobjectbody.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getassavedobjectbody.md
index a370341000960..b318427012c0a 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getassavedobjectbody.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getassavedobjectbody.md
@@ -19,6 +19,7 @@ getAsSavedObjectBody(): {
fieldFormatMap: string | undefined;
type: string | undefined;
typeMeta: string | undefined;
+ allowNoIndex: true | undefined;
};
```
Returns:
@@ -33,5 +34,6 @@ getAsSavedObjectBody(): {
fieldFormatMap: string | undefined;
type: string | undefined;
typeMeta: string | undefined;
+ allowNoIndex: true | undefined;
}`
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md
index 179148265e68d..b640ef1b89606 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md
@@ -20,6 +20,7 @@ export declare class IndexPattern implements IIndexPattern
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
+| [allowNoIndex](./kibana-plugin-plugins-data-public.indexpattern.allownoindex.md) | | boolean
| prevents errors when index pattern exists before indices |
| [deleteFieldFormat](./kibana-plugin-plugins-data-public.indexpattern.deletefieldformat.md) | | (fieldName: string) => void
| |
| [fieldAttrs](./kibana-plugin-plugins-data-public.indexpattern.fieldattrs.md) | | FieldAttrs
| |
| [fieldFormatMap](./kibana-plugin-plugins-data-public.indexpattern.fieldformatmap.md) | | Record<string, any>
| |
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternattributes.allownoindex.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternattributes.allownoindex.md
new file mode 100644
index 0000000000000..9438f38194493
--- /dev/null
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternattributes.allownoindex.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternAttributes](./kibana-plugin-plugins-data-public.indexpatternattributes.md) > [allowNoIndex](./kibana-plugin-plugins-data-public.indexpatternattributes.allownoindex.md)
+
+## IndexPatternAttributes.allowNoIndex property
+
+prevents errors when index pattern exists before indices
+
+Signature:
+
+```typescript
+allowNoIndex?: boolean;
+```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternattributes.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternattributes.md
index c5ea38278e820..1bbede5658942 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternattributes.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternattributes.md
@@ -14,6 +14,7 @@ export interface IndexPatternAttributes
| Property | Type | Description |
| --- | --- | --- |
+| [allowNoIndex](./kibana-plugin-plugins-data-public.indexpatternattributes.allownoindex.md) | boolean
| prevents errors when index pattern exists before indices |
| [fieldAttrs](./kibana-plugin-plugins-data-public.indexpatternattributes.fieldattrs.md) | string
| |
| [fieldFormatMap](./kibana-plugin-plugins-data-public.indexpatternattributes.fieldformatmap.md) | string
| |
| [fields](./kibana-plugin-plugins-data-public.indexpatternattributes.fields.md) | string
| |
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternspec.allownoindex.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternspec.allownoindex.md
new file mode 100644
index 0000000000000..50adef8268694
--- /dev/null
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternspec.allownoindex.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternSpec](./kibana-plugin-plugins-data-public.indexpatternspec.md) > [allowNoIndex](./kibana-plugin-plugins-data-public.indexpatternspec.allownoindex.md)
+
+## IndexPatternSpec.allowNoIndex property
+
+Signature:
+
+```typescript
+allowNoIndex?: boolean;
+```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternspec.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternspec.md
index 06917fcac1b4d..9357ad7d5077e 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternspec.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternspec.md
@@ -14,6 +14,7 @@ export interface IndexPatternSpec
| Property | Type | Description |
| --- | --- | --- |
+| [allowNoIndex](./kibana-plugin-plugins-data-public.indexpatternspec.allownoindex.md) | boolean
| |
| [fieldAttrs](./kibana-plugin-plugins-data-public.indexpatternspec.fieldattrs.md) | FieldAttrs
| |
| [fieldFormats](./kibana-plugin-plugins-data-public.indexpatternspec.fieldformats.md) | Record<string, SerializedFieldFormat>
| |
| [fields](./kibana-plugin-plugins-data-public.indexpatternspec.fields.md) | IndexPatternFieldMap
| |
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md
index 8de3821161ab4..2040043d4351b 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md
@@ -102,6 +102,7 @@
| [ACTION\_GLOBAL\_APPLY\_FILTER](./kibana-plugin-plugins-data-public.action_global_apply_filter.md) | |
| [AggGroupLabels](./kibana-plugin-plugins-data-public.agggrouplabels.md) | |
| [AggGroupNames](./kibana-plugin-plugins-data-public.agggroupnames.md) | |
+| [APPLY\_FILTER\_TRIGGER](./kibana-plugin-plugins-data-public.apply_filter_trigger.md) | |
| [baseFormattersPublic](./kibana-plugin-plugins-data-public.baseformatterspublic.md) | |
| [castEsToKbnFieldTypeName](./kibana-plugin-plugins-data-public.castestokbnfieldtypename.md) | Get the KbnFieldType name for an esType string |
| [connectToQueryState](./kibana-plugin-plugins-data-public.connecttoquerystate.md) | Helper to setup two-way syncing of global data and a state container |
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.allownoindex.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.allownoindex.md
new file mode 100644
index 0000000000000..fe7bec70196c8
--- /dev/null
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.allownoindex.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IndexPattern](./kibana-plugin-plugins-data-server.indexpattern.md) > [allowNoIndex](./kibana-plugin-plugins-data-server.indexpattern.allownoindex.md)
+
+## IndexPattern.allowNoIndex property
+
+prevents errors when index pattern exists before indices
+
+Signature:
+
+```typescript
+readonly allowNoIndex: boolean;
+```
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getassavedobjectbody.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getassavedobjectbody.md
index 274a475872b0b..7d70af4b535fe 100644
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getassavedobjectbody.md
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getassavedobjectbody.md
@@ -19,6 +19,7 @@ getAsSavedObjectBody(): {
fieldFormatMap: string | undefined;
type: string | undefined;
typeMeta: string | undefined;
+ allowNoIndex: true | undefined;
};
```
Returns:
@@ -33,5 +34,6 @@ getAsSavedObjectBody(): {
fieldFormatMap: string | undefined;
type: string | undefined;
typeMeta: string | undefined;
+ allowNoIndex: true | undefined;
}`
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md
index b2cb217fecaa2..54f020e57cf4a 100644
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md
@@ -20,6 +20,7 @@ export declare class IndexPattern implements IIndexPattern
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
+| [allowNoIndex](./kibana-plugin-plugins-data-server.indexpattern.allownoindex.md) | | boolean
| prevents errors when index pattern exists before indices |
| [deleteFieldFormat](./kibana-plugin-plugins-data-server.indexpattern.deletefieldformat.md) | | (fieldName: string) => void
| |
| [fieldAttrs](./kibana-plugin-plugins-data-server.indexpattern.fieldattrs.md) | | FieldAttrs
| |
| [fieldFormatMap](./kibana-plugin-plugins-data-server.indexpattern.fieldformatmap.md) | | Record<string, any>
| |
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternattributes.allownoindex.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternattributes.allownoindex.md
new file mode 100644
index 0000000000000..1255a6fe9f0ca
--- /dev/null
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternattributes.allownoindex.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IndexPatternAttributes](./kibana-plugin-plugins-data-server.indexpatternattributes.md) > [allowNoIndex](./kibana-plugin-plugins-data-server.indexpatternattributes.allownoindex.md)
+
+## IndexPatternAttributes.allowNoIndex property
+
+prevents errors when index pattern exists before indices
+
+Signature:
+
+```typescript
+allowNoIndex?: boolean;
+```
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternattributes.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternattributes.md
index 6559b4d7110be..b9b9f955c7ab5 100644
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternattributes.md
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternattributes.md
@@ -14,6 +14,7 @@ export interface IndexPatternAttributes
| Property | Type | Description |
| --- | --- | --- |
+| [allowNoIndex](./kibana-plugin-plugins-data-server.indexpatternattributes.allownoindex.md) | boolean
| prevents errors when index pattern exists before indices |
| [fieldAttrs](./kibana-plugin-plugins-data-server.indexpatternattributes.fieldattrs.md) | string
| |
| [fieldFormatMap](./kibana-plugin-plugins-data-server.indexpatternattributes.fieldformatmap.md) | string
| |
| [fields](./kibana-plugin-plugins-data-server.indexpatternattributes.fields.md) | string
| |
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.setup.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.setup.md
index b90018c3d9cdd..bd90f23b4ab59 100644
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.setup.md
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.setup.md
@@ -11,7 +11,7 @@ setup(core: CoreSetup, { bfetch, e
__enhance: (enhancements: DataEnhancements) => void;
search: ISearchSetup;
fieldFormats: {
- register: (customFieldFormat: import("../common").FieldFormatInstanceType) => number;
+ register: (customFieldFormat: import("../public").FieldFormatInstanceType) => number;
};
};
```
@@ -29,7 +29,7 @@ setup(core: CoreSetup, { bfetch, e
__enhance: (enhancements: DataEnhancements) => void;
search: ISearchSetup;
fieldFormats: {
- register: (customFieldFormat: import("../common").FieldFormatInstanceType) => number;
+ register: (customFieldFormat: import("../public").FieldFormatInstanceType) => number;
};
}`
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md
index 8a3dbe5a6350c..88f85eb7a7d05 100644
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md
@@ -12,7 +12,7 @@ start(core: CoreStart): {
fieldFormatServiceFactory: (uiSettings: import("src/core/server").IUiSettingsClient) => Promise;
};
indexPatterns: {
- indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("src/core/server").ElasticsearchClient) => Promise;
+ indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("src/core/server").ElasticsearchClient) => Promise;
};
search: ISearchStart>;
};
@@ -31,7 +31,7 @@ start(core: CoreStart): {
fieldFormatServiceFactory: (uiSettings: import("src/core/server").IUiSettingsClient) => Promise;
};
indexPatterns: {
- indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("src/core/server").ElasticsearchClient) => Promise;
+ indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("src/core/server").ElasticsearchClient) => Promise;
};
search: ISearchStart>;
}`
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.embeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.embeddable.md
index 06e51958a2d1e..92926d10a543c 100644
--- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.embeddable.md
+++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.embeddable.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-embeddable: IEmbeddable;
+embeddable: T;
```
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.md
index a2c2d9245eabe..753a3ff2ec6ec 100644
--- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.md
+++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.md
@@ -7,12 +7,12 @@
Signature:
```typescript
-export interface EmbeddableContext
+export interface EmbeddableContext
```
## Properties
| Property | Type | Description |
| --- | --- | --- |
-| [embeddable](./kibana-plugin-plugins-embeddable-public.embeddablecontext.embeddable.md) | IEmbeddable
| |
+| [embeddable](./kibana-plugin-plugins-embeddable-public.embeddablecontext.embeddable.md) | T
| |
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md
index f36f7b4ee77a4..0f14215ff1309 100644
--- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md
+++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md
@@ -16,9 +16,6 @@ export declare type EmbeddableInput = {
enhancements?: SerializableState;
disabledActions?: string[];
disableTriggers?: boolean;
- timeRange?: TimeRange;
- query?: Query;
- filters?: Filter[];
searchSessionId?: string;
};
```
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.data.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.data.md
deleted file mode 100644
index d3a62657372ac..0000000000000
--- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.data.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableSetupDependencies](./kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.md) > [data](./kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.data.md)
-
-## EmbeddableSetupDependencies.data property
-
-Signature:
-
-```typescript
-data: DataPublicPluginSetup;
-```
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.md
index fdd31ca75be2a..957e3f279ff60 100644
--- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.md
+++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.md
@@ -14,6 +14,5 @@ export interface EmbeddableSetupDependencies
| Property | Type | Description |
| --- | --- | --- |
-| [data](./kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.data.md) | DataPublicPluginSetup
| |
| [uiActions](./kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.uiactions.md) | UiActionsSetup
| |
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.data.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.data.md
deleted file mode 100644
index 0595609b11e49..0000000000000
--- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.data.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStartDependencies](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.md) > [data](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.data.md)
-
-## EmbeddableStartDependencies.data property
-
-Signature:
-
-```typescript
-data: DataPublicPluginStart;
-```
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.md
index 5a1b5d1e06861..342163ed2e413 100644
--- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.md
+++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.md
@@ -14,7 +14,6 @@ export interface EmbeddableStartDependencies
| Property | Type | Description |
| --- | --- | --- |
-| [data](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.data.md) | DataPublicPluginStart
| |
| [inspector](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.inspector.md) | InspectorStart
| |
| [uiActions](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.uiactions.md) | UiActionsStart
| |
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer._constructor_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer._constructor_.md
index 276499b435e1f..77e9c2d00b2dd 100644
--- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer._constructor_.md
+++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer._constructor_.md
@@ -9,7 +9,7 @@ Constructs a new instance of the `EmbeddableStateTransfer` class
Signature:
```typescript
-constructor(navigateToApp: ApplicationStart['navigateToApp'], appList?: ReadonlyMap | undefined, customStorage?: Storage);
+constructor(navigateToApp: ApplicationStart['navigateToApp'], currentAppId$: ApplicationStart['currentAppId$'], appList?: ReadonlyMap | undefined, customStorage?: Storage);
```
## Parameters
@@ -17,6 +17,7 @@ constructor(navigateToApp: ApplicationStart['navigateToApp'], appList?: Readonly
| Parameter | Type | Description |
| --- | --- | --- |
| navigateToApp | ApplicationStart['navigateToApp']
| |
+| currentAppId$ | ApplicationStart['currentAppId$']
| |
| appList | ReadonlyMap<string, PublicAppInfo> | undefined
| |
| customStorage | Storage
| |
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.istransferinprogress.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.istransferinprogress.md
new file mode 100644
index 0000000000000..f00d015f316d2
--- /dev/null
+++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.istransferinprogress.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStateTransfer](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md) > [isTransferInProgress](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.istransferinprogress.md)
+
+## EmbeddableStateTransfer.isTransferInProgress property
+
+Signature:
+
+```typescript
+isTransferInProgress: boolean;
+```
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md
index 3676b744b8cc9..76b6708b93bd1 100644
--- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md
+++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md
@@ -16,13 +16,14 @@ export declare class EmbeddableStateTransfer
| Constructor | Modifiers | Description |
| --- | --- | --- |
-| [(constructor)(navigateToApp, appList, customStorage)](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer._constructor_.md) | | Constructs a new instance of the EmbeddableStateTransfer
class |
+| [(constructor)(navigateToApp, currentAppId$, appList, customStorage)](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer._constructor_.md) | | Constructs a new instance of the EmbeddableStateTransfer
class |
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [getAppNameFromId](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getappnamefromid.md) | | (appId: string) => string | undefined
| Fetches an internationalized app title when given an appId. |
+| [isTransferInProgress](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.istransferinprogress.md) | | boolean
| |
## Methods
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iscontextmenutriggercontext.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iscontextmenutriggercontext.md
index 62610624655a1..2f5966f9ba940 100644
--- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iscontextmenutriggercontext.md
+++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iscontextmenutriggercontext.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-isContextMenuTriggerContext: (context: unknown) => context is EmbeddableContext
+isContextMenuTriggerContext: (context: unknown) => context is EmbeddableContext>
```
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.md
index a6aeba23cd280..b875b1fce4288 100644
--- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.md
+++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.md
@@ -86,6 +86,8 @@
| [PANEL\_NOTIFICATION\_TRIGGER](./kibana-plugin-plugins-embeddable-public.panel_notification_trigger.md) | |
| [panelBadgeTrigger](./kibana-plugin-plugins-embeddable-public.panelbadgetrigger.md) | |
| [panelNotificationTrigger](./kibana-plugin-plugins-embeddable-public.panelnotificationtrigger.md) | |
+| [SELECT\_RANGE\_TRIGGER](./kibana-plugin-plugins-embeddable-public.select_range_trigger.md) | |
+| [VALUE\_CLICK\_TRIGGER](./kibana-plugin-plugins-embeddable-public.value_click_trigger.md) | |
| [withEmbeddableSubscription](./kibana-plugin-plugins-embeddable-public.withembeddablesubscription.md) | |
## Type Aliases
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.select_range_trigger.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.select_range_trigger.md
new file mode 100644
index 0000000000000..175e3fe947a0f
--- /dev/null
+++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.select_range_trigger.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [SELECT\_RANGE\_TRIGGER](./kibana-plugin-plugins-embeddable-public.select_range_trigger.md)
+
+## SELECT\_RANGE\_TRIGGER variable
+
+Signature:
+
+```typescript
+SELECT_RANGE_TRIGGER = "SELECT_RANGE_TRIGGER"
+```
diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.value_click_trigger.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.value_click_trigger.md
new file mode 100644
index 0000000000000..a85be3142d0f2
--- /dev/null
+++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.value_click_trigger.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [VALUE\_CLICK\_TRIGGER](./kibana-plugin-plugins-embeddable-public.value_click_trigger.md)
+
+## VALUE\_CLICK\_TRIGGER variable
+
+Signature:
+
+```typescript
+VALUE_CLICK_TRIGGER = "VALUE_CLICK_TRIGGER"
+```
diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md
index 931e474a41006..c22c8bc6b6245 100644
--- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md
+++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md
@@ -20,6 +20,6 @@ export interface IInterpreterRenderHandlers
| [hasCompatibleActions](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.hascompatibleactions.md) | (event: any) => Promise<boolean>
| |
| [onDestroy](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.ondestroy.md) | (fn: () => void) => void
| |
| [reload](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.reload.md) | () => void
| |
-| [uiState](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.uistate.md) | PersistedState
| |
+| [uiState](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.uistate.md) | unknown
| This uiState interface is actually PersistedState
from the visualizations plugin, but expressions cannot know about vis or it creates a mess of circular dependencies. Downstream consumers of the uiState handler will need to cast for now. |
| [update](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.update.md) | (params: any) => void
| |
diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.uistate.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.uistate.md
index 8d74c8e555fee..461bf861d4d5e 100644
--- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.uistate.md
+++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.uistate.md
@@ -4,8 +4,10 @@
## IInterpreterRenderHandlers.uiState property
+This uiState interface is actually `PersistedState` from the visualizations plugin, but expressions cannot know about vis or it creates a mess of circular dependencies. Downstream consumers of the uiState handler will need to cast for now.
+
Signature:
```typescript
-uiState?: PersistedState;
+uiState?: unknown;
```
diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md
index 273703cacca06..547608f40e6aa 100644
--- a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md
+++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md
@@ -20,6 +20,6 @@ export interface IInterpreterRenderHandlers
| [hasCompatibleActions](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.hascompatibleactions.md) | (event: any) => Promise<boolean>
| |
| [onDestroy](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.ondestroy.md) | (fn: () => void) => void
| |
| [reload](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.reload.md) | () => void
| |
-| [uiState](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.uistate.md) | PersistedState
| |
+| [uiState](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.uistate.md) | unknown
| This uiState interface is actually PersistedState
from the visualizations plugin, but expressions cannot know about vis or it creates a mess of circular dependencies. Downstream consumers of the uiState handler will need to cast for now. |
| [update](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.update.md) | (params: any) => void
| |
diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.uistate.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.uistate.md
index b09433c6454ad..ca1c8eec8c2f7 100644
--- a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.uistate.md
+++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.uistate.md
@@ -4,8 +4,10 @@
## IInterpreterRenderHandlers.uiState property
+This uiState interface is actually `PersistedState` from the visualizations plugin, but expressions cannot know about vis or it creates a mess of circular dependencies. Downstream consumers of the uiState handler will need to cast for now.
+
Signature:
```typescript
-uiState?: PersistedState;
+uiState?: unknown;
```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.apply_filter_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.apply_filter_trigger.md
deleted file mode 100644
index 94e66bf404f5c..0000000000000
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.apply_filter_trigger.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [APPLY\_FILTER\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.apply_filter_trigger.md)
-
-## APPLY\_FILTER\_TRIGGER variable
-
-Signature:
-
-```typescript
-APPLY_FILTER_TRIGGER = "FILTER_TRIGGER"
-```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.applyfiltertrigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.applyfiltertrigger.md
deleted file mode 100644
index e1fb6d342457e..0000000000000
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.applyfiltertrigger.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [applyFilterTrigger](./kibana-plugin-plugins-ui_actions-public.applyfiltertrigger.md)
-
-## applyFilterTrigger variable
-
-Signature:
-
-```typescript
-applyFilterTrigger: Trigger<'FILTER_TRIGGER'>
-```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.md
index fd1ea7df4fb74..76e347bddd168 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.md
@@ -41,14 +41,8 @@
| [ACTION\_VISUALIZE\_FIELD](./kibana-plugin-plugins-ui_actions-public.action_visualize_field.md) | |
| [ACTION\_VISUALIZE\_GEO\_FIELD](./kibana-plugin-plugins-ui_actions-public.action_visualize_geo_field.md) | |
| [ACTION\_VISUALIZE\_LENS\_FIELD](./kibana-plugin-plugins-ui_actions-public.action_visualize_lens_field.md) | |
-| [APPLY\_FILTER\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.apply_filter_trigger.md) | |
-| [applyFilterTrigger](./kibana-plugin-plugins-ui_actions-public.applyfiltertrigger.md) | |
| [ROW\_CLICK\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.row_click_trigger.md) | |
| [rowClickTrigger](./kibana-plugin-plugins-ui_actions-public.rowclicktrigger.md) | |
-| [SELECT\_RANGE\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.select_range_trigger.md) | |
-| [selectRangeTrigger](./kibana-plugin-plugins-ui_actions-public.selectrangetrigger.md) | |
-| [VALUE\_CLICK\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.value_click_trigger.md) | |
-| [valueClickTrigger](./kibana-plugin-plugins-ui_actions-public.valueclicktrigger.md) | |
| [VISUALIZE\_FIELD\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.visualize_field_trigger.md) | |
| [VISUALIZE\_GEO\_FIELD\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.visualize_geo_field_trigger.md) | |
| [visualizeFieldTrigger](./kibana-plugin-plugins-ui_actions-public.visualizefieldtrigger.md) | |
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.rowclickcontext.embeddable.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.rowclickcontext.embeddable.md
index e8baf44ff9cbc..a75637e8ea9d3 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.rowclickcontext.embeddable.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.rowclickcontext.embeddable.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-embeddable?: IEmbeddable;
+embeddable?: unknown;
```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.rowclickcontext.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.rowclickcontext.md
index 74b55d85f10e3..b69734cfc3233 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.rowclickcontext.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.rowclickcontext.md
@@ -15,5 +15,5 @@ export interface RowClickContext
| Property | Type | Description |
| --- | --- | --- |
| [data](./kibana-plugin-plugins-ui_actions-public.rowclickcontext.data.md) | {
rowIndex: number;
table: Datatable;
columns?: string[];
}
| |
-| [embeddable](./kibana-plugin-plugins-ui_actions-public.rowclickcontext.embeddable.md) | IEmbeddable
| |
+| [embeddable](./kibana-plugin-plugins-ui_actions-public.rowclickcontext.embeddable.md) | unknown
| |
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.select_range_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.select_range_trigger.md
deleted file mode 100644
index fd784ff17fa84..0000000000000
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.select_range_trigger.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [SELECT\_RANGE\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.select_range_trigger.md)
-
-## SELECT\_RANGE\_TRIGGER variable
-
-Signature:
-
-```typescript
-SELECT_RANGE_TRIGGER = "SELECT_RANGE_TRIGGER"
-```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.selectrangetrigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.selectrangetrigger.md
deleted file mode 100644
index 0d9fa2d83ee57..0000000000000
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.selectrangetrigger.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [selectRangeTrigger](./kibana-plugin-plugins-ui_actions-public.selectrangetrigger.md)
-
-## selectRangeTrigger variable
-
-Signature:
-
-```typescript
-selectRangeTrigger: Trigger<'SELECT_RANGE_TRIGGER'>
-```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.id.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.id.md
index 426f17f9a0352..5603c852ad39d 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.id.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.id.md
@@ -4,7 +4,7 @@
## Trigger.id property
-Unique name of the trigger as identified in `ui_actions` plugin trigger registry, such as "SELECT\_RANGE\_TRIGGER" or "VALUE\_CLICK\_TRIGGER".
+Unique name of the trigger as identified in `ui_actions` plugin trigger registry.
Signature:
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.md
index b69bba892f475..ed76cfea97684 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.md
@@ -21,6 +21,6 @@ export interface Trigger
| Property | Type | Description |
| --- | --- | --- |
| [description](./kibana-plugin-plugins-ui_actions-public.trigger.description.md) | string
| A longer user friendly description of the trigger. |
-| [id](./kibana-plugin-plugins-ui_actions-public.trigger.id.md) | ID
| Unique name of the trigger as identified in ui_actions
plugin trigger registry, such as "SELECT\_RANGE\_TRIGGER" or "VALUE\_CLICK\_TRIGGER". |
+| [id](./kibana-plugin-plugins-ui_actions-public.trigger.id.md) | ID
| Unique name of the trigger as identified in ui_actions
plugin trigger registry. |
| [title](./kibana-plugin-plugins-ui_actions-public.trigger.title.md) | string
| User friendly name of the trigger. |
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.filter_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.filter_trigger.md
deleted file mode 100644
index 0ccf8aa3d7415..0000000000000
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.filter_trigger.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [TriggerContextMapping](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md) > [FILTER\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.filter_trigger.md)
-
-## TriggerContextMapping.FILTER\_TRIGGER property
-
-Signature:
-
-```typescript
-[APPLY_FILTER_TRIGGER]: ApplyGlobalFilterActionContext;
-```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md
index 2f0d22cf6dd74..da7a7a8bfe645 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md
@@ -15,10 +15,7 @@ export interface TriggerContextMapping
| Property | Type | Description |
| --- | --- | --- |
| [""](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.__.md) | TriggerContext
| |
-| [FILTER\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.filter_trigger.md) | ApplyGlobalFilterActionContext
| |
| [ROW\_CLICK\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.row_click_trigger.md) | RowClickContext
| |
-| [SELECT\_RANGE\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.select_range_trigger.md) | RangeSelectContext
| |
-| [VALUE\_CLICK\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.value_click_trigger.md) | ValueClickContext
| |
| [VISUALIZE\_FIELD\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.visualize_field_trigger.md) | VisualizeFieldContext
| |
| [VISUALIZE\_GEO\_FIELD\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.visualize_geo_field_trigger.md) | VisualizeFieldContext
| |
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.select_range_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.select_range_trigger.md
deleted file mode 100644
index c5ef6843390b3..0000000000000
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.select_range_trigger.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [TriggerContextMapping](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md) > [SELECT\_RANGE\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.select_range_trigger.md)
-
-## TriggerContextMapping.SELECT\_RANGE\_TRIGGER property
-
-Signature:
-
-```typescript
-[SELECT_RANGE_TRIGGER]: RangeSelectContext;
-```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.value_click_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.value_click_trigger.md
deleted file mode 100644
index 129144a66cee5..0000000000000
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.value_click_trigger.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [TriggerContextMapping](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md) > [VALUE\_CLICK\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.value_click_trigger.md)
-
-## TriggerContextMapping.VALUE\_CLICK\_TRIGGER property
-
-Signature:
-
-```typescript
-[VALUE_CLICK_TRIGGER]: ValueClickContext;
-```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.addtriggeraction.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.addtriggeraction.md
index ca999322b7a56..f29d487d774e0 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.addtriggeraction.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.addtriggeraction.md
@@ -11,5 +11,5 @@
Signature:
```typescript
-readonly addTriggerAction: (triggerId: T, action: ActionDefinition | Action) => void;
+readonly addTriggerAction: (triggerId: T, action: ActionDefinition | Action) => void;
```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.attachaction.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.attachaction.md
index e95e7e1eb38b6..1ebb30c49c0b3 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.attachaction.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.attachaction.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-readonly attachAction: (triggerId: T, actionId: string) => void;
+readonly attachAction: (triggerId: T, actionId: string) => void;
```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.executetriggeractions.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.executetriggeractions.md
index 8e7fb8b8bbf29..b20f08520c43d 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.executetriggeractions.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.executetriggeractions.md
@@ -12,5 +12,5 @@
Signature:
```typescript
-readonly executeTriggerActions: (triggerId: T, context: TriggerContext) => Promise;
+readonly executeTriggerActions: (triggerId: T, context: TriggerContext) => Promise;
```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.getaction.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.getaction.md
index d540de7637441..300c46a47c47f 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.getaction.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.getaction.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-readonly getAction: >(id: string) => Action, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_EXPORT_CSV">;
+readonly getAction: >(id: string) => Action, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel">;
```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettrigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettrigger.md
index b996620686a28..95b737a8d6cae 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettrigger.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettrigger.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-readonly getTrigger: (triggerId: T) => TriggerContract;
+readonly getTrigger: (triggerId: T) => TriggerContract;
```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggeractions.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggeractions.md
index f94b34ecc2d90..27c1b1eb48f16 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggeractions.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggeractions.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-readonly getTriggerActions: (triggerId: T) => Action[];
+readonly getTriggerActions: (triggerId: T) => Action[];
```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggercompatibleactions.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggercompatibleactions.md
index dff958608ef9e..edb7d2d3a1551 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggercompatibleactions.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggercompatibleactions.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-readonly getTriggerCompatibleActions: (triggerId: T, context: TriggerContextMapping[T]) => Promise[]>;
+readonly getTriggerCompatibleActions: (triggerId: T, context: TriggerContextMapping[T]) => Promise[]>;
```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.md
index e35eb503ab62b..4fe8431770dea 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.md
@@ -21,19 +21,19 @@ export declare class UiActionsService
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [actions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.actions.md) | | ActionRegistry
| |
-| [addTriggerAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.addtriggeraction.md) | | <T extends "" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER" | "ROW_CLICK_TRIGGER" | "FILTER_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER">(triggerId: T, action: ActionDefinition<TriggerContextMapping[T]> | Action<TriggerContextMapping[T], "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_EXPORT_CSV">) => void
| addTriggerAction
is similar to attachAction
as it attaches action to a trigger, but it also registers the action, if it has not been registered, yet.addTriggerAction
also infers better typing of the action
argument. |
-| [attachAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.attachaction.md) | | <T extends "" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER" | "ROW_CLICK_TRIGGER" | "FILTER_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER">(triggerId: T, actionId: string) => void
| |
+| [addTriggerAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.addtriggeraction.md) | | <T extends "" | "ROW_CLICK_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "FILTER_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER">(triggerId: T, action: ActionDefinition<TriggerContextMapping[T]> | Action<TriggerContextMapping[T], "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel">) => void
| addTriggerAction
is similar to attachAction
as it attaches action to a trigger, but it also registers the action, if it has not been registered, yet.addTriggerAction
also infers better typing of the action
argument. |
+| [attachAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.attachaction.md) | | <T extends "" | "ROW_CLICK_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "FILTER_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER">(triggerId: T, actionId: string) => void
| |
| [clear](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.clear.md) | | () => void
| Removes all registered triggers and actions. |
| [detachAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.detachaction.md) | | (triggerId: TriggerId, actionId: string) => void
| |
-| [executeTriggerActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.executetriggeractions.md) | | <T extends "" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER" | "ROW_CLICK_TRIGGER" | "FILTER_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER">(triggerId: T, context: TriggerContext<T>) => Promise<void>
| |
+| [executeTriggerActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.executetriggeractions.md) | | <T extends "" | "ROW_CLICK_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "FILTER_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER">(triggerId: T, context: TriggerContext<T>) => Promise<void>
| |
| [executionService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.executionservice.md) | | UiActionsExecutionService
| |
| [fork](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.fork.md) | | () => UiActionsService
| "Fork" a separate instance of UiActionsService
that inherits all existing triggers and actions, but going forward all new triggers and actions added to this instance of UiActionsService
are only available within this instance. |
-| [getAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.getaction.md) | | <T extends ActionDefinition<{}>>(id: string) => Action<ActionContext<T>, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_EXPORT_CSV">
| |
-| [getTrigger](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettrigger.md) | | <T extends "" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER" | "ROW_CLICK_TRIGGER" | "FILTER_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER">(triggerId: T) => TriggerContract<T>
| |
-| [getTriggerActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggeractions.md) | | <T extends "" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER" | "ROW_CLICK_TRIGGER" | "FILTER_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER">(triggerId: T) => Action<TriggerContextMapping[T], "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_EXPORT_CSV">[]
| |
-| [getTriggerCompatibleActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggercompatibleactions.md) | | <T extends "" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER" | "ROW_CLICK_TRIGGER" | "FILTER_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER">(triggerId: T, context: TriggerContextMapping[T]) => Promise<Action<TriggerContextMapping[T], "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_EXPORT_CSV">[]>
| |
+| [getAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.getaction.md) | | <T extends ActionDefinition<{}>>(id: string) => Action<ActionContext<T>, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel">
| |
+| [getTrigger](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettrigger.md) | | <T extends "" | "ROW_CLICK_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "FILTER_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER">(triggerId: T) => TriggerContract<T>
| |
+| [getTriggerActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggeractions.md) | | <T extends "" | "ROW_CLICK_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "FILTER_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER">(triggerId: T) => Action<TriggerContextMapping[T], "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel">[]
| |
+| [getTriggerCompatibleActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggercompatibleactions.md) | | <T extends "" | "ROW_CLICK_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "FILTER_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER">(triggerId: T, context: TriggerContextMapping[T]) => Promise<Action<TriggerContextMapping[T], "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel">[]>
| |
| [hasAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.hasaction.md) | | (actionId: string) => boolean
| |
-| [registerAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.registeraction.md) | | <A extends ActionDefinition<{}>>(definition: A) => Action<ActionContext<A>, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_EXPORT_CSV">
| |
+| [registerAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.registeraction.md) | | <A extends ActionDefinition<{}>>(definition: A) => Action<ActionContext<A>, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel">
| |
| [registerTrigger](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.registertrigger.md) | | (trigger: Trigger) => void
| |
| [triggers](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.triggers.md) | | TriggerRegistry
| |
| [triggerToActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.triggertoactions.md) | | TriggerToActionsRegistry
| |
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.registeraction.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.registeraction.md
index 6f03777e14552..dee5f75f7c074 100644
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.registeraction.md
+++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.registeraction.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-readonly registerAction: >(definition: A) => Action, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_EXPORT_CSV">;
+readonly registerAction: >(definition: A) => Action, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel">;
```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.value_click_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.value_click_trigger.md
deleted file mode 100644
index bd8d4dc50b8fd..0000000000000
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.value_click_trigger.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [VALUE\_CLICK\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.value_click_trigger.md)
-
-## VALUE\_CLICK\_TRIGGER variable
-
-Signature:
-
-```typescript
-VALUE_CLICK_TRIGGER = "VALUE_CLICK_TRIGGER"
-```
diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.valueclicktrigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.valueclicktrigger.md
deleted file mode 100644
index 5c4fc284d83b1..0000000000000
--- a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.valueclicktrigger.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [valueClickTrigger](./kibana-plugin-plugins-ui_actions-public.valueclicktrigger.md)
-
-## valueClickTrigger variable
-
-Signature:
-
-```typescript
-valueClickTrigger: Trigger<'VALUE_CLICK_TRIGGER'>
-```
diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc
index 9a87d4c9d886a..99fadb240335a 100644
--- a/docs/management/advanced-options.asciidoc
+++ b/docs/management/advanced-options.asciidoc
@@ -453,8 +453,8 @@ of buckets to try to represent.
==== Visualization
[horizontal]
-[[visualization-visualize-chartslibrary]]`visualization:visualize:chartsLibrary`::
-Enables the new charts library for area, line, and bar charts in visualization panels. Does *not* support the split chart aggregation.
+[[visualization-visualize-chartslibrary]]`visualization:visualize:legacyChartsLibrary`::
+Enables legacy charts library for area, line and bar charts in visualize. Currently, only legacy charts library supports split chart aggregation.
[[visualization-colormapping]]`visualization:colorMapping`::
**This setting is deprecated and will not be supported as of 8.0.**
diff --git a/docs/user/security/audit-logging.asciidoc b/docs/user/security/audit-logging.asciidoc
index 7facde28e956f..acb0f94cf878c 100644
--- a/docs/user/security/audit-logging.asciidoc
+++ b/docs/user/security/audit-logging.asciidoc
@@ -47,9 +47,11 @@ For information on how to configure `xpack.security.audit.appender`, refer to
Refer to the table of events that can be logged for auditing purposes.
-Each event is broken down into `category`, `type`, `action` and `outcome` fields
+Each event is broken down into <>, <>, <> and <> fields
to make it easy to filter, query and aggregate the resulting logs.
+Refer to <> for a table of fields that get logged with audit event.
+
[NOTE]
============================================================================
To ensure that a record of every operation is persisted even in case of an
@@ -230,3 +232,188 @@ Refer to the corresponding {es} logs for potential write errors.
| `http_request`
| `unknown` | User is making an HTTP request.
|======
+
+
+[[xpack-security-ecs-audit-schema]]
+==== ECS audit schema
+
+Audit logs are written in JSON using https://www.elastic.co/guide/en/ecs/1.6/index.html[Elastic Common Schema (ECS)] specification.
+
+[cols="2*<"]
+|======
+
+2+a| ===== Base Fields
+
+| *Field*
+| *Description*
+
+| `@timestamp`
+| Time when the event was generated.
+
+Example: `2016-05-23T08:05:34.853Z`
+
+| `message`
+| Human readable description of the event.
+
+2+a| ===== Event Fields
+
+| *Field*
+| *Description*
+
+| [[field-event-action]] `event.action`
+| The action captured by the event.
+
+Refer to <> for a table of possible actions.
+
+| [[field-event-category]] `event.category`
+| High level category associated with the event.
+
+This field is closely related to `event.type`, which is used as a subcategory.
+
+Possible values:
+`database`,
+`web`,
+`authentication`
+
+| [[field-event-type]] `event.type`
+| Subcategory associated with the event.
+
+This field can be used along with the `event.category` field to enable filtering events down to a level appropriate for single visualization.
+
+Possible values:
+`creation`,
+`access`,
+`change`,
+`deletion`
+
+| [[field-event-outcome]] `event.outcome`
+| Denotes whether the event represents a success or failure.
+
+Possible values:
+`success`,
+`failure`,
+`unknown`
+
+2+a| ===== User Fields
+
+| *Field*
+| *Description*
+
+| `user.name`
+| Login name of the user.
+
+Example: `jdoe`
+
+| `user.roles[]`
+| Set of user roles at the time of the event.
+
+Example: `[kibana_admin, reporting_user]`
+
+2+a| ===== Kibana Fields
+
+| *Field*
+| *Description*
+
+| `kibana.space_id`
+| ID of the space associated with the event.
+
+Example: `default`
+
+| `kibana.session_id`
+| ID of the user session associated with the event.
+
+Each login attempt results in a unique session id.
+
+| `kibana.saved_object.type`
+| Type of saved object associated with the event.
+
+Example: `dashboard`
+
+| `kibana.saved_object.id`
+| ID of the saved object associated with the event.
+
+| `kibana.authentication_provider`
+| Name of the authentication provider associated with the event.
+
+Example: `my-saml-provider`
+
+| `kibana.authentication_type`
+| Type of the authentication provider associated with the event.
+
+Example: `saml`
+
+| `kibana.authentication_realm`
+| Name of the Elasticsearch realm that has authenticated the user.
+
+Example: `native`
+
+| `kibana.lookup_realm`
+| Name of the Elasticsearch realm where the user details were retrieved from.
+
+Example: `native`
+
+| `kibana.add_to_spaces[]`
+| Set of space IDs that a saved object is being shared to as part of the event.
+
+Example: `[default, marketing]`
+
+| `kibana.delete_from_spaces[]`
+| Set of space IDs that a saved object is being removed from as part of the event.
+
+Example: `[marketing]`
+
+2+a| ===== Error Fields
+
+| *Field*
+| *Description*
+
+| `error.code`
+| Error code describing the error.
+
+| `error.message`
+| Error message.
+
+2+a| ===== HTTP and URL Fields
+
+| *Field*
+| *Description*
+
+| `http.request.method`
+| HTTP request method.
+
+Example: `get`, `post`, `put`, `delete`
+
+| `url.domain`
+| Domain of the url.
+
+Example: `www.elastic.co`
+
+| `url.path`
+| Path of the request.
+
+Example: `/search`
+
+| `url.port`
+| Port of the request.
+
+Example: `443`
+
+| `url.query`
+| The query field describes the query string of the request.
+
+Example: `q=elasticsearch`
+
+| `url.scheme`
+| Scheme of the request.
+
+Example: `https`
+
+2+a| ===== Tracing Fields
+
+| *Field*
+| *Description*
+
+| `trace.id`
+| Unique identifier allowing events of the same transaction from {kib} and {es} to be be correlated.
+
+|======
diff --git a/docs/user/security/encryption-keys/index.asciidoc b/docs/user/security/encryption-keys/index.asciidoc
new file mode 100644
index 0000000000000..58c0c0bb775ca
--- /dev/null
+++ b/docs/user/security/encryption-keys/index.asciidoc
@@ -0,0 +1,44 @@
+[[kibana-encryption-keys]]
+=== Set up encryptions keys to protect sensitive information
+
+The `kibana-encryption-keys` command helps you set up encryption keys that {kib} uses
+to protect sensitive information.
+
+[discrete]
+=== Synopsis
+
+[source,shell]
+--------------------------------------------------
+bin/kibana-encryption-keys generate
+[-i, --interactive] [-q, --quiet]
+[-f, --force] [-h, --help]
+--------------------------------------------------
+
+[discrete]
+=== Description
+
+{kib} uses encryption keys in several areas, ranging from encrypting data
+in {kib} associated indices to storing session information. By defining these
+encryption keys in your configuration, you'll ensure consistent operations
+across restarts.
+
+[discrete]
+[[encryption-key-parameters]]
+=== Parameters
+
+`generate`:: Randomly generates passwords to the console.
+
+`-i, --interactive`:: Prompts you for which encryption keys to set and optionally
+where to save a sample configuration file.
+
+`-q, --quiet`:: Outputs the encryption keys without helper information.
+
+`-f, --force`:: Shows help information.
+
+[discrete]
+=== Examples
+
+[source,shell]
+--------------------------------------------------
+bin/kibana-encryption-keys generate
+--------------------------------------------------
diff --git a/docs/user/security/index.asciidoc b/docs/user/security/index.asciidoc
index f84e9de87c734..6a5c4a83aa3ad 100644
--- a/docs/user/security/index.asciidoc
+++ b/docs/user/security/index.asciidoc
@@ -45,5 +45,6 @@ cause Kibana's authorization to behave unexpectedly.
include::authorization/index.asciidoc[]
include::authorization/kibana-privileges.asciidoc[]
include::api-keys/index.asciidoc[]
+include::encryption-keys/index.asciidoc[]
include::role-mappings/index.asciidoc[]
include::rbac_tutorial.asciidoc[]
diff --git a/package.json b/package.json
index b4b3cbe22b715..d6e544ddb57e4 100644
--- a/package.json
+++ b/package.json
@@ -73,10 +73,6 @@
"url": "https://github.com/elastic/kibana.git"
},
"resolutions": {
- "**/@hapi/iron": "^5.1.4",
- "**/@types/hapi__boom": "^7.4.1",
- "**/@types/hapi__hapi": "^18.2.6",
- "**/@types/hapi__mimos": "4.1.0",
"**/@types/node": "14.14.14",
"**/chokidar": "^3.4.3",
"**/cross-fetch/node-fetch": "^2.6.1",
@@ -97,14 +93,14 @@
"**/typescript": "4.1.2"
},
"engines": {
- "node": "14.15.2",
+ "node": "14.15.3",
"yarn": "^1.21.1"
},
"dependencies": {
"@babel/core": "^7.11.6",
"@babel/runtime": "^7.11.2",
"@elastic/datemath": "link:packages/elastic-datemath",
- "@elastic/elasticsearch": "7.10.0",
+ "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@^8.0.0-canary",
"@elastic/ems-client": "7.11.0",
"@elastic/eui": "30.6.0",
"@elastic/filesaver": "1.1.2",
@@ -115,17 +111,17 @@
"@elastic/request-crypto": "1.1.4",
"@elastic/safer-lodash-set": "link:packages/elastic-safer-lodash-set",
"@elastic/search-ui-app-search-connector": "^1.5.0",
- "@hapi/boom": "^7.4.11",
- "@hapi/cookie": "^10.1.2",
- "@hapi/good-squeeze": "5.2.1",
- "@hapi/h2o2": "^8.3.2",
- "@hapi/hapi": "^18.4.1",
- "@hapi/hoek": "^8.5.1",
- "@hapi/inert": "^5.2.2",
- "@hapi/podium": "^3.4.3",
- "@hapi/statehood": "^6.1.2",
- "@hapi/vision": "^5.5.4",
- "@hapi/wreck": "^15.0.2",
+ "@hapi/boom": "^9.1.1",
+ "@hapi/cookie": "^11.0.2",
+ "@hapi/good-squeeze": "6.0.0",
+ "@hapi/h2o2": "^9.0.2",
+ "@hapi/hapi": "^20.0.3",
+ "@hapi/hoek": "^9.1.0",
+ "@hapi/inert": "^6.0.3",
+ "@hapi/podium": "^4.1.1",
+ "@hapi/statehood": "^7.0.3",
+ "@hapi/vision": "^6.0.1",
+ "@hapi/wreck": "^17.1.0",
"@kbn/ace": "link:packages/kbn-ace",
"@kbn/analytics": "link:packages/kbn-analytics",
"@kbn/apm-config-loader": "link:packages/kbn-apm-config-loader",
@@ -381,6 +377,7 @@
"@mapbox/geojson-rewind": "^0.5.0",
"@mapbox/mapbox-gl-draw": "^1.2.0",
"@mapbox/mapbox-gl-rtl-text": "^0.2.3",
+ "@mapbox/vector-tile": "1.3.1",
"@microsoft/api-documenter": "7.7.2",
"@microsoft/api-extractor": "7.7.0",
"@octokit/rest": "^16.35.0",
@@ -451,14 +448,11 @@
"@types/graphql": "^0.13.2",
"@types/gulp": "^4.0.6",
"@types/gulp-zip": "^4.0.1",
- "@types/hapi__boom": "^7.4.1",
"@types/hapi__cookie": "^10.1.1",
- "@types/hapi__h2o2": "8.3.0",
- "@types/hapi__hapi": "^18.2.6",
- "@types/hapi__hoek": "^6.2.0",
- "@types/hapi__inert": "^5.2.1",
+ "@types/hapi__h2o2": "^8.3.2",
+ "@types/hapi__hapi": "^20.0.2",
+ "@types/hapi__inert": "^5.2.2",
"@types/hapi__podium": "^3.4.1",
- "@types/hapi__wreck": "^15.0.1",
"@types/has-ansi": "^3.0.0",
"@types/he": "^1.1.1",
"@types/history": "^4.7.3",
@@ -750,6 +744,7 @@
"ora": "^4.0.4",
"p-limit": "^3.0.1",
"parse-link-header": "^1.0.1",
+ "pbf": "3.2.1",
"pirates": "^4.0.1",
"pixelmatch": "^5.1.0",
"pkg-up": "^2.0.0",
diff --git a/packages/kbn-es/src/cluster.js b/packages/kbn-es/src/cluster.js
index 68bcc37c65600..eaf353b3e55d0 100644
--- a/packages/kbn-es/src/cluster.js
+++ b/packages/kbn-es/src/cluster.js
@@ -275,6 +275,15 @@ exports.Cluster = class Cluster {
this._log.debug('%s %s', ES_BIN, args.join(' '));
+ options.esEnvVars = options.esEnvVars || {};
+
+ // ES now automatically sets heap size to 50% of the machine's available memory
+ // so we need to set it to a smaller size for local dev and CI
+ // especially because we currently run many instances of ES on the same machine during CI
+ options.esEnvVars.ES_JAVA_OPTS =
+ (options.esEnvVars.ES_JAVA_OPTS ? `${options.esEnvVars.ES_JAVA_OPTS} ` : '') +
+ '-Xms1g -Xmx1g';
+
this._process = execa(ES_BIN, args, {
cwd: installPath,
env: {
diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts
index b8843b5c85595..2893f4c9a9878 100644
--- a/src/core/public/doc_links/doc_links_service.ts
+++ b/src/core/public/doc_links/doc_links_service.ts
@@ -147,6 +147,7 @@ export class DocLinksService {
featureImportance: `${ELASTIC_WEBSITE_URL}guide/en/machine-learning/${DOC_LINK_VERSION}/ml-feature-importance.html`,
outlierDetectionRoc: `${ELASTIC_WEBSITE_URL}guide/en/machine-learning/${DOC_LINK_VERSION}/ml-dfanalytics-evaluate.html#ml-dfanalytics-roc`,
regressionEvaluation: `${ELASTIC_WEBSITE_URL}guide/en/machine-learning/${DOC_LINK_VERSION}/ml-dfanalytics-evaluate.html#ml-dfanalytics-regression-evaluation`,
+ classificationAucRoc: `${ELASTIC_WEBSITE_URL}guide/en/machine-learning/${DOC_LINK_VERSION}/ml-dfanalytics-evaluate.html#ml-dfanalytics-class-aucroc`,
},
transforms: {
guide: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/transforms.html`,
diff --git a/src/core/server/elasticsearch/legacy/errors.ts b/src/core/server/elasticsearch/legacy/errors.ts
index e557e7395fe56..adc1fa0728784 100644
--- a/src/core/server/elasticsearch/legacy/errors.ts
+++ b/src/core/server/elasticsearch/legacy/errors.ts
@@ -30,7 +30,7 @@ enum ErrorCode {
* @deprecated. The new elasticsearch client doesn't wrap errors anymore.
* @public
* */
-export interface LegacyElasticsearchError extends Boom {
+export interface LegacyElasticsearchError extends Boom.Boom {
[code]?: string;
}
@@ -86,7 +86,7 @@ export class LegacyElasticsearchErrorHelpers {
const decoratedError = decorate(error, ErrorCode.NOT_AUTHORIZED, 401, reason);
const wwwAuthHeader = get(error, 'body.error.header[WWW-Authenticate]') as string;
- decoratedError.output.headers['WWW-Authenticate'] =
+ (decoratedError.output.headers as { [key: string]: string })['WWW-Authenticate'] =
wwwAuthHeader || 'Basic realm="Authorization Required"';
return decoratedError;
diff --git a/src/core/server/http/http_server.test.ts b/src/core/server/http/http_server.test.ts
index 71040598d34b1..cbb60480c4cf1 100644
--- a/src/core/server/http/http_server.test.ts
+++ b/src/core/server/http/http_server.test.ts
@@ -1214,7 +1214,7 @@ describe('timeout options', () => {
router.get(
{
path: '/',
- validate: { body: schema.any() },
+ validate: { body: schema.maybe(schema.any()) },
},
(context, req, res) => {
return res.ok({
@@ -1247,7 +1247,7 @@ describe('timeout options', () => {
router.get(
{
path: '/',
- validate: { body: schema.any() },
+ validate: { body: schema.maybe(schema.any()) },
options: { timeout: { idleSocket: 12000 } },
},
(context, req, res) => {
diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts
index 43f5264ff22e3..42e89b66d9c51 100644
--- a/src/core/server/http/http_server.ts
+++ b/src/core/server/http/http_server.ts
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { Server } from '@hapi/hapi';
+import { Server, ServerRoute } from '@hapi/hapi';
import HapiStaticFiles from '@hapi/inert';
import url from 'url';
import uuid from 'uuid';
@@ -167,8 +167,6 @@ export class HttpServer {
for (const router of this.registeredRouters) {
for (const route of router.getRoutes()) {
this.log.debug(`registering route handler for [${route.path}]`);
- // Hapi does not allow payload validation to be specified for 'head' or 'get' requests
- const validate = isSafeMethod(route.method) ? undefined : { payload: true };
const { authRequired, tags, body = {}, timeout } = route.options;
const { accepts: allow, maxBytes, output, parse } = body;
@@ -176,57 +174,45 @@ export class HttpServer {
xsrfRequired: route.options.xsrfRequired ?? !isSafeMethod(route.method),
};
- // To work around https://github.com/hapijs/hapi/issues/4122 until v20, set the socket
- // timeout on the route to a fake timeout only when the payload timeout is specified.
- // Within the onPreAuth lifecycle of the route itself, we'll override the timeout with the
- // real socket timeout.
- const fakeSocketTimeout = timeout?.payload ? timeout.payload + 1 : undefined;
-
- this.server.route({
+ const routeOpts: ServerRoute = {
handler: route.handler,
method: route.method,
path: route.path,
options: {
auth: this.getAuthOption(authRequired),
app: kibanaRouteOptions,
- ext: {
- onPreAuth: {
- method: (request, h) => {
- // At this point, the socket timeout has only been set to work-around the HapiJS bug.
- // We need to either set the real per-route timeout or use the default idle socket timeout
- if (timeout?.idleSocket) {
- request.raw.req.socket.setTimeout(timeout.idleSocket);
- } else if (fakeSocketTimeout) {
- // NodeJS uses a socket timeout of `0` to denote "no timeout"
- request.raw.req.socket.setTimeout(this.config!.socketTimeout ?? 0);
- }
-
- return h.continue;
- },
- },
- },
tags: tags ? Array.from(tags) : undefined,
- // TODO: This 'validate' section can be removed once the legacy platform is completely removed.
- // We are telling Hapi that NP routes can accept any payload, so that it can bypass the default
- // validation applied in ./http_tools#getServerOptions
- // (All NP routes are already required to specify their own validation in order to access the payload)
- validate,
- payload: [allow, maxBytes, output, parse, timeout?.payload].some(
- (v) => typeof v !== 'undefined'
- )
+ // @ts-expect-error Types are outdated and doesn't allow `payload.multipart` to be `true`
+ payload: [allow, maxBytes, output, parse, timeout?.payload].some((x) => x !== undefined)
? {
allow,
maxBytes,
output,
parse,
timeout: timeout?.payload,
+ multipart: true,
}
: undefined,
timeout: {
- socket: fakeSocketTimeout,
+ socket: timeout?.idleSocket ?? this.config!.socketTimeout,
},
},
- });
+ };
+
+ // Hapi does not allow payload validation to be specified for 'head' or 'get' requests
+ if (!isSafeMethod(route.method)) {
+ // TODO: This 'validate' section can be removed once the legacy platform is completely removed.
+ // We are telling Hapi that NP routes can accept any payload, so that it can bypass the default
+ // validation applied in ./http_tools#getServerOptions
+ // (All NP routes are already required to specify their own validation in order to access the payload)
+ // TODO: Move the setting of the validate option back up to being set at `routeOpts` creation-time once
+ // https://github.com/hapijs/hoek/pull/365 is merged and released in @hapi/hoek v9.1.1. At that point I
+ // imagine the ts-error below will go away as well.
+ // @ts-expect-error "Property 'validate' does not exist on type 'RouteOptions'" <-- ehh?!? yes it does!
+ routeOpts.options!.validate = { payload: true };
+ }
+
+ this.server.route(routeOpts);
}
}
diff --git a/src/core/server/http/lifecycle/on_pre_response.ts b/src/core/server/http/lifecycle/on_pre_response.ts
index 42179374ec672..9efcf46148e1f 100644
--- a/src/core/server/http/lifecycle/on_pre_response.ts
+++ b/src/core/server/http/lifecycle/on_pre_response.ts
@@ -142,7 +142,11 @@ export function adoptToHapiOnPreResponseFormat(fn: OnPreResponseHandler, log: Lo
if (preResponseResult.isNext(result)) {
if (result.headers) {
if (isBoom(response)) {
- findHeadersIntersection(response.output.headers, result.headers, log);
+ findHeadersIntersection(
+ response.output.headers as { [key: string]: string },
+ result.headers,
+ log
+ );
// hapi wraps all error response in Boom object internally
response.output.headers = {
...response.output.headers,
@@ -157,7 +161,7 @@ export function adoptToHapiOnPreResponseFormat(fn: OnPreResponseHandler, log: Lo
const overriddenResponse = responseToolkit.response(result.body).code(statusCode);
const originalHeaders = isBoom(response) ? response.output.headers : response.headers;
- setHeaders(overriddenResponse, originalHeaders);
+ setHeaders(overriddenResponse, originalHeaders as { [key: string]: string });
if (result.headers) {
setHeaders(overriddenResponse, result.headers);
}
@@ -178,8 +182,8 @@ export function adoptToHapiOnPreResponseFormat(fn: OnPreResponseHandler, log: Lo
};
}
-function isBoom(response: any): response is Boom {
- return response instanceof Boom;
+function isBoom(response: any): response is Boom.Boom {
+ return response instanceof Boom.Boom;
}
function setHeaders(response: ResponseObject, headers: ResponseHeaders) {
diff --git a/src/core/server/http/router/error_wrapper.ts b/src/core/server/http/router/error_wrapper.ts
index 5a4b7e9f77582..7d141e81ddf36 100644
--- a/src/core/server/http/router/error_wrapper.ts
+++ b/src/core/server/http/router/error_wrapper.ts
@@ -29,7 +29,7 @@ export const wrapErrors: RequestHandlerWrapper = (handler) => {
return response.customError({
body: e.output.payload,
statusCode: e.output.statusCode,
- headers: e.output.headers,
+ headers: e.output.headers as { [key: string]: string },
});
}
throw e;
diff --git a/src/core/server/http/router/response_adapter.ts b/src/core/server/http/router/response_adapter.ts
index 63acd2207ac3a..d80c21bde8de8 100644
--- a/src/core/server/http/router/response_adapter.ts
+++ b/src/core/server/http/router/response_adapter.ts
@@ -56,7 +56,7 @@ export class HapiResponseAdapter {
}
public toInternalError() {
- const error = new Boom('', {
+ const error = new Boom.Boom('', {
statusCode: 500,
});
@@ -129,7 +129,7 @@ export class HapiResponseAdapter {
}
// we use for BWC with Boom payload for error responses - {error: string, message: string, statusCode: string}
- const error = new Boom('', {
+ const error = new Boom.Boom('', {
statusCode: kibanaResponse.status,
});
@@ -142,8 +142,7 @@ export class HapiResponseAdapter {
const headers = kibanaResponse.options.headers;
if (headers) {
- // Hapi typings for header accept only strings, although string[] is a valid value
- error.output.headers = headers as any;
+ error.output.headers = headers;
}
return error;
diff --git a/src/core/server/http/router/router.ts b/src/core/server/http/router/router.ts
index b1e092ba5786a..ebc41a793f3b3 100644
--- a/src/core/server/http/router/router.ts
+++ b/src/core/server/http/router/router.ts
@@ -44,7 +44,10 @@ interface RouterRoute {
method: RouteMethod;
path: string;
options: RouteConfigOptions;
- handler: (req: Request, responseToolkit: ResponseToolkit) => Promise>;
+ handler: (
+ req: Request,
+ responseToolkit: ResponseToolkit
+ ) => Promise>;
}
/**
diff --git a/src/core/server/saved_objects/service/lib/errors.ts b/src/core/server/saved_objects/service/lib/errors.ts
index e8836dbd8f7a1..c6c8eee003e4e 100644
--- a/src/core/server/saved_objects/service/lib/errors.ts
+++ b/src/core/server/saved_objects/service/lib/errors.ts
@@ -44,7 +44,7 @@ const CODE_GENERAL_ERROR = 'SavedObjectsClient/generalError';
const code = Symbol('SavedObjectsClientErrorCode');
-export interface DecoratedError extends Boom {
+export interface DecoratedError extends Boom.Boom {
[code]?: string;
}
diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md
index 5f07a4b523056..cef5f33726ed5 100644
--- a/src/core/server/server.api.md
+++ b/src/core/server/server.api.md
@@ -1541,7 +1541,7 @@ export type LegacyElasticsearchClientConfig = Pick;
const allowedList: CircularDepList = new Set([
- 'src/plugins/charts -> src/plugins/expressions',
+ 'src/plugins/charts -> src/plugins/discover',
'src/plugins/charts -> src/plugins/vis_default_editor',
- 'src/plugins/data -> src/plugins/embeddable',
- 'src/plugins/data -> src/plugins/expressions',
- 'src/plugins/data -> src/plugins/ui_actions',
- 'src/plugins/embeddable -> src/plugins/ui_actions',
- 'src/plugins/expressions -> src/plugins/visualizations',
'src/plugins/vis_default_editor -> src/plugins/visualizations',
'src/plugins/vis_default_editor -> src/plugins/visualize',
'src/plugins/visualizations -> src/plugins/visualize',
diff --git a/src/plugins/dashboard/public/application/dashboard_app.tsx b/src/plugins/dashboard/public/application/dashboard_app.tsx
index 8eff48251b371..845d64c16500d 100644
--- a/src/plugins/dashboard/public/application/dashboard_app.tsx
+++ b/src/plugins/dashboard/public/application/dashboard_app.tsx
@@ -45,6 +45,7 @@ import { removeQueryParam } from '../services/kibana_utils';
import { IndexPattern } from '../services/data';
import { EmbeddableRenderer } from '../services/embeddable';
import { DashboardContainerInput } from '.';
+import { leaveConfirmStrings } from '../dashboard_strings';
export interface DashboardAppProps {
history: History;
@@ -64,8 +65,9 @@ export function DashboardApp({
core,
onAppLeave,
uiSettings,
- indexPatterns: indexPatternService,
+ embeddable,
dashboardCapabilities,
+ indexPatterns: indexPatternService,
} = useKibana().services;
const [lastReloadTime, setLastReloadTime] = useState(0);
@@ -196,9 +198,14 @@ export function DashboardApp({
return;
}
onAppLeave((actions) => {
- if (dashboardStateManager?.getIsDirty()) {
- // TODO: Finish App leave handler with overrides when redirecting to an editor.
- // return actions.confirm(leaveConfirmStrings.leaveSubtitle, leaveConfirmStrings.leaveTitle);
+ if (
+ dashboardStateManager?.getIsDirty() &&
+ !embeddable.getStateTransfer().isTransferInProgress
+ ) {
+ return actions.confirm(
+ leaveConfirmStrings.getLeaveSubtitle(),
+ leaveConfirmStrings.getLeaveTitle()
+ );
}
return actions.default();
});
@@ -206,7 +213,7 @@ export function DashboardApp({
// reset on app leave handler so leaving from the listing page doesn't trigger a confirmation
onAppLeave((actions) => actions.default());
};
- }, [dashboardStateManager, dashboardContainer, onAppLeave]);
+ }, [dashboardStateManager, dashboardContainer, onAppLeave, embeddable]);
// Refresh the dashboard container when lastReloadTime changes
useEffect(() => {
diff --git a/src/plugins/dashboard/public/application/top_nav/dashboard_top_nav.tsx b/src/plugins/dashboard/public/application/top_nav/dashboard_top_nav.tsx
index 937e6737d2716..915f245fbcd19 100644
--- a/src/plugins/dashboard/public/application/top_nav/dashboard_top_nav.tsx
+++ b/src/plugins/dashboard/public/application/top_nav/dashboard_top_nav.tsx
@@ -27,6 +27,7 @@ import { useKibana } from '../../services/kibana_react';
import { IndexPattern, SavedQuery, TimefilterContract } from '../../services/data';
import {
EmbeddableFactoryNotFoundError,
+ EmbeddableInput,
isErrorEmbeddable,
openAddPanelFlyout,
ViewMode,
@@ -135,10 +136,7 @@ export function DashboardTopNav({
if (!factory) {
throw new EmbeddableFactoryNotFoundError(type);
}
- const explicitInput = await factory.getExplicitInput();
- if (dashboardContainer) {
- await dashboardContainer.addNewEmbeddable(type, explicitInput);
- }
+ await factory.create({} as EmbeddableInput, dashboardContainer);
}, [dashboardContainer, embeddable]);
const onChangeViewMode = useCallback(
diff --git a/src/plugins/data/common/index_patterns/index_pattern.stub.ts b/src/plugins/data/common/index_patterns/index_pattern.stub.ts
index e7384e09494aa..c47a8b605ada3 100644
--- a/src/plugins/data/common/index_patterns/index_pattern.stub.ts
+++ b/src/plugins/data/common/index_patterns/index_pattern.stub.ts
@@ -25,6 +25,7 @@ export const stubIndexPattern: IIndexPattern = {
fields: stubFields,
title: 'logstash-*',
timeFieldName: '@timestamp',
+ getTimeField: () => ({ name: '@timestamp', type: 'date' }),
};
export const stubIndexPatternWithFields: IIndexPattern = {
diff --git a/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_pattern.test.ts.snap b/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_pattern.test.ts.snap
index 19ec286307a09..76de2b2662bb0 100644
--- a/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_pattern.test.ts.snap
+++ b/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_pattern.test.ts.snap
@@ -2,6 +2,7 @@
exports[`IndexPattern toSpec should match snapshot 1`] = `
Object {
+ "allowNoIndex": false,
"fieldAttrs": Object {},
"fieldFormats": Object {},
"fields": Object {
diff --git a/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_patterns.test.ts.snap b/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_patterns.test.ts.snap
index c020e7595c565..bad74430b8966 100644
--- a/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_patterns.test.ts.snap
+++ b/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_patterns.test.ts.snap
@@ -2,6 +2,7 @@
exports[`IndexPatterns savedObjectToSpec 1`] = `
Object {
+ "allowNoIndex": undefined,
"fieldAttrs": Object {},
"fieldFormats": Object {
"field": Object {},
diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts
index 4c89cbeb446a0..590ff872f3bf9 100644
--- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts
+++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts
@@ -74,6 +74,10 @@ export class IndexPattern implements IIndexPattern {
private fieldFormats: FieldFormatsStartCommon;
// make private once manual field refresh is removed
public fieldAttrs: FieldAttrs;
+ /**
+ * prevents errors when index pattern exists before indices
+ */
+ public readonly allowNoIndex: boolean = false;
constructor({
spec = {},
@@ -110,6 +114,7 @@ export class IndexPattern implements IIndexPattern {
this.typeMeta = spec.typeMeta;
this.fieldAttrs = spec.fieldAttrs || {};
this.intervalName = spec.intervalName;
+ this.allowNoIndex = spec.allowNoIndex || false;
}
/**
@@ -204,6 +209,7 @@ export class IndexPattern implements IIndexPattern {
fieldFormats: this.fieldFormatMap,
fieldAttrs: this.fieldAttrs,
intervalName: this.intervalName,
+ allowNoIndex: this.allowNoIndex,
};
}
@@ -309,6 +315,7 @@ export class IndexPattern implements IIndexPattern {
fieldFormatMap,
type: this.type,
typeMeta: this.typeMeta ? JSON.stringify(this.typeMeta) : undefined,
+ allowNoIndex: this.allowNoIndex ? this.allowNoIndex : undefined,
};
}
diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts
index 2a203b57d201b..3d32742c168ad 100644
--- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts
+++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts
@@ -114,6 +114,21 @@ describe('IndexPatterns', () => {
SOClientGetDelay = 0;
});
+ test('allowNoIndex flag preserves existing fields when index is missing', async () => {
+ const id = '2';
+ setDocsourcePayload(id, {
+ id: 'foo',
+ version: 'foo',
+ attributes: {
+ title: 'something',
+ allowNoIndex: true,
+ fields: '[{"name":"field"}]',
+ },
+ });
+
+ expect((await indexPatterns.get(id)).fields.length).toBe(1);
+ });
+
test('savedObjectCache pre-fetches only title', async () => {
expect(await indexPatterns.getIds()).toEqual(['id']);
expect(savedObjectsClient.find).toHaveBeenCalledWith({
diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts
index 0235f748ec1e0..3333dba36fe69 100644
--- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts
+++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts
@@ -222,6 +222,7 @@ export class IndexPatternsService {
metaFields,
type: options.type,
rollupIndex: options.rollupIndex,
+ allowNoIndex: options.allowNoIndex,
});
};
@@ -281,10 +282,21 @@ export class IndexPatternsService {
options: GetFieldsOptions,
fieldAttrs: FieldAttrs = {}
) => {
- const scriptedFields = Object.values(fields).filter((field) => field.scripted);
+ const fieldsAsArr = Object.values(fields);
+ const scriptedFields = fieldsAsArr.filter((field) => field.scripted);
try {
+ let updatedFieldList: FieldSpec[];
const newFields = (await this.getFieldsForWildcard(options)) as FieldSpec[];
- return this.fieldArrayToMap([...newFields, ...scriptedFields], fieldAttrs);
+
+ // If allowNoIndex, only update field list if field caps finds fields. To support
+ // beats creating index pattern and dashboard before docs
+ if (!options.allowNoIndex || (newFields && newFields.length > 5)) {
+ updatedFieldList = [...newFields, ...scriptedFields];
+ } else {
+ updatedFieldList = fieldsAsArr;
+ }
+
+ return this.fieldArrayToMap(updatedFieldList, fieldAttrs);
} catch (err) {
if (err instanceof IndexPatternMissingIndices) {
this.onNotification({ title: (err as any).message, color: 'danger', iconType: 'alert' });
@@ -334,6 +346,7 @@ export class IndexPatternsService {
typeMeta,
type,
fieldAttrs,
+ allowNoIndex,
},
} = savedObject;
@@ -355,6 +368,7 @@ export class IndexPatternsService {
type,
fieldFormats: parsedFieldFormatMap,
fieldAttrs: parsedFieldAttrs,
+ allowNoIndex,
};
};
@@ -384,6 +398,7 @@ export class IndexPatternsService {
metaFields: await this.config.get(UI_SETTINGS.META_FIELDS),
type,
rollupIndex: typeMeta?.params?.rollup_index,
+ allowNoIndex: spec.allowNoIndex,
},
spec.fieldAttrs
);
diff --git a/src/plugins/data/common/index_patterns/types.ts b/src/plugins/data/common/index_patterns/types.ts
index 8d9b29175162e..12496b07d3482 100644
--- a/src/plugins/data/common/index_patterns/types.ts
+++ b/src/plugins/data/common/index_patterns/types.ts
@@ -49,6 +49,10 @@ export interface IndexPatternAttributes {
sourceFilters?: string;
fieldFormatMap?: string;
fieldAttrs?: string;
+ /**
+ * prevents errors when index pattern exists before indices
+ */
+ allowNoIndex?: boolean;
}
export interface FieldAttrs {
@@ -101,6 +105,7 @@ export interface GetFieldsOptions {
lookBack?: boolean;
metaFields?: string[];
rollupIndex?: string;
+ allowNoIndex?: boolean;
}
export interface GetFieldsOptionsTimePattern {
@@ -193,6 +198,7 @@ export interface IndexPatternSpec {
type?: string;
fieldFormats?: Record;
fieldAttrs?: FieldAttrs;
+ allowNoIndex?: boolean;
}
export interface SourceFilter {
diff --git a/src/plugins/data/common/search/aggs/buckets/date_histogram.ts b/src/plugins/data/common/search/aggs/buckets/date_histogram.ts
index ba79a4264d603..6b7f1522d19ad 100644
--- a/src/plugins/data/common/search/aggs/buckets/date_histogram.ts
+++ b/src/plugins/data/common/search/aggs/buckets/date_histogram.ts
@@ -149,7 +149,7 @@ export const getDateHistogramBucketAgg = ({
type: 'field',
filterFieldTypes: KBN_FIELD_TYPES.DATE,
default(agg: IBucketDateHistogramAggConfig) {
- return agg.getIndexPattern().timeFieldName;
+ return agg.getIndexPattern().getTimeField?.()?.name;
},
onChange(agg: IBucketDateHistogramAggConfig) {
if (isAutoInterval(get(agg, 'params.interval')) && !agg.fieldIsTimeField()) {
diff --git a/src/plugins/data/common/search/expressions/esaggs/request_handler.test.ts b/src/plugins/data/common/search/expressions/esaggs/request_handler.test.ts
index 78d169e8529c5..9d0c63a8dc7aa 100644
--- a/src/plugins/data/common/search/expressions/esaggs/request_handler.test.ts
+++ b/src/plugins/data/common/search/expressions/esaggs/request_handler.test.ts
@@ -150,7 +150,8 @@ describe('esaggs expression function - public', () => {
});
});
- test('calls agg.postFlightRequest if it exiests', async () => {
+ test('calls agg.postFlightRequest if it exiests and agg is enabled', async () => {
+ mockParams.aggs.aggs[0].enabled = true;
await handleRequest(mockParams);
expect(mockParams.aggs.aggs[0].type.postFlightRequest).toHaveBeenCalledTimes(1);
@@ -160,6 +161,12 @@ describe('esaggs expression function - public', () => {
expect(async () => await handleRequest(mockParams)).not.toThrowError();
});
+ test('should skip agg.postFlightRequest call if the agg is disabled', async () => {
+ mockParams.aggs.aggs[0].enabled = false;
+ await handleRequest(mockParams);
+ expect(mockParams.aggs.aggs[0].type.postFlightRequest).toHaveBeenCalledTimes(0);
+ });
+
test('tabifies response data', async () => {
await handleRequest(mockParams);
expect(tabifyAggResponse).toHaveBeenCalledWith(
diff --git a/src/plugins/data/common/search/expressions/esaggs/request_handler.ts b/src/plugins/data/common/search/expressions/esaggs/request_handler.ts
index e4385526ee6e8..b773aad67c3f8 100644
--- a/src/plugins/data/common/search/expressions/esaggs/request_handler.ts
+++ b/src/plugins/data/common/search/expressions/esaggs/request_handler.ts
@@ -170,7 +170,7 @@ export const handleRequest = async ({
// response data incorrectly in the inspector.
let response = (searchSource as any).rawResponse;
for (const agg of aggs.aggs) {
- if (typeof agg.type.postFlightRequest === 'function') {
+ if (agg.enabled && typeof agg.type.postFlightRequest === 'function') {
response = await agg.type.postFlightRequest(
response,
aggs,
diff --git a/src/plugins/data/public/actions/apply_filter_action.ts b/src/plugins/data/public/actions/apply_filter_action.ts
index 944da72bd11d1..84ce5b0382624 100644
--- a/src/plugins/data/public/actions/apply_filter_action.ts
+++ b/src/plugins/data/public/actions/apply_filter_action.ts
@@ -22,7 +22,6 @@ import { toMountPoint } from '../../../kibana_react/public';
import { ActionByType, createAction, IncompatibleActionError } from '../../../ui_actions/public';
import { getOverlays, getIndexPatterns } from '../services';
import { applyFiltersPopover } from '../ui/apply_filters';
-import type { IEmbeddable } from '../../../embeddable/public';
import { Filter, FilterManager, TimefilterContract, esFilters } from '..';
export const ACTION_GLOBAL_APPLY_FILTER = 'ACTION_GLOBAL_APPLY_FILTER';
@@ -30,7 +29,9 @@ export const ACTION_GLOBAL_APPLY_FILTER = 'ACTION_GLOBAL_APPLY_FILTER';
export interface ApplyGlobalFilterActionContext {
filters: Filter[];
timeFieldName?: string;
- embeddable?: IEmbeddable;
+ // Need to make this unknown to prevent circular dependencies.
+ // Apps using this property will need to cast to `IEmbeddable`.
+ embeddable?: unknown;
}
async function isCompatible(context: ApplyGlobalFilterActionContext) {
diff --git a/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts b/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts
index 2d7aeff79a689..2b0911b72abd5 100644
--- a/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts
+++ b/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts
@@ -19,12 +19,20 @@
import { last } from 'lodash';
import moment from 'moment';
+import { Datatable } from 'src/plugins/expressions';
import { esFilters, IFieldType, RangeFilterParams } from '../../../public';
import { getIndexPatterns, getSearchService } from '../../../public/services';
-import { RangeSelectContext } from '../../../../embeddable/public';
import { AggConfigSerialized } from '../../../common/search/aggs';
-export async function createFiltersFromRangeSelectAction(event: RangeSelectContext['data']) {
+/** @internal */
+export interface RangeSelectDataContext {
+ table: Datatable;
+ column: number;
+ range: number[];
+ timeFieldName?: string;
+}
+
+export async function createFiltersFromRangeSelectAction(event: RangeSelectDataContext) {
const column: Record = event.table.columns[event.column];
if (!column || !column.meta) {
diff --git a/src/plugins/data/public/actions/filters/create_filters_from_value_click.test.ts b/src/plugins/data/public/actions/filters/create_filters_from_value_click.test.ts
index 23d2ab080d75e..04801a5ee1cea 100644
--- a/src/plugins/data/public/actions/filters/create_filters_from_value_click.test.ts
+++ b/src/plugins/data/public/actions/filters/create_filters_from_value_click.test.ts
@@ -25,8 +25,10 @@ import {
} from '../../../public';
import { dataPluginMock } from '../../../public/mocks';
import { setIndexPatterns, setSearchService } from '../../../public/services';
-import { createFiltersFromValueClickAction } from './create_filters_from_value_click';
-import { ValueClickContext } from '../../../../embeddable/public';
+import {
+ createFiltersFromValueClickAction,
+ ValueClickDataContext,
+} from './create_filters_from_value_click';
const mockField = {
name: 'bytes',
@@ -34,7 +36,7 @@ const mockField = {
};
describe('createFiltersFromValueClick', () => {
- let dataPoints: ValueClickContext['data']['data'];
+ let dataPoints: ValueClickDataContext['data'];
beforeEach(() => {
dataPoints = [
diff --git a/src/plugins/data/public/actions/filters/create_filters_from_value_click.ts b/src/plugins/data/public/actions/filters/create_filters_from_value_click.ts
index ce7ecf434056a..30fef7e3a7c66 100644
--- a/src/plugins/data/public/actions/filters/create_filters_from_value_click.ts
+++ b/src/plugins/data/public/actions/filters/create_filters_from_value_click.ts
@@ -20,9 +20,20 @@
import { Datatable } from '../../../../../plugins/expressions/public';
import { esFilters, Filter } from '../../../public';
import { getIndexPatterns, getSearchService } from '../../../public/services';
-import { ValueClickContext } from '../../../../embeddable/public';
import { AggConfigSerialized } from '../../../common/search/aggs';
+/** @internal */
+export interface ValueClickDataContext {
+ data: Array<{
+ table: Pick;
+ column: number;
+ row: number;
+ value: any;
+ }>;
+ timeFieldName?: string;
+ negate?: boolean;
+}
+
/**
* For terms aggregations on `__other__` buckets, this assembles a list of applicable filter
* terms based on a specific cell in the tabified data.
@@ -120,7 +131,7 @@ const createFilter = async (
export const createFiltersFromValueClickAction = async ({
data,
negate,
-}: ValueClickContext['data']) => {
+}: ValueClickDataContext) => {
const filters: Filter[] = [];
await Promise.all(
diff --git a/src/plugins/data/public/actions/select_range_action.ts b/src/plugins/data/public/actions/select_range_action.ts
index 1781da980dc30..3b84523d782f6 100644
--- a/src/plugins/data/public/actions/select_range_action.ts
+++ b/src/plugins/data/public/actions/select_range_action.ts
@@ -17,16 +17,22 @@
* under the License.
*/
-import {
- ActionByType,
- APPLY_FILTER_TRIGGER,
- createAction,
- UiActionsStart,
-} from '../../../../plugins/ui_actions/public';
+import { Datatable } from 'src/plugins/expressions/public';
+import { ActionByType, createAction, UiActionsStart } from '../../../../plugins/ui_actions/public';
+import { APPLY_FILTER_TRIGGER } from '../triggers';
import { createFiltersFromRangeSelectAction } from './filters/create_filters_from_range_select';
-import type { RangeSelectContext } from '../../../embeddable/public';
-export type SelectRangeActionContext = RangeSelectContext;
+export interface SelectRangeActionContext {
+ // Need to make this unknown to prevent circular dependencies.
+ // Apps using this property will need to cast to `IEmbeddable`.
+ embeddable?: unknown;
+ data: {
+ table: Datatable;
+ column: number;
+ range: number[];
+ timeFieldName?: string;
+ };
+}
export const ACTION_SELECT_RANGE = 'ACTION_SELECT_RANGE';
diff --git a/src/plugins/data/public/actions/value_click_action.ts b/src/plugins/data/public/actions/value_click_action.ts
index 81e62380eacfb..8f207e94e8fbe 100644
--- a/src/plugins/data/public/actions/value_click_action.ts
+++ b/src/plugins/data/public/actions/value_click_action.ts
@@ -17,19 +17,31 @@
* under the License.
*/
-import {
- ActionByType,
- APPLY_FILTER_TRIGGER,
- createAction,
- UiActionsStart,
-} from '../../../../plugins/ui_actions/public';
+import { Datatable } from 'src/plugins/expressions/public';
+import { ActionByType, createAction, UiActionsStart } from '../../../../plugins/ui_actions/public';
+import { APPLY_FILTER_TRIGGER } from '../triggers';
import { createFiltersFromValueClickAction } from './filters/create_filters_from_value_click';
import type { Filter } from '../../common/es_query/filters';
-import type { ValueClickContext } from '../../../embeddable/public';
export type ValueClickActionContext = ValueClickContext;
export const ACTION_VALUE_CLICK = 'ACTION_VALUE_CLICK';
+export interface ValueClickContext {
+ // Need to make this unknown to prevent circular dependencies.
+ // Apps using this property will need to cast to `IEmbeddable`.
+ embeddable?: unknown;
+ data: {
+ data: Array<{
+ table: Pick;
+ column: number;
+ row: number;
+ value: any;
+ }>;
+ timeFieldName?: string;
+ negate?: boolean;
+ };
+}
+
export function createValueClickAction(
getStartServices: () => { uiActions: UiActionsStart }
): ActionByType {
diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts
index 3dda04d738c96..7b15e2576e704 100644
--- a/src/plugins/data/public/index.ts
+++ b/src/plugins/data/public/index.ts
@@ -483,6 +483,7 @@ export {
export { isTimeRange, isQuery, isFilter, isFilters } from '../common';
export { ACTION_GLOBAL_APPLY_FILTER, ApplyGlobalFilterActionContext } from './actions';
+export { APPLY_FILTER_TRIGGER } from './triggers';
/*
* Plugin setup
diff --git a/src/plugins/data/public/index_patterns/index_patterns/index_patterns_api_client.ts b/src/plugins/data/public/index_patterns/index_patterns/index_patterns_api_client.ts
index ca0f35d6612b2..36a193a4f6f94 100644
--- a/src/plugins/data/public/index_patterns/index_patterns/index_patterns_api_client.ts
+++ b/src/plugins/data/public/index_patterns/index_patterns/index_patterns_api_client.ts
@@ -64,12 +64,13 @@ export class IndexPatternsApiClient implements IIndexPatternsApiClient {
}).then((resp: any) => resp.fields);
}
- getFieldsForWildcard({ pattern, metaFields, type, rollupIndex }: GetFieldsOptions) {
+ getFieldsForWildcard({ pattern, metaFields, type, rollupIndex, allowNoIndex }: GetFieldsOptions) {
return this._request(this._getUrl(['_fields_for_wildcard']), {
pattern,
meta_fields: metaFields,
type,
rollup_index: rollupIndex,
- }).then((resp: any) => resp.fields);
+ allow_no_index: allowNoIndex,
+ }).then((resp: any) => resp.fields || []);
}
}
diff --git a/src/plugins/data/public/plugin.ts b/src/plugins/data/public/plugin.ts
index eb3a053b78a2d..c60a1efabf987 100644
--- a/src/plugins/data/public/plugin.ts
+++ b/src/plugins/data/public/plugin.ts
@@ -48,11 +48,6 @@ import {
setUiSettings,
} from './services';
import { createSearchBar } from './ui/search_bar/create_search_bar';
-import {
- SELECT_RANGE_TRIGGER,
- VALUE_CLICK_TRIGGER,
- APPLY_FILTER_TRIGGER,
-} from '../../ui_actions/public';
import {
ACTION_GLOBAL_APPLY_FILTER,
createFilterAction,
@@ -66,13 +61,18 @@ import {
createValueClickAction,
createSelectRangeAction,
} from './actions';
-
+import { APPLY_FILTER_TRIGGER, applyFilterTrigger } from './triggers';
import { SavedObjectsClientPublicToCommon } from './index_patterns';
import { getIndexPatternLoad } from './index_patterns/expressions';
import { UsageCollectionSetup } from '../../usage_collection/public';
import { getTableViewDescription } from './utils/table_inspector_view';
+import { TriggerId } from '../../ui_actions/public';
declare module '../../ui_actions/public' {
+ export interface TriggerContextMapping {
+ [APPLY_FILTER_TRIGGER]: ApplyGlobalFilterActionContext;
+ }
+
export interface ActionContextMapping {
[ACTION_GLOBAL_APPLY_FILTER]: ApplyGlobalFilterActionContext;
[ACTION_SELECT_RANGE]: SelectRangeActionContext;
@@ -118,19 +118,21 @@ export class DataPublicPlugin
storage: this.storage,
});
+ uiActions.registerTrigger(applyFilterTrigger);
+
uiActions.registerAction(
createFilterAction(queryService.filterManager, queryService.timefilter.timefilter)
);
uiActions.addTriggerAction(
- SELECT_RANGE_TRIGGER,
+ 'SELECT_RANGE_TRIGGER' as TriggerId,
createSelectRangeAction(() => ({
uiActions: startServices().plugins.uiActions,
}))
);
uiActions.addTriggerAction(
- VALUE_CLICK_TRIGGER,
+ 'VALUE_CLICK_TRIGGER' as TriggerId,
createValueClickAction(() => ({
uiActions: startServices().plugins.uiActions,
}))
diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md
index e5df6d860b404..3493844a71ac1 100644
--- a/src/plugins/data/public/public.api.md
+++ b/src/plugins/data/public/public.api.md
@@ -464,14 +464,17 @@ export type AggsStart = Assign;
+// Warning: (ae-missing-release-tag) "APPLY_FILTER_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export const APPLY_FILTER_TRIGGER = "FILTER_TRIGGER";
+
// Warning: (ae-missing-release-tag) "ApplyGlobalFilterActionContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export interface ApplyGlobalFilterActionContext {
- // Warning: (ae-forgotten-export) The symbol "IEmbeddable" needs to be exported by the entry point index.d.ts
- //
// (undocumented)
- embeddable?: IEmbeddable;
+ embeddable?: unknown;
// (undocumented)
filters: Filter[];
// (undocumented)
@@ -1253,6 +1256,7 @@ export class IndexPattern implements IIndexPattern {
// Warning: (ae-forgotten-export) The symbol "IndexPatternDeps" needs to be exported by the entry point index.d.ts
constructor({ spec, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps);
addScriptedField(name: string, script: string, fieldType?: string): Promise;
+ readonly allowNoIndex: boolean;
// (undocumented)
readonly deleteFieldFormat: (fieldName: string) => void;
// Warning: (ae-forgotten-export) The symbol "FieldAttrs" needs to be exported by the entry point index.d.ts
@@ -1293,6 +1297,7 @@ export class IndexPattern implements IIndexPattern {
fieldFormatMap: string | undefined;
type: string | undefined;
typeMeta: string | undefined;
+ allowNoIndex: true | undefined;
};
// (undocumented)
getComputedFields(): {
@@ -1385,6 +1390,7 @@ export type IndexPatternAggRestrictions = Record, 'isLo
//
// @public (undocumented)
export interface IndexPatternSpec {
+ // (undocumented)
+ allowNoIndex?: boolean;
// (undocumented)
fieldAttrs?: FieldAttrs;
// (undocumented)
@@ -2561,7 +2569,7 @@ export const UI_SETTINGS: {
// src/plugins/data/common/es_query/filters/phrase_filter.ts:33:3 - (ae-forgotten-export) The symbol "PhraseFilterMeta" needs to be exported by the entry point index.d.ts
// src/plugins/data/common/es_query/filters/phrases_filter.ts:31:3 - (ae-forgotten-export) The symbol "PhrasesFilterMeta" needs to be exported by the entry point index.d.ts
// src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:64:5 - (ae-forgotten-export) The symbol "FormatFieldFn" needs to be exported by the entry point index.d.ts
-// src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:128:7 - (ae-forgotten-export) The symbol "FieldAttrSet" needs to be exported by the entry point index.d.ts
+// src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:133:7 - (ae-forgotten-export) The symbol "FieldAttrSet" needs to be exported by the entry point index.d.ts
// src/plugins/data/common/search/aggs/types.ts:150:51 - (ae-forgotten-export) The symbol "AggTypesRegistryStart" needs to be exported by the entry point index.d.ts
// src/plugins/data/common/search/search_source/search_source.ts:197:7 - (ae-forgotten-export) The symbol "SearchFieldValue" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/field_formats/field_formats_service.ts:67:3 - (ae-forgotten-export) The symbol "FormatFactory" needs to be exported by the entry point index.d.ts
diff --git a/src/plugins/ui_actions/public/triggers/apply_filter_trigger.ts b/src/plugins/data/public/triggers/apply_filter_trigger.ts
similarity index 85%
rename from src/plugins/ui_actions/public/triggers/apply_filter_trigger.ts
rename to src/plugins/data/public/triggers/apply_filter_trigger.ts
index aa54706476a8f..816c1737608da 100644
--- a/src/plugins/ui_actions/public/triggers/apply_filter_trigger.ts
+++ b/src/plugins/data/public/triggers/apply_filter_trigger.ts
@@ -18,15 +18,15 @@
*/
import { i18n } from '@kbn/i18n';
-import { Trigger } from '.';
+import { Trigger } from '../../../ui_actions/public';
export const APPLY_FILTER_TRIGGER = 'FILTER_TRIGGER';
export const applyFilterTrigger: Trigger<'FILTER_TRIGGER'> = {
id: APPLY_FILTER_TRIGGER,
- title: i18n.translate('uiActions.triggers.applyFilterTitle', {
+ title: i18n.translate('data.triggers.applyFilterTitle', {
defaultMessage: 'Apply filter',
}),
- description: i18n.translate('uiActions.triggers.applyFilterDescription', {
+ description: i18n.translate('data.triggers.applyFilterDescription', {
defaultMessage: 'When kibana filter is applied. Could be a single value or a range filter.',
}),
};
diff --git a/src/plugins/ui_actions/public/triggers/value_click_trigger.ts b/src/plugins/data/public/triggers/index.ts
similarity index 62%
rename from src/plugins/ui_actions/public/triggers/value_click_trigger.ts
rename to src/plugins/data/public/triggers/index.ts
index f1aff6322522a..36a38ae76bc0e 100644
--- a/src/plugins/ui_actions/public/triggers/value_click_trigger.ts
+++ b/src/plugins/data/public/triggers/index.ts
@@ -17,16 +17,4 @@
* under the License.
*/
-import { i18n } from '@kbn/i18n';
-import { Trigger } from '.';
-
-export const VALUE_CLICK_TRIGGER = 'VALUE_CLICK_TRIGGER';
-export const valueClickTrigger: Trigger<'VALUE_CLICK_TRIGGER'> = {
- id: VALUE_CLICK_TRIGGER,
- title: i18n.translate('uiActions.triggers.valueClickTitle', {
- defaultMessage: 'Single click',
- }),
- description: i18n.translate('uiActions.triggers.valueClickDescription', {
- defaultMessage: 'A data point click on the visualization',
- }),
-};
+export * from './apply_filter_trigger';
diff --git a/src/plugins/data/public/utils/table_inspector_view/components/data_table.tsx b/src/plugins/data/public/utils/table_inspector_view/components/data_table.tsx
index f4d1a8988da78..f842568859fc2 100644
--- a/src/plugins/data/public/utils/table_inspector_view/components/data_table.tsx
+++ b/src/plugins/data/public/utils/table_inspector_view/components/data_table.tsx
@@ -38,7 +38,7 @@ import { DataViewRow, DataViewColumn } from '../types';
import { IUiSettingsClient } from '../../../../../../core/public';
import { Datatable, DatatableColumn } from '../../../../../expressions/public';
import { FieldFormatsStart } from '../../../field_formats';
-import { UiActionsStart } from '../../../../../ui_actions/public';
+import { TriggerId, UiActionsStart } from '../../../../../ui_actions/public';
interface DataTableFormatState {
columns: DataViewColumn[];
@@ -112,7 +112,7 @@ export class DataTableFormat extends Component {
const value = table.rows[rowIndex][column.id];
const eventData = { table, column: columnIndex, row: rowIndex, value };
- uiActions.executeTriggerActions('VALUE_CLICK_TRIGGER', {
+ uiActions.executeTriggerActions('VALUE_CLICK_TRIGGER' as TriggerId, {
data: { data: [eventData] },
});
}}
@@ -145,7 +145,7 @@ export class DataTableFormat extends Component {
const value = table.rows[rowIndex][column.id];
const eventData = { table, column: columnIndex, row: rowIndex, value };
- uiActions.executeTriggerActions('VALUE_CLICK_TRIGGER', {
+ uiActions.executeTriggerActions('VALUE_CLICK_TRIGGER' as TriggerId, {
data: { data: [eventData], negate: true },
});
}}
diff --git a/src/plugins/data/server/index_patterns/index_patterns_api_client.ts b/src/plugins/data/server/index_patterns/index_patterns_api_client.ts
index 21a3bf6e73e61..9023044184df3 100644
--- a/src/plugins/data/server/index_patterns/index_patterns_api_client.ts
+++ b/src/plugins/data/server/index_patterns/index_patterns_api_client.ts
@@ -30,8 +30,14 @@ export class IndexPatternsApiServer implements IIndexPatternsApiClient {
constructor(elasticsearchClient: ElasticsearchClient) {
this.esClient = elasticsearchClient;
}
- async getFieldsForWildcard({ pattern, metaFields, type, rollupIndex }: GetFieldsOptions) {
- const indexPatterns = new IndexPatternsFetcher(this.esClient);
+ async getFieldsForWildcard({
+ pattern,
+ metaFields,
+ type,
+ rollupIndex,
+ allowNoIndex,
+ }: GetFieldsOptions) {
+ const indexPatterns = new IndexPatternsFetcher(this.esClient, allowNoIndex);
return await indexPatterns.getFieldsForWildcard({
pattern,
metaFields,
diff --git a/src/plugins/data/server/index_patterns/routes.ts b/src/plugins/data/server/index_patterns/routes.ts
index e9dbc2e972c68..f0b51e456337f 100644
--- a/src/plugins/data/server/index_patterns/routes.ts
+++ b/src/plugins/data/server/index_patterns/routes.ts
@@ -75,13 +75,20 @@ export function registerRoutes(
}),
type: schema.maybe(schema.string()),
rollup_index: schema.maybe(schema.string()),
+ allow_no_index: schema.maybe(schema.boolean()),
}),
},
},
async (context, request, response) => {
const { asCurrentUser } = context.core.elasticsearch.client;
const indexPatterns = new IndexPatternsFetcher(asCurrentUser);
- const { pattern, meta_fields: metaFields, type, rollup_index: rollupIndex } = request.query;
+ const {
+ pattern,
+ meta_fields: metaFields,
+ type,
+ rollup_index: rollupIndex,
+ allow_no_index: allowNoIndex,
+ } = request.query;
let parsedFields: string[] = [];
try {
@@ -96,6 +103,9 @@ export function registerRoutes(
metaFields: parsedFields,
type,
rollupIndex,
+ fieldCapsOptions: {
+ allow_no_indices: allowNoIndex || false,
+ },
});
return response.ok({
diff --git a/src/plugins/data/server/index_patterns/routes/create_index_pattern.ts b/src/plugins/data/server/index_patterns/routes/create_index_pattern.ts
index 57a745b19748d..1163fd2dc9953 100644
--- a/src/plugins/data/server/index_patterns/routes/create_index_pattern.ts
+++ b/src/plugins/data/server/index_patterns/routes/create_index_pattern.ts
@@ -50,6 +50,7 @@ const indexPatternSpecSchema = schema.object({
})
)
),
+ allowNoIndex: schema.maybe(schema.boolean()),
});
export const registerCreateIndexPatternRoute = (
diff --git a/src/plugins/data/server/index_patterns/routes/update_index_pattern.ts b/src/plugins/data/server/index_patterns/routes/update_index_pattern.ts
index 10567544af6ea..8bd59e47730fd 100644
--- a/src/plugins/data/server/index_patterns/routes/update_index_pattern.ts
+++ b/src/plugins/data/server/index_patterns/routes/update_index_pattern.ts
@@ -38,6 +38,7 @@ const indexPatternUpdateSchema = schema.object({
),
fieldFormats: schema.maybe(schema.recordOf(schema.string(), serializedFieldFormatSchema)),
fields: schema.maybe(schema.recordOf(schema.string(), fieldSpecSchema)),
+ allowNoIndex: schema.maybe(schema.boolean()),
});
export const registerUpdateIndexPatternRoute = (
diff --git a/src/plugins/data/server/kql_telemetry/usage_collector/fetch.test.ts b/src/plugins/data/server/kql_telemetry/usage_collector/fetch.test.ts
index 1794df7391cb0..038f340babb1f 100644
--- a/src/plugins/data/server/kql_telemetry/usage_collector/fetch.test.ts
+++ b/src/plugins/data/server/kql_telemetry/usage_collector/fetch.test.ts
@@ -18,7 +18,7 @@
*/
import { fetchProvider } from './fetch';
-import { LegacyAPICaller } from 'kibana/server';
+import { ElasticsearchClient } from 'kibana/server';
import { CollectorFetchContext } from 'src/plugins/usage_collection/server';
import { createCollectorFetchContextMock } from 'src/plugins/usage_collection/server/mocks';
@@ -30,7 +30,7 @@ jest.mock('../../../common', () => ({
}));
let fetch: ReturnType;
-let callCluster: LegacyAPICaller;
+let esClient: ElasticsearchClient;
let collectorFetchContext: CollectorFetchContext;
const collectorFetchContextMock = createCollectorFetchContextMock();
@@ -38,34 +38,33 @@ function setupMockCallCluster(
optCount: { optInCount?: number; optOutCount?: number } | null,
language: string | undefined | null
) {
- callCluster = (jest.fn((method, params) => {
- if (params && 'id' in params && params.id === 'kql-telemetry:kql-telemetry') {
- if (optCount === null) {
- return Promise.resolve({
+ function mockedEsGetMethod() {
+ if (optCount === null) {
+ return Promise.resolve({
+ body: {
_index: '.kibana_1',
_id: 'kql-telemetry:kql-telemetry',
found: false,
- });
- } else {
- return Promise.resolve({
+ },
+ });
+ } else {
+ return Promise.resolve({
+ body: {
_source: {
- 'kql-telemetry': {
- ...optCount,
- },
+ 'kql-telemetry': { ...optCount },
type: 'kql-telemetry',
updated_at: '2018-10-05T20:20:56.258Z',
},
- });
- }
- } else if (params && 'body' in params && params.body.query.term.type === 'config') {
- if (language === 'missingConfigDoc') {
- return Promise.resolve({
- hits: {
- hits: [],
- },
- });
- } else {
- return Promise.resolve({
+ },
+ });
+ }
+ }
+ function mockedEsSearchMethod() {
+ if (language === 'missingConfigDoc') {
+ return Promise.resolve({ body: { hits: { hits: [] } } });
+ } else {
+ return Promise.resolve({
+ body: {
hits: {
hits: [
{
@@ -77,12 +76,15 @@ function setupMockCallCluster(
},
],
},
- });
- }
+ },
+ });
}
-
- throw new Error('invalid call');
- }) as unknown) as LegacyAPICaller;
+ }
+ const esClientMock = ({
+ get: jest.fn().mockImplementation(mockedEsGetMethod),
+ search: jest.fn().mockImplementation(mockedEsSearchMethod),
+ } as unknown) as ElasticsearchClient;
+ esClient = esClientMock;
}
describe('makeKQLUsageCollector', () => {
@@ -95,7 +97,7 @@ describe('makeKQLUsageCollector', () => {
setupMockCallCluster({ optInCount: 1 }, 'kuery');
collectorFetchContext = {
...collectorFetchContextMock,
- callCluster,
+ esClient,
};
const fetchResponse = await fetch(collectorFetchContext);
expect(fetchResponse.optInCount).toBe(1);
@@ -106,7 +108,7 @@ describe('makeKQLUsageCollector', () => {
setupMockCallCluster({ optInCount: 1 }, 'kuery');
collectorFetchContext = {
...collectorFetchContextMock,
- callCluster,
+ esClient,
};
const fetchResponse = await fetch(collectorFetchContext);
expect(fetchResponse.defaultQueryLanguage).toBe('kuery');
@@ -117,7 +119,7 @@ describe('makeKQLUsageCollector', () => {
setupMockCallCluster({ optInCount: 1 }, null);
collectorFetchContext = {
...collectorFetchContextMock,
- callCluster,
+ esClient,
};
const fetchResponse = await fetch(collectorFetchContext);
expect(fetchResponse.defaultQueryLanguage).toBe('lucene');
@@ -127,7 +129,7 @@ describe('makeKQLUsageCollector', () => {
setupMockCallCluster({ optInCount: 1 }, undefined);
collectorFetchContext = {
...collectorFetchContextMock,
- callCluster,
+ esClient,
};
const fetchResponse = await fetch(collectorFetchContext);
expect(fetchResponse.defaultQueryLanguage).toBe('default-lucene');
@@ -137,7 +139,7 @@ describe('makeKQLUsageCollector', () => {
setupMockCallCluster(null, 'kuery');
collectorFetchContext = {
...collectorFetchContextMock,
- callCluster,
+ esClient,
};
const fetchResponse = await fetch(collectorFetchContext);
expect(fetchResponse.optInCount).toBe(0);
@@ -148,7 +150,7 @@ describe('makeKQLUsageCollector', () => {
setupMockCallCluster(null, 'missingConfigDoc');
collectorFetchContext = {
...collectorFetchContextMock,
- callCluster,
+ esClient,
};
const fetchResponse = await fetch(collectorFetchContext);
expect(fetchResponse.defaultQueryLanguage).toBe('default-lucene');
diff --git a/src/plugins/data/server/kql_telemetry/usage_collector/fetch.ts b/src/plugins/data/server/kql_telemetry/usage_collector/fetch.ts
index 21a1843d1ec81..5178aa65705d8 100644
--- a/src/plugins/data/server/kql_telemetry/usage_collector/fetch.ts
+++ b/src/plugins/data/server/kql_telemetry/usage_collector/fetch.ts
@@ -30,18 +30,22 @@ export interface Usage {
}
export function fetchProvider(index: string) {
- return async ({ callCluster }: CollectorFetchContext): Promise => {
- const [response, config] = await Promise.all([
- callCluster('get', {
- index,
- id: 'kql-telemetry:kql-telemetry',
- ignore: [404],
- }),
- callCluster('search', {
- index,
- body: { query: { term: { type: 'config' } } },
- ignore: [404],
- }),
+ return async ({ esClient }: CollectorFetchContext): Promise => {
+ const [{ body: response }, { body: config }] = await Promise.all([
+ esClient.get(
+ {
+ index,
+ id: 'kql-telemetry:kql-telemetry',
+ },
+ { ignore: [404] }
+ ),
+ esClient.search(
+ {
+ index,
+ body: { query: { term: { type: 'config' } } },
+ },
+ { ignore: [404] }
+ ),
]);
const queryLanguageConfigValue: string | null | undefined = get(
diff --git a/src/plugins/data/server/saved_objects/index_pattern_migrations.test.ts b/src/plugins/data/server/saved_objects/index_pattern_migrations.test.ts
index b1410e2498667..3b223e6fdb9b2 100644
--- a/src/plugins/data/server/saved_objects/index_pattern_migrations.test.ts
+++ b/src/plugins/data/server/saved_objects/index_pattern_migrations.test.ts
@@ -94,4 +94,55 @@ Object {
expect(migrationFn(input, savedObjectMigrationContext)).toEqual(expected);
});
});
+
+ describe('7.11.0', () => {
+ const migrationFn = indexPatternSavedObjectTypeMigrations['7.11.0'];
+
+ test('should set allowNoIndex', () => {
+ const input = {
+ type: 'index-pattern',
+ id: 'logs-*',
+ attributes: {},
+ };
+ const expected = {
+ type: 'index-pattern',
+ id: 'logs-*',
+ attributes: {
+ allowNoIndex: true,
+ },
+ };
+
+ expect(migrationFn(input, savedObjectMigrationContext)).toEqual(expected);
+
+ const input2 = {
+ type: 'index-pattern',
+ id: 'metrics-*',
+ attributes: {},
+ };
+ const expected2 = {
+ type: 'index-pattern',
+ id: 'metrics-*',
+ attributes: {
+ allowNoIndex: true,
+ },
+ };
+
+ expect(migrationFn(input2, savedObjectMigrationContext)).toEqual(expected2);
+
+ const input3 = {
+ type: 'index-pattern',
+ id: 'xxx',
+ attributes: {},
+ };
+ const expected3 = {
+ type: 'index-pattern',
+ id: 'xxx',
+ attributes: {
+ allowNoIndex: undefined,
+ },
+ };
+
+ expect(migrationFn(input3, savedObjectMigrationContext)).toEqual(expected3);
+ });
+ });
});
diff --git a/src/plugins/data/server/saved_objects/index_pattern_migrations.ts b/src/plugins/data/server/saved_objects/index_pattern_migrations.ts
index 768041a376ad1..4650aeefba056 100644
--- a/src/plugins/data/server/saved_objects/index_pattern_migrations.ts
+++ b/src/plugins/data/server/saved_objects/index_pattern_migrations.ts
@@ -54,7 +54,16 @@ const migrateSubTypeAndParentFieldProperties: SavedObjectMigrationFn =
};
};
+const addAllowNoIndex: SavedObjectMigrationFn = (doc) => ({
+ ...doc,
+ attributes: {
+ ...doc.attributes,
+ allowNoIndex: doc.id === 'logs-*' || doc.id === 'metrics-*' || undefined,
+ },
+});
+
export const indexPatternSavedObjectTypeMigrations = {
'6.5.0': flow(migrateAttributeTypeAndAttributeTypeMeta),
'7.6.0': flow(migrateSubTypeAndParentFieldProperties),
+ '7.11.0': flow(addAllowNoIndex),
};
diff --git a/src/plugins/data/server/search/collectors/fetch.ts b/src/plugins/data/server/search/collectors/fetch.ts
index 344bc18c7b4b6..9d0d431cf4eaf 100644
--- a/src/plugins/data/server/search/collectors/fetch.ts
+++ b/src/plugins/data/server/search/collectors/fetch.ts
@@ -20,31 +20,34 @@
import { Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import { SharedGlobalConfig } from 'kibana/server';
+import { SearchResponse } from 'elasticsearch';
import { CollectorFetchContext } from 'src/plugins/usage_collection/server';
import { Usage } from './register';
-
-interface SearchTelemetrySavedObject {
+interface SearchTelemetry {
'search-telemetry': Usage;
}
+type ESResponse = SearchResponse;
export function fetchProvider(config$: Observable) {
- return async ({ callCluster }: CollectorFetchContext): Promise => {
+ return async ({ esClient }: CollectorFetchContext): Promise => {
const config = await config$.pipe(first()).toPromise();
-
- const response = await callCluster('search', {
- index: config.kibana.index,
- body: {
- query: { term: { type: { value: 'search-telemetry' } } },
+ const { body: esResponse } = await esClient.search(
+ {
+ index: config.kibana.index,
+ body: {
+ query: { term: { type: { value: 'search-telemetry' } } },
+ },
},
- ignore: [404],
- });
-
- return response.hits.hits.length
- ? response.hits.hits[0]._source['search-telemetry']
- : {
- successCount: 0,
- errorCount: 0,
- averageDuration: null,
- };
+ { ignore: [404] }
+ );
+ const size = esResponse?.hits?.hits?.length ?? 0;
+ if (!size) {
+ return {
+ successCount: 0,
+ errorCount: 0,
+ averageDuration: null,
+ };
+ }
+ return esResponse.hits.hits[0]._source['search-telemetry'];
};
}
diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md
index 4d24e6d1afd49..cd3527d5ad7ab 100644
--- a/src/plugins/data/server/server.api.md
+++ b/src/plugins/data/server/server.api.md
@@ -689,6 +689,7 @@ export class IndexPattern implements IIndexPattern {
// Warning: (ae-forgotten-export) The symbol "IndexPatternDeps" needs to be exported by the entry point index.d.ts
constructor({ spec, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps);
addScriptedField(name: string, script: string, fieldType?: string): Promise;
+ readonly allowNoIndex: boolean;
// (undocumented)
readonly deleteFieldFormat: (fieldName: string) => void;
// Warning: (ae-forgotten-export) The symbol "FieldAttrs" needs to be exported by the entry point index.d.ts
@@ -731,6 +732,7 @@ export class IndexPattern implements IIndexPattern {
fieldFormatMap: string | undefined;
type: string | undefined;
typeMeta: string | undefined;
+ allowNoIndex: true | undefined;
};
// (undocumented)
getComputedFields(): {
@@ -819,6 +821,7 @@ export class IndexPattern implements IIndexPattern {
//
// @public (undocumented)
export interface IndexPatternAttributes {
+ allowNoIndex?: boolean;
// (undocumented)
fieldAttrs?: string;
// (undocumented)
@@ -1115,7 +1118,7 @@ export class Plugin implements Plugin_2 void;
search: ISearchSetup;
fieldFormats: {
- register: (customFieldFormat: import("../common").FieldFormatInstanceType) => number;
+ register: (customFieldFormat: import("../public").FieldFormatInstanceType) => number;
};
};
// (undocumented)
@@ -1124,7 +1127,7 @@ export class Plugin implements Plugin_2 Promise;
};
indexPatterns: {
- indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("src/core/server").ElasticsearchClient) => Promise;
+ indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("src/core/server").ElasticsearchClient) => Promise;
};
search: ISearchStart>;
};
@@ -1388,7 +1391,7 @@ export function usageProvider(core: CoreSetup_2): SearchUsage;
// src/plugins/data/common/es_query/filters/meta_filter.ts:54:3 - (ae-forgotten-export) The symbol "FilterMeta" needs to be exported by the entry point index.d.ts
// src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:58:45 - (ae-forgotten-export) The symbol "IndexPatternFieldMap" needs to be exported by the entry point index.d.ts
// src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:64:5 - (ae-forgotten-export) The symbol "FormatFieldFn" needs to be exported by the entry point index.d.ts
-// src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:128:7 - (ae-forgotten-export) The symbol "FieldAttrSet" needs to be exported by the entry point index.d.ts
+// src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:133:7 - (ae-forgotten-export) The symbol "FieldAttrSet" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:40:23 - (ae-forgotten-export) The symbol "buildCustomFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:40:23 - (ae-forgotten-export) The symbol "buildFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:57:23 - (ae-forgotten-export) The symbol "datatableToCSV" needs to be exported by the entry point index.d.ts
diff --git a/src/plugins/discover/public/application/angular/discover.js b/src/plugins/discover/public/application/angular/discover.js
index 2c3b8fd9606a9..99497d61c716e 100644
--- a/src/plugins/discover/public/application/angular/discover.js
+++ b/src/plugins/discover/public/application/angular/discover.js
@@ -65,11 +65,13 @@ import {
MODIFY_COLUMNS_ON_SWITCH,
SAMPLE_SIZE_SETTING,
SEARCH_ON_PAGE_LOAD_SETTING,
+ SORT_DEFAULT_ORDER_SETTING,
} from '../../../common';
import { loadIndexPattern, resolveIndexPattern } from '../helpers/resolve_index_pattern';
import { getTopNavLinks } from '../components/top_nav/get_top_nav_links';
import { updateSearchSource } from '../helpers/update_search_source';
import { calcFieldCounts } from '../helpers/calc_field_counts';
+import { getDefaultSort } from './doc_table/lib/get_default_sort';
const services = getServices();
@@ -410,9 +412,13 @@ function discoverController($element, $route, $scope, $timeout, Promise, uiCapab
function getStateDefaults() {
const query = $scope.searchSource.getField('query') || data.query.queryString.getDefaultQuery();
+ const sort = getSortArray(savedSearch.sort, $scope.indexPattern);
+
return {
query,
- sort: getSortArray(savedSearch.sort, $scope.indexPattern),
+ sort: !sort.length
+ ? getDefaultSort($scope.indexPattern, config.get(SORT_DEFAULT_ORDER_SETTING, 'desc'))
+ : sort,
columns:
savedSearch.columns.length > 0
? savedSearch.columns
diff --git a/src/plugins/discover/public/application/angular/doc_table/lib/get_default_sort.test.ts b/src/plugins/discover/public/application/angular/doc_table/lib/get_default_sort.test.ts
new file mode 100644
index 0000000000000..9ad19653a6c12
--- /dev/null
+++ b/src/plugins/discover/public/application/angular/doc_table/lib/get_default_sort.test.ts
@@ -0,0 +1,43 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { getDefaultSort } from './get_default_sort';
+// @ts-ignore
+import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
+import { IndexPattern } from '../../../../kibana_services';
+
+describe('getDefaultSort function', function () {
+ let indexPattern: IndexPattern;
+ beforeEach(() => {
+ indexPattern = FixturesStubbedLogstashIndexPatternProvider() as IndexPattern;
+ });
+ test('should be a function', function () {
+ expect(typeof getDefaultSort === 'function').toBeTruthy();
+ });
+
+ test('should return default sort for an index pattern with timeFieldName', function () {
+ expect(getDefaultSort(indexPattern, 'desc')).toEqual([['time', 'desc']]);
+ expect(getDefaultSort(indexPattern, 'asc')).toEqual([['time', 'asc']]);
+ });
+
+ test('should return default sort for an index pattern without timeFieldName', function () {
+ delete indexPattern.timeFieldName;
+ expect(getDefaultSort(indexPattern, 'desc')).toEqual([]);
+ expect(getDefaultSort(indexPattern, 'asc')).toEqual([]);
+ });
+});
diff --git a/src/plugins/discover/public/application/angular/doc_table/lib/get_default_sort.ts b/src/plugins/discover/public/application/angular/doc_table/lib/get_default_sort.ts
index 634e3cfec3a0b..c1e4da0bab54d 100644
--- a/src/plugins/discover/public/application/angular/doc_table/lib/get_default_sort.ts
+++ b/src/plugins/discover/public/application/angular/doc_table/lib/get_default_sort.ts
@@ -17,7 +17,6 @@
* under the License.
*/
import { IndexPattern } from '../../../../kibana_services';
-// @ts-ignore
import { isSortable } from './get_sort';
import { SortOrder } from '../components/table_header/helpers';
@@ -26,12 +25,12 @@ import { SortOrder } from '../components/table_header/helpers';
* the default sort is returned depending of the index pattern
*/
export function getDefaultSort(
- indexPattern: IndexPattern,
+ indexPattern: IndexPattern | undefined,
defaultSortOrder: string = 'desc'
): SortOrder[] {
- if (indexPattern.timeFieldName && isSortable(indexPattern.timeFieldName, indexPattern)) {
+ if (indexPattern?.timeFieldName && isSortable(indexPattern.timeFieldName, indexPattern)) {
return [[indexPattern.timeFieldName, defaultSortOrder]];
} else {
- return [['_score', defaultSortOrder]];
+ return [];
}
}
diff --git a/src/plugins/discover/public/application/angular/doc_table/lib/get_sort_for_search_source.test.ts b/src/plugins/discover/public/application/angular/doc_table/lib/get_sort_for_search_source.test.ts
new file mode 100644
index 0000000000000..1dbd31897d307
--- /dev/null
+++ b/src/plugins/discover/public/application/angular/doc_table/lib/get_sort_for_search_source.test.ts
@@ -0,0 +1,51 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { getSortForSearchSource } from './get_sort_for_search_source';
+// @ts-ignore
+import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
+import { IndexPattern } from '../../../../kibana_services';
+import { SortOrder } from '../components/table_header/helpers';
+
+describe('getSortForSearchSource function', function () {
+ let indexPattern: IndexPattern;
+ beforeEach(() => {
+ indexPattern = FixturesStubbedLogstashIndexPatternProvider() as IndexPattern;
+ });
+ test('should be a function', function () {
+ expect(typeof getSortForSearchSource === 'function').toBeTruthy();
+ });
+
+ test('should return an object to use for searchSource when columns are given', function () {
+ const cols = [['bytes', 'desc']] as SortOrder[];
+ expect(getSortForSearchSource(cols, indexPattern)).toEqual([{ bytes: 'desc' }]);
+ expect(getSortForSearchSource(cols, indexPattern, 'asc')).toEqual([{ bytes: 'desc' }]);
+ delete indexPattern.timeFieldName;
+ expect(getSortForSearchSource(cols, indexPattern)).toEqual([{ bytes: 'desc' }]);
+ expect(getSortForSearchSource(cols, indexPattern, 'asc')).toEqual([{ bytes: 'desc' }]);
+ });
+
+ test('should return an object to use for searchSource when no columns are given', function () {
+ const cols = [] as SortOrder[];
+ expect(getSortForSearchSource(cols, indexPattern)).toEqual([{ _doc: 'desc' }]);
+ expect(getSortForSearchSource(cols, indexPattern, 'asc')).toEqual([{ _doc: 'asc' }]);
+ delete indexPattern.timeFieldName;
+ expect(getSortForSearchSource(cols, indexPattern)).toEqual([{ _score: 'desc' }]);
+ expect(getSortForSearchSource(cols, indexPattern, 'asc')).toEqual([{ _score: 'asc' }]);
+ });
+});
diff --git a/src/plugins/discover/public/application/angular/doc_table/lib/get_sort_for_search_source.ts b/src/plugins/discover/public/application/angular/doc_table/lib/get_sort_for_search_source.ts
index 6721f7a03584c..1244a0e229cdb 100644
--- a/src/plugins/discover/public/application/angular/doc_table/lib/get_sort_for_search_source.ts
+++ b/src/plugins/discover/public/application/angular/doc_table/lib/get_sort_for_search_source.ts
@@ -19,7 +19,6 @@
import { EsQuerySortValue, IndexPattern } from '../../../../kibana_services';
import { SortOrder } from '../components/table_header/helpers';
import { getSort } from './get_sort';
-import { getDefaultSort } from './get_default_sort';
/**
* Prepares sort for search source, that's sending the request to ES
@@ -33,10 +32,13 @@ export function getSortForSearchSource(
indexPattern?: IndexPattern,
defaultDirection: string = 'desc'
): EsQuerySortValue[] {
- if (!sort || !indexPattern) {
- return [];
- } else if (Array.isArray(sort) && sort.length === 0) {
- sort = getDefaultSort(indexPattern, defaultDirection);
+ if (!sort || !indexPattern || (Array.isArray(sort) && sort.length === 0)) {
+ if (indexPattern?.timeFieldName) {
+ // sorting by index order
+ return [{ _doc: defaultDirection } as EsQuerySortValue];
+ } else {
+ return [{ _score: defaultDirection } as EsQuerySortValue];
+ }
}
const { timeFieldName } = indexPattern;
return getSort(sort, indexPattern).map((sortPair: Record) => {
diff --git a/src/plugins/discover/public/application/embeddable/search_embeddable.ts b/src/plugins/discover/public/application/embeddable/search_embeddable.ts
index b143afd1988e6..d0c3907d31242 100644
--- a/src/plugins/discover/public/application/embeddable/search_embeddable.ts
+++ b/src/plugins/discover/public/application/embeddable/search_embeddable.ts
@@ -21,9 +21,10 @@ import angular from 'angular';
import _ from 'lodash';
import { Subscription } from 'rxjs';
import { i18n } from '@kbn/i18n';
-import { UiActionsStart, APPLY_FILTER_TRIGGER } from '../../../../ui_actions/public';
+import { UiActionsStart } from '../../../../ui_actions/public';
import { RequestAdapter, Adapters } from '../../../../inspector/public';
import {
+ APPLY_FILTER_TRIGGER,
esFilters,
Filter,
TimeRange,
@@ -48,6 +49,7 @@ import {
import { SEARCH_EMBEDDABLE_TYPE } from './constants';
import { SavedSearch } from '../..';
import { SAMPLE_SIZE_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../../common';
+import { getDefaultSort } from '../angular/doc_table/lib/get_default_sort';
interface SearchScope extends ng.IScope {
columns?: string[];
@@ -200,6 +202,13 @@ export class SearchEmbeddable
const { searchSource } = this.savedSearch;
const indexPattern = (searchScope.indexPattern = searchSource.getField('index'))!;
+ if (!this.savedSearch.sort || !this.savedSearch.sort.length) {
+ this.savedSearch.sort = getDefaultSort(
+ indexPattern,
+ getServices().uiSettings.get(SORT_DEFAULT_ORDER_SETTING, 'desc')
+ );
+ }
+
const timeRangeSearchSource = searchSource.create();
timeRangeSearchSource.setField('filter', () => {
if (!this.searchScope || !this.input.timeRange) return;
@@ -341,7 +350,14 @@ export class SearchEmbeddable
// If there is column or sort data on the panel, that means the original columns or sort settings have
// been overridden in a dashboard.
searchScope.columns = this.input.columns || this.savedSearch.columns;
- searchScope.sort = this.input.sort || this.savedSearch.sort;
+ const savedSearchSort =
+ this.savedSearch.sort && this.savedSearch.sort.length
+ ? this.savedSearch.sort
+ : getDefaultSort(
+ this.searchScope?.indexPattern,
+ getServices().uiSettings.get(SORT_DEFAULT_ORDER_SETTING, 'desc')
+ );
+ searchScope.sort = this.input.sort || savedSearchSort;
searchScope.sharedItemTitle = this.panelTitle;
if (forceFetch || isFetchRequired) {
diff --git a/src/plugins/discover/public/application/helpers/get_sharing_data.test.ts b/src/plugins/discover/public/application/helpers/get_sharing_data.test.ts
index b2aa3a05d7eb0..4dec1f75ba322 100644
--- a/src/plugins/discover/public/application/helpers/get_sharing_data.test.ts
+++ b/src/plugins/discover/public/application/helpers/get_sharing_data.test.ts
@@ -21,6 +21,7 @@ import { getSharingData } from './get_sharing_data';
import { IUiSettingsClient } from 'kibana/public';
import { createSearchSourceMock } from '../../../../data/common/search/search_source/mocks';
import { indexPatternMock } from '../../__mocks__/index_pattern';
+import { SORT_DEFAULT_ORDER_SETTING } from '../../../common';
describe('getSharingData', () => {
test('returns valid data for sharing', async () => {
@@ -29,7 +30,10 @@ describe('getSharingData', () => {
searchSourceMock,
{ columns: [] },
({
- get: () => {
+ get: (key: string) => {
+ if (key === SORT_DEFAULT_ORDER_SETTING) {
+ return 'desc';
+ }
return false;
},
} as unknown) as IUiSettingsClient,
@@ -57,7 +61,13 @@ describe('getSharingData', () => {
},
},
"script_fields": Object {},
- "sort": Array [],
+ "sort": Array [
+ Object {
+ "_score": Object {
+ "order": "desc",
+ },
+ },
+ ],
"stored_fields": undefined,
},
"index": "the-index-pattern-title",
diff --git a/src/plugins/embeddable/common/types.ts b/src/plugins/embeddable/common/types.ts
index 8965446cc85fa..d893724f616d2 100644
--- a/src/plugins/embeddable/common/types.ts
+++ b/src/plugins/embeddable/common/types.ts
@@ -18,8 +18,6 @@
*/
import { PersistableStateService, SerializableState } from '../../kibana_utils/common';
-import { Query, TimeRange } from '../../data/common/query';
-import { Filter } from '../../data/common/es_query/filters';
export enum ViewMode {
EDIT = 'edit',
@@ -53,21 +51,6 @@ export type EmbeddableInput = {
*/
disableTriggers?: boolean;
- /**
- * Time range of the chart.
- */
- timeRange?: TimeRange;
-
- /**
- * Visualization query string used to narrow down results.
- */
- query?: Query;
-
- /**
- * Visualization filters used to narrow down results.
- */
- filters?: Filter[];
-
/**
* Search session id to group searches
*/
diff --git a/src/plugins/embeddable/public/bootstrap.ts b/src/plugins/embeddable/public/bootstrap.ts
index 5c95214ef591b..efaff42c19e2f 100644
--- a/src/plugins/embeddable/public/bootstrap.ts
+++ b/src/plugins/embeddable/public/bootstrap.ts
@@ -18,18 +18,24 @@
*/
import { UiActionsSetup } from '../../ui_actions/public';
import {
- contextMenuTrigger,
- panelBadgeTrigger,
- EmbeddableContext,
- CONTEXT_MENU_TRIGGER,
- PANEL_BADGE_TRIGGER,
ACTION_ADD_PANEL,
ACTION_CUSTOMIZE_PANEL,
- ACTION_INSPECT_PANEL,
- REMOVE_PANEL_ACTION,
ACTION_EDIT_PANEL,
- panelNotificationTrigger,
+ ACTION_INSPECT_PANEL,
+ CONTEXT_MENU_TRIGGER,
+ contextMenuTrigger,
+ EmbeddableContext,
+ PANEL_BADGE_TRIGGER,
PANEL_NOTIFICATION_TRIGGER,
+ panelBadgeTrigger,
+ panelNotificationTrigger,
+ RangeSelectContext,
+ REMOVE_PANEL_ACTION,
+ SELECT_RANGE_TRIGGER,
+ selectRangeTrigger,
+ ValueClickContext,
+ VALUE_CLICK_TRIGGER,
+ valueClickTrigger,
} from './lib';
declare module '../../ui_actions/public' {
@@ -37,6 +43,8 @@ declare module '../../ui_actions/public' {
[CONTEXT_MENU_TRIGGER]: EmbeddableContext;
[PANEL_BADGE_TRIGGER]: EmbeddableContext;
[PANEL_NOTIFICATION_TRIGGER]: EmbeddableContext;
+ [SELECT_RANGE_TRIGGER]: RangeSelectContext;
+ [VALUE_CLICK_TRIGGER]: ValueClickContext;
}
export interface ActionContextMapping {
@@ -56,4 +64,6 @@ export const bootstrap = (uiActions: UiActionsSetup) => {
uiActions.registerTrigger(contextMenuTrigger);
uiActions.registerTrigger(panelBadgeTrigger);
uiActions.registerTrigger(panelNotificationTrigger);
+ uiActions.registerTrigger(selectRangeTrigger);
+ uiActions.registerTrigger(valueClickTrigger);
};
diff --git a/src/plugins/embeddable/public/index.ts b/src/plugins/embeddable/public/index.ts
index 0fc7c7965010b..d537ef2bd0c5c 100644
--- a/src/plugins/embeddable/public/index.ts
+++ b/src/plugins/embeddable/public/index.ts
@@ -65,6 +65,8 @@ export {
PanelNotFoundError,
PanelState,
PropertySpec,
+ SELECT_RANGE_TRIGGER,
+ VALUE_CLICK_TRIGGER,
ViewMode,
withEmbeddableSubscription,
SavedObjectEmbeddableInput,
diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable.test.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable.test.tsx
index c7c71656bceb2..c0e13a84066ca 100644
--- a/src/plugins/embeddable/public/lib/embeddables/embeddable.test.tsx
+++ b/src/plugins/embeddable/public/lib/embeddables/embeddable.test.tsx
@@ -24,8 +24,10 @@ import { Embeddable } from './embeddable';
import { EmbeddableOutput, EmbeddableInput } from './i_embeddable';
import { ViewMode } from '../types';
import { ContactCardEmbeddable } from '../test_samples/embeddables/contact_card/contact_card_embeddable';
-import { FilterableEmbeddable } from '../test_samples/embeddables/filterable_embeddable';
-import type { Filter } from '../../../../data/public';
+import {
+ MockFilter,
+ FilterableEmbeddable,
+} from '../test_samples/embeddables/filterable_embeddable';
class TestClass {
constructor() {}
@@ -83,7 +85,7 @@ test('Embeddable reload is called if lastReloadRequest input time changes', asyn
test('Embeddable reload is called if lastReloadRequest input time changed and new input is used', async () => {
const hello = new FilterableEmbeddable({ id: '123', filters: [], lastReloadRequestTime: 0 });
- const aFilter = ({} as unknown) as Filter;
+ const aFilter = ({} as unknown) as MockFilter;
hello.reload = jest.fn(() => {
// when reload is called embeddable already has new input
expect(hello.getInput().filters).toEqual([aFilter]);
diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.test.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.test.tsx
index 0361939fd07e6..cb78fac5471a9 100644
--- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.test.tsx
+++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.test.tsx
@@ -20,6 +20,7 @@
import { ViewMode, EmbeddableOutput, isErrorEmbeddable } from '../../../../';
import { AddPanelAction } from './add_panel_action';
import {
+ MockFilter,
FILTERABLE_EMBEDDABLE,
FilterableEmbeddable,
FilterableEmbeddableInput,
@@ -28,7 +29,6 @@ import { FilterableEmbeddableFactory } from '../../../../test_samples/embeddable
import { FilterableContainer } from '../../../../test_samples/embeddables/filterable_container';
import { coreMock } from '../../../../../../../../core/public/mocks';
import { ContactCardEmbeddable } from '../../../../test_samples';
-import { esFilters, Filter } from '../../../../../../../../plugins/data/public';
import { EmbeddableStart } from '../../../../../plugin';
import { embeddablePluginMock } from '../../../../../mocks';
import { defaultTrigger } from '../../../../../../../ui_actions/public/triggers';
@@ -51,8 +51,8 @@ beforeEach(async () => {
() => null
);
- const derivedFilter: Filter = {
- $state: { store: esFilters.FilterStateStore.APP_STATE },
+ const derivedFilter: MockFilter = {
+ $state: { store: 'appState' },
meta: { disabled: false, alias: 'name', negate: false },
query: { match: {} },
};
diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/inspect_panel_action.test.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/inspect_panel_action.test.tsx
index eb83641448986..b784a46127305 100644
--- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/inspect_panel_action.test.tsx
+++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/inspect_panel_action.test.tsx
@@ -29,7 +29,6 @@ import {
import { inspectorPluginMock } from '../../../../../../../plugins/inspector/public/mocks';
import { EmbeddableOutput, isErrorEmbeddable, ErrorEmbeddable } from '../../../embeddables';
import { of } from '../../../../tests/helpers';
-import { esFilters } from '../../../../../../../plugins/data/public';
import { embeddablePluginMock } from '../../../../mocks';
import { EmbeddableStart } from '../../../../plugin';
@@ -43,7 +42,7 @@ const setupTests = async () => {
panels: {},
filters: [
{
- $state: { store: esFilters.FilterStateStore.APP_STATE },
+ $state: { store: 'appState' },
meta: { disabled: false, alias: 'name', negate: false },
query: { match: {} },
},
diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/remove_panel_action.test.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/remove_panel_action.test.tsx
index dea4a88bda082..ce6a1cc20fc4d 100644
--- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/remove_panel_action.test.tsx
+++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/remove_panel_action.test.tsx
@@ -21,6 +21,7 @@ import { EmbeddableOutput, isErrorEmbeddable } from '../../../';
import { RemovePanelAction } from './remove_panel_action';
import { EmbeddableStart } from '../../../../plugin';
import {
+ MockFilter,
FILTERABLE_EMBEDDABLE,
FilterableEmbeddable,
FilterableEmbeddableInput,
@@ -29,7 +30,6 @@ import { FilterableEmbeddableFactory } from '../../../test_samples/embeddables/f
import { FilterableContainer } from '../../../test_samples/embeddables/filterable_container';
import { ViewMode } from '../../../types';
import { ContactCardEmbeddable } from '../../../test_samples/embeddables/contact_card/contact_card_embeddable';
-import { esFilters, Filter } from '../../../../../../../plugins/data/public';
import { embeddablePluginMock } from '../../../../mocks';
const { setup, doStart } = embeddablePluginMock.createInstance();
@@ -39,8 +39,8 @@ let container: FilterableContainer;
let embeddable: FilterableEmbeddable;
beforeEach(async () => {
- const derivedFilter: Filter = {
- $state: { store: esFilters.FilterStateStore.APP_STATE },
+ const derivedFilter: MockFilter = {
+ $state: { store: 'appState' },
meta: { disabled: false, alias: 'name', negate: false },
query: { match: {} },
};
diff --git a/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.test.ts b/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.test.ts
index cbaeddf472d52..be034d125dcee 100644
--- a/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.test.ts
+++ b/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.test.ts
@@ -23,6 +23,7 @@ import { EmbeddableStateTransfer } from '.';
import { ApplicationStart, PublicAppInfo } from '../../../../../core/public';
import { EMBEDDABLE_EDITOR_STATE_KEY, EMBEDDABLE_PACKAGE_STATE_KEY } from './types';
import { EMBEDDABLE_STATE_TRANSFER_STORAGE_KEY } from './embeddable_state_transfer';
+import { Subject } from 'rxjs';
const createStorage = (): Storage => {
const createMockStore = () => {
@@ -46,16 +47,24 @@ const createStorage = (): Storage => {
describe('embeddable state transfer', () => {
let application: jest.Mocked;
let stateTransfer: EmbeddableStateTransfer;
+ let currentAppId$: Subject;
let store: Storage;
const destinationApp = 'superUltraVisualize';
const originatingApp = 'superUltraTestDashboard';
beforeEach(() => {
+ currentAppId$ = new Subject();
+ currentAppId$.next(originatingApp);
const core = coreMock.createStart();
application = core.application;
store = createStorage();
- stateTransfer = new EmbeddableStateTransfer(application.navigateToApp, undefined, store);
+ stateTransfer = new EmbeddableStateTransfer(
+ application.navigateToApp,
+ currentAppId$,
+ undefined,
+ store
+ );
});
it('cannot fetch app name when given no app list', async () => {
@@ -67,7 +76,7 @@ describe('embeddable state transfer', () => {
['testId', { title: 'State Transfer Test App Hello' } as PublicAppInfo],
['testId2', { title: 'State Transfer Test App Goodbye' } as PublicAppInfo],
]);
- stateTransfer = new EmbeddableStateTransfer(application.navigateToApp, appsList);
+ stateTransfer = new EmbeddableStateTransfer(application.navigateToApp, currentAppId$, appsList);
expect(stateTransfer.getAppNameFromId('kibanana')).toBeUndefined();
});
@@ -76,7 +85,7 @@ describe('embeddable state transfer', () => {
['testId', { title: 'State Transfer Test App Hello' } as PublicAppInfo],
['testId2', { title: 'State Transfer Test App Goodbye' } as PublicAppInfo],
]);
- stateTransfer = new EmbeddableStateTransfer(application.navigateToApp, appsList);
+ stateTransfer = new EmbeddableStateTransfer(application.navigateToApp, currentAppId$, appsList);
expect(stateTransfer.getAppNameFromId('testId')).toBe('State Transfer Test App Hello');
expect(stateTransfer.getAppNameFromId('testId2')).toBe('State Transfer Test App Goodbye');
});
@@ -107,6 +116,13 @@ describe('embeddable state transfer', () => {
});
});
+ it('sets isTransferInProgress to true when sending an outgoing editor state', async () => {
+ await stateTransfer.navigateToEditor(destinationApp, { state: { originatingApp } });
+ expect(stateTransfer.isTransferInProgress).toEqual(true);
+ currentAppId$.next(destinationApp);
+ expect(stateTransfer.isTransferInProgress).toEqual(false);
+ });
+
it('can send an outgoing embeddable package state', async () => {
await stateTransfer.navigateToWithEmbeddablePackage(destinationApp, {
state: { type: 'coolestType', input: { savedObjectId: '150' } },
@@ -135,6 +151,15 @@ describe('embeddable state transfer', () => {
});
});
+ it('sets isTransferInProgress to true when sending an outgoing embeddable package state', async () => {
+ await stateTransfer.navigateToWithEmbeddablePackage(destinationApp, {
+ state: { type: 'coolestType', input: { savedObjectId: '150' } },
+ });
+ expect(stateTransfer.isTransferInProgress).toEqual(true);
+ currentAppId$.next(destinationApp);
+ expect(stateTransfer.isTransferInProgress).toEqual(false);
+ });
+
it('can fetch an incoming editor state', async () => {
store.set(EMBEDDABLE_STATE_TRANSFER_STORAGE_KEY, {
[EMBEDDABLE_EDITOR_STATE_KEY]: { originatingApp: 'superUltraTestDashboard' },
diff --git a/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.ts b/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.ts
index 0b34bea810520..92900059668db 100644
--- a/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.ts
+++ b/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.ts
@@ -38,14 +38,20 @@ export const EMBEDDABLE_STATE_TRANSFER_STORAGE_KEY = 'EMBEDDABLE_STATE_TRANSFER'
* @public
*/
export class EmbeddableStateTransfer {
+ public isTransferInProgress: boolean;
private storage: Storage;
constructor(
private navigateToApp: ApplicationStart['navigateToApp'],
+ currentAppId$: ApplicationStart['currentAppId$'],
private appList?: ReadonlyMap | undefined,
customStorage?: Storage
) {
this.storage = customStorage ? customStorage : new Storage(sessionStorage);
+ this.isTransferInProgress = false;
+ currentAppId$.subscribe(() => {
+ this.isTransferInProgress = false;
+ });
}
/**
@@ -105,6 +111,7 @@ export class EmbeddableStateTransfer {
state: EmbeddableEditorState;
}
): Promise {
+ this.isTransferInProgress = true;
await this.navigateToWithState(appId, EMBEDDABLE_EDITOR_STATE_KEY, {
...options,
appendToExistingState: true,
@@ -119,6 +126,7 @@ export class EmbeddableStateTransfer {
appId: string,
options?: { path?: string; state: EmbeddablePackageState }
): Promise {
+ this.isTransferInProgress = true;
await this.navigateToWithState(appId, EMBEDDABLE_PACKAGE_STATE_KEY, {
...options,
appendToExistingState: true,
diff --git a/src/plugins/embeddable/public/lib/test_samples/embeddables/filterable_container.tsx b/src/plugins/embeddable/public/lib/test_samples/embeddables/filterable_container.tsx
index db71b94ac855f..23696612fd82a 100644
--- a/src/plugins/embeddable/public/lib/test_samples/embeddables/filterable_container.tsx
+++ b/src/plugins/embeddable/public/lib/test_samples/embeddables/filterable_container.tsx
@@ -18,13 +18,13 @@
*/
import { Container, ContainerInput } from '../../containers';
-import { Filter } from '../../../../../data/public';
import { EmbeddableStart } from '../../../plugin';
+import { MockFilter } from './filterable_embeddable';
export const FILTERABLE_CONTAINER = 'FILTERABLE_CONTAINER';
export interface FilterableContainerInput extends ContainerInput {
- filters: Filter[];
+ filters: MockFilter[];
}
/**
@@ -33,7 +33,7 @@ export interface FilterableContainerInput extends ContainerInput {
* here instead
*/
export type InheritedChildrenInput = {
- filters: Filter[];
+ filters: MockFilter[];
id?: string;
};
diff --git a/src/plugins/embeddable/public/lib/test_samples/embeddables/filterable_embeddable.tsx b/src/plugins/embeddable/public/lib/test_samples/embeddables/filterable_embeddable.tsx
index fd6ea3b9aa2b2..99d21198dd151 100644
--- a/src/plugins/embeddable/public/lib/test_samples/embeddables/filterable_embeddable.tsx
+++ b/src/plugins/embeddable/public/lib/test_samples/embeddables/filterable_embeddable.tsx
@@ -19,12 +19,18 @@
import { IContainer } from '../../containers';
import { EmbeddableOutput, EmbeddableInput, Embeddable } from '../../embeddables';
-import { Filter } from '../../../../../data/public';
+
+/** @internal */
+export interface MockFilter {
+ $state?: any;
+ meta: any;
+ query?: any;
+}
export const FILTERABLE_EMBEDDABLE = 'FILTERABLE_EMBEDDABLE';
export interface FilterableEmbeddableInput extends EmbeddableInput {
- filters: Filter[];
+ filters: MockFilter[];
}
export class FilterableEmbeddable extends Embeddable {
diff --git a/src/plugins/embeddable/public/lib/triggers/triggers.ts b/src/plugins/embeddable/public/lib/triggers/triggers.ts
index c3b1496b8eca8..d9fb063a5bb56 100644
--- a/src/plugins/embeddable/public/lib/triggers/triggers.ts
+++ b/src/plugins/embeddable/public/lib/triggers/triggers.ts
@@ -22,8 +22,8 @@ import { Datatable } from '../../../../expressions';
import { Trigger, RowClickContext } from '../../../../ui_actions/public';
import { IEmbeddable } from '..';
-export interface EmbeddableContext {
- embeddable: IEmbeddable;
+export interface EmbeddableContext {
+ embeddable: T;
}
export interface ValueClickContext {
@@ -88,6 +88,28 @@ export const panelNotificationTrigger: Trigger<'PANEL_NOTIFICATION_TRIGGER'> = {
}),
};
+export const SELECT_RANGE_TRIGGER = 'SELECT_RANGE_TRIGGER';
+export const selectRangeTrigger: Trigger<'SELECT_RANGE_TRIGGER'> = {
+ id: SELECT_RANGE_TRIGGER,
+ title: i18n.translate('embeddableApi.selectRangeTrigger.title', {
+ defaultMessage: 'Range selection',
+ }),
+ description: i18n.translate('embeddableApi.selectRangeTrigger.description', {
+ defaultMessage: 'A range of values on the visualization',
+ }),
+};
+
+export const VALUE_CLICK_TRIGGER = 'VALUE_CLICK_TRIGGER';
+export const valueClickTrigger: Trigger<'VALUE_CLICK_TRIGGER'> = {
+ id: VALUE_CLICK_TRIGGER,
+ title: i18n.translate('embeddableApi.valueClickTrigger.title', {
+ defaultMessage: 'Single click',
+ }),
+ description: i18n.translate('embeddableApi.valueClickTrigger.description', {
+ defaultMessage: 'A data point click on the visualization',
+ }),
+};
+
export const isValueClickTriggerContext = (
context: ChartActionContext
): context is ValueClickContext => context.data && 'data' in context.data;
diff --git a/src/plugins/embeddable/public/mocks.tsx b/src/plugins/embeddable/public/mocks.tsx
index df24d9c0393fe..c41ecaabe8479 100644
--- a/src/plugins/embeddable/public/mocks.tsx
+++ b/src/plugins/embeddable/public/mocks.tsx
@@ -34,7 +34,6 @@ import { coreMock } from '../../../core/public/mocks';
import { UiActionsService } from './lib/ui_actions';
import { CoreStart } from '../../../core/public';
import { Start as InspectorStart } from '../../inspector/public';
-import { dataPluginMock } from '../../data/public/mocks';
import { inspectorPluginMock } from '../../inspector/public/mocks';
import { uiActionsPluginMock } from '../../ui_actions/public/mocks';
@@ -136,13 +135,11 @@ const createInstance = (setupPlugins: Partial = {})
const plugin = new EmbeddablePublicPlugin({} as any);
const setup = plugin.setup(coreMock.createSetup(), {
uiActions: setupPlugins.uiActions || uiActionsPluginMock.createSetupContract(),
- data: dataPluginMock.createSetupContract(),
});
const doStart = (startPlugins: Partial = {}) =>
plugin.start(coreMock.createStart(), {
uiActions: startPlugins.uiActions || uiActionsPluginMock.createStartContract(),
inspector: inspectorPluginMock.createStartContract(),
- data: dataPluginMock.createStartContract(),
});
return {
plugin,
diff --git a/src/plugins/embeddable/public/plugin.tsx b/src/plugins/embeddable/public/plugin.tsx
index 5118a1a8818c0..a417fb3938b8a 100644
--- a/src/plugins/embeddable/public/plugin.tsx
+++ b/src/plugins/embeddable/public/plugin.tsx
@@ -19,7 +19,6 @@
import React from 'react';
import { Subscription } from 'rxjs';
import { identity } from 'lodash';
-import { DataPublicPluginSetup, DataPublicPluginStart } from '../../data/public';
import { getSavedObjectFinder, showSaveModal } from '../../saved_objects/public';
import { UiActionsSetup, UiActionsStart } from '../../ui_actions/public';
import { Start as InspectorStart } from '../../inspector/public';
@@ -62,12 +61,10 @@ import {
} from '../common/lib';
export interface EmbeddableSetupDependencies {
- data: DataPublicPluginSetup;
uiActions: UiActionsSetup;
}
export interface EmbeddableStartDependencies {
- data: DataPublicPluginStart;
uiActions: UiActionsStart;
inspector: InspectorStart;
}
@@ -144,7 +141,7 @@ export class EmbeddablePublicPlugin implements Plugin {
this.embeddableFactories.set(
@@ -161,6 +158,7 @@ export class EmbeddablePublicPlugin implements Plugin
storage
- ? new EmbeddableStateTransfer(core.application.navigateToApp, this.appList, storage)
+ ? new EmbeddableStateTransfer(
+ core.application.navigateToApp,
+ core.application.currentAppId$,
+ this.appList,
+ storage
+ )
: this.stateTransferService,
EmbeddablePanel: getEmbeddablePanelHoc(),
telemetry: getTelemetryFunction(commonContract),
diff --git a/src/plugins/embeddable/public/public.api.md b/src/plugins/embeddable/public/public.api.md
index 03818fccda0bc..a401795c498b3 100644
--- a/src/plugins/embeddable/public/public.api.md
+++ b/src/plugins/embeddable/public/public.api.md
@@ -8,48 +8,29 @@ import { Action } from 'history';
import { Action as Action_3 } from 'src/plugins/ui_actions/public';
import { ActionExecutionContext as ActionExecutionContext_2 } from 'src/plugins/ui_actions/public';
import { ApiResponse } from '@elastic/elasticsearch/lib/Transport';
-import { ApiResponse as ApiResponse_2 } from '@elastic/elasticsearch';
import { ApplicationStart as ApplicationStart_2 } from 'kibana/public';
-import { Assign } from '@kbn/utility-types';
-import { BehaviorSubject } from 'rxjs';
-import { BfetchPublicSetup } from 'src/plugins/bfetch/public';
import Boom from '@hapi/boom';
import { ConfigDeprecationProvider } from '@kbn/config';
-import { CoreSetup as CoreSetup_2 } from 'src/core/public';
-import { CoreSetup as CoreSetup_3 } from 'kibana/public';
-import { CoreStart as CoreStart_2 } from 'kibana/public';
import * as CSS from 'csstype';
-import { DatatableColumn as DatatableColumn_2 } from 'src/plugins/expressions';
import { EmbeddableStart as EmbeddableStart_2 } from 'src/plugins/embeddable/public/plugin';
-import { Ensure } from '@kbn/utility-types';
import { EnvironmentMode } from '@kbn/config';
-import { ErrorToastOptions as ErrorToastOptions_2 } from 'src/core/public/notifications';
import { EuiBreadcrumb } from '@elastic/eui';
import { EuiButtonEmptyProps } from '@elastic/eui';
-import { EuiComboBoxProps } from '@elastic/eui';
import { EuiConfirmModalProps } from '@elastic/eui';
import { EuiContextMenuPanelDescriptor } from '@elastic/eui';
import { EuiFlyoutSize } from '@elastic/eui';
import { EuiGlobalToastListToast } from '@elastic/eui';
import { EventEmitter } from 'events';
-import { ExpressionAstExpression } from 'src/plugins/expressions/common';
import { History } from 'history';
import { Href } from 'history';
-import { HttpSetup as HttpSetup_2 } from 'kibana/public';
import { I18nStart as I18nStart_2 } from 'src/core/public';
import { IconType } from '@elastic/eui';
-import { ISearchOptions } from 'src/plugins/data/public';
-import { ISearchSource } from 'src/plugins/data/public';
-import { IStorageWrapper as IStorageWrapper_2 } from 'src/plugins/kibana_utils/public';
-import { IUiSettingsClient as IUiSettingsClient_2 } from 'src/core/public';
import { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import { Location } from 'history';
import { LocationDescriptorObject } from 'history';
import { Logger } from '@kbn/logging';
import { LogMeta } from '@kbn/logging';
import { MaybePromise } from '@kbn/utility-types';
-import { Moment } from 'moment';
-import { NameList } from 'elasticsearch';
import { NotificationsStart as NotificationsStart_2 } from 'src/core/public';
import { Observable } from 'rxjs';
import { Optional } from '@kbn/utility-types';
@@ -57,39 +38,23 @@ import { OverlayStart as OverlayStart_2 } from 'src/core/public';
import { PackageInfo } from '@kbn/config';
import { Path } from 'history';
import { PluginInitializerContext } from 'src/core/public';
-import { PluginInitializerContext as PluginInitializerContext_3 } from 'kibana/public';
import * as PropTypes from 'prop-types';
-import { PublicContract } from '@kbn/utility-types';
import { PublicMethodsOf } from '@kbn/utility-types';
import { PublicUiSettingsParams } from 'src/core/server/types';
import React from 'react';
import { RecursiveReadonly } from '@kbn/utility-types';
-import { RequestAdapter as RequestAdapter_2 } from 'src/plugins/inspector/common';
-import { Required } from '@kbn/utility-types';
import * as Rx from 'rxjs';
-import { SavedObject as SavedObject_2 } from 'kibana/server';
-import { SavedObject as SavedObject_3 } from 'src/core/server';
import { SavedObjectAttributes } from 'kibana/server';
import { SavedObjectAttributes as SavedObjectAttributes_2 } from 'src/core/public';
import { SavedObjectAttributes as SavedObjectAttributes_3 } from 'kibana/public';
-import { SavedObjectsClientContract as SavedObjectsClientContract_3 } from 'src/core/public';
-import { SavedObjectsFindOptions as SavedObjectsFindOptions_3 } from 'kibana/public';
-import { SavedObjectsFindResponse as SavedObjectsFindResponse_2 } from 'kibana/server';
-import { Search } from '@elastic/elasticsearch/api/requestParams';
-import { SearchResponse } from 'elasticsearch';
-import { SerializedFieldFormat as SerializedFieldFormat_2 } from 'src/plugins/expressions/common';
import { ShallowPromise } from '@kbn/utility-types';
import { SimpleSavedObject as SimpleSavedObject_2 } from 'src/core/public';
import { Start as Start_2 } from 'src/plugins/inspector/public';
-import { StartServicesAccessor as StartServicesAccessor_2 } from 'kibana/public';
-import { ToastInputFields as ToastInputFields_2 } from 'src/core/public/notifications';
-import { ToastsSetup as ToastsSetup_2 } from 'kibana/public';
import { TransportRequestOptions } from '@elastic/elasticsearch/lib/Transport';
import { TransportRequestParams } from '@elastic/elasticsearch/lib/Transport';
import { TransportRequestPromise } from '@elastic/elasticsearch/lib/Transport';
import { TypeOf } from '@kbn/config-schema';
import { UiComponent } from 'src/plugins/kibana_utils/public';
-import { UiCounterMetricType } from '@kbn/analytics';
import { UnregisterCallback } from 'history';
import { UserProvidedValues } from 'src/core/server/types';
@@ -348,7 +313,7 @@ export abstract class Embeddable {
+export class EmbeddableChildPanel extends React.Component {
constructor(props: EmbeddableChildPanelProps);
// (undocumented)
[panel: string]: any;
@@ -381,9 +346,9 @@ export interface EmbeddableChildPanelProps {
// Warning: (ae-missing-release-tag) "EmbeddableContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
-export interface EmbeddableContext {
+export interface EmbeddableContext {
// (undocumented)
- embeddable: IEmbeddable;
+ embeddable: T;
}
// @public
@@ -444,9 +409,6 @@ export type EmbeddableInput = {
enhancements?: SerializableState;
disabledActions?: string[];
disableTriggers?: boolean;
- timeRange?: TimeRange;
- query?: Query;
- filters?: Filter[];
searchSessionId?: string;
};
@@ -501,7 +463,7 @@ export interface EmbeddablePackageState {
// Warning: (ae-missing-release-tag) "EmbeddablePanel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
-export class EmbeddablePanel extends React.Component {
+export class EmbeddablePanel extends React.Component {
constructor(props: Props);
// (undocumented)
closeMyContextMenuPanel: () => void;
@@ -571,10 +533,6 @@ export interface EmbeddableSetup {
//
// @public (undocumented)
export interface EmbeddableSetupDependencies {
- // Warning: (ae-forgotten-export) The symbol "DataPublicPluginSetup" needs to be exported by the entry point index.d.ts
- //
- // (undocumented)
- data: DataPublicPluginSetup;
// Warning: (ae-forgotten-export) The symbol "UiActionsSetup" needs to be exported by the entry point index.d.ts
//
// (undocumented)
@@ -610,10 +568,6 @@ export interface EmbeddableStart extends PersistableStateService | undefined, customStorage?: Storage);
+ constructor(navigateToApp: ApplicationStart['navigateToApp'], currentAppId$: ApplicationStart['currentAppId$'], appList?: ReadonlyMap | undefined, customStorage?: Storage);
// (undocumented)
clearEditorState(): void;
getAppNameFromId: (appId: string) => string | undefined;
getIncomingEditorState(removeAfterFetch?: boolean): EmbeddableEditorState | undefined;
getIncomingEmbeddablePackage(removeAfterFetch?: boolean): EmbeddablePackageState | undefined;
+ // (undocumented)
+ isTransferInProgress: boolean;
// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ApplicationStart"
navigateToEditor(appId: string, options?: {
path?: string;
@@ -713,7 +669,7 @@ export interface IEmbeddable context is EmbeddableContext;
+export const isContextMenuTriggerContext: (context: unknown) => context is EmbeddableContext>;
// Warning: (ae-missing-release-tag) "isEmbeddable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
@@ -867,6 +823,16 @@ export interface SavedObjectEmbeddableInput extends EmbeddableInput {
savedObjectId: string;
}
+// Warning: (ae-missing-release-tag) "SELECT_RANGE_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export const SELECT_RANGE_TRIGGER = "SELECT_RANGE_TRIGGER";
+
+// Warning: (ae-missing-release-tag) "VALUE_CLICK_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export const VALUE_CLICK_TRIGGER = "VALUE_CLICK_TRIGGER";
+
// Warning: (ae-missing-release-tag) "ValueClickContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@@ -910,10 +876,7 @@ export const withEmbeddableSubscription: {
test('Explicit embeddable input mapped to undefined will default to inherited', async () => {
const { start } = await creatHelloWorldContainerAndEmbeddable();
- const derivedFilter: Filter = {
- $state: { store: esFilters.FilterStateStore.APP_STATE },
+ const derivedFilter: MockFilter = {
+ $state: { store: 'appState' },
meta: { disabled: false, alias: 'name', negate: false },
query: { match: {} },
};
diff --git a/src/plugins/embeddable/public/tests/explicit_input.test.ts b/src/plugins/embeddable/public/tests/explicit_input.test.ts
index 24785dd50a032..531fbcee94db6 100644
--- a/src/plugins/embeddable/public/tests/explicit_input.test.ts
+++ b/src/plugins/embeddable/public/tests/explicit_input.test.ts
@@ -20,6 +20,7 @@
import { skip } from 'rxjs/operators';
import { testPlugin } from './test_plugin';
import {
+ MockFilter,
FILTERABLE_EMBEDDABLE,
FilterableEmbeddableInput,
} from '../lib/test_samples/embeddables/filterable_embeddable';
@@ -34,7 +35,6 @@ import { FilterableContainer } from '../lib/test_samples/embeddables/filterable_
import { isErrorEmbeddable } from '../lib';
import { HelloWorldContainer } from '../lib/test_samples/embeddables/hello_world_container';
import { coreMock } from '../../../../core/public/mocks';
-import { esFilters, Filter } from '../../../../plugins/data/public';
import { createEmbeddablePanelMock } from '../mocks';
const { setup, doStart, coreStart, uiActions } = testPlugin(
@@ -56,8 +56,8 @@ setup.registerEmbeddableFactory(
const start = doStart();
test('Explicit embeddable input mapped to undefined will default to inherited', async () => {
- const derivedFilter: Filter = {
- $state: { store: esFilters.FilterStateStore.APP_STATE },
+ const derivedFilter: MockFilter = {
+ $state: { store: 'appState' },
meta: { disabled: false, alias: 'name', negate: false },
query: { match: {} },
};
diff --git a/src/plugins/embeddable/public/tests/test_plugin.ts b/src/plugins/embeddable/public/tests/test_plugin.ts
index 2c298b437a118..74bb70e913bcc 100644
--- a/src/plugins/embeddable/public/tests/test_plugin.ts
+++ b/src/plugins/embeddable/public/tests/test_plugin.ts
@@ -21,7 +21,6 @@ import { CoreSetup, CoreStart } from 'src/core/public';
import { UiActionsStart } from '../../../ui_actions/public';
import { uiActionsPluginMock } from '../../../ui_actions/public/mocks';
import { inspectorPluginMock } from '../../../inspector/public/mocks';
-import { dataPluginMock } from '../../../data/public/mocks';
import { coreMock } from '../../../../core/public/mocks';
import { EmbeddablePublicPlugin, EmbeddableSetup, EmbeddableStart } from '../plugin';
@@ -42,7 +41,6 @@ export const testPlugin = (
const initializerContext = {} as any;
const plugin = new EmbeddablePublicPlugin(initializerContext);
const setup = plugin.setup(coreSetup, {
- data: dataPluginMock.createSetupContract(),
uiActions: uiActions.setup,
});
@@ -53,7 +51,6 @@ export const testPlugin = (
setup,
doStart: (anotherCoreStart: CoreStart = coreStart) => {
const start = plugin.start(anotherCoreStart, {
- data: dataPluginMock.createStartContract(),
inspector: inspectorPluginMock.createStartContract(),
uiActions: uiActionsPluginMock.createStartContract(),
});
diff --git a/src/plugins/es_ui_shared/public/components/cron_editor/cron_editor.tsx b/src/plugins/es_ui_shared/public/components/cron_editor/cron_editor.tsx
index 72e2f51c37e4c..19af93b67aca0 100644
--- a/src/plugins/es_ui_shared/public/components/cron_editor/cron_editor.tsx
+++ b/src/plugins/es_ui_shared/public/components/cron_editor/cron_editor.tsx
@@ -67,6 +67,7 @@ interface Props {
fieldToPreferredValueMap: FieldToValueMap;
frequency: Frequency;
}) => void;
+ autoFocus?: boolean;
}
type State = FieldToValueMap;
@@ -234,6 +235,7 @@ export class CronEditor extends Component {
fullWidth
>
) =>
diff --git a/src/plugins/expressions/common/expression_renderers/types.ts b/src/plugins/expressions/common/expression_renderers/types.ts
index 88aca4c07ee31..fca1694747ce2 100644
--- a/src/plugins/expressions/common/expression_renderers/types.ts
+++ b/src/plugins/expressions/common/expression_renderers/types.ts
@@ -17,8 +17,6 @@
* under the License.
*/
-import { PersistedState } from 'src/plugins/visualizations/public';
-
export interface ExpressionRenderDefinition {
/**
* Technical name of the renderer, used as ID to identify renderer in
@@ -84,5 +82,10 @@ export interface IInterpreterRenderHandlers {
event: (event: any) => void;
hasCompatibleActions?: (event: any) => Promise;
getRenderMode: () => RenderMode;
- uiState?: PersistedState;
+ /**
+ * This uiState interface is actually `PersistedState` from the visualizations plugin,
+ * but expressions cannot know about vis or it creates a mess of circular dependencies.
+ * Downstream consumers of the uiState handler will need to cast for now.
+ */
+ uiState?: unknown;
}
diff --git a/src/plugins/expressions/public/public.api.md b/src/plugins/expressions/public/public.api.md
index bb1f5dd9270d5..404df2db019a1 100644
--- a/src/plugins/expressions/public/public.api.md
+++ b/src/plugins/expressions/public/public.api.md
@@ -12,7 +12,6 @@ import { EventEmitter } from 'events';
import { KibanaRequest } from 'src/core/server';
import { Observable } from 'rxjs';
import { PackageInfo } from '@kbn/config';
-import { PersistedState } from 'src/plugins/visualizations/public';
import { Plugin as Plugin_2 } from 'src/core/public';
import { PluginInitializerContext as PluginInitializerContext_2 } from 'src/core/public';
import React from 'react';
@@ -924,8 +923,7 @@ export interface IInterpreterRenderHandlers {
onDestroy: (fn: () => void) => void;
// (undocumented)
reload: () => void;
- // (undocumented)
- uiState?: PersistedState;
+ uiState?: unknown;
// (undocumented)
update: (params: any) => void;
}
diff --git a/src/plugins/expressions/public/react_expression_renderer.test.tsx b/src/plugins/expressions/public/react_expression_renderer.test.tsx
index e52d4d153882f..4ebd626e70fc3 100644
--- a/src/plugins/expressions/public/react_expression_renderer.test.tsx
+++ b/src/plugins/expressions/public/react_expression_renderer.test.tsx
@@ -146,6 +146,44 @@ describe('ExpressionRenderer', () => {
instance.unmount();
});
+ it('waits for debounce period on other loader option change if specified', () => {
+ jest.useFakeTimers();
+
+ const refreshSubject = new Subject();
+ const loaderUpdate = jest.fn();
+
+ (ExpressionLoader as jest.Mock).mockImplementation(() => {
+ return {
+ render$: new Subject(),
+ data$: new Subject(),
+ loading$: new Subject(),
+ update: loaderUpdate,
+ destroy: jest.fn(),
+ };
+ });
+
+ const instance = mount(
+
+ );
+
+ instance.setProps({ searchContext: { from: 'now-30m', to: 'now' } });
+
+ expect(loaderUpdate).toHaveBeenCalledTimes(1);
+
+ act(() => {
+ jest.runAllTimers();
+ });
+
+ expect(loaderUpdate).toHaveBeenCalledTimes(2);
+
+ instance.unmount();
+ });
+
it('should display a custom error message if the user provides one and then remove it after successful render', () => {
const dataSubject = new Subject();
const data$ = dataSubject.asObservable().pipe(share());
diff --git a/src/plugins/expressions/public/react_expression_renderer.tsx b/src/plugins/expressions/public/react_expression_renderer.tsx
index 894325c8b65f7..eac2371ec66d0 100644
--- a/src/plugins/expressions/public/react_expression_renderer.tsx
+++ b/src/plugins/expressions/public/react_expression_renderer.tsx
@@ -90,21 +90,23 @@ export const ReactExpressionRenderer = ({
null
);
const [debouncedExpression, setDebouncedExpression] = useState(expression);
- useEffect(() => {
+ const [waitingForDebounceToComplete, setDebouncePending] = useState(false);
+ useShallowCompareEffect(() => {
if (debounce === undefined) {
return;
}
+ setDebouncePending(true);
const handler = setTimeout(() => {
setDebouncedExpression(expression);
+ setDebouncePending(false);
}, debounce);
return () => {
clearTimeout(handler);
};
- }, [expression, debounce]);
+ }, [expression, expressionLoaderOptions, debounce]);
const activeExpression = debounce !== undefined ? debouncedExpression : expression;
- const waitingForDebounceToComplete = debounce !== undefined && expression !== debouncedExpression;
/* eslint-disable react-hooks/exhaustive-deps */
// OK to ignore react-hooks/exhaustive-deps because options update is handled by calling .update()
@@ -182,12 +184,16 @@ export const ReactExpressionRenderer = ({
// Re-fetch data automatically when the inputs change
useShallowCompareEffect(
() => {
- if (expressionLoaderRef.current) {
+ // only update the loader if the debounce period is over
+ if (expressionLoaderRef.current && !waitingForDebounceToComplete) {
expressionLoaderRef.current.update(activeExpression, expressionLoaderOptions);
}
},
- // when expression is changed by reference and when any other loaderOption is changed by reference
- [{ activeExpression, ...expressionLoaderOptions }]
+ // when debounced, wait for debounce status to change to update loader.
+ // Otherwise, update when expression is changed by reference and when any other loaderOption is changed by reference
+ debounce === undefined
+ ? [{ activeExpression, ...expressionLoaderOptions }]
+ : [{ waitingForDebounceToComplete }]
);
/* eslint-enable react-hooks/exhaustive-deps */
diff --git a/src/plugins/expressions/server/server.api.md b/src/plugins/expressions/server/server.api.md
index 7c1ab11f75027..8b8678371dd83 100644
--- a/src/plugins/expressions/server/server.api.md
+++ b/src/plugins/expressions/server/server.api.md
@@ -10,7 +10,6 @@ import { Ensure } from '@kbn/utility-types';
import { EventEmitter } from 'events';
import { KibanaRequest } from 'src/core/server';
import { Observable } from 'rxjs';
-import { PersistedState } from 'src/plugins/visualizations/public';
import { Plugin as Plugin_2 } from 'src/core/server';
import { PluginInitializerContext } from 'src/core/server';
import { UnwrapPromiseOrReturn } from '@kbn/utility-types';
@@ -741,8 +740,7 @@ export interface IInterpreterRenderHandlers {
onDestroy: (fn: () => void) => void;
// (undocumented)
reload: () => void;
- // (undocumented)
- uiState?: PersistedState;
+ uiState?: unknown;
// (undocumented)
update: (params: any) => void;
}
diff --git a/src/plugins/kibana_usage_collection/server/collectors/kibana/get_saved_object_counts.test.ts b/src/plugins/kibana_usage_collection/server/collectors/kibana/get_saved_object_counts.test.ts
index a7681e1766427..64f1088dc3392 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/kibana/get_saved_object_counts.test.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/kibana/get_saved_object_counts.test.ts
@@ -16,14 +16,25 @@
* specific language governing permissions and limitations
* under the License.
*/
-
+import { elasticsearchServiceMock } from '../../../../../../src/core/server/mocks';
import { getSavedObjectsCounts } from './get_saved_object_counts';
+export function mockGetSavedObjectsCounts(params: any) {
+ const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser;
+ esClient.search.mockResolvedValue(
+ // @ts-ignore we only care about the response body
+ {
+ body: { ...params },
+ }
+ );
+ return esClient;
+}
+
describe('getSavedObjectsCounts', () => {
test('Get all the saved objects equal to 0 because no results were found', async () => {
- const callCluster = jest.fn(() => ({}));
+ const esClient = mockGetSavedObjectsCounts({});
- const results = await getSavedObjectsCounts(callCluster as any, '.kibana');
+ const results = await getSavedObjectsCounts(esClient, '.kibana');
expect(results).toStrictEqual({
dashboard: { total: 0 },
visualization: { total: 0 },
@@ -35,7 +46,7 @@ describe('getSavedObjectsCounts', () => {
});
test('Merge the zeros with the results', async () => {
- const callCluster = jest.fn(() => ({
+ const esClient = mockGetSavedObjectsCounts({
aggregations: {
types: {
buckets: [
@@ -46,9 +57,9 @@ describe('getSavedObjectsCounts', () => {
],
},
},
- }));
+ });
- const results = await getSavedObjectsCounts(callCluster as any, '.kibana');
+ const results = await getSavedObjectsCounts(esClient, '.kibana');
expect(results).toStrictEqual({
dashboard: { total: 1 },
visualization: { total: 0 },
diff --git a/src/plugins/kibana_usage_collection/server/collectors/kibana/get_saved_object_counts.ts b/src/plugins/kibana_usage_collection/server/collectors/kibana/get_saved_object_counts.ts
index e88d90fe5b24b..65cc3643a88cb 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/kibana/get_saved_object_counts.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/kibana/get_saved_object_counts.ts
@@ -27,7 +27,7 @@
*/
import { snakeCase } from 'lodash';
-import { LegacyAPICaller } from 'kibana/server';
+import { ElasticsearchClient } from 'src/core/server';
const TYPES = [
'dashboard',
@@ -48,7 +48,7 @@ export interface KibanaSavedObjectCounts {
}
export async function getSavedObjectsCounts(
- callCluster: LegacyAPICaller,
+ esClient: ElasticsearchClient,
kibanaIndex: string // Typically '.kibana'. We might need a way to obtain it from the SavedObjects client (or the SavedObjects client to provide a way to run aggregations?)
): Promise {
const savedObjectCountSearchParams = {
@@ -67,9 +67,9 @@ export async function getSavedObjectsCounts(
},
},
};
- const resp = await callCluster('search', savedObjectCountSearchParams);
+ const { body } = await esClient.search(savedObjectCountSearchParams);
const buckets: Array<{ key: string; doc_count: number }> =
- resp.aggregations?.types?.buckets || [];
+ body.aggregations?.types?.buckets || [];
// Initialise the object with all zeros for all the types
const allZeros: KibanaSavedObjectCounts = TYPES.reduce(
diff --git a/src/plugins/kibana_usage_collection/server/collectors/kibana/index.test.ts b/src/plugins/kibana_usage_collection/server/collectors/kibana/index.test.ts
index 83cac1d456a3a..dee9ca4d32c5f 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/kibana/index.test.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/kibana/index.test.ts
@@ -20,12 +20,13 @@
import {
loggingSystemMock,
pluginInitializerContextConfigMock,
+ elasticsearchServiceMock,
} from '../../../../../core/server/mocks';
import {
Collector,
+ createCollectorFetchContextMock,
createUsageCollectionSetupMock,
} from '../../../../usage_collection/server/usage_collection.mock';
-import { createCollectorFetchContextMock } from '../../../../usage_collection/server/mocks';
import { registerKibanaUsageCollector } from './';
const logger = loggingSystemMock.createLogger();
@@ -43,7 +44,9 @@ describe('telemetry_kibana', () => {
const getMockFetchClients = (hits?: unknown[]) => {
const fetchParamsMock = createCollectorFetchContextMock();
- fetchParamsMock.callCluster.mockResolvedValue({ hits: { hits } });
+ const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser;
+ esClient.search.mockResolvedValue({ body: { hits: { hits } } } as any);
+ fetchParamsMock.esClient = esClient;
return fetchParamsMock;
};
diff --git a/src/plugins/kibana_usage_collection/server/collectors/kibana/kibana_usage_collector.ts b/src/plugins/kibana_usage_collection/server/collectors/kibana/kibana_usage_collector.ts
index 6c2e0a2c926ad..5dd39d172e1c2 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/kibana/kibana_usage_collector.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/kibana/kibana_usage_collector.ts
@@ -43,13 +43,13 @@ export function getKibanaUsageCollector(
graph_workspace: { total: { type: 'long' } },
timelion_sheet: { total: { type: 'long' } },
},
- async fetch({ callCluster }) {
+ async fetch({ esClient }) {
const {
kibana: { index },
} = await legacyConfig$.pipe(take(1)).toPromise();
return {
index,
- ...(await getSavedObjectsCounts(callCluster, index)),
+ ...(await getSavedObjectsCounts(esClient, index)),
};
},
});
diff --git a/src/plugins/telemetry/common/constants.ts b/src/plugins/telemetry/common/constants.ts
index fc77332c18fc9..2fa8b32f68291 100644
--- a/src/plugins/telemetry/common/constants.ts
+++ b/src/plugins/telemetry/common/constants.ts
@@ -49,7 +49,7 @@ export const LOCALSTORAGE_KEY = 'telemetry.data';
/**
* Link to Advanced Settings.
*/
-export const PATH_TO_ADVANCED_SETTINGS = 'management/kibana/settings';
+export const PATH_TO_ADVANCED_SETTINGS = '/app/management/kibana/settings';
/**
* Link to the Elastic Telemetry privacy statement.
diff --git a/src/plugins/telemetry/public/components/__snapshots__/opted_in_notice_banner.test.tsx.snap b/src/plugins/telemetry/public/components/__snapshots__/opted_in_notice_banner.test.tsx.snap
index 62998da73d6f9..897e3b2761c74 100644
--- a/src/plugins/telemetry/public/components/__snapshots__/opted_in_notice_banner.test.tsx.snap
+++ b/src/plugins/telemetry/public/components/__snapshots__/opted_in_notice_banner.test.tsx.snap
@@ -10,7 +10,7 @@ exports[`OptInDetailsComponent renders as expected 1`] = `
values={
Object {
"disableLink":
{
it('renders as expected', () => {
- expect(shallowWithIntl( {}} />)).toMatchSnapshot();
+ expect(
+ shallowWithIntl( {}} http={mockHttp} />)
+ ).toMatchSnapshot();
});
it('fires the "onSeenBanner" prop when a link is clicked', () => {
const onLinkClick = jest.fn();
- const component = shallowWithIntl();
+ const component = shallowWithIntl(
+
+ );
const button = component.findWhere((n) => n.type() === EuiButton);
diff --git a/src/plugins/telemetry/public/components/opted_in_notice_banner.tsx b/src/plugins/telemetry/public/components/opted_in_notice_banner.tsx
index 090893964c881..46ae17171203c 100644
--- a/src/plugins/telemetry/public/components/opted_in_notice_banner.tsx
+++ b/src/plugins/telemetry/public/components/opted_in_notice_banner.tsx
@@ -24,14 +24,18 @@ import { EuiButton, EuiLink, EuiCallOut, EuiSpacer } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import { PATH_TO_ADVANCED_SETTINGS, PRIVACY_STATEMENT_URL } from '../../common/constants';
+import { HttpSetup } from '../../../../core/public';
interface Props {
+ http: HttpSetup;
onSeenBanner: () => any;
}
export class OptedInNoticeBanner extends React.PureComponent {
render() {
- const { onSeenBanner } = this.props;
+ const { onSeenBanner, http } = this.props;
+ const basePath = http.basePath.get();
+
const bannerTitle = i18n.translate('telemetry.telemetryOptedInNoticeTitle', {
defaultMessage: 'Help us improve the Elastic Stack',
});
@@ -56,7 +60,7 @@ export class OptedInNoticeBanner extends React.PureComponent {
),
disableLink: (
-
+
{
it('adds a banner to banners with priority of 10000', () => {
const bannerID = 'brucer-wayne';
const overlays = overlayServiceMock.createStartContract();
+ const mockHttp = httpServiceMock.createStartContract();
overlays.banners.add.mockReturnValue(bannerID);
const returnedBannerId = renderOptedInNoticeBanner({
+ http: mockHttp,
onSeen: jest.fn(),
overlays,
});
diff --git a/src/plugins/telemetry/public/services/telemetry_notifications/render_opted_in_notice_banner.tsx b/src/plugins/telemetry/public/services/telemetry_notifications/render_opted_in_notice_banner.tsx
index e63e46af6e8ca..e1feea4b6cbe1 100644
--- a/src/plugins/telemetry/public/services/telemetry_notifications/render_opted_in_notice_banner.tsx
+++ b/src/plugins/telemetry/public/services/telemetry_notifications/render_opted_in_notice_banner.tsx
@@ -23,11 +23,12 @@ import { OptedInNoticeBanner } from '../../components/opted_in_notice_banner';
import { toMountPoint } from '../../../../kibana_react/public';
interface RenderBannerConfig {
+ http: CoreStart['http'];
overlays: CoreStart['overlays'];
onSeen: () => void;
}
-export function renderOptedInNoticeBanner({ onSeen, overlays }: RenderBannerConfig) {
- const mount = toMountPoint();
+export function renderOptedInNoticeBanner({ onSeen, overlays, http }: RenderBannerConfig) {
+ const mount = toMountPoint();
const bannerId = overlays.banners.add(mount, 10000);
return bannerId;
diff --git a/src/plugins/telemetry/public/services/telemetry_notifications/telemetry_notifications.ts b/src/plugins/telemetry/public/services/telemetry_notifications/telemetry_notifications.ts
index fc44a4db7cf5e..6ebbfcfb91336 100644
--- a/src/plugins/telemetry/public/services/telemetry_notifications/telemetry_notifications.ts
+++ b/src/plugins/telemetry/public/services/telemetry_notifications/telemetry_notifications.ts
@@ -23,18 +23,21 @@ import { renderOptInBanner } from './render_opt_in_banner';
import { TelemetryService } from '../telemetry_service';
interface TelemetryNotificationsConstructor {
+ http: CoreStart['http'];
overlays: CoreStart['overlays'];
telemetryService: TelemetryService;
}
export class TelemetryNotifications {
+ private readonly http: CoreStart['http'];
private readonly overlays: CoreStart['overlays'];
private readonly telemetryService: TelemetryService;
private optedInNoticeBannerId?: string;
private optInBannerId?: string;
- constructor({ overlays, telemetryService }: TelemetryNotificationsConstructor) {
+ constructor({ http, overlays, telemetryService }: TelemetryNotificationsConstructor) {
this.telemetryService = telemetryService;
+ this.http = http;
this.overlays = overlays;
}
@@ -46,6 +49,7 @@ export class TelemetryNotifications {
public renderOptedInNoticeBanner = (): void => {
const bannerId = renderOptedInNoticeBanner({
+ http: this.http,
onSeen: this.setOptedInNoticeSeen,
overlays: this.overlays,
});
diff --git a/src/plugins/ui_actions/public/index.ts b/src/plugins/ui_actions/public/index.ts
index d223c0abcccb7..7890e4bab44a3 100644
--- a/src/plugins/ui_actions/public/index.ts
+++ b/src/plugins/ui_actions/public/index.ts
@@ -40,12 +40,6 @@ export {
export {
Trigger,
TriggerContext,
- SELECT_RANGE_TRIGGER,
- selectRangeTrigger,
- VALUE_CLICK_TRIGGER,
- valueClickTrigger,
- APPLY_FILTER_TRIGGER,
- applyFilterTrigger,
VISUALIZE_FIELD_TRIGGER,
visualizeFieldTrigger,
VISUALIZE_GEO_FIELD_TRIGGER,
diff --git a/src/plugins/ui_actions/public/plugin.ts b/src/plugins/ui_actions/public/plugin.ts
index fdb75e9a426e9..84a7ae45fc7b8 100644
--- a/src/plugins/ui_actions/public/plugin.ts
+++ b/src/plugins/ui_actions/public/plugin.ts
@@ -20,14 +20,7 @@
import { CoreStart, CoreSetup, Plugin, PluginInitializerContext } from 'src/core/public';
import { PublicMethodsOf } from '@kbn/utility-types';
import { UiActionsService } from './service';
-import {
- selectRangeTrigger,
- valueClickTrigger,
- rowClickTrigger,
- applyFilterTrigger,
- visualizeFieldTrigger,
- visualizeGeoFieldTrigger,
-} from './triggers';
+import { rowClickTrigger, visualizeFieldTrigger, visualizeGeoFieldTrigger } from './triggers';
export type UiActionsSetup = Pick<
UiActionsService,
@@ -47,10 +40,7 @@ export class UiActionsPlugin implements Plugin {
constructor(initializerContext: PluginInitializerContext) {}
public setup(core: CoreSetup): UiActionsSetup {
- this.service.registerTrigger(selectRangeTrigger);
- this.service.registerTrigger(valueClickTrigger);
this.service.registerTrigger(rowClickTrigger);
- this.service.registerTrigger(applyFilterTrigger);
this.service.registerTrigger(visualizeFieldTrigger);
this.service.registerTrigger(visualizeGeoFieldTrigger);
return this.service;
diff --git a/src/plugins/ui_actions/public/public.api.md b/src/plugins/ui_actions/public/public.api.md
index 2384dfab13c8c..808cb1f3fbca0 100644
--- a/src/plugins/ui_actions/public/public.api.md
+++ b/src/plugins/ui_actions/public/public.api.md
@@ -8,14 +8,11 @@ import { CoreSetup } from 'src/core/public';
import { CoreStart } from 'src/core/public';
import { EnvironmentMode } from '@kbn/config';
import { EuiContextMenuPanelDescriptor } from '@elastic/eui';
-import { EventEmitter } from 'events';
-import { Observable } from 'rxjs';
import { PackageInfo } from '@kbn/config';
import { Plugin } from 'src/core/public';
import { PluginInitializerContext as PluginInitializerContext_2 } from 'src/core/public';
import { PublicMethodsOf } from '@kbn/utility-types';
import React from 'react';
-import * as Rx from 'rxjs';
import { UiComponent } from 'src/plugins/kibana_utils/public';
// Warning: (ae-forgotten-export) The symbol "BaseContext" needs to be exported by the entry point index.d.ts
@@ -95,16 +92,6 @@ export interface ActionExecutionMeta {
// @public (undocumented)
export type ActionType = keyof ActionContextMapping;
-// Warning: (ae-missing-release-tag) "APPLY_FILTER_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
-export const APPLY_FILTER_TRIGGER = "FILTER_TRIGGER";
-
-// Warning: (ae-missing-release-tag) "applyFilterTrigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
-export const applyFilterTrigger: Trigger<'FILTER_TRIGGER'>;
-
// Warning: (ae-forgotten-export) The symbol "BuildContextMenuParams" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "buildContextMenuForActions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
@@ -148,10 +135,8 @@ export interface RowClickContext {
table: Datatable;
columns?: string[];
};
- // Warning: (ae-forgotten-export) The symbol "IEmbeddable" needs to be exported by the entry point index.d.ts
- //
// (undocumented)
- embeddable?: IEmbeddable;
+ embeddable?: unknown;
}
// Warning: (ae-missing-release-tag) "rowClickTrigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
@@ -159,16 +144,6 @@ export interface RowClickContext {
// @public (undocumented)
export const rowClickTrigger: Trigger<'ROW_CLICK_TRIGGER'>;
-// Warning: (ae-missing-release-tag) "SELECT_RANGE_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
-export const SELECT_RANGE_TRIGGER = "SELECT_RANGE_TRIGGER";
-
-// Warning: (ae-missing-release-tag) "selectRangeTrigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
-export const selectRangeTrigger: Trigger<'SELECT_RANGE_TRIGGER'>;
-
// Warning: (ae-missing-release-tag) "Trigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
@@ -192,20 +167,8 @@ export interface TriggerContextMapping {
//
// (undocumented)
[DEFAULT_TRIGGER]: TriggerContext_2;
- // Warning: (ae-forgotten-export) The symbol "ApplyGlobalFilterActionContext" needs to be exported by the entry point index.d.ts
- //
- // (undocumented)
- [APPLY_FILTER_TRIGGER]: ApplyGlobalFilterActionContext;
// (undocumented)
[ROW_CLICK_TRIGGER]: RowClickContext;
- // Warning: (ae-forgotten-export) The symbol "RangeSelectContext" needs to be exported by the entry point index.d.ts
- //
- // (undocumented)
- [SELECT_RANGE_TRIGGER]: RangeSelectContext;
- // Warning: (ae-forgotten-export) The symbol "ValueClickContext" needs to be exported by the entry point index.d.ts
- //
- // (undocumented)
- [VALUE_CLICK_TRIGGER]: ValueClickContext;
// (undocumented)
[VISUALIZE_FIELD_TRIGGER]: VisualizeFieldContext;
// (undocumented)
@@ -262,35 +225,35 @@ export class UiActionsService {
//
// (undocumented)
protected readonly actions: ActionRegistry;
- readonly addTriggerAction: (triggerId: T, action: UiActionsActionDefinition | Action) => void;
+ readonly addTriggerAction: (triggerId: T, action: UiActionsActionDefinition | Action) => void;
// (undocumented)
- readonly attachAction: (triggerId: T, actionId: string) => void;
+ readonly attachAction: (triggerId: T, actionId: string) => void;
readonly clear: () => void;
// (undocumented)
readonly detachAction: (triggerId: TriggerId, actionId: string) => void;
// @deprecated (undocumented)
- readonly executeTriggerActions: (triggerId: T, context: TriggerContext) => Promise;
+ readonly executeTriggerActions: (triggerId: T, context: TriggerContext) => Promise;
// Warning: (ae-forgotten-export) The symbol "UiActionsExecutionService" needs to be exported by the entry point index.d.ts
//
// (undocumented)
readonly executionService: UiActionsExecutionService;
readonly fork: () => UiActionsService;
// (undocumented)
- readonly getAction: >(id: string) => Action, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_EXPORT_CSV">;
+ readonly getAction: >(id: string) => Action, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel">;
// Warning: (ae-forgotten-export) The symbol "TriggerContract" needs to be exported by the entry point index.d.ts
//
// (undocumented)
- readonly getTrigger: (triggerId: T) => TriggerContract;
+ readonly getTrigger: (triggerId: T) => TriggerContract;
// (undocumented)
- readonly getTriggerActions: (triggerId: T) => Action[];
+ readonly getTriggerActions: (triggerId: T) => Action[];
// (undocumented)
- readonly getTriggerCompatibleActions: (triggerId: T, context: TriggerContextMapping[T]) => Promise[]>;
+ readonly getTriggerCompatibleActions: (triggerId: T, context: TriggerContextMapping[T]) => Promise[]>;
// (undocumented)
readonly hasAction: (actionId: string) => boolean;
// Warning: (ae-forgotten-export) The symbol "ActionContext" needs to be exported by the entry point index.d.ts
//
// (undocumented)
- readonly registerAction: >(definition: A) => Action, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_EXPORT_CSV">;
+ readonly registerAction: >(definition: A) => Action, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_VISUALIZE_LENS_FIELD" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel">;
// (undocumented)
readonly registerTrigger: (trigger: Trigger) => void;
// Warning: (ae-forgotten-export) The symbol "TriggerRegistry" needs to be exported by the entry point index.d.ts
@@ -326,16 +289,6 @@ export type UiActionsSetup = Pick;
-// Warning: (ae-missing-release-tag) "VALUE_CLICK_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
-export const VALUE_CLICK_TRIGGER = "VALUE_CLICK_TRIGGER";
-
-// Warning: (ae-missing-release-tag) "valueClickTrigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
-export const valueClickTrigger: Trigger<'VALUE_CLICK_TRIGGER'>;
-
// Warning: (ae-missing-release-tag) "VISUALIZE_FIELD_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@@ -371,7 +324,7 @@ export const visualizeGeoFieldTrigger: Trigger<'VISUALIZE_GEO_FIELD_TRIGGER'>;
// Warnings were encountered during analysis:
//
-// src/plugins/ui_actions/public/triggers/row_click_trigger.ts:45:5 - (ae-forgotten-export) The symbol "Datatable" needs to be exported by the entry point index.d.ts
+// src/plugins/ui_actions/public/triggers/row_click_trigger.ts:46:5 - (ae-forgotten-export) The symbol "Datatable" needs to be exported by the entry point index.d.ts
// (No @packageDocumentation comment for this package)
diff --git a/src/plugins/ui_actions/public/triggers/index.ts b/src/plugins/ui_actions/public/triggers/index.ts
index ecbf4d1f7b988..6bba87e85eb95 100644
--- a/src/plugins/ui_actions/public/triggers/index.ts
+++ b/src/plugins/ui_actions/public/triggers/index.ts
@@ -20,10 +20,7 @@
export * from './trigger';
export * from './trigger_contract';
export * from './trigger_internal';
-export * from './select_range_trigger';
-export * from './value_click_trigger';
export * from './row_click_trigger';
-export * from './apply_filter_trigger';
export * from './visualize_field_trigger';
export * from './visualize_geo_field_trigger';
export * from './default_trigger';
diff --git a/src/plugins/ui_actions/public/triggers/row_click_trigger.ts b/src/plugins/ui_actions/public/triggers/row_click_trigger.ts
index 87bca03f8c3ba..0fc261b3e1fb3 100644
--- a/src/plugins/ui_actions/public/triggers/row_click_trigger.ts
+++ b/src/plugins/ui_actions/public/triggers/row_click_trigger.ts
@@ -18,7 +18,6 @@
*/
import { i18n } from '@kbn/i18n';
-import { IEmbeddable } from '../../../embeddable/public';
import { Trigger } from '.';
import { Datatable } from '../../../expressions';
@@ -35,7 +34,9 @@ export const rowClickTrigger: Trigger<'ROW_CLICK_TRIGGER'> = {
};
export interface RowClickContext {
- embeddable?: IEmbeddable;
+ // Need to make this unknown to prevent circular dependencies.
+ // Apps using this property will need to cast to `IEmbeddable`.
+ embeddable?: unknown;
data: {
/**
* Row index, starting from 0, where user clicked.
diff --git a/src/plugins/ui_actions/public/triggers/select_range_trigger.ts b/src/plugins/ui_actions/public/triggers/select_range_trigger.ts
deleted file mode 100644
index 312e75314bd92..0000000000000
--- a/src/plugins/ui_actions/public/triggers/select_range_trigger.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { i18n } from '@kbn/i18n';
-import { Trigger } from '.';
-
-export const SELECT_RANGE_TRIGGER = 'SELECT_RANGE_TRIGGER';
-export const selectRangeTrigger: Trigger<'SELECT_RANGE_TRIGGER'> = {
- id: SELECT_RANGE_TRIGGER,
- title: i18n.translate('uiActions.triggers.selectRangeTitle', {
- defaultMessage: 'Range selection',
- }),
- description: i18n.translate('uiActions.triggers.selectRangeDescription', {
- defaultMessage: 'A range of values on the visualization',
- }),
-};
diff --git a/src/plugins/ui_actions/public/triggers/trigger.ts b/src/plugins/ui_actions/public/triggers/trigger.ts
index 2c019b09881d1..1b1231c132dde 100644
--- a/src/plugins/ui_actions/public/triggers/trigger.ts
+++ b/src/plugins/ui_actions/public/triggers/trigger.ts
@@ -32,8 +32,7 @@ import { TriggerContextMapping, TriggerId } from '../types';
*/
export interface Trigger {
/**
- * Unique name of the trigger as identified in `ui_actions` plugin trigger
- * registry, such as "SELECT_RANGE_TRIGGER" or "VALUE_CLICK_TRIGGER".
+ * Unique name of the trigger as identified in `ui_actions` plugin trigger registry.
*/
id: ID;
diff --git a/src/plugins/ui_actions/public/triggers/trigger_contract.ts b/src/plugins/ui_actions/public/triggers/trigger_contract.ts
index 04a75cb3a53d0..7e7fba0ba80d3 100644
--- a/src/plugins/ui_actions/public/triggers/trigger_contract.ts
+++ b/src/plugins/ui_actions/public/triggers/trigger_contract.ts
@@ -25,8 +25,7 @@ import { TriggerId, TriggerContextMapping } from '../types';
*/
export class TriggerContract {
/**
- * Unique name of the trigger as identified in `ui_actions` plugin trigger
- * registry, such as "SELECT_RANGE_TRIGGER" or "VALUE_CLICK_TRIGGER".
+ * Unique name of the trigger as identified in `ui_actions` plugin trigger registry.
*/
public readonly id: T;
diff --git a/src/plugins/ui_actions/public/types.ts b/src/plugins/ui_actions/public/types.ts
index 0266a755be926..62fac245514cd 100644
--- a/src/plugins/ui_actions/public/types.ts
+++ b/src/plugins/ui_actions/public/types.ts
@@ -20,17 +20,12 @@
import { ActionInternal } from './actions/action_internal';
import { TriggerInternal } from './triggers/trigger_internal';
import {
- SELECT_RANGE_TRIGGER,
- VALUE_CLICK_TRIGGER,
ROW_CLICK_TRIGGER,
- APPLY_FILTER_TRIGGER,
VISUALIZE_FIELD_TRIGGER,
VISUALIZE_GEO_FIELD_TRIGGER,
DEFAULT_TRIGGER,
RowClickContext,
} from './triggers';
-import type { RangeSelectContext, ValueClickContext } from '../../embeddable/public';
-import type { ApplyGlobalFilterActionContext } from '../../data/public';
export type TriggerRegistry = Map>;
export type ActionRegistry = Map;
@@ -49,10 +44,7 @@ export type TriggerContext = BaseContext;
export interface TriggerContextMapping {
[DEFAULT_TRIGGER]: TriggerContext;
- [SELECT_RANGE_TRIGGER]: RangeSelectContext;
- [VALUE_CLICK_TRIGGER]: ValueClickContext;
[ROW_CLICK_TRIGGER]: RowClickContext;
- [APPLY_FILTER_TRIGGER]: ApplyGlobalFilterActionContext;
[VISUALIZE_FIELD_TRIGGER]: VisualizeFieldContext;
[VISUALIZE_GEO_FIELD_TRIGGER]: VisualizeFieldContext;
}
diff --git a/src/plugins/vis_type_table/public/components/table_visualization.tsx b/src/plugins/vis_type_table/public/components/table_visualization.tsx
index 2d38acc57519f..a1e4fad719dc4 100644
--- a/src/plugins/vis_type_table/public/components/table_visualization.tsx
+++ b/src/plugins/vis_type_table/public/components/table_visualization.tsx
@@ -23,6 +23,7 @@ import classNames from 'classnames';
import { CoreStart } from 'kibana/public';
import { IInterpreterRenderHandlers } from 'src/plugins/expressions';
+import type { PersistedState } from 'src/plugins/visualizations/public';
import { KibanaContextProvider } from '../../../kibana_react/public';
import { TableVisConfig } from '../types';
import { TableContext } from '../table_vis_response_handler';
@@ -47,7 +48,7 @@ const TableVisualizationComponent = ({
handlers.done();
}, [handlers]);
- const uiStateProps = useUiState(handlers.uiState);
+ const uiStateProps = useUiState(handlers.uiState as PersistedState);
const className = classNames('tbvChart', {
// eslint-disable-next-line @typescript-eslint/naming-convention
diff --git a/src/plugins/vis_type_table/public/utils/use/use_ui_state.ts b/src/plugins/vis_type_table/public/utils/use/use_ui_state.ts
index 68bad16972ec2..cc43fc6bcb582 100644
--- a/src/plugins/vis_type_table/public/utils/use/use_ui_state.ts
+++ b/src/plugins/vis_type_table/public/utils/use/use_ui_state.ts
@@ -19,7 +19,7 @@
import { debounce, isEqual } from 'lodash';
import { useCallback, useEffect, useRef, useState } from 'react';
-import { IInterpreterRenderHandlers } from 'src/plugins/expressions';
+import type { PersistedState } from 'src/plugins/visualizations/public';
import { ColumnWidthData, TableVisUiState, TableVisUseUiStateProps } from '../../types';
@@ -28,9 +28,7 @@ const defaultSort = {
direction: null,
};
-export const useUiState = (
- uiState: IInterpreterRenderHandlers['uiState']
-): TableVisUseUiStateProps => {
+export const useUiState = (uiState: PersistedState): TableVisUseUiStateProps => {
const [sort, setSortState] = useState(
uiState?.get('vis.params.sort') || defaultSort
);
diff --git a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx
index 67ed487d29378..dec169c59c6ef 100644
--- a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx
+++ b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx
@@ -21,6 +21,7 @@ import React, { lazy } from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { IUiSettingsClient } from 'kibana/public';
+import type { PersistedState } from '../../visualizations/public';
import { VisualizationContainer } from '../../visualizations/public';
import { ExpressionRenderDefinition } from '../../expressions/common/expression_renderers';
import { TimeseriesRenderValue, TimeseriesVisParams } from './metrics_fn';
@@ -63,7 +64,7 @@ export const getTimeseriesVisRenderer: (deps: {
handlers={handlers}
model={config.visParams}
visData={config.visData as TimeseriesVisData}
- uiState={handlers.uiState!}
+ uiState={handlers.uiState! as PersistedState}
/>
,
domNode
diff --git a/src/plugins/vis_type_timeseries/server/routes/fields.ts b/src/plugins/vis_type_timeseries/server/routes/fields.ts
index a9a890845d154..e787fd8d08a29 100644
--- a/src/plugins/vis_type_timeseries/server/routes/fields.ts
+++ b/src/plugins/vis_type_timeseries/server/routes/fields.ts
@@ -39,7 +39,7 @@ export const fieldsRoutes = (framework: Framework) => {
return res.customError({
body: err.output.payload,
statusCode: err.output.statusCode,
- headers: err.output.headers,
+ headers: err.output.headers as { [key: string]: string },
});
}
diff --git a/src/plugins/vis_type_vislib/public/plugin.ts b/src/plugins/vis_type_vislib/public/plugin.ts
index bef8ad26fb12c..36a184d3da507 100644
--- a/src/plugins/vis_type_vislib/public/plugin.ts
+++ b/src/plugins/vis_type_vislib/public/plugin.ts
@@ -24,7 +24,7 @@ import { VisualizationsSetup } from '../../visualizations/public';
import { ChartsPluginSetup } from '../../charts/public';
import { DataPublicPluginStart } from '../../data/public';
import { KibanaLegacyStart } from '../../kibana_legacy/public';
-import { CHARTS_LIBRARY } from '../../vis_type_xy/public';
+import { LEGACY_CHARTS_LIBRARY } from '../../vis_type_xy/public';
import { createVisTypeVislibVisFn } from './vis_type_vislib_vis_fn';
import { createPieVisFn } from './pie_fn';
@@ -61,7 +61,7 @@ export class VisTypeVislibPlugin
core: VisTypeVislibCoreSetup,
{ expressions, visualizations, charts }: VisTypeVislibPluginSetupDependencies
) {
- if (core.uiSettings.get(CHARTS_LIBRARY)) {
+ if (!core.uiSettings.get(LEGACY_CHARTS_LIBRARY, true)) {
// Register only non-replaced vis types
convertedTypeDefinitions.forEach(visualizations.createBaseVisualization);
visualizations.createBaseVisualization(pieVisTypeDefinition);
diff --git a/src/plugins/vis_type_vislib/public/vis_controller.tsx b/src/plugins/vis_type_vislib/public/vis_controller.tsx
index 1804d0d52ae7a..2a32d19874c22 100644
--- a/src/plugins/vis_type_vislib/public/vis_controller.tsx
+++ b/src/plugins/vis_type_vislib/public/vis_controller.tsx
@@ -22,7 +22,7 @@ import React, { RefObject } from 'react';
import { mountReactNode } from '../../../core/public/utils';
import { ChartsPluginSetup } from '../../charts/public';
-import { PersistedState } from '../../visualizations/public';
+import type { PersistedState } from '../../visualizations/public';
import { IInterpreterRenderHandlers } from '../../expressions/public';
import { VisTypeVislibCoreSetup } from './plugin';
@@ -115,7 +115,7 @@ export const createVislibVisController = (
})
.addClass((legendClassName as any)[visParams.legendPosition]);
- this.mountLegend(esResponse, visParams, fireEvent, uiState);
+ this.mountLegend(esResponse, visParams, fireEvent, uiState as PersistedState);
}
this.vislibVis.render(esResponse, uiState);
@@ -128,7 +128,7 @@ export const createVislibVisController = (
CUSTOM_LEGEND_VIS_TYPES.includes(this.vislibVis.visConfigArgs.type)
) {
this.unmountLegend?.();
- this.mountLegend(esResponse, visParams, fireEvent, uiState);
+ this.mountLegend(esResponse, visParams, fireEvent, uiState as PersistedState);
this.vislibVis.render(esResponse, uiState);
}
}
diff --git a/src/plugins/vis_type_vislib/public/vis_wrapper.tsx b/src/plugins/vis_type_vislib/public/vis_wrapper.tsx
index 280a957396c34..b8dbd0f945c32 100644
--- a/src/plugins/vis_type_vislib/public/vis_wrapper.tsx
+++ b/src/plugins/vis_type_vislib/public/vis_wrapper.tsx
@@ -22,6 +22,7 @@ import { EuiResizeObserver } from '@elastic/eui';
import { debounce } from 'lodash';
import { IInterpreterRenderHandlers } from '../../expressions/public';
+import type { PersistedState } from '../../visualizations/public';
import { ChartsPluginSetup } from '../../charts/public';
import { VislibRenderValue } from './vis_type_vislib_vis_fn';
@@ -66,10 +67,12 @@ const VislibWrapper = ({ core, charts, visData, visConfig, handlers }: VislibWra
useEffect(() => {
if (handlers.uiState) {
- handlers.uiState.on('change', updateChart);
+ const uiState = handlers.uiState as PersistedState;
+
+ uiState.on('change', updateChart);
return () => {
- handlers.uiState?.off('change', updateChart);
+ uiState?.off('change', updateChart);
};
}
}, [handlers.uiState, updateChart]);
diff --git a/src/plugins/vis_type_xy/common/index.ts b/src/plugins/vis_type_xy/common/index.ts
index bf498229a1b54..edee1ea3219db 100644
--- a/src/plugins/vis_type_xy/common/index.ts
+++ b/src/plugins/vis_type_xy/common/index.ts
@@ -34,4 +34,4 @@ export type ChartType = $Values;
*/
export type XyVisType = ChartType | 'horizontal_bar';
-export const CHARTS_LIBRARY = 'visualization:visualize:chartsLibrary';
+export const LEGACY_CHARTS_LIBRARY = 'visualization:visualize:legacyChartsLibrary';
diff --git a/src/plugins/vis_type_xy/public/components/split_chart_warning.tsx b/src/plugins/vis_type_xy/public/components/split_chart_warning.tsx
index a9aa2bf24601b..7265e70a791a3 100644
--- a/src/plugins/vis_type_xy/public/components/split_chart_warning.tsx
+++ b/src/plugins/vis_type_xy/public/components/split_chart_warning.tsx
@@ -38,13 +38,13 @@ export const SplitChartWarning: FC = () => {
>
),
diff --git a/src/plugins/vis_type_xy/public/plugin.ts b/src/plugins/vis_type_xy/public/plugin.ts
index c8812b07e5949..7425c5f7248ac 100644
--- a/src/plugins/vis_type_xy/public/plugin.ts
+++ b/src/plugins/vis_type_xy/public/plugin.ts
@@ -34,7 +34,7 @@ import {
setDocLinks,
} from './services';
import { visTypesDefinitions } from './vis_types';
-import { CHARTS_LIBRARY } from '../common';
+import { LEGACY_CHARTS_LIBRARY } from '../common';
import { xyVisRenderer } from './vis_renderer';
// eslint-disable-next-line @typescript-eslint/no-empty-interface
@@ -71,7 +71,7 @@ export class VisTypeXyPlugin
core: VisTypeXyCoreSetup,
{ expressions, visualizations, charts }: VisTypeXyPluginSetupDependencies
) {
- if (core.uiSettings.get(CHARTS_LIBRARY, false)) {
+ if (!core.uiSettings.get(LEGACY_CHARTS_LIBRARY, true)) {
setUISettings(core.uiSettings);
setThemeService(charts.theme);
setColorsService(charts.legacyColors);
diff --git a/src/plugins/vis_type_xy/public/vis_component.tsx b/src/plugins/vis_type_xy/public/vis_component.tsx
index d87500218975a..dcf9f69cc291d 100644
--- a/src/plugins/vis_type_xy/public/vis_component.tsx
+++ b/src/plugins/vis_type_xy/public/vis_component.tsx
@@ -50,6 +50,7 @@ import {
ClickTriggerEvent,
} from '../../charts/public';
import { Datatable, IInterpreterRenderHandlers } from '../../expressions/public';
+import type { PersistedState } from '../../visualizations/public';
import { VisParams } from './types';
import {
@@ -77,7 +78,7 @@ import {
export interface VisComponentProps {
visParams: VisParams;
visData: Datatable;
- uiState: IInterpreterRenderHandlers['uiState'];
+ uiState: PersistedState;
fireEvent: IInterpreterRenderHandlers['event'];
renderComplete: IInterpreterRenderHandlers['done'];
}
diff --git a/src/plugins/vis_type_xy/public/vis_renderer.tsx b/src/plugins/vis_type_xy/public/vis_renderer.tsx
index 4ac7c23c30893..16463abb07631 100644
--- a/src/plugins/vis_type_xy/public/vis_renderer.tsx
+++ b/src/plugins/vis_type_xy/public/vis_renderer.tsx
@@ -24,6 +24,7 @@ import { I18nProvider } from '@kbn/i18n/react';
import { ExpressionRenderDefinition } from '../../expressions/public';
import { VisualizationContainer } from '../../visualizations/public';
+import type { PersistedState } from '../../visualizations/public';
import { XyVisType } from '../common';
import { SplitChartWarning } from './components/split_chart_warning';
@@ -59,7 +60,7 @@ export const xyVisRenderer: ExpressionRenderDefinition = {
visData={visData}
renderComplete={handlers.done}
fireEvent={handlers.event}
- uiState={handlers.uiState}
+ uiState={handlers.uiState as PersistedState}
/>
>
diff --git a/src/plugins/vis_type_xy/public/vis_types/split_tooltip.tsx b/src/plugins/vis_type_xy/public/vis_types/split_tooltip.tsx
index 2abe3e9b8cf71..84f1fd9187f4f 100644
--- a/src/plugins/vis_type_xy/public/vis_types/split_tooltip.tsx
+++ b/src/plugins/vis_type_xy/public/vis_types/split_tooltip.tsx
@@ -25,10 +25,7 @@ export function SplitTooltip() {
return (
charts library,
- }}
+ defaultMessage="Split chart aggregation is not supported with the new charts library. Please enable the legacy charts library advanced setting to use split chart aggregation."
/>
);
}
diff --git a/src/plugins/vis_type_xy/server/plugin.ts b/src/plugins/vis_type_xy/server/plugin.ts
index 51d741f9374fe..b5999535064aa 100644
--- a/src/plugins/vis_type_xy/server/plugin.ts
+++ b/src/plugins/vis_type_xy/server/plugin.ts
@@ -22,21 +22,21 @@ import { schema } from '@kbn/config-schema';
import { CoreSetup, Plugin, UiSettingsParams } from 'kibana/server';
-import { CHARTS_LIBRARY } from '../common';
+import { LEGACY_CHARTS_LIBRARY } from '../common';
export const uiSettingsConfig: Record> = {
// TODO: Remove this when vis_type_vislib is removed
// https://github.com/elastic/kibana/issues/56143
- [CHARTS_LIBRARY]: {
- name: i18n.translate('visTypeXy.advancedSettings.visualization.chartsLibrary', {
- defaultMessage: 'Charts library',
+ [LEGACY_CHARTS_LIBRARY]: {
+ name: i18n.translate('visTypeXy.advancedSettings.visualization.legacyChartsLibrary.name', {
+ defaultMessage: 'Legacy charts library',
}),
- value: false,
+ value: true,
description: i18n.translate(
- 'visTypeXy.advancedSettings.visualization.chartsLibrary.description',
+ 'visTypeXy.advancedSettings.visualization.legacyChartsLibrary.description',
{
defaultMessage:
- 'Enables new charts library for areas, lines and bars in visualize. Currently, does not support split chart aggregation.',
+ 'Enables legacy charts library for area, line and bar charts in visualize. Currently, only legacy charts library supports split chart aggregation.',
}
),
category: ['visualization'],
diff --git a/src/plugins/visualizations/public/embeddable/events.ts b/src/plugins/visualizations/public/embeddable/events.ts
index 41e52c3ac1327..7065d758bbc49 100644
--- a/src/plugins/visualizations/public/embeddable/events.ts
+++ b/src/plugins/visualizations/public/embeddable/events.ts
@@ -17,12 +17,9 @@
* under the License.
*/
-import {
- APPLY_FILTER_TRIGGER,
- SELECT_RANGE_TRIGGER,
- VALUE_CLICK_TRIGGER,
- ROW_CLICK_TRIGGER,
-} from '../../../ui_actions/public';
+import { ROW_CLICK_TRIGGER } from '../../../ui_actions/public';
+import { APPLY_FILTER_TRIGGER } from '../../../../plugins/data/public';
+import { SELECT_RANGE_TRIGGER, VALUE_CLICK_TRIGGER } from '../../../../plugins/embeddable/public';
export interface VisEventToTrigger {
['applyFilter']: typeof APPLY_FILTER_TRIGGER;
diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts
index f7592977858d2..5661acc26fdb6 100644
--- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts
+++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts
@@ -71,6 +71,9 @@ export interface VisualizeInput extends EmbeddableInput {
};
savedVis?: SerializedVis;
table?: unknown;
+ query?: Query;
+ filters?: Filter[];
+ timeRange?: TimeRange;
}
export interface VisualizeOutput extends EmbeddableOutput {
diff --git a/tasks/check_plugins.js b/tasks/check_plugins.js
deleted file mode 100644
index 20fb8a895af6c..0000000000000
--- a/tasks/check_plugins.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import fs from 'fs';
-import path from 'path';
-
-export default function checkPlugins(grunt) {
- grunt.registerTask(
- 'checkPlugins',
- 'Checks for plugins which may disrupt tests',
- function checkPlugins() {
- const done = this.async();
- const pluginsDir = path.resolve('./plugins/');
-
- fs.readdir(pluginsDir, (err, files) => {
- if (!files) {
- return done();
- }
-
- const plugins = files.filter((file) => {
- return fs.statSync(path.join(pluginsDir, file)).isDirectory();
- });
-
- if (plugins.length) {
- grunt.log.error(
- '==================================================================================================='
- );
- plugins.forEach((plugin) => {
- grunt.log.error(
- `The ${plugin} plugin may disrupt the test process. Consider removing it and re-running your tests.`
- );
- });
- grunt.log.error(
- '==================================================================================================='
- );
- }
-
- done();
- });
- }
- );
-}
diff --git a/tasks/docker_docs.js b/tasks/docker_docs.js
deleted file mode 100644
index 3a2041abc9301..0000000000000
--- a/tasks/docker_docs.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import del from 'del';
-import { join } from 'path';
-import { execFileSync as exec } from 'child_process';
-
-export default function (grunt) {
- grunt.registerTask('docker:docs', 'Build docs from docker', function () {
- const rootPath = grunt.config.get('root');
- const composePath = join(rootPath, 'tasks/docker_docs/docker-compose.yml');
- const htmlDocsDir = join(rootPath, 'html_docs');
-
- const env = Object.assign(process.env, {
- KIBANA_DOCS_CONTAINER_NAME: 'kibana_docs',
- KIBANA_DOCS_CONTEXT: rootPath,
- });
- const stdio = [0, 1, 2];
- const execOptions = { env, stdio };
-
- exec('docker-compose', ['-f', composePath, 'up'], execOptions);
-
- const containerId = String(
- exec('docker-compose', ['-f', composePath, 'ps', '-q', env.KIBANA_DOCS_CONTAINER_NAME], {
- env,
- })
- ).trim();
-
- grunt.log.write('Clearing old docs ... ');
- del.sync(htmlDocsDir);
- grunt.log.writeln('done');
-
- grunt.log.write('Copying new docs ... ');
- exec('docker', ['cp', `${containerId}:/home/kibana/html_docs`, htmlDocsDir]);
- grunt.log.writeln('done');
- });
-}
diff --git a/tasks/docker_docs/Dockerfile b/tasks/docker_docs/Dockerfile
deleted file mode 100644
index 435b78f89f2e7..0000000000000
--- a/tasks/docker_docs/Dockerfile
+++ /dev/null
@@ -1,18 +0,0 @@
-FROM alpine:3.6
-
-RUN apk add --no-cache \
- git \
- libxslt \
- curl \
- python \
- libxml2-utils \
- perl
-
-RUN addgroup kibana && \
- adduser -D -G kibana -s /bin/bash -h /home/kibana kibana
-
-USER kibana
-RUN git clone --depth 1 https://github.com/elastic/docs.git /home/kibana/docs_builder
-
-WORKDIR /home/kibana/docs_builder
-CMD git pull origin master && ./build_docs.pl --doc /home/kibana/ascii_docs/index.asciidoc --out /home/kibana/html_docs --chunk=1
diff --git a/tasks/docker_docs/docker-compose.yml b/tasks/docker_docs/docker-compose.yml
deleted file mode 100644
index 8d0bd2c136596..0000000000000
--- a/tasks/docker_docs/docker-compose.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-version: '2'
-services:
- kibana_docs:
- container_name: $KIBANA_DOCS_CONTAINER_NAME
- build:
- context: $KIBANA_DOCS_CONTEXT/tasks/docker_docs
- volumes:
- - $KIBANA_DOCS_CONTEXT/docs:/home/kibana/ascii_docs
diff --git a/test/common/services/security/test_user.ts b/test/common/services/security/test_user.ts
index 7183943591c88..25a36fed9c9c5 100644
--- a/test/common/services/security/test_user.ts
+++ b/test/common/services/security/test_user.ts
@@ -87,11 +87,11 @@ export async function createTestUserService(
});
if (browser && testSubjects && shouldRefreshBrowser) {
- // accept alert if it pops up
- const alert = await browser.getAlert();
- await alert?.accept();
if (await testSubjects.exists('kibanaChrome', { allowHidden: true })) {
await browser.refresh();
+ // accept alert if it pops up
+ const alert = await browser.getAlert();
+ await alert?.accept();
await testSubjects.find('kibanaChrome', config.get('timeouts.find') * 10);
}
}
diff --git a/test/functional/apps/dashboard/create_and_add_embeddables.ts b/test/functional/apps/dashboard/create_and_add_embeddables.ts
index d8b8a6f91fe31..605ea26b76c6f 100644
--- a/test/functional/apps/dashboard/create_and_add_embeddables.ts
+++ b/test/functional/apps/dashboard/create_and_add_embeddables.ts
@@ -81,7 +81,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('saves the saved visualization url to the app link', async () => {
- await PageObjects.header.clickVisualize();
+ await PageObjects.header.clickVisualize(true);
const currentUrl = await browser.getCurrentUrl();
expect(currentUrl).to.contain(VisualizeConstants.EDIT_PATH);
});
diff --git a/test/functional/apps/dashboard/dashboard_state.ts b/test/functional/apps/dashboard/dashboard_state.ts
index 48fec4efee5db..728787543927c 100644
--- a/test/functional/apps/dashboard/dashboard_state.ts
+++ b/test/functional/apps/dashboard/dashboard_state.ts
@@ -46,16 +46,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('dashboard state', function describeIndexTests() {
// Used to track flag before and after reset
- let isNewChartUiEnabled = false;
+ let isNewChartsLibraryEnabled = false;
before(async function () {
- isNewChartUiEnabled = await PageObjects.visChart.isNewChartUiEnabled();
+ isNewChartsLibraryEnabled = await PageObjects.visChart.isNewChartsLibraryEnabled();
await PageObjects.dashboard.initTests();
await PageObjects.dashboard.preserveCrossAppState();
- if (isNewChartUiEnabled) {
+ if (isNewChartsLibraryEnabled) {
await kibanaServer.uiSettings.update({
- 'visualization:visualize:chartsLibrary': true,
+ 'visualization:visualize:legacyChartsLibrary': false,
});
await browser.refresh();
}
@@ -73,12 +73,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const visName = await PageObjects.visChart.getExpectedValue(
AREA_CHART_VIS_NAME,
- `${AREA_CHART_VIS_NAME} - chartsLibrary`
+ `${AREA_CHART_VIS_NAME} - new charts library`
);
await dashboardAddPanel.addVisualization(visName);
const dashboarName = await PageObjects.visChart.getExpectedValue(
'Overridden colors',
- 'Overridden colors - chartsLibrary'
+ 'Overridden colors - new charts library'
);
await PageObjects.dashboard.saveDashboard(dashboarName);
@@ -93,7 +93,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.gotoDashboardLandingPage();
await PageObjects.dashboard.loadSavedDashboard(dashboarName);
- if (await PageObjects.visChart.isNewChartUiEnabled()) {
+ if (await PageObjects.visChart.isNewChartsLibraryEnabled()) {
await elasticChart.setNewChartUiDebugFlag();
await queryBar.submitQuery();
}
diff --git a/test/functional/apps/dashboard/dashboard_time_picker.ts b/test/functional/apps/dashboard/dashboard_time_picker.ts
index 274a4355e26e2..c759edd638260 100644
--- a/test/functional/apps/dashboard/dashboard_time_picker.ts
+++ b/test/functional/apps/dashboard/dashboard_time_picker.ts
@@ -40,6 +40,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
after(async () => {
await kibanaServer.uiSettings.replace({});
await browser.refresh();
+ const alert = await browser.getAlert();
+ await alert?.accept();
});
it('Visualization updated when time picker changes', async () => {
@@ -88,6 +90,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
`)`;
log.debug('go to url' + `${kibanaBaseUrl}#${urlQuery}`);
await browser.get(`${kibanaBaseUrl}#${urlQuery}`, true);
+ const alert = await browser.getAlert();
+ await alert?.accept();
await PageObjects.header.waitUntilLoadingHasFinished();
const time = await PageObjects.timePicker.getTimeConfig();
const refresh = await PageObjects.timePicker.getRefreshConfig();
@@ -99,6 +103,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('Timepicker respects dateFormat from UI settings', async () => {
await kibanaServer.uiSettings.replace({ dateFormat: 'YYYY-MM-DD HH:mm:ss.SSS' });
await browser.refresh();
+ const alert = await browser.getAlert();
+ await alert?.accept();
await PageObjects.dashboard.gotoDashboardLandingPage();
await PageObjects.dashboard.clickNewDashboard();
await PageObjects.dashboard.addVisualizations([PIE_CHART_VIS_NAME]);
diff --git a/test/functional/apps/dashboard/index.ts b/test/functional/apps/dashboard/index.ts
index f2dba4785ea05..6fb5f874022a0 100644
--- a/test/functional/apps/dashboard/index.ts
+++ b/test/functional/apps/dashboard/index.ts
@@ -126,7 +126,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
before(async () => {
await loadLogstash();
await kibanaServer.uiSettings.update({
- 'visualization:visualize:chartsLibrary': true,
+ 'visualization:visualize:legacyChartsLibrary': false,
});
await browser.refresh();
});
@@ -134,7 +134,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
after(async () => {
await unloadLogstash();
await kibanaServer.uiSettings.update({
- 'visualization:visualize:chartsLibrary': false,
+ 'visualization:visualize:legacyChartsLibrary': true,
});
await browser.refresh();
});
diff --git a/test/functional/apps/dashboard/panel_context_menu.ts b/test/functional/apps/dashboard/panel_context_menu.ts
index 0b9e873f46151..bd6756835af31 100644
--- a/test/functional/apps/dashboard/panel_context_menu.ts
+++ b/test/functional/apps/dashboard/panel_context_menu.ts
@@ -110,7 +110,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const searchName = 'my search';
before(async () => {
- await PageObjects.header.clickDiscover();
+ await PageObjects.header.clickDiscover(true);
await PageObjects.discover.clickNewSearchButton();
await dashboardVisualizations.createSavedSearch({ name: searchName, fields: ['bytes'] });
await PageObjects.header.waitUntilLoadingHasFinished();
diff --git a/test/functional/apps/dashboard/panel_replacing.ts b/test/functional/apps/dashboard/panel_replacing.ts
index 6bf3dbbe47b1d..c9ecf42dbc8e8 100644
--- a/test/functional/apps/dashboard/panel_replacing.ts
+++ b/test/functional/apps/dashboard/panel_replacing.ts
@@ -70,6 +70,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('replaced panel persisted correctly when dashboard is hard refreshed', async () => {
const currentUrl = await browser.getCurrentUrl();
await browser.get(currentUrl, true);
+ const alert = await browser.getAlert();
+ await alert?.accept();
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.dashboard.waitForRenderComplete();
const panelTitles = await PageObjects.dashboard.getPanelTitles();
diff --git a/test/functional/apps/discover/_discover.ts b/test/functional/apps/discover/_discover.ts
index e52c33078029a..1b333c377f777 100644
--- a/test/functional/apps/discover/_discover.ts
+++ b/test/functional/apps/discover/_discover.ts
@@ -110,7 +110,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
- it('should modify the time range when the histogram is brushed', async function () {
+ it.skip('should modify the time range when the histogram is brushed', async function () {
await PageObjects.timePicker.setDefaultAbsoluteRange();
await PageObjects.discover.brushHistogram();
await PageObjects.discover.waitUntilSearchingHasFinished();
diff --git a/test/functional/apps/discover/_shared_links.ts b/test/functional/apps/discover/_shared_links.ts
index a676878382865..51ea5f997e859 100644
--- a/test/functional/apps/discover/_shared_links.ts
+++ b/test/functional/apps/discover/_shared_links.ts
@@ -90,7 +90,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
":(from:'2015-09-19T06:31:44.000Z',to:'2015-09" +
"-23T18:31:44.000Z'))&_a=(columns:!(_source),filters:!(),index:'logstash-" +
"*',interval:auto,query:(language:kuery,query:'')" +
- ',sort:!())';
+ ",sort:!(!('@timestamp',desc)))";
const actualUrl = await PageObjects.share.getSharedUrl();
// strip the timestamp out of each URL
expect(actualUrl.replace(/_t=\d{13}/, '_t=TIMESTAMP')).to.be(
diff --git a/test/functional/apps/getting_started/_shakespeare.ts b/test/functional/apps/getting_started/_shakespeare.ts
index fa7d932aca1e8..09fdff9977b5e 100644
--- a/test/functional/apps/getting_started/_shakespeare.ts
+++ b/test/functional/apps/getting_started/_shakespeare.ts
@@ -49,22 +49,22 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// order they are added.
let aggIndex = 1;
// Used to track flag before and after reset
- let isNewChartUiEnabled = false;
+ let isNewChartsLibraryEnabled = false;
before(async function () {
log.debug(
'Load empty_kibana and Shakespeare Getting Started data\n' +
'https://www.elastic.co/guide/en/kibana/current/tutorial-load-dataset.html'
);
- isNewChartUiEnabled = await PageObjects.visChart.isNewChartUiEnabled();
+ isNewChartsLibraryEnabled = await PageObjects.visChart.isNewChartsLibraryEnabled();
await security.testUser.setRoles(['kibana_admin', 'test_shakespeare_reader']);
await esArchiver.load('empty_kibana', { skipExisting: true });
log.debug('Load shakespeare data');
await esArchiver.loadIfNeeded('getting_started/shakespeare');
- if (isNewChartUiEnabled) {
+ if (isNewChartsLibraryEnabled) {
await kibanaServer.uiSettings.update({
- 'visualization:visualize:chartsLibrary': true,
+ 'visualization:visualize:legacyChartsLibrary': false,
});
await browser.refresh();
}
diff --git a/test/functional/apps/getting_started/index.ts b/test/functional/apps/getting_started/index.ts
index 4cef16a47571e..b832c797adac6 100644
--- a/test/functional/apps/getting_started/index.ts
+++ b/test/functional/apps/getting_started/index.ts
@@ -31,17 +31,17 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
});
// TODO: Remove when vislib is removed
- describe('chartsLibrary', function () {
+ describe('new charts library', function () {
before(async () => {
await kibanaServer.uiSettings.update({
- 'visualization:visualize:chartsLibrary': true,
+ 'visualization:visualize:legacyChartsLibrary': false,
});
await browser.refresh();
});
after(async () => {
await kibanaServer.uiSettings.update({
- 'visualization:visualize:chartsLibrary': false,
+ 'visualization:visualize:legacyChartsLibrary': true,
});
await browser.refresh();
});
diff --git a/test/functional/apps/visualize/index.ts b/test/functional/apps/visualize/index.ts
index ad69ad5ab41cd..94b0c5b6c8a27 100644
--- a/test/functional/apps/visualize/index.ts
+++ b/test/functional/apps/visualize/index.ts
@@ -43,19 +43,19 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
});
// TODO: Remove when vislib is removed
- describe('chartsLibrary', function () {
+ describe('new charts library', function () {
this.tags('ciGroup7');
before(async () => {
await kibanaServer.uiSettings.update({
- 'visualization:visualize:chartsLibrary': true,
+ 'visualization:visualize:legacyChartsLibrary': false,
});
await browser.refresh();
});
after(async () => {
await kibanaServer.uiSettings.update({
- 'visualization:visualize:chartsLibrary': false,
+ 'visualization:visualize:legacyChartsLibrary': true,
});
await browser.refresh();
});
diff --git a/test/functional/page_objects/header_page.ts b/test/functional/page_objects/header_page.ts
index d69a01ab6bb26..5a892bb4f6ca3 100644
--- a/test/functional/page_objects/header_page.ts
+++ b/test/functional/page_objects/header_page.ts
@@ -31,14 +31,16 @@ export function HeaderPageProvider({ getService, getPageObjects }: FtrProviderCo
const defaultFindTimeout = config.get('timeouts.find');
class HeaderPage {
- public async clickDiscover() {
+ public async clickDiscover(ignoreAppLeaveWarning = false) {
await appsMenu.clickLink('Discover', { category: 'kibana' });
+ await this.onAppLeaveWarning(ignoreAppLeaveWarning);
await PageObjects.common.waitForTopNavToBeVisible();
await this.awaitGlobalLoadingIndicatorHidden();
}
- public async clickVisualize() {
+ public async clickVisualize(ignoreAppLeaveWarning = false) {
await appsMenu.clickLink('Visualize', { category: 'kibana' });
+ await this.onAppLeaveWarning(ignoreAppLeaveWarning);
await this.awaitGlobalLoadingIndicatorHidden();
await retry.waitFor('first breadcrumb to be "Visualize"', async () => {
const firstBreadcrumb = await globalNav.getFirstBreadcrumb();
@@ -95,6 +97,17 @@ export function HeaderPageProvider({ getService, getPageObjects }: FtrProviderCo
log.debug('awaitKibanaChrome');
await testSubjects.find('kibanaChrome', defaultFindTimeout * 10);
}
+
+ public async onAppLeaveWarning(ignoreWarning = false) {
+ await retry.try(async () => {
+ const warning = await testSubjects.exists('confirmModalTitleText');
+ if (warning) {
+ await testSubjects.click(
+ ignoreWarning ? 'confirmModalConfirmButton' : 'confirmModalCancelButton'
+ );
+ }
+ });
+ }
}
return new HeaderPage();
diff --git a/test/functional/page_objects/visualize_chart_page.ts b/test/functional/page_objects/visualize_chart_page.ts
index 2ad7c77a58ca9..41af5a4c47e78 100644
--- a/test/functional/page_objects/visualize_chart_page.ts
+++ b/test/functional/page_objects/visualize_chart_page.ts
@@ -41,22 +41,23 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr
}
/**
- * Is chartsLibrary advanced setting enabled
+ * Is new charts library advanced setting enabled
*/
- public async isNewChartUiEnabled(): Promise {
- const enabled =
- Boolean(await kibanaServer.uiSettings.get('visualization:visualize:chartsLibrary')) ??
- false;
- log.debug(`-- isNewChartUiEnabled = ${enabled}`);
+ public async isNewChartsLibraryEnabled(): Promise {
+ const legacyChartsLibrary =
+ Boolean(await kibanaServer.uiSettings.get('visualization:visualize:legacyChartsLibrary')) ??
+ true;
+ const enabled = !legacyChartsLibrary;
+ log.debug(`-- isNewChartsLibraryEnabled = ${enabled}`);
return enabled;
}
/**
- * Is chartsLibrary enabled and an area, line or histogram chart is available
+ * Is new charts library enabled and an area, line or histogram chart exists
*/
private async isVisTypeXYChart(): Promise {
- const enabled = await this.isNewChartUiEnabled();
+ const enabled = await this.isNewChartsLibraryEnabled();
if (!enabled) {
log.debug(`-- isVisTypeXYChart = false`);
diff --git a/test/functional/page_objects/visualize_editor_page.ts b/test/functional/page_objects/visualize_editor_page.ts
index d6134883332e3..18573c5084618 100644
--- a/test/functional/page_objects/visualize_editor_page.ts
+++ b/test/functional/page_objects/visualize_editor_page.ts
@@ -74,7 +74,7 @@ export function VisualizeEditorPageProvider({ getService, getPageObjects }: FtrP
}
public async clickGo() {
- if (await visChart.isNewChartUiEnabled()) {
+ if (await visChart.isNewChartsLibraryEnabled()) {
await elasticChart.setNewChartUiDebugFlag();
}
diff --git a/test/functional/page_objects/visualize_page.ts b/test/functional/page_objects/visualize_page.ts
index e5bd6a0f10d82..d8329f492fe80 100644
--- a/test/functional/page_objects/visualize_page.ts
+++ b/test/functional/page_objects/visualize_page.ts
@@ -99,7 +99,7 @@ export function VisualizePageProvider({ getService, getPageObjects }: FtrProvide
}
public async clickRefresh() {
- if (await visChart.isNewChartUiEnabled()) {
+ if (await visChart.isNewChartsLibraryEnabled()) {
await elasticChart.setNewChartUiDebugFlag();
}
await queryBar.clickQuerySubmitButton();
diff --git a/test/functional/services/dashboard/visualizations.ts b/test/functional/services/dashboard/visualizations.ts
index b35ef1e8f2f9a..22e1769145f88 100644
--- a/test/functional/services/dashboard/visualizations.ts
+++ b/test/functional/services/dashboard/visualizations.ts
@@ -58,8 +58,7 @@ export function DashboardVisualizationProvider({ getService, getPageObjects }: F
fields?: string[];
}) {
log.debug(`createSavedSearch(${name})`);
- await PageObjects.header.clickDiscover();
-
+ await PageObjects.header.clickDiscover(true);
await PageObjects.timePicker.setHistoricalDataRange();
if (query) {
diff --git a/test/scripts/jenkins_docs.sh b/test/scripts/jenkins_docs.sh
deleted file mode 100755
index f447afda1f948..0000000000000
--- a/test/scripts/jenkins_docs.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-source "$(dirname $0)/../../src/dev/ci_setup/setup.sh"
-
-"$(FORCE_COLOR=0 yarn bin)/grunt" docker:docs;
diff --git a/test/scripts/test/xpack_karma.sh b/test/scripts/test/xpack_karma.sh
deleted file mode 100755
index 9078f01f1b870..0000000000000
--- a/test/scripts/test/xpack_karma.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env bash
-
-source src/dev/ci_setup/setup_env.sh
-
-cd x-pack
-checks-reporter-with-killswitch "X-Pack Karma Tests" yarn test:karma
diff --git a/vars/workers.groovy b/vars/workers.groovy
index 365c30204ebdc..dd634f3c25a32 100644
--- a/vars/workers.groovy
+++ b/vars/workers.groovy
@@ -18,7 +18,7 @@ def label(size) {
case 'xl-highmem':
return 'docker && tests-xl-highmem'
case 'xxl':
- return 'docker && tests-xxl'
+ return 'docker && tests-xxl && gobld/machineType:custom-64-270336'
}
error "unknown size '${size}'"
@@ -147,7 +147,7 @@ def intake(jobName, String script) {
// Worker for running functional tests. Runs a setup process (e.g. the kibana build) then executes a map of closures in parallel (e.g. one for each ciGroup)
def functional(name, Closure setup, Map processes) {
return {
- parallelProcesses(name: name, setup: setup, processes: processes, delayBetweenProcesses: 20, size: 'xl-highmem')
+ parallelProcesses(name: name, setup: setup, processes: processes, delayBetweenProcesses: 20, size: 'xl')
}
}
diff --git a/x-pack/examples/alerting_example/common/constants.ts b/x-pack/examples/alerting_example/common/constants.ts
index 40cc298db795a..8e4ea4faf014c 100644
--- a/x-pack/examples/alerting_example/common/constants.ts
+++ b/x-pack/examples/alerting_example/common/constants.ts
@@ -4,11 +4,13 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { AlertTypeParams } from '../../../plugins/alerts/common';
+
export const ALERTING_EXAMPLE_APP_ID = 'AlertingExample';
// always firing
export const DEFAULT_INSTANCES_TO_GENERATE = 5;
-export interface AlwaysFiringParams {
+export interface AlwaysFiringParams extends AlertTypeParams {
instances?: number;
thresholds?: {
small?: number;
diff --git a/x-pack/examples/alerting_example/public/alert_types/always_firing.tsx b/x-pack/examples/alerting_example/public/alert_types/always_firing.tsx
index 134cda6f54188..cee7ee62e3210 100644
--- a/x-pack/examples/alerting_example/public/alert_types/always_firing.tsx
+++ b/x-pack/examples/alerting_example/public/alert_types/always_firing.tsx
@@ -32,7 +32,6 @@ import {
export function getAlertType(): AlertTypeModel {
return {
id: 'example.always-firing',
- name: 'Always Fires',
description: 'Alert when called',
iconClass: 'bolt',
documentationUrl: null,
diff --git a/x-pack/examples/alerting_example/public/alert_types/astros.tsx b/x-pack/examples/alerting_example/public/alert_types/astros.tsx
index 54f989b93e22f..cb65c9f52ca3f 100644
--- a/x-pack/examples/alerting_example/public/alert_types/astros.tsx
+++ b/x-pack/examples/alerting_example/public/alert_types/astros.tsx
@@ -44,7 +44,6 @@ function isValueInEnum(enumeratin: Record, value: any): boolean {
export function getAlertType(): AlertTypeModel {
return {
id: 'example.people-in-space',
- name: 'People Are In Space Right Now',
description: 'Alert when people are in space right now',
iconClass: 'globe',
documentationUrl: null,
diff --git a/x-pack/examples/alerting_example/public/components/view_astros_alert.tsx b/x-pack/examples/alerting_example/public/components/view_astros_alert.tsx
index e4687c75fa0b7..eb682a86f5ff6 100644
--- a/x-pack/examples/alerting_example/public/components/view_astros_alert.tsx
+++ b/x-pack/examples/alerting_example/public/components/view_astros_alert.tsx
@@ -23,7 +23,7 @@ import { withRouter, RouteComponentProps } from 'react-router-dom';
import { CoreStart } from 'kibana/public';
import { isEmpty } from 'lodash';
import { Alert, AlertTaskState, BASE_ALERT_API_PATH } from '../../../../plugins/alerts/common';
-import { ALERTING_EXAMPLE_APP_ID } from '../../common/constants';
+import { ALERTING_EXAMPLE_APP_ID, AlwaysFiringParams } from '../../common/constants';
type Props = RouteComponentProps & {
http: CoreStart['http'];
@@ -34,7 +34,7 @@ function hasCraft(state: any): state is { craft: string } {
return state && state.craft;
}
export const ViewPeopleInSpaceAlertPage = withRouter(({ http, id }: Props) => {
- const [alert, setAlert] = useState(null);
+ const [alert, setAlert] = useState | null>(null);
const [alertState, setAlertState] = useState(null);
useEffect(() => {
diff --git a/x-pack/examples/alerting_example/server/alert_types/astros.ts b/x-pack/examples/alerting_example/server/alert_types/astros.ts
index 27a8bfc7a53a3..22c2f25c410cd 100644
--- a/x-pack/examples/alerting_example/server/alert_types/astros.ts
+++ b/x-pack/examples/alerting_example/server/alert_types/astros.ts
@@ -38,7 +38,11 @@ function getCraftFilter(craft: string) {
craft === Craft.OuterSpace ? true : craft === person.craft;
}
-export const alertType: AlertType = {
+export const alertType: AlertType<
+ { outerSpaceCapacity: number; craft: string; op: string },
+ { peopleInSpace: number },
+ { craft: string }
+> = {
id: 'example.people-in-space',
name: 'People In Space Right Now',
actionGroups: [{ id: 'default', name: 'default' }],
diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/containers/drilldowns_with_embeddable_example/drilldowns_with_embeddable_example.tsx b/x-pack/examples/ui_actions_enhanced_examples/public/containers/drilldowns_with_embeddable_example/drilldowns_with_embeddable_example.tsx
index 48b64a1c84588..27c63aba791dd 100644
--- a/x-pack/examples/ui_actions_enhanced_examples/public/containers/drilldowns_with_embeddable_example/drilldowns_with_embeddable_example.tsx
+++ b/x-pack/examples/ui_actions_enhanced_examples/public/containers/drilldowns_with_embeddable_example/drilldowns_with_embeddable_example.tsx
@@ -18,10 +18,12 @@ import {
EuiFlexGroup,
} from '@elastic/eui';
import { SampleMlJob, SampleApp1ClickContext } from '../../triggers';
-import { EmbeddableRoot } from '../../../../../../src/plugins/embeddable/public';
+import {
+ EmbeddableRoot,
+ VALUE_CLICK_TRIGGER,
+} from '../../../../../../src/plugins/embeddable/public';
import { ButtonEmbeddable } from '../../embeddables/button_embeddable';
import { useUiActions } from '../../context';
-import { VALUE_CLICK_TRIGGER } from '../../../../../../src/plugins/ui_actions/public';
export const job: SampleMlJob = {
job_id: '123',
diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_hello_world_drilldown/index.tsx b/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_hello_world_drilldown/index.tsx
index a7324f5530130..50ad350cd90b9 100644
--- a/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_hello_world_drilldown/index.tsx
+++ b/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_hello_world_drilldown/index.tsx
@@ -8,12 +8,12 @@ import React from 'react';
import { EuiFormRow, EuiFieldText } from '@elastic/eui';
import { reactToUiComponent } from '../../../../../../src/plugins/kibana_react/public';
import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../../plugins/ui_actions_enhanced/public';
-import { ChartActionContext } from '../../../../../../src/plugins/embeddable/public';
-import { CollectConfigProps } from '../../../../../../src/plugins/kibana_utils/public';
import {
+ ChartActionContext,
SELECT_RANGE_TRIGGER,
VALUE_CLICK_TRIGGER,
-} from '../../../../../../src/plugins/ui_actions/public';
+} from '../../../../../../src/plugins/embeddable/public';
+import { CollectConfigProps } from '../../../../../../src/plugins/kibana_utils/public';
export type ActionContext = ChartActionContext;
diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_hello_world_only_range_select_drilldown/index.tsx b/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_hello_world_only_range_select_drilldown/index.tsx
index 24385bd6baa42..4e5b3187af42b 100644
--- a/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_hello_world_only_range_select_drilldown/index.tsx
+++ b/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_hello_world_only_range_select_drilldown/index.tsx
@@ -8,9 +8,11 @@ import React from 'react';
import { EuiFormRow, EuiFieldText } from '@elastic/eui';
import { reactToUiComponent } from '../../../../../../src/plugins/kibana_react/public';
import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../../plugins/ui_actions_enhanced/public';
-import { RangeSelectContext } from '../../../../../../src/plugins/embeddable/public';
+import {
+ RangeSelectContext,
+ SELECT_RANGE_TRIGGER,
+} from '../../../../../../src/plugins/embeddable/public';
import { CollectConfigProps } from '../../../../../../src/plugins/kibana_utils/public';
-import { SELECT_RANGE_TRIGGER } from '../../../../../../src/plugins/ui_actions/public';
import { BaseActionFactoryContext } from '../../../../../plugins/ui_actions_enhanced/public/dynamic_actions';
export type Config = {
diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_to_discover_drilldown/drilldown.tsx b/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_to_discover_drilldown/drilldown.tsx
index 9cda534a340d6..2f161efe6f388 100644
--- a/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_to_discover_drilldown/drilldown.tsx
+++ b/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_to_discover_drilldown/drilldown.tsx
@@ -13,7 +13,7 @@ import { CollectConfigContainer } from './collect_config_container';
import { SAMPLE_DASHBOARD_TO_DISCOVER_DRILLDOWN } from './constants';
import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../../plugins/ui_actions_enhanced/public';
import { txtGoToDiscover } from './i18n';
-import { APPLY_FILTER_TRIGGER } from '../../../../../../src/plugins/ui_actions/public';
+import { APPLY_FILTER_TRIGGER } from '../../../../../../src/plugins/data/public';
const isOutputWithIndexPatterns = (
output: unknown
diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_to_discover_drilldown/types.ts b/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_to_discover_drilldown/types.ts
index f0497780430d4..7c8915c3f143f 100644
--- a/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_to_discover_drilldown/types.ts
+++ b/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/dashboard_to_discover_drilldown/types.ts
@@ -6,8 +6,9 @@
import { CollectConfigProps as CollectConfigPropsBase } from '../../../../../../src/plugins/kibana_utils/public';
import { ApplyGlobalFilterActionContext } from '../../../../../../src/plugins/data/public';
+import { IEmbeddable } from '../../../../../../src/plugins/embeddable/public';
-export type ActionContext = ApplyGlobalFilterActionContext;
+export type ActionContext = ApplyGlobalFilterActionContext & { embeddable: IEmbeddable };
export type Config = {
/**
diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/embeddables/button_embeddable/button_embeddable.ts b/x-pack/examples/ui_actions_enhanced_examples/public/embeddables/button_embeddable/button_embeddable.ts
index fcd0c9b94c988..e58ab5b8ea9d2 100644
--- a/x-pack/examples/ui_actions_enhanced_examples/public/embeddables/button_embeddable/button_embeddable.ts
+++ b/x-pack/examples/ui_actions_enhanced_examples/public/embeddables/button_embeddable/button_embeddable.ts
@@ -7,9 +7,12 @@
import { createElement } from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { AdvancedUiActionsStart } from '../../../../../plugins/ui_actions_enhanced/public';
-import { Embeddable, EmbeddableInput } from '../../../../../../src/plugins/embeddable/public';
+import {
+ Embeddable,
+ EmbeddableInput,
+ VALUE_CLICK_TRIGGER,
+} from '../../../../../../src/plugins/embeddable/public';
import { ButtonEmbeddableComponent } from './button_embeddable_component';
-import { VALUE_CLICK_TRIGGER } from '../../../../../../src/plugins/ui_actions/public';
export const BUTTON_EMBEDDABLE = 'BUTTON_EMBEDDABLE';
diff --git a/x-pack/plugins/alerts/common/alert.ts b/x-pack/plugins/alerts/common/alert.ts
index d74f66898eff6..ed3fbcf2ddc9b 100644
--- a/x-pack/plugins/alerts/common/alert.ts
+++ b/x-pack/plugins/alerts/common/alert.ts
@@ -7,10 +7,8 @@
import { SavedObjectAttribute, SavedObjectAttributes } from 'kibana/server';
import { AlertNotifyWhenType } from './alert_notify_when_type';
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export type AlertTypeState = Record;
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export type AlertTypeParams = Record;
+export type AlertTypeState = Record;
+export type AlertTypeParams = Record;
export interface IntervalSchedule extends SavedObjectAttributes {
interval: string;
@@ -52,7 +50,7 @@ export interface AlertAggregations {
alertExecutionStatus: { [status: string]: number };
}
-export interface Alert {
+export interface Alert {
id: string;
enabled: boolean;
name: string;
@@ -61,7 +59,7 @@ export interface Alert {
consumer: string;
schedule: IntervalSchedule;
actions: AlertAction[];
- params: AlertTypeParams;
+ params: Params;
scheduledTaskId?: string;
createdBy: string | null;
updatedBy: string | null;
@@ -76,7 +74,7 @@ export interface Alert {
executionStatus: AlertExecutionStatus;
}
-export type SanitizedAlert = Omit;
+export type SanitizedAlert = Omit, 'apiKey'>;
export enum HealthStatus {
OK = 'ok',
diff --git a/x-pack/plugins/alerts/server/alert_instance/create_alert_instance_factory.ts b/x-pack/plugins/alerts/server/alert_instance/create_alert_instance_factory.ts
index 0b29262ddcc07..47f013a5d0e55 100644
--- a/x-pack/plugins/alerts/server/alert_instance/create_alert_instance_factory.ts
+++ b/x-pack/plugins/alerts/server/alert_instance/create_alert_instance_factory.ts
@@ -4,12 +4,16 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { AlertInstanceContext, AlertInstanceState } from '../types';
import { AlertInstance } from './alert_instance';
-export function createAlertInstanceFactory(alertInstances: Record) {
- return (id: string): AlertInstance => {
+export function createAlertInstanceFactory<
+ InstanceState extends AlertInstanceState,
+ InstanceContext extends AlertInstanceContext
+>(alertInstances: Record>) {
+ return (id: string): AlertInstance => {
if (!alertInstances[id]) {
- alertInstances[id] = new AlertInstance();
+ alertInstances[id] = new AlertInstance();
}
return alertInstances[id];
diff --git a/x-pack/plugins/alerts/server/alert_type_registry.ts b/x-pack/plugins/alerts/server/alert_type_registry.ts
index d436d1987c027..5e4188c1f3bc1 100644
--- a/x-pack/plugins/alerts/server/alert_type_registry.ts
+++ b/x-pack/plugins/alerts/server/alert_type_registry.ts
@@ -32,7 +32,7 @@ export interface ConstructorOptions {
export interface RegistryAlertType
extends Pick<
- NormalizedAlertType,
+ UntypedNormalizedAlertType,
| 'name'
| 'actionGroups'
| 'recoveryActionGroup'
@@ -66,16 +66,23 @@ const alertIdSchema = schema.string({
});
export type NormalizedAlertType<
- Params extends AlertTypeParams = AlertTypeParams,
- State extends AlertTypeState = AlertTypeState,
- InstanceState extends AlertInstanceState = AlertInstanceState,
- InstanceContext extends AlertInstanceContext = AlertInstanceContext
+ Params extends AlertTypeParams,
+ State extends AlertTypeState,
+ InstanceState extends AlertInstanceState,
+ InstanceContext extends AlertInstanceContext
> = Omit, 'recoveryActionGroup'> &
Pick>, 'recoveryActionGroup'>;
+export type UntypedNormalizedAlertType = NormalizedAlertType<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+>;
+
export class AlertTypeRegistry {
private readonly taskManager: TaskManagerSetupContract;
- private readonly alertTypes: Map = new Map();
+ private readonly alertTypes: Map = new Map();
private readonly taskRunnerFactory: TaskRunnerFactory;
private readonly licenseState: ILicenseState;
private readonly licensing: LicensingPluginSetup;
@@ -96,10 +103,10 @@ export class AlertTypeRegistry {
}
public register<
- Params extends AlertTypeParams = AlertTypeParams,
- State extends AlertTypeState = AlertTypeState,
- InstanceState extends AlertInstanceState = AlertInstanceState,
- InstanceContext extends AlertInstanceContext = AlertInstanceContext
+ Params extends AlertTypeParams,
+ State extends AlertTypeState,
+ InstanceState extends AlertInstanceState,
+ InstanceContext extends AlertInstanceContext
>(alertType: AlertType) {
if (this.has(alertType.id)) {
throw new Error(
@@ -113,14 +120,22 @@ export class AlertTypeRegistry {
}
alertType.actionVariables = normalizedActionVariables(alertType.actionVariables);
- const normalizedAlertType = augmentActionGroupsWithReserved(alertType as AlertType);
+ const normalizedAlertType = augmentActionGroupsWithReserved<
+ Params,
+ State,
+ InstanceState,
+ InstanceContext
+ >(alertType);
- this.alertTypes.set(alertIdSchema.validate(alertType.id), normalizedAlertType);
+ this.alertTypes.set(
+ alertIdSchema.validate(alertType.id),
+ normalizedAlertType as UntypedNormalizedAlertType
+ );
this.taskManager.registerTaskDefinitions({
[`alerting:${alertType.id}`]: {
title: alertType.name,
createTaskRunner: (context: RunContext) =>
- this.taskRunnerFactory.create(normalizedAlertType, context),
+ this.taskRunnerFactory.create(normalizedAlertType as UntypedNormalizedAlertType, context),
},
});
// No need to notify usage on basic alert types
@@ -170,7 +185,7 @@ export class AlertTypeRegistry {
producer,
minimumLicenseRequired,
},
- ]: [string, NormalizedAlertType]) => ({
+ ]: [string, UntypedNormalizedAlertType]) => ({
id,
name,
actionGroups,
diff --git a/x-pack/plugins/alerts/server/alerts_client/alerts_client.ts b/x-pack/plugins/alerts/server/alerts_client/alerts_client.ts
index f21cd2b02943a..e21fee4ce3d61 100644
--- a/x-pack/plugins/alerts/server/alerts_client/alerts_client.ts
+++ b/x-pack/plugins/alerts/server/alerts_client/alerts_client.ts
@@ -23,13 +23,13 @@ import {
RawAlert,
AlertTypeRegistry,
AlertAction,
- AlertType,
IntervalSchedule,
SanitizedAlert,
AlertTaskState,
AlertInstanceSummary,
AlertExecutionStatusValues,
AlertNotifyWhenType,
+ AlertTypeParams,
} from '../types';
import {
validateAlertTypeParams,
@@ -44,7 +44,7 @@ import { EncryptedSavedObjectsClient } from '../../../encrypted_saved_objects/se
import { TaskManagerStartContract } from '../../../task_manager/server';
import { taskInstanceToAlertTaskInstance } from '../task_runner/alert_task_instance';
import { deleteTaskIfItExists } from '../lib/delete_task_if_it_exists';
-import { RegistryAlertType } from '../alert_type_registry';
+import { RegistryAlertType, UntypedNormalizedAlertType } from '../alert_type_registry';
import { AlertsAuthorization, WriteOperations, ReadOperations } from '../authorization';
import { IEventLogClient } from '../../../../plugins/event_log/server';
import { parseIsoOrRelativeDate } from '../lib/iso_or_relative_date';
@@ -127,16 +127,16 @@ interface AggregateResult {
alertExecutionStatus: { [status: string]: number };
}
-export interface FindResult {
+export interface FindResult {
page: number;
perPage: number;
total: number;
- data: SanitizedAlert[];
+ data: Array>;
}
-export interface CreateOptions {
+export interface CreateOptions {
data: Omit<
- Alert,
+ Alert,
| 'id'
| 'createdBy'
| 'updatedBy'
@@ -154,14 +154,14 @@ export interface CreateOptions {
};
}
-interface UpdateOptions {
+interface UpdateOptions {
id: string;
data: {
name: string;
tags: string[];
schedule: IntervalSchedule;
actions: NormalizedAlertAction[];
- params: Record;
+ params: Params;
throttle: string | null;
notifyWhen: AlertNotifyWhenType | null;
};
@@ -223,7 +223,10 @@ export class AlertsClient {
this.auditLogger = auditLogger;
}
- public async create({ data, options }: CreateOptions): Promise {
+ public async create({
+ data,
+ options,
+ }: CreateOptions): Promise> {
const id = SavedObjectsUtils.generateId();
try {
@@ -248,7 +251,10 @@ export class AlertsClient {
// Throws an error if alert type isn't registered
const alertType = this.alertTypeRegistry.get(data.alertTypeId);
- const validatedAlertTypeParams = validateAlertTypeParams(alertType, data.params);
+ const validatedAlertTypeParams = validateAlertTypeParams(
+ data.params,
+ alertType.validate?.params
+ );
const username = await this.getUserName();
const createdAPIKey = data.enabled
@@ -334,10 +340,14 @@ export class AlertsClient {
});
createdAlert.attributes.scheduledTaskId = scheduledTask.id;
}
- return this.getAlertFromRaw(createdAlert.id, createdAlert.attributes, references);
+ return this.getAlertFromRaw(createdAlert.id, createdAlert.attributes, references);
}
- public async get({ id }: { id: string }): Promise {
+ public async get({
+ id,
+ }: {
+ id: string;
+ }): Promise> {
const result = await this.unsecuredSavedObjectsClient.get('alert', id);
try {
await this.authorization.ensureAuthorized(
@@ -361,7 +371,7 @@ export class AlertsClient {
savedObject: { type: 'alert', id },
})
);
- return this.getAlertFromRaw(result.id, result.attributes, result.references);
+ return this.getAlertFromRaw(result.id, result.attributes, result.references);
}
public async getAlertState({ id }: { id: string }): Promise {
@@ -426,9 +436,9 @@ export class AlertsClient {
});
}
- public async find({
+ public async find({
options: { fields, ...options } = {},
- }: { options?: FindOptions } = {}): Promise {
+ }: { options?: FindOptions } = {}): Promise> {
let authorizationTuple;
try {
authorizationTuple = await this.authorization.getFindAuthorizationFilter();
@@ -475,7 +485,7 @@ export class AlertsClient {
);
throw error;
}
- return this.getAlertFromRaw(
+ return this.getAlertFromRaw(
id,
fields ? (pick(attributes, fields) as RawAlert) : attributes,
references
@@ -605,15 +615,21 @@ export class AlertsClient {
return removeResult;
}
- public async update({ id, data }: UpdateOptions): Promise {
+ public async update({
+ id,
+ data,
+ }: UpdateOptions): Promise> {
return await retryIfConflicts(
this.logger,
`alertsClient.update('${id}')`,
- async () => await this.updateWithOCC({ id, data })
+ async () => await this.updateWithOCC({ id, data })
);
}
- private async updateWithOCC({ id, data }: UpdateOptions): Promise {
+ private async updateWithOCC({
+ id,
+ data,
+ }: UpdateOptions): Promise> {
let alertSavedObject: SavedObject;
try {
@@ -658,7 +674,7 @@ export class AlertsClient {
this.alertTypeRegistry.ensureAlertTypeEnabled(alertSavedObject.attributes.alertTypeId);
- const updateResult = await this.updateAlert({ id, data }, alertSavedObject);
+ const updateResult = await this.updateAlert({ id, data }, alertSavedObject);
await Promise.all([
alertSavedObject.attributes.apiKey
@@ -692,14 +708,17 @@ export class AlertsClient {
return updateResult;
}
- private async updateAlert(
- { id, data }: UpdateOptions,
+ private async updateAlert(
+ { id, data }: UpdateOptions,
{ attributes, version }: SavedObject
- ): Promise {
+ ): Promise> {
const alertType = this.alertTypeRegistry.get(attributes.alertTypeId);
// Validate
- const validatedAlertTypeParams = validateAlertTypeParams(alertType, data.params);
+ const validatedAlertTypeParams = validateAlertTypeParams(
+ data.params,
+ alertType.validate?.params
+ );
this.validateActions(alertType, data.actions);
const { actions, references } = await this.denormalizeActions(data.actions);
@@ -1343,7 +1362,7 @@ export class AlertsClient {
}) as Alert['actions'];
}
- private getAlertFromRaw(
+ private getAlertFromRaw(
id: string,
rawAlert: RawAlert,
references: SavedObjectReference[] | undefined
@@ -1351,14 +1370,14 @@ export class AlertsClient {
// In order to support the partial update API of Saved Objects we have to support
// partial updates of an Alert, but when we receive an actual RawAlert, it is safe
// to cast the result to an Alert
- return this.getPartialAlertFromRaw(id, rawAlert, references) as Alert;
+ return this.getPartialAlertFromRaw(id, rawAlert, references) as Alert;
}
- private getPartialAlertFromRaw(
+ private getPartialAlertFromRaw(
id: string,
{ createdAt, updatedAt, meta, notifyWhen, scheduledTaskId, ...rawAlert }: Partial,
references: SavedObjectReference[] | undefined
- ): PartialAlert {
+ ): PartialAlert {
// Not the prettiest code here, but if we want to use most of the
// alert fields from the rawAlert using `...rawAlert` kind of access, we
// need to specifically delete the executionStatus as it's a different type
@@ -1386,7 +1405,10 @@ export class AlertsClient {
};
}
- private validateActions(alertType: AlertType, actions: NormalizedAlertAction[]): void {
+ private validateActions(
+ alertType: UntypedNormalizedAlertType,
+ actions: NormalizedAlertAction[]
+ ): void {
const { actionGroups: alertTypeActionGroups } = alertType;
const usedAlertActionGroups = actions.map((action) => action.group);
const availableAlertTypeActionGroups = new Set(map(alertTypeActionGroups, 'id'));
diff --git a/x-pack/plugins/alerts/server/alerts_client/tests/create.test.ts b/x-pack/plugins/alerts/server/alerts_client/tests/create.test.ts
index 5f830a6c5bc51..0424a1295c9b9 100644
--- a/x-pack/plugins/alerts/server/alerts_client/tests/create.test.ts
+++ b/x-pack/plugins/alerts/server/alerts_client/tests/create.test.ts
@@ -59,7 +59,11 @@ beforeEach(() => {
setGlobalDate();
-function getMockData(overwrites: Record = {}): CreateOptions['data'] {
+function getMockData(
+ overwrites: Record = {}
+): CreateOptions<{
+ bar: boolean;
+}>['data'] {
return {
enabled: true,
name: 'abc',
@@ -93,7 +97,11 @@ describe('create()', () => {
});
describe('authorization', () => {
- function tryToExecuteOperation(options: CreateOptions): Promise {
+ function tryToExecuteOperation(
+ options: CreateOptions<{
+ bar: boolean;
+ }>
+ ): Promise {
unsecuredSavedObjectsClient.bulkGet.mockResolvedValueOnce({
saved_objects: [
{
diff --git a/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.test.ts b/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.test.ts
index d6357494546b0..0f91e5d0c24a9 100644
--- a/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.test.ts
+++ b/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.test.ts
@@ -635,11 +635,11 @@ export class EventsFactory {
}
}
-function createAlert(overrides: Partial): SanitizedAlert {
+function createAlert(overrides: Partial): SanitizedAlert<{ bar: boolean }> {
return { ...BaseAlert, ...overrides };
}
-const BaseAlert: SanitizedAlert = {
+const BaseAlert: SanitizedAlert<{ bar: boolean }> = {
id: 'alert-123',
alertTypeId: '123',
schedule: { interval: '10s' },
diff --git a/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.ts b/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.ts
index f540f9a9b884c..a020eecd448a4 100644
--- a/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.ts
+++ b/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.ts
@@ -9,7 +9,7 @@ import { IEvent } from '../../../event_log/server';
import { EVENT_LOG_ACTIONS, EVENT_LOG_PROVIDER, LEGACY_EVENT_LOG_ACTIONS } from '../plugin';
export interface AlertInstanceSummaryFromEventLogParams {
- alert: SanitizedAlert;
+ alert: SanitizedAlert<{ bar: boolean }>;
events: IEvent[];
dateStart: string;
dateEnd: string;
diff --git a/x-pack/plugins/alerts/server/lib/validate_alert_type_params.test.ts b/x-pack/plugins/alerts/server/lib/validate_alert_type_params.test.ts
index 2814eaef3e02a..634b6885aa59b 100644
--- a/x-pack/plugins/alerts/server/lib/validate_alert_type_params.test.ts
+++ b/x-pack/plugins/alerts/server/lib/validate_alert_type_params.test.ts
@@ -8,51 +8,19 @@ import { schema } from '@kbn/config-schema';
import { validateAlertTypeParams } from './validate_alert_type_params';
test('should return passed in params when validation not defined', () => {
- const result = validateAlertTypeParams(
- {
- id: 'my-alert-type',
- name: 'My description',
- actionGroups: [
- {
- id: 'default',
- name: 'Default',
- },
- ],
- defaultActionGroupId: 'default',
- minimumLicenseRequired: 'basic',
- async executor() {},
- producer: 'alerts',
- },
- {
- foo: true,
- }
- );
+ const result = validateAlertTypeParams({
+ foo: true,
+ });
expect(result).toEqual({ foo: true });
});
test('should validate and apply defaults when params is valid', () => {
const result = validateAlertTypeParams(
- {
- id: 'my-alert-type',
- name: 'My description',
- actionGroups: [
- {
- id: 'default',
- name: 'Default',
- },
- ],
- defaultActionGroupId: 'default',
- minimumLicenseRequired: 'basic',
- validate: {
- params: schema.object({
- param1: schema.string(),
- param2: schema.string({ defaultValue: 'default-value' }),
- }),
- },
- async executor() {},
- producer: 'alerts',
- },
- { param1: 'value' }
+ { param1: 'value' },
+ schema.object({
+ param1: schema.string(),
+ param2: schema.string({ defaultValue: 'default-value' }),
+ })
);
expect(result).toEqual({
param1: 'value',
@@ -63,26 +31,10 @@ test('should validate and apply defaults when params is valid', () => {
test('should validate and throw error when params is invalid', () => {
expect(() =>
validateAlertTypeParams(
- {
- id: 'my-alert-type',
- name: 'My description',
- actionGroups: [
- {
- id: 'default',
- name: 'Default',
- },
- ],
- defaultActionGroupId: 'default',
- minimumLicenseRequired: 'basic',
- validate: {
- params: schema.object({
- param1: schema.string(),
- }),
- },
- async executor() {},
- producer: 'alerts',
- },
- {}
+ {},
+ schema.object({
+ param1: schema.string(),
+ })
)
).toThrowErrorMatchingInlineSnapshot(
`"params invalid: [param1]: expected value of type [string] but got [undefined]"`
diff --git a/x-pack/plugins/alerts/server/lib/validate_alert_type_params.ts b/x-pack/plugins/alerts/server/lib/validate_alert_type_params.ts
index a443143d8cbde..2f510f90a2367 100644
--- a/x-pack/plugins/alerts/server/lib/validate_alert_type_params.ts
+++ b/x-pack/plugins/alerts/server/lib/validate_alert_type_params.ts
@@ -5,15 +5,14 @@
*/
import Boom from '@hapi/boom';
-import { AlertType, AlertExecutorOptions } from '../types';
+import { AlertTypeParams, AlertTypeParamsValidator } from '../types';
-export function validateAlertTypeParams(
- alertType: AlertType,
- params: Record
-): AlertExecutorOptions['params'] {
- const validator = alertType.validate && alertType.validate.params;
+export function validateAlertTypeParams(
+ params: Record,
+ validator?: AlertTypeParamsValidator
+): Params {
if (!validator) {
- return params as AlertExecutorOptions['params'];
+ return params as Params;
}
try {
diff --git a/x-pack/plugins/alerts/server/mocks.ts b/x-pack/plugins/alerts/server/mocks.ts
index cfae4c650bd42..0f042b7a81d6c 100644
--- a/x-pack/plugins/alerts/server/mocks.ts
+++ b/x-pack/plugins/alerts/server/mocks.ts
@@ -11,6 +11,7 @@ import {
elasticsearchServiceMock,
savedObjectsClientMock,
} from '../../../../src/core/server/mocks';
+import { AlertInstanceContext, AlertInstanceState } from './types';
export { alertsClientMock };
@@ -30,8 +31,14 @@ const createStartMock = () => {
return mock;
};
-export type AlertInstanceMock = jest.Mocked;
-const createAlertInstanceFactoryMock = () => {
+export type AlertInstanceMock<
+ State extends AlertInstanceState = AlertInstanceState,
+ Context extends AlertInstanceContext = AlertInstanceContext
+> = jest.Mocked>;
+const createAlertInstanceFactoryMock = <
+ InstanceState extends AlertInstanceState = AlertInstanceState,
+ InstanceContext extends AlertInstanceContext = AlertInstanceContext
+>() => {
const mock = {
hasScheduledActions: jest.fn(),
isThrottled: jest.fn(),
@@ -50,14 +57,17 @@ const createAlertInstanceFactoryMock = () => {
mock.unscheduleActions.mockReturnValue(mock);
mock.scheduleActions.mockReturnValue(mock);
- return (mock as unknown) as AlertInstanceMock;
+ return (mock as unknown) as AlertInstanceMock;
};
-const createAlertServicesMock = () => {
- const alertInstanceFactoryMock = createAlertInstanceFactoryMock();
+const createAlertServicesMock = <
+ InstanceState extends AlertInstanceState = AlertInstanceState,
+ InstanceContext extends AlertInstanceContext = AlertInstanceContext
+>() => {
+ const alertInstanceFactoryMock = createAlertInstanceFactoryMock();
return {
alertInstanceFactory: jest
- .fn, [string]>()
+ .fn>, [string]>()
.mockReturnValue(alertInstanceFactoryMock),
callCluster: elasticsearchServiceMock.createLegacyScopedClusterClient().callAsCurrentUser,
getLegacyScopedClusterClient: jest.fn(),
diff --git a/x-pack/plugins/alerts/server/routes/create.test.ts b/x-pack/plugins/alerts/server/routes/create.test.ts
index 5597b315158cd..fc531821f25b6 100644
--- a/x-pack/plugins/alerts/server/routes/create.test.ts
+++ b/x-pack/plugins/alerts/server/routes/create.test.ts
@@ -49,7 +49,7 @@ describe('createAlertRoute', () => {
],
};
- const createResult: Alert = {
+ const createResult: Alert<{ bar: boolean }> = {
...mockedAlert,
enabled: true,
muteAll: false,
diff --git a/x-pack/plugins/alerts/server/routes/create.ts b/x-pack/plugins/alerts/server/routes/create.ts
index a34a3118985fa..a79a9d40b236f 100644
--- a/x-pack/plugins/alerts/server/routes/create.ts
+++ b/x-pack/plugins/alerts/server/routes/create.ts
@@ -16,7 +16,13 @@ import { ILicenseState } from '../lib/license_state';
import { verifyApiAccess } from '../lib/license_api_access';
import { validateDurationSchema } from '../lib';
import { handleDisabledApiKeysError } from './lib/error_handler';
-import { Alert, AlertNotifyWhenType, BASE_ALERT_API_PATH, validateNotifyWhenType } from '../types';
+import {
+ Alert,
+ AlertNotifyWhenType,
+ AlertTypeParams,
+ BASE_ALERT_API_PATH,
+ validateNotifyWhenType,
+} from '../types';
import { AlertTypeDisabledError } from '../lib/errors/alert_type_disabled';
export const bodySchema = schema.object({
@@ -65,7 +71,9 @@ export const createAlertRoute = (router: IRouter, licenseState: ILicenseState) =
const alert = req.body;
const notifyWhen = alert?.notifyWhen ? (alert.notifyWhen as AlertNotifyWhenType) : null;
try {
- const alertRes: Alert = await alertsClient.create({ data: { ...alert, notifyWhen } });
+ const alertRes: Alert = await alertsClient.create({
+ data: { ...alert, notifyWhen },
+ });
return res.ok({
body: alertRes,
});
diff --git a/x-pack/plugins/alerts/server/routes/get.test.ts b/x-pack/plugins/alerts/server/routes/get.test.ts
index 21e52ece82d2d..747f9b11e2b47 100644
--- a/x-pack/plugins/alerts/server/routes/get.test.ts
+++ b/x-pack/plugins/alerts/server/routes/get.test.ts
@@ -22,7 +22,9 @@ beforeEach(() => {
});
describe('getAlertRoute', () => {
- const mockedAlert: Alert = {
+ const mockedAlert: Alert<{
+ bar: true;
+ }> = {
id: '1',
alertTypeId: '1',
schedule: { interval: '10s' },
diff --git a/x-pack/plugins/alerts/server/task_runner/alert_task_instance.test.ts b/x-pack/plugins/alerts/server/task_runner/alert_task_instance.test.ts
index 09236ec5e0ad1..1bd8b75e2133d 100644
--- a/x-pack/plugins/alerts/server/task_runner/alert_task_instance.test.ts
+++ b/x-pack/plugins/alerts/server/task_runner/alert_task_instance.test.ts
@@ -9,7 +9,9 @@ import { AlertTaskInstance, taskInstanceToAlertTaskInstance } from './alert_task
import uuid from 'uuid';
import { SanitizedAlert } from '../types';
-const alert: SanitizedAlert = {
+const alert: SanitizedAlert<{
+ bar: boolean;
+}> = {
id: 'alert-123',
alertTypeId: '123',
schedule: { interval: '10s' },
diff --git a/x-pack/plugins/alerts/server/task_runner/alert_task_instance.ts b/x-pack/plugins/alerts/server/task_runner/alert_task_instance.ts
index a290f3fa33c70..ab074cfdffa1c 100644
--- a/x-pack/plugins/alerts/server/task_runner/alert_task_instance.ts
+++ b/x-pack/plugins/alerts/server/task_runner/alert_task_instance.ts
@@ -13,6 +13,7 @@ import {
alertParamsSchema,
alertStateSchema,
AlertTaskParams,
+ AlertTypeParams,
} from '../../common';
export interface AlertTaskInstance extends ConcreteTaskInstance {
@@ -23,9 +24,9 @@ export interface AlertTaskInstance extends ConcreteTaskInstance {
const enumerateErrorFields = (e: t.Errors) =>
`${e.map(({ context }) => context.map(({ key }) => key).join('.'))}`;
-export function taskInstanceToAlertTaskInstance(
+export function taskInstanceToAlertTaskInstance(
taskInstance: ConcreteTaskInstance,
- alert?: SanitizedAlert
+ alert?: SanitizedAlert
): AlertTaskInstance {
return {
...taskInstance,
diff --git a/x-pack/plugins/alerts/server/task_runner/create_execution_handler.test.ts b/x-pack/plugins/alerts/server/task_runner/create_execution_handler.test.ts
index b414e726f0101..5603b13a3b1f5 100644
--- a/x-pack/plugins/alerts/server/task_runner/create_execution_handler.test.ts
+++ b/x-pack/plugins/alerts/server/task_runner/create_execution_handler.test.ts
@@ -4,8 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { AlertType } from '../types';
-import { createExecutionHandler } from './create_execution_handler';
+import { createExecutionHandler, CreateExecutionHandlerOptions } from './create_execution_handler';
import { loggingSystemMock } from '../../../../../src/core/server/mocks';
import {
actionsMock,
@@ -16,12 +15,19 @@ import { eventLoggerMock } from '../../../event_log/server/event_logger.mock';
import { KibanaRequest } from 'kibana/server';
import { asSavedObjectExecutionSource } from '../../../actions/server';
import { InjectActionParamsOpts } from './inject_action_params';
+import { UntypedNormalizedAlertType } from '../alert_type_registry';
+import {
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext,
+} from '../types';
jest.mock('./inject_action_params', () => ({
injectActionParams: jest.fn(),
}));
-const alertType: AlertType = {
+const alertType: UntypedNormalizedAlertType = {
id: 'test',
name: 'Test',
actionGroups: [
@@ -39,18 +45,26 @@ const alertType: AlertType = {
};
const actionsClient = actionsClientMock.create();
-const createExecutionHandlerParams = {
- actionsPlugin: actionsMock.createStart(),
+
+const mockActionsPlugin = actionsMock.createStart();
+const mockEventLogger = eventLoggerMock.create();
+const createExecutionHandlerParams: jest.Mocked<
+ CreateExecutionHandlerOptions<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+ >
+> = {
+ actionsPlugin: mockActionsPlugin,
spaceId: 'default',
alertId: '1',
alertName: 'name-of-alert',
tags: ['tag-A', 'tag-B'],
apiKey: 'MTIzOmFiYw==',
- spaceIdToNamespace: jest.fn().mockReturnValue(undefined),
- getBasePath: jest.fn().mockReturnValue(undefined),
alertType,
logger: loggingSystemMock.create().get(),
- eventLogger: eventLoggerMock.create(),
+ eventLogger: mockEventLogger,
actions: [
{
id: '1',
@@ -79,12 +93,10 @@ beforeEach(() => {
.injectActionParams.mockImplementation(
({ actionParams }: InjectActionParamsOpts) => actionParams
);
- createExecutionHandlerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true);
- createExecutionHandlerParams.actionsPlugin.isActionExecutable.mockReturnValue(true);
- createExecutionHandlerParams.actionsPlugin.getActionsClientWithRequest.mockResolvedValue(
- actionsClient
- );
- createExecutionHandlerParams.actionsPlugin.renderActionParameterTemplates.mockImplementation(
+ mockActionsPlugin.isActionTypeEnabled.mockReturnValue(true);
+ mockActionsPlugin.isActionExecutable.mockReturnValue(true);
+ mockActionsPlugin.getActionsClientWithRequest.mockResolvedValue(actionsClient);
+ mockActionsPlugin.renderActionParameterTemplates.mockImplementation(
renderActionParameterTemplatesDefault
);
});
@@ -97,9 +109,9 @@ test('enqueues execution per selected action', async () => {
context: {},
alertInstanceId: '2',
});
- expect(
- createExecutionHandlerParams.actionsPlugin.getActionsClientWithRequest
- ).toHaveBeenCalledWith(createExecutionHandlerParams.request);
+ expect(mockActionsPlugin.getActionsClientWithRequest).toHaveBeenCalledWith(
+ createExecutionHandlerParams.request
+ );
expect(actionsClient.enqueueExecution).toHaveBeenCalledTimes(1);
expect(actionsClient.enqueueExecution.mock.calls[0]).toMatchInlineSnapshot(`
Array [
@@ -124,9 +136,8 @@ test('enqueues execution per selected action', async () => {
]
`);
- const eventLogger = createExecutionHandlerParams.eventLogger;
- expect(eventLogger.logEvent).toHaveBeenCalledTimes(1);
- expect(eventLogger.logEvent.mock.calls).toMatchInlineSnapshot(`
+ expect(mockEventLogger.logEvent).toHaveBeenCalledTimes(1);
+ expect(mockEventLogger.logEvent.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
Object {
@@ -171,9 +182,9 @@ test('enqueues execution per selected action', async () => {
test(`doesn't call actionsPlugin.execute for disabled actionTypes`, async () => {
// Mock two calls, one for check against actions[0] and the second for actions[1]
- createExecutionHandlerParams.actionsPlugin.isActionExecutable.mockReturnValueOnce(false);
- createExecutionHandlerParams.actionsPlugin.isActionTypeEnabled.mockReturnValueOnce(false);
- createExecutionHandlerParams.actionsPlugin.isActionTypeEnabled.mockReturnValueOnce(true);
+ mockActionsPlugin.isActionExecutable.mockReturnValueOnce(false);
+ mockActionsPlugin.isActionTypeEnabled.mockReturnValueOnce(false);
+ mockActionsPlugin.isActionTypeEnabled.mockReturnValueOnce(true);
const executionHandler = createExecutionHandler({
...createExecutionHandlerParams,
actions: [
@@ -214,9 +225,9 @@ test(`doesn't call actionsPlugin.execute for disabled actionTypes`, async () =>
});
test('trow error error message when action type is disabled', async () => {
- createExecutionHandlerParams.actionsPlugin.preconfiguredActions = [];
- createExecutionHandlerParams.actionsPlugin.isActionExecutable.mockReturnValue(false);
- createExecutionHandlerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(false);
+ mockActionsPlugin.preconfiguredActions = [];
+ mockActionsPlugin.isActionExecutable.mockReturnValue(false);
+ mockActionsPlugin.isActionTypeEnabled.mockReturnValue(false);
const executionHandler = createExecutionHandler({
...createExecutionHandlerParams,
actions: [
@@ -243,7 +254,7 @@ test('trow error error message when action type is disabled', async () => {
expect(actionsClient.enqueueExecution).toHaveBeenCalledTimes(0);
- createExecutionHandlerParams.actionsPlugin.isActionExecutable.mockImplementation(() => true);
+ mockActionsPlugin.isActionExecutable.mockImplementation(() => true);
const executionHandlerForPreconfiguredAction = createExecutionHandler({
...createExecutionHandlerParams,
actions: [...createExecutionHandlerParams.actions],
diff --git a/x-pack/plugins/alerts/server/task_runner/create_execution_handler.ts b/x-pack/plugins/alerts/server/task_runner/create_execution_handler.ts
index 8c7ad79483194..8b4412aeb23e5 100644
--- a/x-pack/plugins/alerts/server/task_runner/create_execution_handler.ts
+++ b/x-pack/plugins/alerts/server/task_runner/create_execution_handler.ts
@@ -15,14 +15,20 @@ import { EVENT_LOG_ACTIONS } from '../plugin';
import { injectActionParams } from './inject_action_params';
import {
AlertAction,
+ AlertTypeParams,
+ AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
- AlertType,
- AlertTypeParams,
RawAlert,
} from '../types';
+import { NormalizedAlertType } from '../alert_type_registry';
-interface CreateExecutionHandlerOptions {
+export interface CreateExecutionHandlerOptions<
+ Params extends AlertTypeParams,
+ State extends AlertTypeState,
+ InstanceState extends AlertInstanceState,
+ InstanceContext extends AlertInstanceContext
+> {
alertId: string;
alertName: string;
tags?: string[];
@@ -30,7 +36,7 @@ interface CreateExecutionHandlerOptions {
actions: AlertAction[];
spaceId: string;
apiKey: RawAlert['apiKey'];
- alertType: AlertType;
+ alertType: NormalizedAlertType;
logger: Logger;
eventLogger: IEventLogger;
request: KibanaRequest;
@@ -45,7 +51,12 @@ interface ExecutionHandlerOptions {
state: AlertInstanceState;
}
-export function createExecutionHandler({
+export function createExecutionHandler<
+ Params extends AlertTypeParams,
+ State extends AlertTypeState,
+ InstanceState extends AlertInstanceState,
+ InstanceContext extends AlertInstanceContext
+>({
logger,
alertId,
alertName,
@@ -58,7 +69,7 @@ export function createExecutionHandler({
eventLogger,
request,
alertParams,
-}: CreateExecutionHandlerOptions) {
+}: CreateExecutionHandlerOptions) {
const alertTypeActionGroups = new Map(
alertType.actionGroups.map((actionGroup) => [actionGroup.id, actionGroup.name])
);
diff --git a/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts b/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts
index a4b565194e431..967c5263b9730 100644
--- a/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts
+++ b/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts
@@ -6,7 +6,13 @@
import sinon from 'sinon';
import { schema } from '@kbn/config-schema';
-import { AlertExecutorOptions } from '../types';
+import {
+ AlertExecutorOptions,
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext,
+} from '../types';
import {
ConcreteTaskInstance,
isUnrecoverableError,
@@ -28,9 +34,9 @@ import { IEventLogger } from '../../../event_log/server';
import { SavedObjectsErrorHelpers } from '../../../../../src/core/server';
import { Alert, RecoveredActionGroup } from '../../common';
import { omit } from 'lodash';
-import { NormalizedAlertType } from '../alert_type_registry';
+import { UntypedNormalizedAlertType } from '../alert_type_registry';
import { alertTypeRegistryMock } from '../alert_type_registry.mock';
-const alertType = {
+const alertType: jest.Mocked = {
id: 'test',
name: 'My test alert',
actionGroups: [{ id: 'default', name: 'Default' }, RecoveredActionGroup],
@@ -91,7 +97,7 @@ describe('Task Runner', () => {
alertTypeRegistry,
};
- const mockedAlertTypeSavedObject: Alert = {
+ const mockedAlertTypeSavedObject: Alert = {
id: '1',
consumer: 'bar',
createdAt: new Date('2019-02-12T21:01:22.479Z'),
@@ -150,7 +156,7 @@ describe('Task Runner', () => {
test('successfully executes the task', async () => {
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
{
...mockedTaskInstance,
state: {
@@ -254,14 +260,21 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true);
taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true);
alertType.executor.mockImplementation(
- ({ services: executorServices }: AlertExecutorOptions) => {
+ async ({
+ services: executorServices,
+ }: AlertExecutorOptions<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+ >) => {
executorServices
.alertInstanceFactory('1')
.scheduleActionsWithSubGroup('default', 'subDefault');
}
);
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -407,12 +420,19 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true);
taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true);
alertType.executor.mockImplementation(
- ({ services: executorServices }: AlertExecutorOptions) => {
+ async ({
+ services: executorServices,
+ }: AlertExecutorOptions<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+ >) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
);
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -516,13 +536,20 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true);
taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true);
alertType.executor.mockImplementation(
- ({ services: executorServices }: AlertExecutorOptions) => {
+ async ({
+ services: executorServices,
+ }: AlertExecutorOptions<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+ >) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
executorServices.alertInstanceFactory('2').scheduleActions('default');
}
);
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -562,12 +589,19 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true);
taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true);
alertType.executor.mockImplementation(
- ({ services: executorServices }: AlertExecutorOptions) => {
+ async ({
+ services: executorServices,
+ }: AlertExecutorOptions<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+ >) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
);
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
{
...mockedTaskInstance,
state: {
@@ -656,12 +690,19 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true);
taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true);
alertType.executor.mockImplementation(
- ({ services: executorServices }: AlertExecutorOptions) => {
+ async ({
+ services: executorServices,
+ }: AlertExecutorOptions<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+ >) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
);
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
{
...mockedTaskInstance,
state: {
@@ -696,14 +737,21 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true);
taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true);
alertType.executor.mockImplementation(
- ({ services: executorServices }: AlertExecutorOptions) => {
+ async ({
+ services: executorServices,
+ }: AlertExecutorOptions<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+ >) => {
executorServices
.alertInstanceFactory('1')
.scheduleActionsWithSubGroup('default', 'subgroup1');
}
);
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
{
...mockedTaskInstance,
state: {
@@ -744,12 +792,19 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true);
taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true);
alertType.executor.mockImplementation(
- ({ services: executorServices }: AlertExecutorOptions) => {
+ async ({
+ services: executorServices,
+ }: AlertExecutorOptions<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+ >) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
);
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -912,12 +967,19 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true);
alertType.executor.mockImplementation(
- ({ services: executorServices }: AlertExecutorOptions) => {
+ async ({
+ services: executorServices,
+ }: AlertExecutorOptions<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+ >) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
);
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
{
...mockedTaskInstance,
state: {
@@ -1012,12 +1074,19 @@ describe('Task Runner', () => {
};
alertTypeWithCustomRecovery.executor.mockImplementation(
- ({ services: executorServices }: AlertExecutorOptions) => {
+ async ({
+ services: executorServices,
+ }: AlertExecutorOptions<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+ >) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
);
const taskRunner = new TaskRunner(
- alertTypeWithCustomRecovery as NormalizedAlertType,
+ alertTypeWithCustomRecovery,
{
...mockedTaskInstance,
state: {
@@ -1103,13 +1172,20 @@ describe('Task Runner', () => {
test('persists alertInstances passed in from state, only if they are scheduled for execution', async () => {
alertType.executor.mockImplementation(
- ({ services: executorServices }: AlertExecutorOptions) => {
+ async ({
+ services: executorServices,
+ }: AlertExecutorOptions<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+ >) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
);
const date = new Date().toISOString();
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
{
...mockedTaskInstance,
state: {
@@ -1239,7 +1315,7 @@ describe('Task Runner', () => {
param1: schema.string(),
}),
},
- } as NormalizedAlertType,
+ },
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -1267,7 +1343,7 @@ describe('Task Runner', () => {
test('uses API key when provided', async () => {
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -1300,7 +1376,7 @@ describe('Task Runner', () => {
test(`doesn't use API key when not provided`, async () => {
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -1330,7 +1406,7 @@ describe('Task Runner', () => {
test('rescheduled the Alert if the schedule has update during a task run', async () => {
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -1365,13 +1441,20 @@ describe('Task Runner', () => {
test('recovers gracefully when the AlertType executor throws an exception', async () => {
alertType.executor.mockImplementation(
- ({ services: executorServices }: AlertExecutorOptions) => {
+ async ({
+ services: executorServices,
+ }: AlertExecutorOptions<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+ >) => {
throw new Error('OMG');
}
);
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -1438,7 +1521,7 @@ describe('Task Runner', () => {
});
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -1497,7 +1580,7 @@ describe('Task Runner', () => {
});
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -1564,7 +1647,7 @@ describe('Task Runner', () => {
});
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -1631,7 +1714,7 @@ describe('Task Runner', () => {
});
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -1701,7 +1784,7 @@ describe('Task Runner', () => {
const legacyTaskInstance = omit(mockedTaskInstance, 'schedule');
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
legacyTaskInstance,
taskRunnerFactoryInitializerParams
);
@@ -1733,13 +1816,20 @@ describe('Task Runner', () => {
};
alertType.executor.mockImplementation(
- ({ services: executorServices }: AlertExecutorOptions) => {
+ async ({
+ services: executorServices,
+ }: AlertExecutorOptions<
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext
+ >) => {
throw new Error('OMG');
}
);
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
{
...mockedTaskInstance,
state: originalAlertSate,
@@ -1770,7 +1860,7 @@ describe('Task Runner', () => {
});
const taskRunner = new TaskRunner(
- alertType as NormalizedAlertType,
+ alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
diff --git a/x-pack/plugins/alerts/server/task_runner/task_runner.ts b/x-pack/plugins/alerts/server/task_runner/task_runner.ts
index 44cf7dd91be7d..c4187145e5a16 100644
--- a/x-pack/plugins/alerts/server/task_runner/task_runner.ts
+++ b/x-pack/plugins/alerts/server/task_runner/task_runner.ts
@@ -26,7 +26,6 @@ import {
RawAlertInstance,
AlertTaskState,
Alert,
- AlertExecutorOptions,
SanitizedAlert,
AlertExecutionStatus,
AlertExecutionStatusErrorReasons,
@@ -39,7 +38,13 @@ import { IEvent, IEventLogger, SAVED_OBJECT_REL_PRIMARY } from '../../../event_l
import { isAlertSavedObjectNotFoundError } from '../lib/is_alert_not_found_error';
import { AlertsClient } from '../alerts_client';
import { partiallyUpdateAlert } from '../saved_objects';
-import { ActionGroup } from '../../common';
+import {
+ ActionGroup,
+ AlertTypeParams,
+ AlertTypeState,
+ AlertInstanceState,
+ AlertInstanceContext,
+} from '../../common';
import { NormalizedAlertType } from '../alert_type_registry';
const FALLBACK_RETRY_INTERVAL = '5m';
@@ -55,15 +60,20 @@ interface AlertTaskInstance extends ConcreteTaskInstance {
state: AlertTaskState;
}
-export class TaskRunner {
+export class TaskRunner<
+ Params extends AlertTypeParams,
+ State extends AlertTypeState,
+ InstanceState extends AlertInstanceState,
+ InstanceContext extends AlertInstanceContext
+> {
private context: TaskRunnerContext;
private logger: Logger;
private taskInstance: AlertTaskInstance;
- private alertType: NormalizedAlertType;
+ private alertType: NormalizedAlertType;
private readonly alertTypeRegistry: AlertTypeRegistry;
constructor(
- alertType: NormalizedAlertType,
+ alertType: NormalizedAlertType,
taskInstance: ConcreteTaskInstance,
context: TaskRunnerContext
) {
@@ -131,8 +141,8 @@ export class TaskRunner {
tags: string[] | undefined,
spaceId: string,
apiKey: RawAlert['apiKey'],
- actions: Alert['actions'],
- alertParams: RawAlert['params']
+ actions: Alert['actions'],
+ alertParams: Params
) {
return createExecutionHandler({
alertId,
@@ -152,7 +162,7 @@ export class TaskRunner {
async executeAlertInstance(
alertInstanceId: string,
- alertInstance: AlertInstance,
+ alertInstance: AlertInstance,
executionHandler: ReturnType
) {
const {
@@ -168,8 +178,8 @@ export class TaskRunner {
async executeAlertInstances(
services: Services,
- alert: SanitizedAlert,
- params: AlertExecutorOptions['params'],
+ alert: SanitizedAlert,
+ params: Params,
executionHandler: ReturnType,
spaceId: string,
event: Event
@@ -190,9 +200,12 @@ export class TaskRunner {
} = this.taskInstance;
const namespace = this.context.spaceIdToNamespace(spaceId);
- const alertInstances = mapValues, AlertInstance>(
+ const alertInstances = mapValues<
+ Record,
+ AlertInstance
+ >(
alertRawInstances,
- (rawAlertInstance) => new AlertInstance(rawAlertInstance)
+ (rawAlertInstance) => new AlertInstance(rawAlertInstance)
);
const originalAlertInstances = cloneDeep(alertInstances);
@@ -205,10 +218,12 @@ export class TaskRunner {
alertId,
services: {
...services,
- alertInstanceFactory: createAlertInstanceFactory(alertInstances),
+ alertInstanceFactory: createAlertInstanceFactory(
+ alertInstances
+ ),
},
params,
- state: alertTypeState,
+ state: alertTypeState as State,
startedAt: this.taskInstance.startedAt!,
previousStartedAt: previousStartedAt ? new Date(previousStartedAt) : null,
spaceId,
@@ -232,12 +247,15 @@ export class TaskRunner {
event.event.outcome = 'success';
// Cleanup alert instances that are no longer scheduling actions to avoid over populating the alertInstances object
- const instancesWithScheduledActions = pickBy(alertInstances, (alertInstance: AlertInstance) =>
- alertInstance.hasScheduledActions()
+ const instancesWithScheduledActions = pickBy(
+ alertInstances,
+ (alertInstance: AlertInstance) =>
+ alertInstance.hasScheduledActions()
);
const recoveredAlertInstances = pickBy(
alertInstances,
- (alertInstance: AlertInstance) => !alertInstance.hasScheduledActions()
+ (alertInstance: AlertInstance) =>
+ !alertInstance.hasScheduledActions()
);
logActiveAndRecoveredInstances({
@@ -272,7 +290,10 @@ export class TaskRunner {
const instancesToExecute =
notifyWhen === 'onActionGroupChange'
? Object.entries(instancesWithScheduledActions).filter(
- ([alertInstanceName, alertInstance]: [string, AlertInstance]) => {
+ ([alertInstanceName, alertInstance]: [
+ string,
+ AlertInstance
+ ]) => {
const shouldExecuteAction = alertInstance.scheduledActionGroupOrSubgroupHasChanged();
if (!shouldExecuteAction) {
this.logger.debug(
@@ -283,7 +304,10 @@ export class TaskRunner {
}
)
: Object.entries(instancesWithScheduledActions).filter(
- ([alertInstanceName, alertInstance]: [string, AlertInstance]) => {
+ ([alertInstanceName, alertInstance]: [
+ string,
+ AlertInstance
+ ]) => {
const throttled = alertInstance.isThrottled(throttle);
const muted = mutedInstanceIdsSet.has(alertInstanceName);
const shouldExecuteAction = !throttled && !muted;
@@ -299,8 +323,9 @@ export class TaskRunner {
);
await Promise.all(
- instancesToExecute.map(([id, alertInstance]: [string, AlertInstance]) =>
- this.executeAlertInstance(id, alertInstance, executionHandler)
+ instancesToExecute.map(
+ ([id, alertInstance]: [string, AlertInstance]) =>
+ this.executeAlertInstance(id, alertInstance, executionHandler)
)
);
} else {
@@ -309,17 +334,17 @@ export class TaskRunner {
return {
alertTypeState: updatedAlertTypeState || undefined,
- alertInstances: mapValues, RawAlertInstance>(
- instancesWithScheduledActions,
- (alertInstance) => alertInstance.toRaw()
- ),
+ alertInstances: mapValues<
+ Record>,
+ RawAlertInstance
+ >(instancesWithScheduledActions, (alertInstance) => alertInstance.toRaw()),
};
}
async validateAndExecuteAlert(
services: Services,
apiKey: RawAlert['apiKey'],
- alert: SanitizedAlert,
+ alert: SanitizedAlert,
event: Event
) {
const {
@@ -327,7 +352,7 @@ export class TaskRunner {
} = this.taskInstance;
// Validate
- const validatedParams = validateAlertTypeParams(this.alertType, alert.params);
+ const validatedParams = validateAlertTypeParams(alert.params, this.alertType.validate?.params);
const executionHandler = this.getExecutionHandler(
alertId,
alert.name,
@@ -359,7 +384,7 @@ export class TaskRunner {
}
const [services, alertsClient] = this.getServicesWithSpaceLevelPermissions(spaceId, apiKey);
- let alert: SanitizedAlert;
+ let alert: SanitizedAlert;
// Ensure API key is still valid and user has access
try {
@@ -501,19 +526,23 @@ export class TaskRunner {
}
}
-interface GenerateNewAndRecoveredInstanceEventsParams {
+interface GenerateNewAndRecoveredInstanceEventsParams<
+ InstanceState extends AlertInstanceState,
+ InstanceContext extends AlertInstanceContext
+> {
eventLogger: IEventLogger;
- originalAlertInstances: Dictionary;
- currentAlertInstances: Dictionary;
- recoveredAlertInstances: Dictionary;
+ originalAlertInstances: Dictionary>;
+ currentAlertInstances: Dictionary>;
+ recoveredAlertInstances: Dictionary>;
alertId: string;
alertLabel: string;
namespace: string | undefined;
}
-function generateNewAndRecoveredInstanceEvents(
- params: GenerateNewAndRecoveredInstanceEventsParams
-) {
+function generateNewAndRecoveredInstanceEvents<
+ InstanceState extends AlertInstanceState,
+ InstanceContext extends AlertInstanceContext
+>(params: GenerateNewAndRecoveredInstanceEventsParams) {
const {
eventLogger,
alertId,
@@ -584,16 +613,22 @@ function generateNewAndRecoveredInstanceEvents(
}
}
-interface ScheduleActionsForRecoveredInstancesParams {
+interface ScheduleActionsForRecoveredInstancesParams<
+ InstanceState extends AlertInstanceState,
+ InstanceContext extends AlertInstanceContext
+> {
logger: Logger;
recoveryActionGroup: ActionGroup;
- recoveredAlertInstances: Dictionary;
+ recoveredAlertInstances: Dictionary>;
executionHandler: ReturnType;
mutedInstanceIdsSet: Set;
alertLabel: string;
}
-function scheduleActionsForRecoveredInstances(params: ScheduleActionsForRecoveredInstancesParams) {
+function scheduleActionsForRecoveredInstances<
+ InstanceState extends AlertInstanceState,
+ InstanceContext extends AlertInstanceContext
+>(params: ScheduleActionsForRecoveredInstancesParams) {
const {
logger,
recoveryActionGroup,
@@ -623,14 +658,20 @@ function scheduleActionsForRecoveredInstances(params: ScheduleActionsForRecovere
}
}
-interface LogActiveAndRecoveredInstancesParams {
+interface LogActiveAndRecoveredInstancesParams<
+ InstanceState extends AlertInstanceState,
+ InstanceContext extends AlertInstanceContext
+> {
logger: Logger;
- activeAlertInstances: Dictionary;
- recoveredAlertInstances: Dictionary;
+ activeAlertInstances: Dictionary